in src/ansible_collections/alibaba/apsarastack/plugins/modules/ali_instance.py [0:0]
def main():
argument_spec = common_argument_spec()
argument_spec.update(dict(
security_groups=dict(type='list', elements='str', aliases=['group_ids']),
availability_zone=dict(type='str', aliases=['zone_id', 'apsarastack_zone'],
fallback=(env_fallback, ['APSARASTACK_ZONE', 'APSARASTACK_ZONE_ID'])),
instance_type=dict(type='str', aliases=['type']),
image_id=dict(type='str', aliases=['image']),
count=dict(type='int', default=1),
count_tag=dict(type='str'),
vswitch_id=dict(type='str', aliases=['subnet_id']),
instance_name=dict(type='str', aliases=['name']),
host_name=dict(type='str'),
password=dict(type='str', no_log=True),
internet_charge_type=dict(type='str', default='PayByBandwidth', choices=['PayByBandwidth', 'PayByTraffic']),
max_bandwidth_in=dict(type='int', default=200),
max_bandwidth_out=dict(type='int', default=0),
system_disk_category=dict(type='str', default='cloud_efficiency', choices=['cloud_efficiency', 'cloud_ssd', 'cloud_essd']),
system_disk_size=dict(type='int', default=40),
system_disk_name=dict(type='str'),
system_disk_description=dict(type='str'),
force=dict(type='bool', default=False),
tags=dict(type='dict', aliases=['instance_tags']),
purge_tags=dict(type='bool', default=False),
state=dict(default='present', choices=['present', 'running', 'stopped', 'restarted', 'absent']),
description=dict(type='str'),
allocate_public_ip=dict(type='bool', aliases=['assign_public_ip'], default=False),
instance_charge_type=dict(type='str', default='PostPaid', choices=['PrePaid', 'PostPaid']),
period=dict(type='int', default=1),
auto_renew=dict(type='bool', default=False),
instance_ids=dict(type='list', elements='str'),
auto_renew_period=dict(type='int', choices=[1, 2, 3, 6, 12]),
key_name=dict(type='str', aliases=['keypair']),
user_data=dict(type='str'),
ram_role_name=dict(type='str'),
spot_price_limit=dict(type='float'),
spot_strategy=dict(type='str', default='NoSpot', choices=['NoSpot', 'SpotWithPriceLimit', 'SpotAsPriceGo']),
unique_suffix=dict(type='bool', default=False),
period_unit=dict(type='str', default='Month', choices=['Month', 'Week']),
dry_run=dict(type='bool', default=False),
include_data_disks=dict(type='bool', default=True)
)
)
module = AnsibleModule(argument_spec=argument_spec)
if HAS_FOOTMARK is False:
module.fail_json(msg=missing_required_lib('footmark'), exception=FOOTMARK_IMP_ERR)
ecs = ecs_connect(module)
host_name = module.params['host_name']
state = module.params['state']
instance_ids = module.params['instance_ids']
count_tag = module.params['count_tag']
count = module.params['count']
instance_name = module.params['instance_name']
force = module.params['force']
zone_id = module.params['availability_zone']
key_name = module.params['key_name']
tags = module.params['tags']
max_bandwidth_out = module.params['max_bandwidth_out']
instance_charge_type = module.params['instance_charge_type']
if instance_charge_type == "PrePaid":
module.params['spot_strategy'] = ''
changed = False
instances = []
if instance_ids:
if not isinstance(instance_ids, list):
module.fail_json(msg='The parameter instance_ids should be a list, aborting')
instances = ecs.describe_instances(zone_id=zone_id, instance_ids=instance_ids)
if not instances:
module.fail_json(msg="There are no instances in our record based on instance_ids {0}. "
"Please check it and try again.".format(instance_ids))
elif count_tag:
instances = ecs.describe_instances(zone_id=zone_id, tags=literal_eval(count_tag))
elif instance_name:
instances = ecs.describe_instances(zone_id=zone_id, instance_name=instance_name)
ids = []
if state == 'absent':
if len(instances) < 1:
module.fail_json(msg='Please specify ECS instances that you want to operate by using '
'parameters instance_ids, tags or instance_name, aborting')
try:
targets = []
for inst in instances:
if inst.status != 'stopped' and not force:
module.fail_json(msg="Instance is running, and please stop it or set 'force' as True.")
targets.append(inst.id)
if ecs.delete_instances(instance_ids=targets, force=force):
changed = True
ids.extend(targets)
module.exit_json(changed=changed, ids=ids, instances=[])
except Exception as e:
module.fail_json(msg='Delete instance got an error: {0}'.format(e))
if module.params['allocate_public_ip'] and max_bandwidth_out <= 0:
module.fail_json(msg="'max_bandwidth_out' should be greater than 0 when 'allocate_public_ip' is True.")
if not module.params['allocate_public_ip']:
module.params['max_bandwidth_out'] = 0
if state == 'present':
if not instance_ids:
if len(instances) > count:
for i in range(0, len(instances) - count):
inst = instances[len(instances) - 1]
if inst.status != 'stopped' and not force:
module.fail_json(msg="That to delete instance {0} is failed results from it is running, "
"and please stop it or set 'force' as True.".format(inst.id))
try:
if inst.terminate(force=force):
changed = False
except Exception as e:
module.fail_json(msg="Delete instance {0} got an error: {1}".format(inst.id, e))
instances.pop(len(instances) - 1)
else:
try:
if host_name and re.search(r"-\[\d+,\d+\]-", host_name):
module.fail_json(msg='Ordered hostname is not supported, If you want to add an ordered '
'suffix to the hostname, you can set unique_suffix to True')
new_instances = run_instance(module, ecs, count - len(instances))
if new_instances:
changed = False
instances.extend(new_instances)
except Exception as e:
module.fail_json(msg="Create new instances got an error: {0}".format(e))
# Security Group join/leave begin
security_groups = module.params['security_groups']
if security_groups:
if not isinstance(security_groups, list):
module.fail_json(msg='The parameter security_groups should be a list, aborting')
for inst in instances:
existing = inst.security_group_ids['security_group_id']
remove = list(set(existing).difference(set(security_groups)))
add = list(set(security_groups).difference(set(existing)))
for sg in remove:
if inst.leave_security_group(sg):
changed = True
for sg in add:
if inst.join_security_group(sg):
changed = True
# Security Group join/leave ends here
# Attach/Detach key pair
keypair_ids = []
for inst in instances:
if key_name is not None and key_name != inst.key_name:
if key_name == "":
if inst.detach_key_pair():
changed = True
else:
keypair_ids.append(inst.id)
if keypair_ids:
changed = ecs.attach_key_pair(instance_ids=keypair_ids, key_pair_name=key_name)
# Modify instance attribute
for inst in instances:
if modify_instance(module, inst):
changed = True
if inst.id not in ids:
ids.append(inst.id)
# Modify instance charge type
charge_type_ids = []
for inst in instances:
if inst.instance_charge_type != instance_charge_type:
charge_type_ids.append(inst.id)
if charge_type_ids:
params = {"instance_ids": charge_type_ids, "instance_charge_type": instance_charge_type,
"include_data_disks": module.params['include_data_disks'], "dry_run": module.params['dry_run'],
"auto_pay": True}
if instance_charge_type == 'PrePaid':
params['period'] = module.params['period']
params['period_unit'] = module.params['period_unit']
if ecs.modify_instance_charge_type(**params):
changed = True
wait_for_instance_modify_charge(ecs, charge_type_ids, instance_charge_type)
else:
if len(instances) < 1:
module.fail_json(msg='Please specify ECS instances that you want to operate by using '
'parameters instance_ids, tags or instance_name, aborting')
if state == 'running':
try:
targets = []
for inst in instances:
if modify_instance(module, inst):
changed = True
if inst.status != "running":
targets.append(inst.id)
ids.append(inst.id)
if targets and ecs.start_instances(instance_ids=targets):
changed = True
ids.extend(targets)
except Exception as e:
module.fail_json(msg='Start instances got an error: {0}'.format(e))
elif state == 'stopped':
try:
targets = []
for inst in instances:
if inst.status != "stopped":
targets.append(inst.id)
if targets and ecs.stop_instances(instance_ids=targets, force_stop=force):
changed = True
ids.extend(targets)
for inst in instances:
if modify_instance(module, inst):
changed = True
except Exception as e:
module.fail_json(msg='Stop instances got an error: {0}'.format(e))
elif state == 'restarted':
try:
targets = []
for inst in instances:
if modify_instance(module, inst):
changed = True
targets.append(inst.id)
if ecs.reboot_instances(instance_ids=targets, force_stop=module.params['force']):
changed = True
ids.extend(targets)
except Exception as e:
module.fail_json(msg='Reboot instances got an error: {0}'.format(e))
tags = module.params['tags']
if module.params['purge_tags']:
for inst in instances:
if not tags:
tags = inst.tags
try:
if inst.remove_tags(tags):
changed = True
except Exception as e:
module.fail_json(msg="{0}".format(e))
module.exit_json(changed=changed, instances=get_instances_info(ecs, ids))
if tags:
for inst in instances:
try:
if inst.add_tags(tags):
changed = True
except Exception as e:
module.fail_json(msg="{0}".format(e))
module.exit_json(changed=changed, instances=get_instances_info(ecs, ids))