def sync(resource, state, params, check_mode): if state == 'absent': vpc = _identify_vpc(resource, params) if not vpc: # trying to delete a non-existing vpc return False, None, None return delete(vpc, check_mode) else: vpc = _identify_vpc(resource, params, fail_nonexisting_id=True) if not vpc: # we're creating a VPC return create(resource, params, check_mode) # we're trying to update an existing VPC # check if it needs updating at all diff = vpcs_diff(params, vpc) current_tags = tag_utils.from_boto3(vpc.tags) tag_diff = tag_utils.get_diff(params['name'], params['tags'], current_tags) tags_to_update, tags_to_remove = tag_utils.from_diff( tag_diff, clear_existing=params['clear_tags']) # they don't differ, do nothing if not (diff or tags_to_update or tags_to_remove): return False, vpc, None # validate and perform the update validation.validate_update(['CidrBlock'], diff) return update(vpc, diff, tag_diff, params, check_mode)
def update(instance, instance_diff, tag_diff, params, check_mode): instance_before = ec2_instance_utils.result_from_remote(instance) diff = dict(before=instance_before) update_info = copy.deepcopy(diff['before']) for (attr, update_attr_func) in [ ('monitoring', update_monitoring), ('on_instance_initiated_shutdown', update_shutdown_behavior), ]: if attr in instance_diff: update_info[attr] = params[attr] update_attr_func(instance, params[attr], check_mode) if check_mode: updated_tags_preview = tag_utils.preview_updated_tags( instance_before['tags'], tag_diff, params['clear_tags']) update_info['tags'] = updated_tags_preview diff['after'] = update_info return True, update_info, diff if tag_diff: tags_to_update, tags_to_remove = tag_utils.from_diff( tag_diff, clear_existing=params['clear_tags']) if tags_to_update or tags_to_remove: tag_utils.update_resource(instance, tags_to_update, tags_to_remove) instance.reload() result = ec2_instance_utils.result_from_remote(instance) diff['after'] = result return True, result, diff
def update(vpc, diff, tag_diff, params, check_mode): if check_mode: return True, None, diff vpc_before_update = vpc.meta.data.copy() if 'InstanceTenancy' in diff: requested_tenancy = diff['InstanceTenancy']['after'] if requested_tenancy != 'default': raise errors.ValidationError( "instance_tenancy can only be changed to 'default'") vpc.meta.client.modify_vpc_tenancy( VpcId=vpc.id, InstanceTenancy=requested_tenancy, ) if tag_diff: tags_to_update, tags_to_remove = tag_utils.from_diff( tag_diff, clear_existing=params['clear_tags']) if tags_to_update or tags_to_remove: tag_utils.update_resource(vpc, tags_to_update, tags_to_remove) vpc.reload() return True, vpc, dict( before=vpc_before_update, after=vpc.meta.data, )
def update(subnet, diff, tag_diff, params, check_mode): if check_mode: return True, None, None before = ec2_subnet_utils.result_from_resource(subnet) if 'auto_assign_ip' in diff: subnet.meta.client.modify_subnet_attribute( SubnetId=subnet.id, MapPublicIpOnLaunch=dict( Value=diff['auto_assign_ip']['after'] ), ) if tag_diff: tags_to_update, tags_to_remove = tag_utils.from_diff( tag_diff, clear_existing=params['clear_tags'] ) if tags_to_update or tags_to_remove: tag_utils.update_resource(subnet, tags_to_update, tags_to_remove) subnet.reload() return True, subnet, dict( before=before, after=ec2_subnet_utils.result_from_resource(subnet) )
def update(ec2, gateway, gateway_diff, tag_diff, params, check_mode): diff = dict( before=ec2_internet_gateway_utils.result_from_remote(gateway), ) if 'vpc' in gateway_diff: # we run this in advance to verify that the referenced vpc exists _validate_vpc_attachment(ec2, gateway_diff['vpc']['after']) if check_mode: result = ec2_internet_gateway_utils.result_from_params( gateway.id, params['vpc'], params['name'], params['tags']) diff['after'] = result return True, result, diff if 'vpc' in gateway_diff: update_vpc_attachment(gateway, gateway_diff['vpc']['before'], gateway_diff['vpc']['after']) if tag_diff: tags_to_update, tags_to_remove = tag_utils.from_diff( tag_diff, clear_existing=params['clear_tags']) if tags_to_update or tags_to_remove: tag_utils.update_resource(gateway, tags_to_update, tags_to_remove) gateway.reload() result = ec2_internet_gateway_utils.result_from_remote(gateway) diff['after'] = result return True, result, diff
def check_update(instance, params): """ Checks if update is necessary, and if it is, reports what needs to be updated. """ diff = instances_diff(instance, params) current_tags = tag_utils.from_boto3(instance.tags) tag_diff = tag_utils.get_diff(params['name'], params['tags'], current_tags) tags_to_update, tags_to_remove = tag_utils.from_diff( tag_diff, clear_existing=params['clear_tags']) # they don't differ, do nothing to_update = diff or tags_to_update or tags_to_remove return to_update, diff, tag_diff
def process_eni_differences(ec2, eni, entity_before, entity_after, differences): for difference in differences: if difference == "description": eni.modify_attribute( Description={"Value": entity_after.description}) elif difference == "security_groups": # accepts ids, replaces existing eni.modify_attribute(Groups=entity_after.security_groups) elif difference == "tags": tag_diff = tag_utils.get_diff(None, entity_after.tags, entity_before.tags) # we always clear existing here because we've done the processing already tag_update, tag_remove = tag_utils.from_diff(tag_diff, clear_existing=True) tag_utils.update_resource(eni, tag_update, tag_remove) elif difference == "source_dest_check": eni.modify_attribute( SourceDestCheck={"Value": entity_after.source_dest_check}) elif difference == "state": # assumption: attaching requires the attachment parameter if entity_before.state == "detached": # detached -> attached do_new_attachment(ec2, eni, entity_after.attachment) else: # attached -> detached detach_and_wait(eni) elif difference == "attachment": # assumption: this is when modifying the attachment attribute, could be reattachment, # could be a modification of the device index or the keep on termination attribute # pure attachment/detachment is handled with a difference in "state", # so this ignores that case if "state" not in differences: attachment_differences = entity_before.attachment.differing_properties_to( entity_after.attachment) process_attachment_differences(ec2, eni, entity_before.attachment, entity_after.attachment, attachment_differences) else: raise AssertionError( "Unexpected eni difference: {0}.".format(difference))
def _update(sg, module_params, check_mode): changed = False if module_params["tags"]: tag_diff = tag_utils.get_diff(module_params["name"], module_params["tags"], tag_utils.from_boto3(sg.tags or [])) tag_update, tag_remove = tag_utils.from_diff( tag_diff, module_params["clear_tags"]) changed |= bool(tag_update) or bool(tag_remove) if not check_mode: tag_utils.update_resource(sg, tag_update, tag_remove) request_ingress_rules = [ r.render_loopback_reference(sg.id).normalize_ip_range() for r in itertools.chain.from_iterable( SimpleSecurityGroupRule.from_module_params("ingress", d) for d in module_params["ingress"].get("rules", [])) ] request_egress_rules = [ r.render_loopback_reference(sg.id).normalize_ip_range() for r in itertools.chain.from_iterable( SimpleSecurityGroupRule.from_module_params("egress", d) for d in module_params["egress"].get("rules", [])) ] existing_ingress_rules = list( itertools.chain.from_iterable( SimpleSecurityGroupRule.from_boto_dict("ingress", d) for d in sg.ip_permissions)) existing_egress_rules = list( itertools.chain.from_iterable( SimpleSecurityGroupRule.from_boto_dict("egress", d) for d in sg.ip_permissions_egress)) changed |= _apply_ruleset_changes( sg, "ingress", existing_ingress_rules, request_ingress_rules, module_params["ingress"].get("clear_rules", False), check_mode) changed |= _apply_ruleset_changes( sg, "egress", existing_egress_rules, request_egress_rules, module_params["egress"].get("clear_rules", False), check_mode) return changed, sg