def attach_to(ctx, resource_config, **_): '''Attaches an RDS Option to something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.OptionGroup'): params['OptionName'] = utils.get_resource_id( raise_on_missing=True, node=ctx.target.node, instance=ctx.target.instance) OptionGroup(ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).include_option(params) elif utils.is_node_type(ctx.target.node, SECGROUP_TYPE) or \ utils.is_node_type(ctx.target.node, SECGROUP_TYPE_DEPRECATED): security_groups = rtprops.get('resource_config').get( 'VpcSecurityGroupMemberships', list()) security_groups.append( utils.get_resource_id(node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)) ctx.source.instance.runtime_properties['resource_config'][ 'VpcSecurityGroupMemberships'] = security_groups
def detach_from(ctx, iface, resource_config, **_): '''Detaches an IAM User from 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)).detach_user(resource_config) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.LoginProfile'): iface.delete_login_profile(resource_config) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.AccessKey'): resource_config['AccessKeyId'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) iface.delete_access_key(resource_config) 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.detach_policy(resource_config)
def attach_to(ctx, resource_config, **_): '''Attaches an RDS Option to something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.OptionGroup'): params['OptionName'] = utils.get_resource_id( raise_on_missing=True, node=ctx.target.node, instance=ctx.target.instance ) OptionGroup( ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).include_option(params) elif utils.is_node_type(ctx.target.node, SECGROUP_TYPE) or \ utils.is_node_type(ctx.target.node, SECGROUP_TYPE_DEPRECATED): security_groups = rtprops.get('resource_config').get( 'VpcSecurityGroupMemberships', list()) security_groups.append( utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)) ctx.source.instance.runtime_properties[ 'resource_config']['VpcSecurityGroupMemberships'] = security_groups
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 detach_from(ctx, resource_config, **_): '''Detaches an IAM Access Key from something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.User'): resource_config['AccessKeyId'] = utils.get_resource_id( node=ctx.source.node, instance=ctx.source.instance, raise_on_missing=True) IAMUser(ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).delete_access_key(resource_config)
def test_get_resource_id(self): _test_name = 'test_get_resource_id' _test_node_properties = {'use_external_resource': False} _test_runtime_properties = {'resource_config': {}} _ctx = self.get_mock_ctx( _test_name, test_properties=_test_node_properties, test_runtime_properties=_test_runtime_properties, type_hierarchy=['cloudify.nodes.Root']) current_ctx.set(_ctx) self.assertEqual(utils.get_resource_id(), None) with self.assertRaises(NonRecoverableError): utils.get_resource_id(raise_on_missing=True)
def detach_from(ctx, iface, resource_config, **_): '''Detaches an RDS OptionGroup from something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.Option'): iface.remove_option( utils.get_resource_id(node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True))
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 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 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 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 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 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 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, resource_config, **_): '''Creates an AWS Route53 Resource Record Set''' Route53HostedZone(ctx.node, resource_id=utils.get_resource_id(raise_on_missing=True), logger=ctx.logger).change_resource_record_sets( ctx.instance.runtime_properties['resource_config'] or dict())
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 attach_to(ctx, resource_config, **_): '''Attaches an RDS Parameter to something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.ParameterGroup'): params['ParameterName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) ParameterGroup(ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).update_parameter(params)
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 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 detach_from(ctx, resource_config, **_): '''Detaches an RDS Option from something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.OptionGroup'): params['OptionName'] = utils.get_resource_id( raise_on_missing=True, node=ctx.target.node, instance=ctx.target.instance) OptionGroup(ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).remove_option(params)
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 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 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_using_relationship(ctx, iface, **_): """ Attaches an AWS EC2 EBS Volume TO Instance :param ctx: :param iface: :param _: """ device_name = ctx.source.node.properties.get('device_name') # Check if device name is provide or not if not device_name: raise NonRecoverableError('Cannot attach volume {0} to EC2 instance ' 'without specifying device name') instance_id = utils.find_ids_of_rels_by_node_type( ctx.source.instance, EC2_INSTANCE_TYPE) volume_id = iface.resource_id if not instance_id: raise NonRecoverableError( 'EC2 instance id {0} is missing.Attaching volume' ' {1} is not possible'.format(instance_id, volume_id) ) # Prepare params in order to attach volume params = { 'Device': device_name, 'InstanceId': instance_id[0], 'VolumeId': volume_id } iface = EC2VolumeAttachment(ctx.source.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.source.node, instance=ctx.source.instance, raise_on_missing=True)) _attach_ebs(params, iface, ctx.source)
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 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 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 prepare_assoc(ctx, iface, resource_config, **inputs): '''Prepares to associate an RDS Instance to something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.SubnetGroup'): ctx.source.instance.runtime_properties[ 'resource_config']['DBSubnetGroupName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.OptionGroup'): ctx.source.instance.runtime_properties[ 'resource_config']['OptionGroupName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.ParameterGroup'): ctx.source.instance.runtime_properties[ 'resource_config']['DBParameterGroupName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) elif utils.is_node_type(ctx.target.node, 'cloudify.aws.nodes.SecurityGroup'): security_groups = ctx.source.instance.runtime_properties[ 'resource_config'].get('VpcSecurityGroupIds', list()) security_groups.append( utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)) ctx.source.instance.runtime_properties[ 'resource_config']['VpcSecurityGroupIds'] = security_groups elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.Role'): if not inputs.get('iam_role_type_key') or \ not inputs.get('iam_role_id_key'): raise NonRecoverableError( 'Missing required relationship inputs "iam_role_type_key" ' 'and/or "iam_role_id_key".') ctx.source.instance.runtime_properties[ 'resource_config'][inputs['iam_role_type_key']] = \ utils.get_resource_string( node=ctx.target.node, instance=ctx.target.instance, attribute_key=inputs['iam_role_id_key'])
def attach_to(ctx, resource_config, **_): '''Attaches an RDS Parameter to something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.ParameterGroup'): params['ParameterName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True ) ParameterGroup( ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).update_parameter(params)
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 detach_from(ctx, iface, resource_config, **_): '''Detaches an RDS OptionGroup from something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.Option'): iface.remove_option(utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True))
def detach_from(ctx, resource_config, **_): '''Detaches an RDS Option from something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.OptionGroup'): params['OptionName'] = utils.get_resource_id( raise_on_missing=True, node=ctx.target.node, instance=ctx.target.instance ) OptionGroup( ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).remove_option(params)
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 prepare_assoc(ctx, iface, resource_config, **inputs): '''Prepares to associate an RDS Instance to something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.SubnetGroup'): ctx.source.instance.runtime_properties['resource_config'][ 'DBSubnetGroupName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.OptionGroup'): ctx.source.instance.runtime_properties['resource_config'][ 'OptionGroupName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.ParameterGroup'): ctx.source.instance.runtime_properties['resource_config'][ 'DBParameterGroupName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) elif utils.is_node_type(ctx.target.node, 'cloudify.aws.nodes.SecurityGroup'): security_groups = ctx.source.instance.runtime_properties[ 'resource_config'].get('VpcSecurityGroupIds', list()) security_groups.append( utils.get_resource_id(node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)) ctx.source.instance.runtime_properties['resource_config'][ 'VpcSecurityGroupIds'] = security_groups elif utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.Role'): if not inputs.get('iam_role_type_key') or \ not inputs.get('iam_role_id_key'): raise NonRecoverableError( 'Missing required relationship inputs "iam_role_type_key" ' 'and/or "iam_role_id_key".') ctx.source.instance.runtime_properties[ 'resource_config'][inputs['iam_role_type_key']] = \ utils.get_resource_string( node=ctx.target.node, instance=ctx.target.instance, attribute_key=inputs['iam_role_id_key'])
def wrapper_inner(**kwargs): '''Inner, worker function''' ctx = kwargs['ctx'] # Add new operation arguments kwargs['resource_type'] = resource_type kwargs['iface'] = class_decl( ctx.source.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.source.node, instance=ctx.source.instance, raise_on_missing=True)) if class_decl else None kwargs['resource_config'] = kwargs.get('resource_config') or dict() # Check if using external if ctx.source.node.properties.get('use_external_resource', False): resource_id = utils.get_resource_id( node=ctx.source.node, instance=ctx.source.instance) ctx.logger.info('%s ID# "%s" is user-provided.' % (resource_type, resource_id)) force_op = kwargs.get('force_operation', False) old_target = ctx.target.node.properties.get( 'use_external_resource', False) if not force_op and not old_target: ctx.logger.info( '%s ID# "%s" does not have force_operation ' 'set but target ID "%s" is new, therefore ' 'execution relationship operation.' % (resource_type, ctx.target.instance.runtime_properties[EXT_RES_ID], resource_id)) elif not kwargs.get('force_operation', False): return ctx.logger.warn('%s ID# "%s" has force_operation set.' % (resource_type, resource_id)) # Execute the function ret = function(**kwargs) # When modifying nested runtime properties, the internal # "dirty checking" mechanism will not know of our changes. # This forces the internal tracking to mark the properties as # dirty and will be refreshed on next query. # pylint: disable=W0212 ctx.source.instance.runtime_properties._set_changed() ctx.target.instance.runtime_properties._set_changed() return ret
def detach_from(ctx, resource_config, **_): '''Detaches an IAM Login Profile from something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.User'): IAMUser( ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).delete_login_profile(resource_config)
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, text_type(uuid4())) ctx.instance.runtime_properties['resource_config'] = resource_config
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 prepare_assoc(ctx, **_): '''Prepares to associate an Route53 Resource Record Set to something''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.route53.HostedZone'): zone_id = utils.get_resource_id(node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) utils.update_resource_id(ctx.source.instance, zone_id) ctx.source.instance.runtime_properties['resource_config'].update( dict(HostedZoneId=zone_id))
def test_get_resource_id(self): _test_name = 'test_get_resource_id' _test_node_properties = { 'use_external_resource': False } _test_runtime_properties = { 'resource_config': {} } _ctx = self.get_mock_ctx( _test_name, test_properties=_test_node_properties, test_runtime_properties=_test_runtime_properties, type_hierarchy=['cloudify.nodes.Root'] ) current_ctx.set(_ctx) self.assertEqual(utils.get_resource_id(), None) with self.assertRaises(NonRecoverableError): utils.get_resource_id(raise_on_missing=True)
def attach_to(ctx, resource_config, **_): '''Attaches an IAM Login Profile to something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.User'): IAMUser(ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).create_login_profile(params)
def wrapper(**kwargs): ctx = kwargs.get('ctx') iface = kwargs.get('iface') resource_id = utils.get_resource_id(node=ctx.node, instance=ctx.instance) tags = utils.get_tags_list(ctx.node.properties.get('Tags'), ctx.instance.runtime_properties.get('Tags'), kwargs.get('Tags')) if iface and tags and resource_id: iface.untag({'Tags': tags, 'Resources': [resource_id]}) return fn(**kwargs)
def attach_to(ctx, iface, resource_config, **_): '''Attaches an RDS OptionGroup to something else''' rtprops = ctx.target.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.rds.Option'): params['OptionName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) iface.include_option(params)
def prepare_assoc(ctx, iface, resource_config, **_): '''Prepares to associate an RDS SubnetGroup to something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.ec2.Subnet'): subnet_ids = ctx.source.instance.runtime_properties[ 'resource_config'].get('SubnetIds', list()) subnet_ids.append( utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)) ctx.source.instance.runtime_properties[ 'resource_config']['SubnetIds'] = subnet_ids
def attach_to(ctx, resource_config, **_): '''Attaches an Lambda Invoke to something else''' rtprops = ctx.source.instance.runtime_properties if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.lambda.Function'): ctx.source.instance.runtime_properties['output'] = LambdaFunction( ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).invoke( resource_config or rtprops.get('resource_config'))
def attach_to(ctx, resource_config, **_): '''Attaches an IAM Login Profile to something else''' rtprops = ctx.source.instance.runtime_properties params = resource_config or rtprops.get('resource_config') or dict() if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.User'): IAMUser( ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).create_login_profile(params)
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 VPN Connection Route""" params = dict() if not resource_config else resource_config.copy() resource_id = \ utils.get_resource_id( ctx.node, ctx.instance, params.get(VPN_CONNECTION_ID), use_instance_id=True ) utils.update_resource_id(ctx.instance, resource_id) # Actually create the resource create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict()
def attach_to(ctx, resource_config, **_): '''Attaches an IAM Access Key to something else''' rtprops = ctx.source.instance.runtime_properties if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.User'): resp = IAMUser( ctx.target.node, logger=ctx.logger, resource_id=utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True)).create_access_key( resource_config or rtprops.get('resource_config')) utils.update_resource_id(ctx.source.instance, resp['AccessKeyId']) ctx.source.instance.runtime_properties['SecretAccessKey'] = \ resp['SecretAccessKey']
def detach_from(ctx, iface, resource_config, **_): '''Detaches an IAM Group from something else''' if utils.is_node_type(ctx.target.node, 'cloudify.nodes.aws.iam.User'): resource_config['UserName'] = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) iface.detach_user(resource_config) 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.detach_policy(resource_config)
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 prepare_assoc(ctx, iface, resource_config, **inputs): '''Prepares to associate an Route53 Hosted Zone to something else''' if utils.is_node_type(ctx.target.node, 'cloudify.aws.nodes.VPC'): vpc_id = utils.get_resource_id( node=ctx.target.node, instance=ctx.target.instance, raise_on_missing=True) # Update VPC configuration vpccfg = ctx.source.instance.runtime_properties[ 'resource_config'].get('VPC', dict()) vpccfg['VPCId'] = vpc_id if not vpccfg.get('VPCRegion'): vpccfg['VPCRegion'] = detect_vpc_region(Boto3Connection( ctx.source.node).client('ec2'), vpc_id) ctx.source.instance.runtime_properties[ 'resource_config']['VPC'] = vpccfg
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 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)