def start_sticky(ctx, iface, resource_config, **_): """Starts an AWS ELB classic policy""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() lb_name = params.get(LB_NAME) lb_port = params.get(LB_PORT) policy_names = params.get(RESOURCE_NAMES) # This operations requires the LoadBalancerName, LoadBalancerPort, # and the PolicyName. 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] ctx.instance.runtime_properties[LB_NAME] = \ lb_name params.update({LB_NAME: lb_name}) # The LoadBalancerPort can come either from the resource config, # or it can come from a relationship to a Listener or a LoadBalancer. # A listener is prefered because only one LoadBalancerPort is expected # to be defined per listener, whereas a LoadBalancer many listeners # are defined. If many listeners are found then the first listener is # used. if not lb_port: targs = \ utils.find_rels_by_node_type( ctx.instance, LISTENER_TYPE) if not targs: targs = \ utils.find_rels_by_node_type( ctx.instance, LB_TYPE) instance_cfg = \ targs[0].target.instance.runtime_properties['resource_config'] else: instance_cfg = \ targs[0].target.instance.runtime_properties['resource_config'] listener = instance_cfg.get('Listeners', [{}])[0] lb_port = listener.get(LB_PORT) params.update({LB_PORT: lb_port}) # This API call takes a list of policies as an argument. # However this node type represents only one policy. # Therefore we restrict the usage. if not policy_names: policy_names = ctx.instance.runtime_properties[RESOURCE_NAME] params.update({RESOURCE_NAMES: [policy_names]}) # Actually create the resource iface.start(params)
def start_sticky(ctx, iface, resource_config, **_): """Starts an AWS ELB classic policy""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() lb_name = params.get(LB_NAME) lb_port = params.get(LB_PORT) policy_names = params.get(RESOURCE_NAMES) # This operations requires the LoadBalancerName, LoadBalancerPort, # and the PolicyName. 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] ctx.instance.runtime_properties[LB_NAME] = \ lb_name params.update({LB_NAME: lb_name}) # The LoadBalancerPort can come either from the resource config, # or it can come from a relationship to a Listener or a LoadBalancer. # A listener is prefered because only one LoadBalancerPort is expected # to be defined per listener, whereas a LoadBalancer many listeners # are defined. If many listeners are found then the first listener is # used. if not lb_port: targs = \ utils.find_rels_by_node_type( ctx.instance, LISTENER_TYPE) if not targs: targs = \ utils.find_rels_by_node_type( ctx.instance, LB_TYPE) instance_cfg = \ targs[0].target.instance.runtime_properties['resource_config'] else: instance_cfg = \ targs[0].target.instance.runtime_properties['resource_config'] listener = instance_cfg.get('Listeners', [{}])[0] lb_port = listener.get(LB_PORT) params.update({LB_PORT: lb_port}) # This API call takes a list of policies as an argument. # However this node type represents only one policy. # Therefore we restrict the usage. if not policy_names: policy_names = ctx.instance.runtime_properties[RESOURCE_NAME] params.update({RESOURCE_NAMES: [policy_names]}) # Actually create the resource iface.start(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 _get_security_groups_to_attach(ctx, vpc_config): security_groups = vpc_config.get('SecurityGroupIds', list()) sg_rels = \ utils.find_rels_by_node_type( ctx.instance, SECGROUP_TYPE) or \ utils.find_rels_by_node_type( ctx.instance, SECGROUP_TYPE_DEPRECATED) for rel in sg_rels: security_groups.append( utils.get_resource_id(node=rel.target.node, instance=rel.target.instance, raise_on_missing=True)) return security_groups
def create_sticky(ctx, iface, resource_config, **_): """Creates an AWS ELB classic policy""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() lb_name = params.get(LB_NAME) policy_name = params.get(RESOURCE_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 ctx.instance.runtime_properties[RESOURCE_NAME] = \ policy_name # Actually create the resource iface.create_sticky(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 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 create_sticky(ctx, iface, resource_config, **_): """Creates an AWS ELB classic policy""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() lb_name = params.get(LB_NAME) policy_name = params.get(RESOURCE_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 ctx.instance.runtime_properties[RESOURCE_NAME] = \ policy_name # Actually create the resource iface.create_sticky(params)
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 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 _get_subnets_to_attach(ctx, vpc_config): # Attach a Subnet Group if it exists subnet_ids = vpc_config.get('SubnetIds', list()) subnet_rels = \ utils.find_rels_by_node_type( ctx.instance, SUBNET_TYPE) or \ utils.find_rels_by_node_type( ctx.instance, SUBNET_TYPE) for rel in subnet_rels: subnet_ids.append( utils.get_resource_id(node=rel.target.node, instance=rel.target.instance, raise_on_missing=True)) return subnet_ids
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 attach(ctx, iface, resource_config, **_): '''Attaches an AWS EC2 Route Table to a Subnet''' params = dict() if not resource_config else resource_config.copy() route_table_id = params.get(ROUTETABLE_ID) if not route_table_id: route_table_id = iface.resource_id params.update({ROUTETABLE_ID: route_table_id}) targets = \ utils.find_rels_by_node_type(ctx.instance, SUBNET_TYPE) or \ utils.find_rels_by_node_type(ctx.instance, SUBNET_TYPE_DEPRECATED) association_id_list = [] for target in targets: params[SUBNET_ID] = \ target.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) association_id = iface.attach(params).get(ASSOCIATION_ID) association_id_list.append(association_id) ctx.instance.runtime_properties['association_ids'] = \ association_id_list
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 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 EC2 NetworkInterface""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() subnet_id = params.get(SUBNET_ID) if not subnet_id: targ = \ utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[SUBNET_ID] = \ subnet_id or \ targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) groups = params.get(SEC_GROUPS, []) for targ in utils.find_rels_by_node_type(ctx.instance, SEC_GROUP_TYPE): group_id = \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) if group_id and group_id not in groups: groups.append(group_id) params[SEC_GROUPS] = groups # Actually create the resource create_response = iface.create(params)['NetworkInterface'] cleaned_create_response = utils.JsonCleanuper(create_response).to_dict() ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(cleaned_create_response).to_dict() eni_id = cleaned_create_response.get(NETWORKINTERFACE_ID, '') iface.update_resource_id(eni_id) utils.update_resource_id(ctx.instance, eni_id) ctx.instance.runtime_properties['device_index'] = \ cleaned_create_response.get( 'Attachment', {}).get( 'DeviceIndex', ctx.instance.runtime_properties.get('device_index')) modify_network_interface_attribute_args = \ _.get('modify_network_interface_attribute_args') if modify_network_interface_attribute_args: modify_network_interface_attribute_args[NETWORKINTERFACE_ID] = \ eni_id iface.modify_network_interface_attribute( modify_network_interface_attribute_args)
def create(ctx, iface, resource_config, **_): """Creates an AWS EC2 NetworkInterface""" # Create a copy of the resource config for clean manipulation. params = \ dict() if not resource_config else resource_config.copy() subnet_id = params.get(SUBNET_ID) if not subnet_id: targ = \ utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE) or \ utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE_DEPRECATED) # Attempt to use the VPC ID from parameters. # Fallback to connected VPC. params[SUBNET_ID] = \ subnet_id or \ targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID) groups = params.get(SEC_GROUPS, []) for targ in utils.find_rels_by_node_type(ctx.instance, SEC_GROUP_TYPE): group_id = \ targ.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) if group_id and group_id not in groups: groups.append(group_id) params[SEC_GROUPS] = groups # Actually create the resource create_response = iface.create(params)['NetworkInterface'] cleaned_create_response = utils.JsonCleanuper(create_response).to_dict() ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(cleaned_create_response).to_dict() eni_id = cleaned_create_response.get(NETWORKINTERFACE_ID, '') iface.update_resource_id(eni_id) utils.update_resource_id(ctx.instance, eni_id) ctx.instance.runtime_properties['device_index'] = \ cleaned_create_response.get( 'Attachment', {}).get( 'DeviceIndex', ctx.instance.runtime_properties.get('device_index')) modify_network_interface_attribute_args = \ _.get('modify_network_interface_attribute_args') if modify_network_interface_attribute_args: modify_network_interface_attribute_args[NETWORKINTERFACE_ID] = \ eni_id iface.modify_network_interface_attribute( modify_network_interface_attribute_args)
def create(ctx, iface, resource_config, params, **_): """Creates an AWS ELB classic policy""" 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 create(ctx, iface, resource_config, params, **_): """Creates an AWS ELB classic policy""" 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 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 = vpc_config.get('SubnetIds', list()) subnet_rels = \ utils.find_rels_by_node_type( ctx.instance, SUBNET_TYPE) or \ utils.find_rels_by_node_type( ctx.instance, SUBNET_TYPE) for rel in subnet_rels: subnet_ids.append(utils.get_resource_id( node=rel.target.node, instance=rel.target.instance, raise_on_missing=True)) vpc_config['SubnetIds'] = subnet_ids # Attach any security groups if they exist security_groups = vpc_config.get('SecurityGroupIds', list()) sg_rels = \ utils.find_rels_by_node_type( ctx.instance, SECGROUP_TYPE) or \ utils.find_rels_by_node_type( ctx.instance, SECGROUP_TYPE_DEPRECATED) for rel in sg_rels: security_groups.append( utils.get_resource_id( node=rel.target.node, instance=rel.target.instance, raise_on_missing=True)) vpc_config['SecurityGroupIds'] = security_groups params['VpcConfig'] = vpc_config # Attach an IAM Role if it exists iam_role = utils.find_rel_by_node_type( ctx.instance, 'cloudify.nodes.aws.iam.Role') if iam_role: params['Role'] = utils.get_resource_arn( node=iam_role.target.node, instance=iam_role.target.instance, raise_on_missing=True) # 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 AWS EC2 Instances''' params = \ dict() if not resource_config else resource_config.copy() params['UserData'] = _handle_userdata(params.get('UserData', '')) # Add subnet from relationship if provided. subnet_id = params.get(SUBNET_ID) if not subnet_id: relationship = utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE) if relationship: target = relationship if target: params[SUBNET_ID] = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) del subnet_id, target, relationship # Add security groups from relationships if provided. group_ids = params.get(GROUPIDS, []) relationships = utils.find_rels_by_node_type(ctx.instance, GROUP_TYPE) for relationship in relationships: target = relationship if target is not None: group_id = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) if group_id not in group_ids: group_ids.append(group_id) del group_id del target, relationship params[GROUPIDS] = group_ids # Get all nics from relationships. nics_from_rels = [] relationships = utils.find_rels_by_node_type( ctx.instance, NETWORK_INTERFACE_TYPE) for relationship in relationships: target = relationship if target is not None: rel_nic_id = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) rel_device_index = target.target.instance.runtime_properties.get( 'device_index') rel_nic = { NIC_ID: rel_nic_id, DEVICE_INDEX: rel_device_index } nics_from_rels.append(rel_nic) del target, rel_nic_id, rel_device_index, rel_nic # Get all nics from the resource_config dict. nics_from_params = params.get(NETWORK_INTERFACES, []) # Merge the two lists. merged_nics = [] nics = defaultdict(dict) for nic in (nics_from_rels, nics_from_params): for i in nic: nics[i[NIC_ID]].update(i) merged_nics = nics.values() del nic, nics for counter, nic in enumerate( sorted(merged_nics, key=lambda k: k.get(DEVICE_INDEX))): if not nic[DEVICE_INDEX]: nic[DEVICE_INDEX] = counter params[NETWORK_INTERFACES] = merged_nics create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() try: instance = create_response[INSTANCES][0] except (KeyError, IndexError) as e: raise NonRecoverableError( 'Error {0}: create response has no instances: {1}'.format( e.message, create_response)) instance_id = instance.get(INSTANCE_ID, '') iface.update_resource_id(instance_id) utils.update_resource_id(ctx.instance, instance_id) modify_instance_attribute_args = \ _.get('modify_instance_attribute_args') if modify_instance_attribute_args: modify_instance_attribute_args[INSTANCE_ID] = \ instance_id iface.modify_instance_attribute( modify_instance_attribute_args)
def create(ctx, iface, resource_config, **_): '''Creates AWS EC2 Instances''' params = \ dict() if not resource_config else resource_config.copy() params['UserData'] = _handle_userdata(params.get('UserData', '')) # Add subnet from relationship if provided. subnet_id = params.get(SUBNET_ID) if not subnet_id: relationship = utils.find_rel_by_node_type(ctx.instance, SUBNET_TYPE) if relationship: target = relationship if target: params[SUBNET_ID] = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) del subnet_id, target, relationship # Add security groups from relationships if provided. group_ids = params.get(GROUPIDS, []) relationships = utils.find_rels_by_node_type(ctx.instance, GROUP_TYPE) for relationship in relationships: target = relationship if target is not None: group_id = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) if group_id not in group_ids: group_ids.append(group_id) del group_id del target, relationship params[GROUPIDS] = group_ids # Get all nics from relationships. nics_from_rels = [] relationships = utils.find_rels_by_node_type(ctx.instance, NETWORK_INTERFACE_TYPE) for relationship in relationships: target = relationship if target is not None: rel_nic_id = \ target.target.instance.runtime_properties.get( EXTERNAL_RESOURCE_ID) rel_device_index = target.target.instance.runtime_properties.get( 'device_index') rel_nic = {NIC_ID: rel_nic_id, DEVICE_INDEX: rel_device_index} nics_from_rels.append(rel_nic) del target, rel_nic_id, rel_device_index, rel_nic # Get all nics from the resource_config dict. nics_from_params = params.get(NETWORK_INTERFACES, []) # Merge the two lists. merged_nics = [] nics = defaultdict(dict) for nic in (nics_from_rels, nics_from_params): for i in nic: nics[i[NIC_ID]].update(i) merged_nics = nics.values() del nic, nics for counter, nic in enumerate( sorted(merged_nics, key=lambda k: k.get(DEVICE_INDEX))): if not nic[DEVICE_INDEX]: nic[DEVICE_INDEX] = counter params[NETWORK_INTERFACES] = merged_nics create_response = iface.create(params) ctx.instance.runtime_properties['create_response'] = \ utils.JsonCleanuper(create_response).to_dict() try: instance = create_response[INSTANCES][0] except (KeyError, IndexError) as e: raise NonRecoverableError( 'Error {0}: create response has no instances: {1}'.format( e.message, create_response)) instance_id = instance.get(INSTANCE_ID, '') iface.update_resource_id(instance_id) utils.update_resource_id(ctx.instance, instance_id) modify_instance_attribute_args = \ _.get('modify_instance_attribute_args') if modify_instance_attribute_args: modify_instance_attribute_args[INSTANCE_ID] = \ instance_id iface.modify_instance_attribute(modify_instance_attribute_args)