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 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 Autoscaling Policy""" 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 # Actually create the resource if not iface.resource_id: setattr(iface, 'resource_id', params.get(RESOURCE_NAME)) resource_arn = iface.create(params)[POLICY_ARN] utils.update_resource_arn(ctx.instance, resource_arn)
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 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 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 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 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 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 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 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, **_): '''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, 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 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 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 test_update_resource_arn(self): mock_instance = MagicMock() mock_instance.runtime_properties = {} utils.update_resource_arn(mock_instance, 'val') self.assertEqual(mock_instance.runtime_properties, {'aws_resource_arn': 'val'})
def create(ctx, iface, resource_config, params, **_): """Creates an AWS DynamoDB Table""" # Actually create the resource create_respose = iface.create(params) resource_id = create_respose['TableDescription']['TableName'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, create_respose['TableDescription']['TableArn'])
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, **_): """Creates an AWS KMS Key""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() create_response = iface.create(params)[KEY_META] utils.update_resource_arn(ctx.instance, create_response.get(ARN)) utils.update_resource_id(ctx.instance, create_response.get(KEY_ID))
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, 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 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 RDS Instance Read Replica''' # Build API params params = \ dict() if not resource_config else resource_config.copy() if iface.resource_id: params.update({'DBInstanceIdentifier': iface.resource_id}) # Actually create the resource create_response = iface.create(params) resource_id = create_response['DBInstance']['DBInstanceIdentifier'] iface.update_resource_id(resource_id) utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, create_response['DBInstance']['DBInstanceArn'])
def create(ctx, iface, resource_config, **_): '''Creates an AWS Lambda Function''' # Build API params params = utils.clean_params( dict() if not resource_config else resource_config.copy()) if RESOURCE_ID not in params: params[RESOURCE_ID] = iface.resource_id vpc_config = params.get('VpcConfig', dict()) # Attach a Subnet Group if it exists subnet_ids = _get_subnets_to_attach(ctx, vpc_config) if subnet_ids: vpc_config['SubnetIds'] = subnet_ids # Attach any security groups if they exist security_groups = _get_security_groups_to_attach(ctx, vpc_config) if security_groups: vpc_config['SecurityGroupIds'] = security_groups params['VpcConfig'] = vpc_config # Attach an IAM Role if it exists iam_role = _get_iam_role_to_attach(ctx) if iam_role: params['Role'] = iam_role # Handle user-profided code ZIP file if params.get('Code', dict()).get('ZipFile'): codezip = params['Code']['ZipFile'] ctx.logger.debug('ZipFile: "%s" (%s)' % (codezip, type(codezip))) if not path_exists(codezip): codezip = ctx.download_resource(codezip) ctx.logger.debug('Downloaded resource: "%s"' % codezip) with open(codezip, mode='rb') as _file: params['Code']['ZipFile'] = _file.read() ctx.logger.debug('Deleting resource: "%s"' % codezip) os_remove(codezip) else: with open(codezip, mode='rb') as _file: params['Code']['ZipFile'] = _file.read() # Actually create the resource create_response = iface.create(params) resource_id = create_response['FunctionName'] utils.update_resource_id(ctx.instance, resource_id) utils.update_resource_arn(ctx.instance, create_response['FunctionArn']) # Save vpc_config to be used later on when remove eni created by invoke # function if vpc_config and create_response.get('VpcConfig'): ctx.instance.runtime_properties['vpc_config'] =\ create_response['VpcConfig']
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 start(ctx, iface, resource_config, **_): '''Updates an AWS RDS Instance Runtime Properties''' db_instance = iface.properties for key, value in db_instance.items(): if key == 'DBInstanceIdentifier': iface.update_resource_id(value) utils.update_resource_id(ctx.instance, value) continue elif key == 'DBInstanceArn': utils.update_resource_arn(ctx.instance, value) continue elif isinstance(value, datetime): value = text_type(value) ctx.instance.runtime_properties[key] = value
def start(ctx, iface, resource_config, **_): '''Updates an AWS RDS Instance Runtime Properties''' db_instance = iface.properties for key, value in db_instance.items(): if key == 'DBInstanceIdentifier': iface.update_resource_id(value) utils.update_resource_id(ctx.instance, value) continue elif key == 'DBInstanceArn': utils.update_resource_arn(ctx.instance, value) continue elif isinstance(value, datetime): value = str(value) ctx.instance.runtime_properties[key] = value
def create(ctx, iface, resource_config, **_): """Creates an AWS SNS Subscription""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() topic_arn = params.get(TOPIC_ARN) # Add the required TopicArn parameter. if not topic_arn: rel = \ utils.find_rel_by_node_type( ctx.instance, TOPIC_TYPE) topic_arn = \ rel.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ARN) ctx.instance.runtime_properties[TOPIC_ARN] = \ topic_arn params[TOPIC_ARN] = topic_arn topic_iface = SNSTopic( ctx_node=ctx.node, resource_id=topic_arn, client=iface.client, logger=ctx.logger) # Subscribe Endpoint is the arn of an endpoint endpoint_name = params.get('Endpoint') if not endpoint_name: raise NonRecoverableError( 'Endpoint ARN or node_name was not provided.') # If endpoint_name is not a valid arn get arn from relationship. if not utils.validate_arn(endpoint_name): rel = \ utils.find_rels_by_node_name( ctx.instance, endpoint_name)[0] endpoint_arn = \ rel.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ARN) params['Endpoint'] = endpoint_arn # Request the subscription request_arn = topic_iface.subscribe(params) utils.update_resource_id(ctx.instance, request_arn) utils.update_resource_arn(ctx.instance, request_arn)
def create(ctx, iface, resource_config, **_): """Creates an AWS KMS Key""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() create_response = iface.create(params)[KEY_META] utils.update_resource_arn( ctx.instance, create_response.get(ARN) ) utils.update_resource_id( ctx.instance, create_response.get(KEY_ID) )
def create(ctx, iface, resource_config, **_): """Creates an AWS Cloudwatch Events Rule""" 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) # Actually create the resource rule_arn = iface.create(params)[ARN] utils.update_resource_arn(ctx.instance, rule_arn)
def create(ctx, iface, resource_config, **_): """Creates an AWS ECS Task Definition""" params = dict() if not resource_config else resource_config.copy() # Get the cluster name from either params or a relationship. task_definition_name = params.get(TASK_DEFINITION_FAMILY) ctx.instance.runtime_properties[ TASK_DEFINITION_RESOURCE] = task_definition_name utils.update_resource_id(ctx.instance, task_definition_name) iface = prepare_describe_task_definition_filter(resource_config.copy(), iface) response = iface.create(params) if response and response.get(TASK_DEFINITION): resource_arn = response[TASK_DEFINITION].get(TASK_DEFINITION_ARN) utils.update_resource_arn(ctx.instance, resource_arn)
def create(ctx, iface, resource_config, params, **_): '''Creates an AWS ELB load balancer''' # 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 create(ctx, iface, resource_config, **_): """Creates an AWS ECS Cluster""" params = dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(CLUSTER_RESOURCE_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[CLUSTER].get(CLUSTER_ARN) utils.update_resource_arn(ctx.instance, resource_arn)
def create(ctx, iface, resource_config, **_): """Creates an AWS ECS Task Definition""" params = dict() if not resource_config else resource_config.copy() # Get the cluster name from either params or a relationship. task_definition_name = params.get(TASK_DEFINITION_FAMILY) ctx.instance.runtime_properties[ TASK_DEFINITION_RESOURCE] = task_definition_name utils.update_resource_id(ctx.instance, task_definition_name) iface = prepare_describe_task_definition_filter( resource_config.copy(), iface ) response = iface.create(params) if response and response.get(TASK_DEFINITION): resource_arn = response[TASK_DEFINITION].get(TASK_DEFINITION_ARN) utils.update_resource_arn(ctx.instance, resource_arn)
def create(ctx, iface, resource_config, **_): """Creates an AWS ECS Service""" params = dict() if not resource_config else resource_config.copy() # Get the cluster name from either params or a relationship. cluster_name = params.get(CLUSTER) if not cluster_name: params[CLUSTER] = get_cluster_name(ctx) ctx.instance.runtime_properties[SERVICE] = params.get(SERVICE_RESOURCE) utils.update_resource_id(ctx.instance, params.get(SERVICE_RESOURCE)) iface = prepare_describe_service_filter(resource_config.copy(), iface) response = iface.create(params) if response and response.get(SERVICE): resource_arn = response[SERVICE].get(SERVICE_ARN) utils.update_resource_arn(ctx.instance, resource_arn)
def create(ctx, iface, resource_config, **_): """Creates an AWS SNS Topic""" 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) # Actually create the resource res_id = iface.create(params) utils.update_resource_id(ctx.instance, res_id) utils.update_resource_arn(ctx.instance, res_id)
def create(ctx, iface, resource_config, params, **_): """Creates an AWS Autoscaling Autoscaling Policy""" # 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 # Actually create the resource if not iface.resource_id: setattr(iface, 'resource_id', params.get(RESOURCE_NAME)) resource_arn = iface.create(params)[POLICY_ARN] utils.update_resource_arn(ctx.instance, resource_arn)
def create(ctx, iface, resource_config, **_): '''Creates an AWS IAM Group''' # Build API params 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) # 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, params, **_): """Creates an AWS Autoscaling Autoscaling Policy""" # 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 # Actually create the resource if not iface.resource_id: setattr(iface, 'resource_id', params.get(RESOURCE_NAME)) resource_arn = iface.create(params)[POLICY_ARN] utils.update_resource_arn( ctx.instance, resource_arn)
def create(ctx, iface, resource_config, **_): '''Creates an AWS RDS Instance''' # Build API params params = \ dict() if not resource_config else resource_config.copy() params.update(dict(DBInstanceIdentifier=iface.resource_id)) # Actually create the resource res = iface.create(params) db_instance = res['DBInstance'] for key, value in db_instance.items(): if key == 'DBInstanceIdentifier': iface.update_resource_id(value) utils.update_resource_id(ctx.instance, value) continue elif key == 'DBInstanceArn': utils.update_resource_arn(ctx.instance, value) continue elif isinstance(value, datetime): value = str(value) ctx.instance.runtime_properties[key] = value
def create(ctx, iface, resource_config, **_): """Creates an AWS EKS Node Group""" params = dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(NODEGROUP_NAME), use_instance_id=True ) utils.update_resource_id(ctx.instance, resource_id) iface = prepare_describe_node_group_filter(resource_config.copy(), iface) response = iface.create(params) if response and response.get(NODEGROUP): resource_arn = response.get(NODEGROUP).get(NODEGROUP_ARN) utils.update_resource_arn(ctx.instance, resource_arn) # wait for nodegroup to be active ctx.logger.info("Waiting for NodeGroup to become Active") iface.wait_for_nodegroup(params, 'nodegroup_active')
def create(ctx, iface, resource_config, **_): '''Creates an AWS ELB rule''' # Build API params resource_config = \ resource_config or ctx.instance.runtime_properties['resource_config'] params = utils.clean_params( dict() if not resource_config else resource_config.copy()) if LISTENER_ARN not in params: targs = \ utils.find_rels_by_node_type( ctx.instance, LISTENER_TYPE) listener_arn = \ targs[0].target.instance.runtime_properties[EXTERNAL_RESOURCE_ARN] params.update({LISTENER_ARN: listener_arn}) del targs for action in params.get('Actions', []): target_grp = action.get(TARGET_ARN) if not ARN_MATCHER.match(action.get(target_grp, '')): targs = \ utils.find_rels_by_node_type( ctx.instance, TARGET_TYPE) for targ in targs: target_group_arn = \ targ.target.instance.runtime_properties[ EXTERNAL_RESOURCE_ARN] if targ.target.node.name == target_grp: action.update({TARGET_ARN: target_group_arn}) # Actually create the resource create_response = iface.create(params) iface.update_resource_id( create_response['Rules'][0][RULE_ARN]) utils.update_resource_id( ctx.instance, create_response['Rules'][0][RULE_ARN]) utils.update_resource_arn( ctx.instance, create_response['Rules'][0][RULE_ARN])
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, basestring): 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 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)