def create(ctx, iface, resource_config, **_): '''Creates an AWS RDS Subnet Group''' # Build API params params = \ dict() if not resource_config else resource_config.copy() node_subnet_ids = params.get('SubnetIds', list()) instance_subnet_ids = \ ctx.instance.runtime_properties['resource_config'].get('SubnetIds', list()) if not node_subnet_ids: if not instance_subnet_ids: raise NonRecoverableError( 'Missing required parameter in input: SubnetIds') params['SubnetIds'] = instance_subnet_ids # if it is set then we need to combine them to what we already have as # runtime_properties else: for subnet_id in instance_subnet_ids: if subnet_id not in node_subnet_ids: node_subnet_ids.append(subnet_id) params['SubnetIds'] = node_subnet_ids if iface.resource_id: params.update({'DBSubnetGroupName': iface.resource_id}) create_response = iface.create(params) resource_id = create_response['DBSubnetGroup']['DBSubnetGroupName'] utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn( ctx.instance, create_response['DBSubnetGroup']['DBSubnetGroupArn'])
def wrapper_inner(*argc, **kwargs): ctx = kwargs.get('ctx') iface = kwargs.get('iface') resource_config = kwargs.get('resource_config') # Create a copy of the resource config for clean manipulation. params = utils.clean_params( dict() if not resource_config else resource_config.copy()) if params_priority: # params value will overwrite other resources id resource_id = params.get(resource_name) if not resource_id: resource_id = \ iface.resource_id or \ utils.get_resource_id( ctx.node, ctx.instance, use_instance_id=True) params[resource_name] = resource_id else: # resource id from runtime has priority over params resource_id = \ iface.resource_id or \ utils.get_resource_id( ctx.node, ctx.instance, params.get(resource_name), use_instance_id=True) params[resource_name] = resource_id ctx.instance.runtime_properties[resource_name] = \ resource_id utils.update_resource_id(ctx.instance, resource_id) kwargs['params'] = params return function(*argc, **kwargs)
def create(ctx, iface, resource_config, **_): """Creates an AWS S3 Bucket Policy""" # Create a copy of the resource config for clean manipulation. params = utils.clean_params( dict() if not resource_config else resource_config.copy()) # Get the bucket name from either params or a relationship. bucket_name = params.get(BUCKET) if not bucket_name: targ = utils.find_rel_by_node_type( ctx.instance, BUCKET_TYPE ) bucket_name = \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID ) params[BUCKET] = bucket_name ctx.instance.runtime_properties[BUCKET] = bucket_name utils.update_resource_id(ctx.instance, bucket_name) # Get the policy name from either params or a relationship. bucket_policy = params.get(POLICY) if not isinstance(bucket_policy, basestring): bucket_policy = json.dumps(bucket_policy) params[POLICY] = bucket_policy ctx.instance.runtime_properties[POLICY] = bucket_policy # Actually create the resource iface.create(params)
def create(ctx, iface, resource_config, **_): '''Creates AWS EC2 Keypairs''' params = \ dict() if not resource_config else resource_config.copy() params[KEYNAME] = utils.get_resource_name(params.get(KEYNAME)) key_name = params[KEYNAME] if PUBLIC_KEY_MATERIAL in params: create_response = \ iface.import_keypair( params, log_response=ctx.node.properties['log_create_response']) else: create_response = iface.create( params, log_response=ctx.node.properties['log_create_response']) # Allow the end user to store the key material in a secret. if ctx.node.properties['create_secret']: try: client = get_rest_client() except KeyError: # No pun intended. raise NonRecoverableError( 'create_secret is only supported with a Cloudify Manager.') # This makes the line too long for flake8 if included in args. secret_name = ctx.node.properties.get('secret_name', key_name) secrets_count = len(client.secrets.list(key=secret_name)) secret_value = create_response.get('KeyMaterial') try: if secrets_count == 0: client.secrets.create( key=secret_name, value=secret_value) elif secrets_count == 1 and \ ctx.node.properties.get( 'update_existing_secret', False) is True: client.secrets.update( key=secret_name, value=secret_value) except CloudifyClientError as e: raise NonRecoverableError(str(e)) cleaned_create_response = \ utils.JsonCleanuper(create_response).to_dict() # Allow the end user to opt-in to storing the key # material in the runtime properties. # Default is false if 'KeyMaterial' in cleaned_create_response and not \ ctx.node.properties['store_in_runtime_properties']: del cleaned_create_response['KeyMaterial'] ctx.instance.runtime_properties['create_response'] = \ cleaned_create_response iface.update_resource_id(cleaned_create_response.get(KEYNAME)) utils.update_resource_id(ctx.instance, key_name)
def create(ctx, iface, resource_config, **_): """ Creates an AWS EC2 EBS Volume :param ctx: :param iface: :param resource_config: :param _: :return: """ params = utils.clean_params( dict() if not resource_config else resource_config.copy()) # Create ebs resource create_response = iface.create(params) # Check if the resource created if create_response: ctx.instance.runtime_properties['eps_create'] =\ utils.JsonCleanuper(create_response).to_dict() # Update the esp_id (volume_id) esp_id = create_response.get(VOLUME_ID, '') utils.update_resource_id(ctx.instance, esp_id) iface.update_resource_id(esp_id) else: raise NonRecoverableError( '{0} ID# "{1}" reported an empty response'.format( RESOURCE_TYPE_VOLUME, iface.resource_id))
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Route Table''' params = dict() if not resource_config else resource_config.copy() vpc_id = params.get(VPC_ID) # If either of these values is missing, # they must be filled from a connected VPC. if not vpc_id: targ = \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[VPC_ID] = vpc_id or targ.target\ .instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params)[ROUTETABLE] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() route_table_id = create_response.get(ROUTETABLE_ID) iface.update_resource_id(route_table_id) utils.update_resource_id(ctx.instance, route_table_id)
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Security Group''' params = utils.clean_params( dict() if not resource_config else resource_config.copy()) vpc_id = params.get(VPC_ID) # Try to get the group_name and if it does not exits then try to # generate new one based on instance_id group_name = params.get(GROUP_NAME) params[GROUP_NAME] = utils.get_ec2_vpc_resource_name(group_name) if not vpc_id: vpc = \ utils.find_rel_by_node_type( ctx.instance, VPC_TYPE) or utils.find_rel_by_node_type( ctx.instance, VPC_TYPE_DEPRECATED) if vpc_id or vpc: params[VPC_ID] = \ vpc_id or \ vpc.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() group_id = create_response.get(GROUPID, '') iface.update_resource_id(group_id) utils.update_resource_id(ctx.instance, group_id)
def create(ctx, iface, resource_config, **_): '''Creates an AWS Lambda Permission''' # Build API params params = utils.clean_params( dict() if not resource_config else resource_config.copy()) function_rels = \ utils.find_rels_by_node_type( ctx.instance, FUNCTION_TYPE) lambda_function = None if len(function_rels) != 1 else function_rels[0] if lambda_function: params[FUNCTION_NAME] = utils.get_resource_id( node=lambda_function.target.node, instance=lambda_function.target.instance, raise_on_missing=False) if STATEMENT_ID not in params and iface.resource_id: params.update({'StatementId': iface.resource_id}) create_response = iface.create(params) statement = create_response.get('Statement') # The actual value for key "statement" is not a python dict type, # so it is required to check if it is "unicode" and then convert it back # as python dict type if statement: if isinstance(statement, text_type): statement = json.loads(statement) resource_id = statement['Sid'] if statement.get('Sid') else None iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, resource_id)
def attach_to(ctx, iface, resource_config, **_): '''Attaches an IAM User to something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.Group'): resource_config['UserName'] = iface.resource_id IAMGroup(ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).attach_user(resource_config) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.LoginProfile'): iface.create_login_profile( resource_config or ctx.target.instance.runtime_properties.get('resource_config')) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.AccessKey'): resp = iface.create_access_key( resource_config or ctx.target.instance.runtime_properties.get('resource_config')) utils.update_resource_id(ctx.target.instance, resp['AccessKeyId']) ctx.target.instance.runtime_properties['SecretAccessKey'] = \ resp['SecretAccessKey'] elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.Policy'): resource_config['PolicyArn'] = utils.get_resource_arn( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) iface.attach_policy(resource_config)
def create(ctx, iface, resource_config, **_): """Creates an AWS KMS Key Alias""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) target_key_id = params.get(TARGET_KEY_ID) if not target_key_id: target_key = \ utils.find_rel_by_node_type( ctx.instance, KEY_TYPE) target_key_id = \ target_key.target.instance.runtime_properties[EXTERNAL_RESOURCE_ID] params[TARGET_KEY_ID] = target_key_id # Actually create the resource iface.create(params)
def create(ctx, iface, resource_config, **_): """Creates an AWS S3 Bucket Policy""" # Create a copy of the resource config for clean manipulation. params = utils.clean_params( dict() if not resource_config else resource_config.copy()) # Get the bucket name from either params or a relationship. bucket_name = params.get(BUCKET) if not bucket_name: targ = utils.find_rel_by_node_type(ctx.instance, BUCKET_TYPE) bucket_name = \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID ) params[BUCKET] = bucket_name ctx.instance.runtime_properties[BUCKET] = bucket_name utils.update_resource_id(ctx.instance, bucket_name) # Get the policy name from either params or a relationship. bucket_policy = params.get(POLICY) if not isinstance(bucket_policy, basestring): bucket_policy = json.dumps(bucket_policy) params[POLICY] = bucket_policy ctx.instance.runtime_properties[POLICY] = bucket_policy # Actually create the resource iface.create(params)
def create(ctx, iface, resource_config, **_): """Creates an AWS EKS Cluster""" store_kube_config_in_runtime = \ ctx.node.properties['store_kube_config_in_runtime'] params = dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(CLUSTER_NAME), use_instance_id=True ) utils.update_resource_id(ctx.instance, resource_id) iface = prepare_describe_cluster_filter(resource_config.copy(), iface) response = iface.create(params) if response and response.get(CLUSTER): resource_arn = response.get(CLUSTER).get(CLUSTER_ARN) utils.update_resource_arn(ctx.instance, resource_arn) # wait for cluster to be active ctx.logger.info("Waiting for Cluster to become Active") iface.wait_for_cluster(params, 'cluster_active') if store_kube_config_in_runtime: try: client_config = ctx.node.properties['client_config'] kubeconf = iface.get_kubeconf(client_config, params) # check if kubeconf is json serializable or not json.dumps(kubeconf) ctx.instance.runtime_properties['kubeconf'] = kubeconf except TypeError as error: raise NonRecoverableError( 'kubeconf not json serializable {0}'.format(text_type(error)))
def create(ctx, iface, resource_config, **_): """Creates an AWS SQS Queue""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) queue_attributes = params.get('Attributes', {}) queue_attributes_policy = queue_attributes.get('Policy') if not isinstance(queue_attributes_policy, text_type): queue_attributes[POLICY] = json.dumps(queue_attributes_policy) # Actually create the resource create_response = iface.create(params) # Attempt to retrieve the ARN. try: resource_attributes = iface.client.get_queue_attributes( QueueUrl=create_response[QUEUE_URL], AttributeNames=[QUEUE_ARN]) except ClientError: utils.update_resource_arn(ctx.instance, None) else: utils.update_resource_arn( ctx.instance, resource_attributes.get('Attributes', {}).get(QUEUE_ARN)) utils.update_resource_id(ctx.instance, create_response[QUEUE_URL])
def create(ctx, iface, resource_config, params, **_): '''Creates an AWS IAM Group''' # Actually create the resource res_id, res_arn = iface.create(params) utils.update_resource_id(ctx.instance, res_id) utils.update_resource_arn(ctx.instance, res_arn)
def create(ctx, iface, resource_config, **_): """Creates an AWS KMS Key Grant""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) key_id = params.get(KEY_ID) if not key_id: target_key = \ utils.find_rel_by_node_type( ctx.instance, KEY_TYPE) key_id = \ target_key.target.instance.runtime_properties[EXTERNAL_RESOURCE_ID] params[KEY_ID] = key_id ctx.instance.runtime_properties[KEY_ID] = key_id # Actually create the resource output = iface.create(params) ctx.instance.runtime_properties[GRANT_TOKEN] = \ output.get(GRANT_TOKEN) utils.update_resource_id(ctx.instance, output.get(GRANT_ID))
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 NetworkAcl""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() vpc_id = params.get(VPC_ID) if not vpc_id: targ = \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, VPC_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[VPC_ID] = \ vpc_id or \ targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params)['NetworkAcl'] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() network_acl_id = create_response.get(NETWORKACL_ID, '') iface.update_resource_id(network_acl_id) utils.update_resource_id(ctx.instance, network_acl_id)
def create(ctx, iface, resource_config, **_): '''Creates an AWS ELB target group''' # Build API params params = utils.clean_params( dict() if not resource_config else resource_config.copy()) # TG attributes are only applied in modify operation. params.pop(GRP_ATTR, {}) if VPC_ID not in params.keys(): targs = \ utils.find_rels_by_node_type( ctx.instance, VPC_TYPE) or utils.find_rels_by_node_name( ctx.instance, VPC_TYPE_DEPRECATED) tg_attr = targs[0].target.instance.runtime_properties params[VPC_ID] = \ tg_attr.get(EXTERNAL_RESOURCE_ID) del targs # Actually create the resource create_response = iface.create(params) iface.update_resource_id( create_response['TargetGroups'][0][TARGETGROUP_ARN]) utils.update_resource_id( ctx.instance, create_response['TargetGroups'][0][TARGETGROUP_ARN]) utils.update_resource_arn( ctx.instance, create_response['TargetGroups'][0][TARGETGROUP_ARN])
def create(ctx, iface, resource_config, **_): """Creates an AWS Autoscaling Lifecycle Hook""" params = utils.clean_params( dict() if not resource_config else resource_config.copy()) resource_id = params.get(RESOURCE_NAME) if not resource_id: resource_id = \ iface.resource_id or \ utils.get_resource_id( ctx.node, ctx.instance, use_instance_id=True) params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) # Ensure the $GROUP_NAME parameter is populated. autoscaling_group = params.get(GROUP_NAME) if not autoscaling_group: autoscaling_group = \ utils.find_resource_id_by_type( ctx.instance, GROUP_TYPE) params[GROUP_NAME] = autoscaling_group ctx.instance.runtime_properties[GROUP_NAME] = \ autoscaling_group if not iface.resource_id: setattr(iface, 'resource_id', params.get(RESOURCE_NAME)) # Actually create the resource iface.create(params)
def create(ctx, iface, resource_config, **_): """Creates an AWS KMS Key Grant""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) key_id = params.get(KEY_ID) if not key_id: target_key = \ utils.find_rel_by_node_type( ctx.instance, KEY_TYPE) key_id = \ target_key.target.instance.runtime_properties[EXTERNAL_RESOURCE_ID] params[KEY_ID] = key_id ctx.instance.runtime_properties[KEY_ID] = key_id # Actually create the resource output = iface.create(params) ctx.instance.runtime_properties[GRANT_TOKEN] = \ output.get(GRANT_TOKEN) utils.update_resource_id( ctx.instance, output.get(GRANT_ID) )
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Security Group''' params = utils.clean_params( dict() if not resource_config else resource_config.copy()) vpc_id = params.get(VPC_ID) # Try to get the group_name and if it does not exits then try to # generate new one based on instance_id group_name = params.get(GROUP_NAME) params[GROUP_NAME] = utils.get_ec2_vpc_resource_name(group_name) if not vpc_id: vpc = \ utils.find_rel_by_node_type( ctx.instance, VPC_TYPE) or utils.find_rel_by_node_type( ctx.instance, VPC_TYPE_DEPRECATED) if vpc_id or vpc: params[VPC_ID] = \ vpc_id or \ vpc.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() group_id = create_response.get(GROUPID, '') iface.update_resource_id(group_id) utils.update_resource_id( ctx.instance, group_id)
def create(ctx, iface, resource_config, **_): """ Creates an AWS EC2 EBS Volume :param ctx: :param iface: :param resource_config: :param _: :return: """ params = utils.clean_params( dict() if not resource_config else resource_config.copy()) # Create ebs resource create_response = iface.create(params) # Check if the resource created if create_response: ctx.instance.runtime_properties['eps_create'] =\ utils.JsonCleanuper(create_response).to_dict() # Update the esp_id (volume_id) esp_id = create_response.get(VOLUME_ID, '') utils.update_resource_id(ctx.instance, esp_id) iface.update_resource_id(esp_id) else: raise NonRecoverableError( '{0} ID# "{1}" reported an empty response' .format(RESOURCE_TYPE_VOLUME, iface.resource_id))
def create(ctx, iface, resource_config, **_): '''Creates an AWS IAM Profile''' # Build API params params = \ dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) or iface.resource_id params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) role_name = params.pop('RoleName', None) create_response = iface.create(params) resource_id = create_response['InstanceProfile'][RESOURCE_NAME] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, create_response['InstanceProfile']['Arn']) role_name = role_name or \ utils.find_resource_id_by_type(ctx.instance, IAM_ROLE_TYPE) if role_name: add_role_params = { RESOURCE_NAME: iface.resource_id, 'RoleName': role_name } iface.add_role_to_instance_profile(add_role_params) ctx.instance.runtime_properties['RoleName'] = role_name
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 Vpc Peering""" params = dict() if not resource_config else resource_config.copy() # Accepter and Requester options are not part of create api, so we # Should check them if they are exists and then remove them accepter_vpc_options = params.get(ACCEPTER_VPC_PEERING_CONNECTION) requester_vpc_options = params.get(REQUESTER_VPC_PEERING_CONNECTION) if accepter_vpc_options: del params[ACCEPTER_VPC_PEERING_CONNECTION] if requester_vpc_options: del params[REQUESTER_VPC_PEERING_CONNECTION] # Actually create the resource create_response = iface.create(params)[VPC_PEERING_CONNECTION] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() if create_response: resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, create_response.get(VPC_PEERING_CONNECTION_ID), use_instance_id=True ) utils.update_resource_id(ctx.instance, resource_id) prepare_describe_vpc_peering_filter(resource_config.copy(), iface)
def create(ctx, iface, resource_config, params, **_): '''Creates an AWS IAM Role''' if 'AssumeRolePolicyDocument' in params and \ isinstance(params['AssumeRolePolicyDocument'], dict): params['AssumeRolePolicyDocument'] = \ json_dumps(params['AssumeRolePolicyDocument']) # Actually create the resource create_response = iface.create(params) resource_id = create_response['Role']['RoleName'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn( ctx.instance, create_response['Role']['Arn']) # attach policy role policies_arn = [] policies = _.get('modify_role_attribute_args', []) for policy in policies: payload = dict() payload['RoleName'] = resource_id payload['PolicyArn'] = policy['PolicyArn'] policies_arn.append(payload['PolicyArn']) iface.attach_policy(payload) # If there are policies added attached to role, then we need to make # sure that when uninstall triggers, all the attached policies arn are # available to detach if policies_arn: ctx.instance.runtime_properties['policies'] = policies_arn
def configure(ctx, resource_config, **_): '''Configures an AWS RDS Parameter''' # Save the parameters if resource_config.get('ParameterName') and not utils.get_resource_id(): utils.update_resource_id(ctx.instance, resource_config['ParameterName']) ctx.instance.runtime_properties['resource_config'] = resource_config
def create(ctx, iface, resource_config, **_): '''Creates an AWS Lambda Permission''' # Build API params params = utils.clean_params( dict() if not resource_config else resource_config.copy()) function_rels = \ utils.find_rels_by_node_type( ctx.instance, FUNCTION_TYPE) lambda_function = None if len(function_rels) != 1 else function_rels[0] if lambda_function: params[FUNCTION_NAME] = utils.get_resource_id( node=lambda_function.target.node, instance=lambda_function.target.instance, raise_on_missing=False) if STATEMENT_ID not in params and iface.resource_id: params.update({'StatementId': iface.resource_id}) create_response = iface.create(params) statement = create_response.get('Statement') # The actual value for key "statement" is not a python dict type, # so it is required to check if it is "unicode" and then convert it back # as python dict type if statement: if isinstance(statement, unicode): statement = json.loads(statement) resource_id = statement['Sid'] if statement.get('Sid') else None iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, resource_id)
def create(ctx, iface, resource_config, **_): '''Creates an AWS IAM Policy''' # Build API params params = \ utils.clean_params( dict() if not resource_config else resource_config.copy()) resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) or iface.resource_id params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) if 'PolicyDocument' in params and \ isinstance(params['PolicyDocument'], dict): params['PolicyDocument'] = json_dumps(params['PolicyDocument']) # Actually create the resource create_response = iface.create(params) resource_id = create_response['Policy']['PolicyName'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, create_response['Policy']['Arn'])
def create(ctx, iface, resource_config, **_): """Creates an AWS ELB classic policy""" # Create a copy of the resource config for clean manipulation. params = utils.clean_params( dict() if not resource_config else resource_config.copy()) resource_id = \ iface.resource_id or \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True) params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) ctx.instance.runtime_properties[RESOURCE_NAME] = \ resource_id lb_name = params.get(LB_NAME) if not lb_name: targs = \ utils.find_rels_by_node_type( ctx.instance, LB_TYPE) lb_name = \ targs[0].target.instance.runtime_properties[ EXTERNAL_RESOURCE_ID] params.update({LB_NAME: lb_name}) ctx.instance.runtime_properties[LB_NAME] = \ lb_name # Actually create the resource iface.create(params)
def attach(ctx, iface, resource_config, **_): """ Attaches an AWS EC2 EBS Volume TO Instance :param ctx: :param iface: :param resource_config: :param _: :return: """ params = \ dict() if not resource_config else resource_config.copy() # Attach ebs volume to ec2 instance resource create_response = iface.create(params) # Check if the resource attaching done if create_response: ctx.instance.runtime_properties['eps_attach'] =\ utils.JsonCleanuper(create_response).to_dict() # Update the esp_id (volume_id) esp_id = create_response.get(VOLUME_ID, '') utils.update_resource_id(ctx.instance, esp_id) iface.update_resource_id(esp_id) else: raise NonRecoverableError( '{0} ID# "{1}" reported an empty response' .format(RESOURCE_TYPE_VOLUME_ATTACHMENT, iface.resource_id))
def create(ctx, iface, resource_config, **_): '''Creates an AWS IAM Role Policy''' # Build API params params = utils.clean_params( dict() if not resource_config else resource_config.copy()) resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) or iface.resource_id params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) # Add RoleName role_name = params.get(ROLE_NAME, '') if not role_name: params[ROLE_NAME] = \ utils.find_resource_id_by_type( ctx.instance, ROLE_TYPE) if 'PolicyDocument' in params and \ isinstance(params['PolicyDocument'], dict): params['PolicyDocument'] = json_dumps(params['PolicyDocument']) # Actually create the resource iface.create(params)
def create(ctx, iface, resource_config, **_): '''Creates an AWS IAM Profile''' # Build API params params = \ dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(RESOURCE_NAME), use_instance_id=True ) or iface.resource_id params[RESOURCE_NAME] = resource_id utils.update_resource_id(ctx.instance, resource_id) role_name = params.pop('RoleName', None) create_response = iface.create(params) resource_id = create_response['InstanceProfile'][RESOURCE_NAME] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn( ctx.instance, create_response['InstanceProfile']['Arn']) role_name = role_name or \ utils.find_resource_id_by_type(ctx.instance, IAM_ROLE_TYPE) if role_name: add_role_params = { RESOURCE_NAME: iface.resource_id, 'RoleName': role_name } iface.add_role_to_instance_profile(add_role_params) ctx.instance.runtime_properties['RoleName'] = role_name
def attach(ctx, iface, resource_config, **_): """ Attaches an AWS EC2 EBS Volume TO Instance :param ctx: :param iface: :param resource_config: :param _: :return: """ params = \ dict() if not resource_config else resource_config.copy() # Attach ebs volume to ec2 instance resource create_response = iface.create(params) # Check if the resource attaching done if create_response: ctx.instance.runtime_properties['eps_attach'] =\ utils.JsonCleanuper(create_response).to_dict() # Update the esp_id (volume_id) esp_id = create_response.get(VOLUME_ID, '') utils.update_resource_id(ctx.instance, esp_id) iface.update_resource_id(esp_id) else: raise NonRecoverableError( '{0} ID# "{1}" reported an empty response'.format( RESOURCE_TYPE_VOLUME_ATTACHMENT, iface.resource_id))
def create(ctx, iface, resource_config, params, **_): """Creates an AWS Autoscaling Autoscaling Launch Configuration""" # Check if the "IamInstanceProfile" is passed or not and then update it iam_instance_profile = params.get(IAM_INSTANCE_PROFILE) if iam_instance_profile: if isinstance(iam_instance_profile, basestring): iam_instance_profile = iam_instance_profile.strip() params[IAM_INSTANCE_PROFILE] = str(iam_instance_profile) else: raise NonRecoverableError('Invalid {0} data type for {1}' ''.format(type(iam_instance_profile), IAM_INSTANCE_PROFILE)) # Add Security Groups secgroups_list = params.get(SECGROUPS, []) params[SECGROUPS] = \ utils.add_resources_from_rels( ctx.instance, SECGROUP_TYPE, secgroups_list) image_id = params.get(IMAGEID) # Add Instance and Instance Type instance_id = params.get(INSTANCEID) instance_type = params.get(INSTANCE_TYPE_PROPERTY) if not image_id and not instance_id: instance_id = utils.find_resource_id_by_type( ctx.instance, INSTANCE_TYPE_NEW) or \ utils.find_resource_id_by_type( ctx.instance, INSTANCE_TYPE) params.update({INSTANCEID: instance_id}) if instance_id and not instance_type: targ = utils.find_rel_by_node_type( ctx.instance, INSTANCE_TYPE_NEW) or \ utils.find_rel_by_node_type( ctx.instance, INSTANCE_TYPE) if targ: instance_type = \ targ.target.instance.runtime_properties.get( 'resource_config', {}).get( INSTANCE_TYPE_PROPERTY) or \ targ.target.node.properties.get( INSTANCE_TYPE_PROPERTY_DEPRECATED) params.update({INSTANCE_TYPE_PROPERTY: instance_type}) utils.update_resource_id(ctx.instance, params.get(RESOURCE_NAME)) iface.update_resource_id(params.get(RESOURCE_NAME)) # Actually create the resource if not iface.resource_id: setattr(iface, 'resource_id', params.get(RESOURCE_NAME)) iface.create(params) resource_arn = iface.properties[LC_ARN] utils.update_resource_arn(ctx.instance, resource_arn)
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Internet Gateway''' params = dict() if not resource_config else resource_config.copy() create_response = iface.create(params)['InternetGateway'] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() utils.update_resource_id(ctx.instance, create_response.get(INTERNETGATEWAY_ID))
def configure(ctx, resource_config, **_): '''Configures an AWS RDS Parameter''' # Save the parameters if resource_config.get('ParameterName') and not utils.get_resource_id(): utils.update_resource_id( ctx.instance, resource_config['ParameterName']) ctx.instance.runtime_properties['resource_config'] = resource_config
def create(ctx, iface, params, **_): # Actually create the resource ctx.logger.debug("create params: {params}".format(params=params)) params.pop(RESOURCE_NAME) create_response = iface.create(params) resource_id = create_response['pipeline']['name'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id)
def create(ctx, iface, resource_config, **_): '''Creates an AWS ELB load balancer''' # Build API params params = utils.clean_params( dict() if not resource_config else resource_config.copy()) resource_id = \ params.get('Name') or \ iface.resource_id or \ utils.get_resource_id( ctx.node, ctx.instance, use_instance_id=True) params['Name'] = resource_id utils.update_resource_id(ctx.instance, resource_id) # LB attributes are only applied in modify operation. params.pop(LB_ATTR, {}) # Add Subnets subnets_from_params = params.get(SUBNETS, []) subnets = \ utils.find_rels_by_node_type( ctx.instance, SUBNET_TYPE) or utils.find_rels_by_node_name( ctx.instance, SUBNET_TYPE_DEPRECATED) for subnet in subnets: subnet_id = \ subnet.target.instance.runtime_properties[EXTERNAL_RESOURCE_ID] subnets_from_params.append(subnet_id) params[SUBNETS] = subnets_from_params # Add Security Groups secgroups_from_params = params.get(SECGROUPS, []) secgroups = \ utils.find_rels_by_node_type( ctx.instance, SECGROUP_TYPE) or \ utils.find_rels_by_node_type( ctx.instance, SECGROUP_TYPE_DEPRECATED) for secgroup in secgroups: secgroup_id = \ secgroup.target.instance.runtime_properties[EXTERNAL_RESOURCE_ID] secgroups_from_params.append(secgroup_id) params[SECGROUPS] = secgroups_from_params # Actually create the resource output = iface.create(params) lb_id = output['LoadBalancers'][0][RESOURCE_NAME] iface.resource_id = lb_id try: utils.update_resource_id(ctx.instance, lb_id) utils.update_resource_arn(ctx.instance, output['LoadBalancers'][0][LB_ARN]) except (IndexError, KeyError) as e: raise NonRecoverableError( '{0}: {1} or {2} not located in response: {3}'.format( str(e), RESOURCE_NAME, LB_ARN, output))
def test_update_resource_id(self): mock_instance = MagicMock() mock_instance.runtime_properties = {} utils.update_resource_id(mock_instance, 'val') self.assertEqual(mock_instance.runtime_properties, {'aws_resource_id': 'val'})
def create(ctx, iface, resource_config, params, **_): '''Creates an AWS IAM User''' # Actually create the resource create_response = iface.create(params) resource_id = create_response['User']['UserName'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, create_response['User']['Arn'])
def prepare(ctx, iface, resource_config, **_): """Prepares an AWS EC2 Image""" # Save the parameters ctx.instance.runtime_properties['resource_config'] = resource_config iface = \ prepare_describe_image_filter( resource_config.copy(), iface) ami = iface.properties utils.update_resource_id(ctx.instance, ami.get(IMAGE_ID))
def prepare(ctx, resource_config, **_): '''Prepares an AWS Lambda Permission''' # Save the parameters if not utils.get_resource_id(): if resource_config.get('StatementId'): utils.update_resource_id( ctx.instance, resource_config['StatementId']) else: utils.update_resource_id(ctx.instance, str(uuid4())) ctx.instance.runtime_properties['resource_config'] = resource_config
def create(ctx, iface, resource_config, params, **_): '''Creates an AWS IAM User''' # Actually create the resource create_response = iface.create(params) resource_id = create_response['User']['UserName'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn( ctx.instance, create_response['User']['Arn'])
def create(ctx, iface, resource_config, params, **_): """Creates an AWS Autoscaling Group""" # Try to populate the Launch Configuration field # with a relationship lc_name = params.get(LC_NAME) instance_id = params.get(INSTANCE_ID) if not lc_name and not instance_id: lc_name = \ utils.find_resource_id_by_type( ctx.instance, LC_TYPE) if lc_name: params.update({LC_NAME: lc_name}) # If no LC_NAME, try to populate the # InstanceId field with a relationship. if not lc_name: instance_id = \ utils.find_resource_id_by_type( ctx.instance, INSTANCE_TYPE) params[INSTANCE_ID] = instance_id subnet_list_string = params.get(SUBNET_LIST) subnet_list = \ sub("[^\w]", " ", subnet_list_string).split() if \ subnet_list_string else [] subnet_list = \ utils.add_resources_from_rels( ctx.instance, SUBNET_TYPE, subnet_list) subnet_list = \ utils.add_resources_from_rels( ctx.instance, SUBNET_TYPE_DEPRECATED, subnet_list) if subnet_list: # Remove any duplicate items from subnet list subnet_list = list(set(subnet_list)) params[SUBNET_LIST] = ', '.join(subnet_list) # Actually create the resource if not iface.resource_id: setattr(iface, 'resource_id', params.get(RESOURCE_NAME)) iface.create(params) iface.update_resource_id(iface.properties.get(RESOURCE_NAME)) utils.update_resource_id( ctx.instance, iface.properties.get(RESOURCE_NAME)) utils.update_resource_arn( ctx.instance, iface.properties.get(GROUP_ARN))
def create(ctx, iface, resource_config, **_): '''Creates an AWS EC2 Subnet''' params = utils.clean_params( dict() if not resource_config else resource_config.copy()) vpc_id = params.get(VPC_ID) cidr_block = params.get(CIDR_BLOCK) ipv6_cidr_block = params.get(IPV6_CIDR_BLOCK) # If either of these values is missing, # they must be filled from a connected VPC. if not vpc_id or not cidr_block: targ = \ utils.find_rel_by_node_type( ctx.instance, VPC_TYPE) or utils.find_rel_by_node_type( ctx.instance, VPC_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[VPC_ID] = \ vpc_id or \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) # Attempt to use the CIDR Block from parameters. # Fallback to connected VPC. params[CIDR_BLOCK] = \ cidr_block or \ targ.instance.runtime_properties.get( 'resource_config', {}).get(CIDR_BLOCK) # If ipv6 cidr block is provided by user, then we need to make sure that # The subnet size must use a /64 prefix length if ipv6_cidr_block: ipv6_cidr_block = ipv6_cidr_block[:-2] + '64' params[IPV6_CIDR_BLOCK] = ipv6_cidr_block # Actually create the resource create_response = iface.create(params)[SUBNET] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() subnet_id = create_response.get(SUBNET_ID) iface.update_resource_id(subnet_id) utils.update_resource_id(ctx.instance, subnet_id) modify_subnet_attribute_args = \ _.get('modify_subnet_attribute_args') if modify_subnet_attribute_args: modify_subnet_attribute_args[SUBNET_ID] = \ subnet_id iface.modify_subnet_attribute( modify_subnet_attribute_args)
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 VPN Gateway""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() # Actually create the resource # Actually create the resource create_response = iface.create(params)['VpnGateway'] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() utils.update_resource_id(ctx.instance, create_response.get(VPNGATEWAY_ID))
def reject(ctx, iface, resource_config, **_): """Rejects an AWS EC2 Vpc Peer Request""" params = dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(VPC_PEERING_CONNECTION_ID), use_instance_id=True ) utils.update_resource_id(ctx.instance, resource_id) iface.reject(params)
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 DhcpOptions""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() # Actually create the resource create_response = iface.create(params)[DHCPOPTIONS] ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() dhcp_options_id = create_response.get(DHCPOPTIONS_ID, '') iface.update_resource_id(dhcp_options_id) utils.update_resource_id(ctx.instance, dhcp_options_id)
def create(ctx, iface, resource_config, **_): '''Creates an AWS Route53 Hosted Zone''' # Build API params params = \ dict() if not resource_config else resource_config.copy() if iface.resource_id: params.update({'Name': iface.resource_id}) if not params.get('CallerReference'): params.update(dict(CallerReference=str(ctx.instance.id))) # Actually create the resource create_response = iface.create(params)['HostedZone']['Id'] iface.update_resource_id(create_response) utils.update_resource_id(ctx.instance, create_response) utils.update_resource_arn(ctx.instance, create_response)
def create(ctx, iface, resource_config, **_): '''Creates an AWS RDS Option Group''' # Build API params params = \ dict() if not resource_config else resource_config.copy() # Actually create the resource if iface.resource_id: params.update({'OptionGroupName': iface.resource_id}) create_response = iface.create(params) resource_id = create_response['OptionGroup']['OptionGroupName'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn( ctx.instance, create_response['OptionGroup']['OptionGroupArn'])
def create(ctx, iface, resource_config, **_): """Creates an AWS EFS Mount Target""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() # Add File System ID file_system_id = params.get(FILESYSTEM_ID) if not file_system_id: file_system = \ utils.find_rel_by_node_type( ctx.instance, FILESYSTEM_TYPE) file_system_id = file_system.target.instance.runtime_properties[ EXTERNAL_RESOURCE_ID] params[FILESYSTEM_ID] = file_system_id # Add Subnet subnet_id = params.get(SUBNET_ID) if not subnet_id: subnet = \ utils.find_rel_by_node_type( ctx.instance, SUBNET_TYPE) or utils.find_rel_by_node_type( ctx.instance, SUBNET_TYPE_DEPRECATED) subnet_id = \ subnet.target.instance.runtime_properties[EXTERNAL_RESOURCE_ID] params[SUBNET_ID] = subnet_id # Add Security Groups secgroups_list = params.get(SECGROUPS, []) params[SECGROUPS] = \ utils.add_resources_from_rels( ctx.instance, SECGROUP_TYPE, secgroups_list) or \ utils.add_resources_from_rels( ctx.instance, SECGROUP_TYPE_DEPRECATED, secgroups_list) output = iface.create(params) utils.update_resource_id(ctx.instance, output.get(MOUNTTARGET_ID)) ctx.instance.runtime_properties[FILESYSTEM_ID] = output.get(FILESYSTEM_ID) ctx.instance.runtime_properties[SUBNET_ID] = output.get(SUBNET_ID) ctx.instance.runtime_properties[IP_ADDRESS] = output.get(IP_ADDRESS) ctx.instance.runtime_properties[NAT_ID] = output.get(NAT_ID)