예제 #1
0
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)
예제 #2
0
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Route Table'''
    params = dict() if not resource_config else resource_config.copy()

    vpc_id = params.get(VPC_ID)

    # If either of these values is missing,
    # they must be filled from a connected VPC.
    if not vpc_id:
        targ = \
            utils.find_rel_by_node_type(ctx.instance, VPC_TYPE) or \
            utils.find_rel_by_node_type(ctx.instance, VPC_TYPE_DEPRECATED)

        # Attempt to use the VPC ID from parameters.
        # Fallback to connected VPC.
        params[VPC_ID] = vpc_id or targ.target\
            .instance.runtime_properties.get(EXTERNAL_RESOURCE_ID)

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    route_table_id = create_response.get(ROUTETABLE_ID)
    iface.update_resource_id(route_table_id)
    utils.update_resource_id(ctx.instance, route_table_id)
def create(ctx, iface, resource_config, **_):
    """Creates an AWS EC2 NetworkAcl"""

    # Create a copy of the resource config for clean manipulation.
    params = \
        dict() if not resource_config else resource_config.copy()

    vpc_id = params.get(VPC_ID)
    if not vpc_id:
        targ = \
            utils.find_rel_by_node_type(ctx.instance, VPC_TYPE) or \
            utils.find_rel_by_node_type(ctx.instance, VPC_TYPE_DEPRECATED)

        # Attempt to use the VPC ID from parameters.
        # Fallback to connected VPC.
        params[VPC_ID] = \
            vpc_id or \
            targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID)

    # Actually create the resource
    create_response = iface.create(params)['NetworkAcl']
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    network_acl_id = create_response.get(NETWORKACL_ID, '')
    iface.update_resource_id(network_acl_id)
    utils.update_resource_id(ctx.instance, network_acl_id)
def create(ctx, iface, resource_config, **_):
    """Creates an AWS 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)
예제 #5
0
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Security Group'''
    params = \
        dict() if not resource_config else resource_config.copy()

    vpc_id = params.get(VPC_ID)

    # Try to get the group_name and if it does not exits then try to
    # generate new one based on instance_id
    group_name = params.get(GROUP_NAME)
    params[GROUP_NAME] = utils.get_ec2_vpc_resource_name(group_name)

    if not vpc_id:
        vpc = \
            utils.find_rel_by_node_type(
                ctx.instance,
                VPC_TYPE) or utils.find_rel_by_node_type(
                ctx.instance,
                VPC_TYPE_DEPRECATED)
        params[VPC_ID] = \
            vpc_id or \
            vpc.target.instance.runtime_properties.get(
                EXTERNAL_RESOURCE_ID)

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    group_id = create_response.get(GROUPID, '')
    iface.update_resource_id(group_id)
    utils.update_resource_id(ctx.instance, group_id)
예제 #6
0
def attach(ctx, iface, resource_config, **_):
    """
    Attaches an AWS EC2 EBS Volume TO Instance
    :param ctx:
    :param iface:
    :param resource_config:
    :param _:
    :return:
    """
    params = \
        dict() if not resource_config else resource_config.copy()

    # Attach ebs volume to ec2 instance resource
    create_response = iface.create(params)

    # Check if the resource attaching done
    if create_response:
        ctx.instance.runtime_properties['eps_attach'] =\
            utils.JsonCleanuper(create_response).to_dict()

        # Update the esp_id (volume_id)
        esp_id = create_response.get(VOLUME_ID, '')
        utils.update_resource_id(ctx.instance, esp_id)
        iface.update_resource_id(esp_id)

    else:
        raise NonRecoverableError(
            '{0} ID# "{1}" reported an empty response'
            .format(RESOURCE_TYPE_VOLUME_ATTACHMENT, iface.resource_id))
예제 #7
0
def create(ctx, iface, resource_config, **_):
    '''Creates AWS EC2 Keypairs'''

    params = \
        dict() if not resource_config else resource_config.copy()

    params[KEYNAME] = utils.get_resource_name(params.get(KEYNAME))
    key_name = params[KEYNAME]

    if PUBLIC_KEY_MATERIAL in params:
        create_response = \
            iface.import_keypair(
                params,
                log_response=ctx.node.properties['log_create_response'])
    else:
        create_response = iface.create(
            params, log_response=ctx.node.properties['log_create_response'])

        # Allow the end user to store the key material in a secret.
        if ctx.node.properties['create_secret']:

            try:
                client = get_rest_client()
            except KeyError:  # No pun intended.
                raise NonRecoverableError(
                    'create_secret is only supported with a Cloudify Manager.')

            # This makes the line too long for flake8 if included in args.
            secret_name = ctx.node.properties.get('secret_name', key_name)
            secrets_count = len(client.secrets.list(key=secret_name))
            secret_value = create_response.get('KeyMaterial')

            try:
                if secrets_count == 0:
                    client.secrets.create(
                        key=secret_name,
                        value=secret_value)
                elif secrets_count == 1 and \
                        ctx.node.properties.get(
                            'update_existing_secret', False) is True:
                    client.secrets.update(
                        key=secret_name,
                        value=secret_value)
            except CloudifyClientError as e:
                raise NonRecoverableError(str(e))

    cleaned_create_response = \
        utils.JsonCleanuper(create_response).to_dict()

    # Allow the end user to opt-in to storing the key
    # material in the runtime properties.
    # Default is false
    if 'KeyMaterial' in cleaned_create_response and not \
            ctx.node.properties['store_in_runtime_properties']:
        del cleaned_create_response['KeyMaterial']
    ctx.instance.runtime_properties['create_response'] = \
        cleaned_create_response

    iface.update_resource_id(cleaned_create_response.get(KEYNAME))
    utils.update_resource_id(ctx.instance, key_name)
예제 #8
0
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Route'''
    params = dict() if not resource_config else resource_config.copy()

    routetable_id = params.get(ROUTETABLE_ID)
    gateway_id = params.get(GATEWAY_ID)
    natgateway_id = params.get(NATGATEWAY_ID)

    # If this value is missing,
    # it must be filled from a connected Route Table.
    if not routetable_id:
        targ = \
            utils.find_rel_by_node_type(ctx.instance, ROUTETABLE_TYPE) or \
            utils.find_rel_by_node_type(ctx.instance,
                                        ROUTETABLE_TYPE_DEPRECATED)

        # Attempt to use the Route Table ID from parameters.
        # Fallback to connected Route Table.
        params[ROUTETABLE_ID] = \
            routetable_id or \
            targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID)

    ctx.instance.runtime_properties['routetable_id'] = params[ROUTETABLE_ID]
    ctx.instance.runtime_properties['destination_cidr_block'] = \
        params[DESTINATION_CIDR_BLOCK]

    # If this value is missing,
    # it must be filled from a connected Route Table.
    if not gateway_id:
        targ = \
            utils.find_rel_by_node_type(ctx.instance,
                                        INTERNETGATEWAY_TYPE) or \
            utils.find_rel_by_node_type(ctx.instance,
                                        INTERNETGATEWAY_TYPE_DEPRECATED) or \
            utils.find_rel_by_node_type(ctx.instance, VPNGATEWAY_TYPE) or \
            utils.find_rel_by_node_type(ctx.instance,
                                        VPNGATEWAY_TYPE_DEPRECATED)

        # Attempt to use the Route Table ID from parameters.
        # Fallback to connected Route Table.
        if gateway_id or targ:
            params[GATEWAY_ID] = \
                gateway_id or targ.target.instance.runtime_properties\
                .get(EXTERNAL_RESOURCE_ID)

    if not natgateway_id:
        targ = utils.find_rel_by_node_type(ctx.instance, NATGATEWAY_TYPE)

        # Attempt to use the Route Table ID from parameters.
        # Fallback to connected Route Table.
        if natgateway_id or targ:
            params[NATGATEWAY_ID] = \
                natgateway_id or targ.target.instance.runtime_properties\
                .get(EXTERNAL_RESOURCE_ID)

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Internet Gateway'''
    params = dict() if not resource_config else resource_config.copy()
    create_response = iface.create(params)['InternetGateway']
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    utils.update_resource_id(ctx.instance,
                             create_response.get(INTERNETGATEWAY_ID))
예제 #10
0
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Vpc'''
    params = \
        dict() if not resource_config else resource_config.copy()

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    vpc_id = create_response.get(VPC_ID, '')
    iface.update_resource_id(vpc_id)
    utils.update_resource_id(ctx.instance, vpc_id)
예제 #11
0
        def wrapper_inner(**kwargs):
            '''Inner, worker function'''
            ctx = kwargs['ctx']
            _, _, _, operation_name = ctx.operation.name.split('.')
            resource_type = kwargs.get('resource_type', 'AWS Resource')
            iface = kwargs['iface']
            # Run the operation if this is the first pass
            if ctx.operation.retry_number == 0:
                function(**kwargs)
                # issue 128 and issue 129
                # by updating iface object with actual details from the
                # AWS response assuming that actual state is available
                # at ctx.instance.runtime_properties['create_response']
                # and ctx.instance.runtime_properties[EXT_RES_ID]
                # correctly updated after creation

                # At first let's verify was a new AWS resource
                # really created
                if iface.resource_id != \
                        ctx.instance.runtime_properties.get(EXT_RES_ID):
                    # Assuming new resource was really created,
                    # so updating iface object
                    iface.resource_id = \
                        ctx.instance.runtime_properties.get(EXT_RES_ID)
                    # If sequence of install -> uninstall workflows was
                    # executed, we should remove '__deleted'
                    # flag set in the decorator wait_for_delete below
                    if '__deleted' in ctx.instance.runtime_properties:
                        del ctx.instance.runtime_properties['__deleted']

            # Get a resource interface and query for the status
            status = iface.status
            ctx.logger.debug('%s ID# "%s" reported status: %s' %
                             (resource_type, iface.resource_id, status))
            if status_pending and status in status_pending:
                raise OperationRetry(
                    '%s ID# "%s" is still in a pending state.' %
                    (resource_type, iface.resource_id))

            elif status_good and status in status_good:
                if operation_name in ['create', 'configure']:
                    ctx.instance.runtime_properties['create_response'] = \
                        utils.JsonCleanuper(iface.properties).to_dict()

            elif not status and fail_on_missing:
                raise NonRecoverableError(
                    '%s ID# "%s" no longer exists but "fail_on_missing" set' %
                    (resource_type, iface.resource_id))
            elif status_good and status not in status_good and fail_on_missing:
                raise NonRecoverableError(
                    '%s ID# "%s" reported an unexpected status: "%s"' %
                    (resource_type, iface.resource_id, status))
예제 #12
0
def create(ctx, iface, resource_config, **_):
    """Creates an AWS EC2 VPN Gateway"""

    # Create a copy of the resource config for clean manipulation.
    params = \
        dict() if not resource_config else resource_config.copy()

    # Actually create the resource
    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    utils.update_resource_id(ctx.instance, create_response.get(VPNGATEWAY_ID))
예제 #13
0
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Subnet'''
    params = dict() if not resource_config else resource_config.copy()

    vpc_id = params.get(VPC_ID)
    cidr_block = params.get(CIDR_BLOCK)
    ipv6_cidr_block = params.get(IPV6_CIDR_BLOCK)

    # If either of these values is missing,
    # they must be filled from a connected VPC.
    if not vpc_id or not cidr_block:
        targ = \
            utils.find_rel_by_node_type(
                ctx.instance,
                VPC_TYPE) or utils.find_rel_by_node_type(
                ctx.instance,
                VPC_TYPE_DEPRECATED)

        # Attempt to use the VPC ID from parameters.
        # Fallback to connected VPC.
        params[VPC_ID] = \
            vpc_id or \
            targ.target.instance.runtime_properties.get(
                EXTERNAL_RESOURCE_ID)
        # Attempt to use the CIDR Block from parameters.
        # Fallback to connected VPC.
        params[CIDR_BLOCK] = \
            cidr_block or \
            targ.instance.runtime_properties.get(
                'resource_config', {}).get(CIDR_BLOCK)

    # If ipv6 cidr block is provided by user, then we need to make sure that
    # The subnet size must use a /64 prefix length
    if ipv6_cidr_block:
        ipv6_cidr_block = ipv6_cidr_block[:-2] + '64'
        params[IPV6_CIDR_BLOCK] = ipv6_cidr_block

    # Actually create the resource
    create_response = iface.create(params)[SUBNET]
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    subnet_id = create_response.get(SUBNET_ID)
    iface.update_resource_id(subnet_id)
    utils.update_resource_id(ctx.instance, subnet_id)

    modify_subnet_attribute_args = \
        _.get('modify_subnet_attribute_args')
    if modify_subnet_attribute_args:
        modify_subnet_attribute_args[SUBNET_ID] = \
            subnet_id
        iface.modify_subnet_attribute(modify_subnet_attribute_args)
예제 #14
0
def create(ctx, iface, resource_config, **_):
    """Creates an AWS EC2 DhcpOptions"""

    # Create a copy of the resource config for clean manipulation.
    params = \
        dict() if not resource_config else resource_config.copy()

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    dhcp_options_id = create_response.get(DHCPOPTIONS_ID, '')
    iface.update_resource_id(dhcp_options_id)
    utils.update_resource_id(ctx.instance, dhcp_options_id)
예제 #15
0
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()
예제 #16
0
def create(ctx, iface, resource_config, **_):
    """Creates an AWS EC2 ElasticIP"""

    # Create a copy of the resource config for clean manipulation.
    params = \
        dict() if not resource_config else resource_config.copy()

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    elasticip_id = create_response.get(ELASTICIP_ID, '')
    iface.update_resource_id(elasticip_id)
    utils.update_resource_id(ctx.instance, elasticip_id)
    ctx.instance.runtime_properties['allocation_id'] = \
        create_response.get(ALLOCATION_ID)
예제 #17
0
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Tags'''
    params = \
        dict() if not resource_config else resource_config.copy()

    resources = params.get('Resources')
    if not resources:
        targets = \
            utils.find_rels_by_type(
                ctx.instance,
                'cloudify.relationships.depends_on')
        resources = \
            [rel.target.instance.runtime_properties
             .get(EXTERNAL_RESOURCE_ID) for rel in targets]
        params['Resources'] = resources

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
def create(ctx, iface, resource_config, **_):
    """Creates an AWS EC2 NAT Gateway"""

    # 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:
        subnet_id = \
            utils.find_resource_id_by_type(
                ctx.instance, SUBNET_TYPE) or \
            utils.find_resource_id_by_type(
                ctx.instance, SUBNET_TYPE_DEPRECATED)
        params.update({SUBNET_ID: subnet_id})

    allocation_id = params.get(ALLOCATION_ID)
    if not allocation_id:
        targ = \
            utils.find_rel_by_node_type(
                ctx.instance,
                ELASTICIP_TYPE) or \
            utils.find_rel_by_node_type(
                ctx.instance,
                ELASTICIP_TYPE_DEPRECATED)
        if targ:
            allocation_id = \
                targ.target.instance.runtime_properties.get(
                    ALLOCATION_ID_DEPRECATED)
    params[ALLOCATION_ID] = allocation_id
    ctx.instance.runtime_properties['allocation_id'] = \
        allocation_id

    # Actually create the resource
    create_response = iface.create(params)['NatGateway']
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    utils.update_resource_id(
        ctx.instance, create_response.get(NATGATEWAY_ID))
예제 #19
0
def create(ctx, iface, resource_config, **_):
    """Creates an AWS EC2 NetworkAcl Entry"""

    # Create a copy of the resource config for clean manipulation.
    params = \
        dict() if not resource_config else resource_config.copy()

    network_acl_id = params.get(NETWORKACL_ID)
    rule_number = params.get(RULE_NUMBER)
    egress = params.get(EGRESS)

    if not network_acl_id:
        targ = \
            utils.find_rel_by_node_type(ctx.instance, NETWORKACL_TYPE) or \
            utils.find_rel_by_node_type(ctx.instance,
                                        NETWORKACL_TYPE_DEPRECATED)

        # Attempt to use the NETWORKACL ID from parameters.
        # Fallback to connected NETWORKACL.
        params[NETWORKACL_ID] = \
            network_acl_id or \
            targ.target.instance.runtime_properties.get(EXTERNAL_RESOURCE_ID)

    ctx.instance.runtime_properties['network_acl_id'] = params[NETWORKACL_ID]
    ctx.instance.runtime_properties['rule_number'] = rule_number
    ctx.instance.runtime_properties['egress'] = egress

    filters = {NETWORKACL_IDS: [params[NETWORKACL_ID]]}
    network_acl_entry = iface.get_properties_by_filter(**filters)
    entry = network_acl_entry.get(ENTRIES)[0]
    # for rule in entries:
    if rule_number == entry.get(RULE_NUMBER):
        return iface.replace(params)

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
예제 #20
0
def create(ctx, iface, resource_config, **_):
    """Creates an AWS EC2 Customer Gateway"""

    # Create a copy of the resource config for clean manipulation.
    params = \
        dict() if not resource_config else resource_config.copy()

    public_ip = params.get(PUBLIC_IP)
    if not public_ip:
        targ = \
            utils.find_rel_by_node_type(ctx.instance, ELASTICIP_TYPE)
        if targ:
            public_ip = \
                targ.target.instance.runtime_properties \
                    .get(ELASTICIP_TYPE_DEPRECATED)
        params.update({PUBLIC_IP: public_ip})

    # Actually create the resource
    create_response = iface.create(params)['CustomerGateway']
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    utils.update_resource_id(ctx.instance,
                             create_response.get(CUSTOMERGATEWAY_ID))
예제 #21
0
def create(ctx, iface, resource_config, **_):
    '''Creates an AWS EC2 Subnet'''
    params = dict() if not resource_config else resource_config.copy()

    vpc_id = params.get(VPC_ID)
    cidr_block = params.get(CIDR_BLOCK)

    # If either of these values is missing,
    # they must be filled from a connected VPC.
    if not vpc_id or not cidr_block:
        targ = \
            utils.find_rel_by_node_type(
                ctx.instance,
                VPC_TYPE) or utils.find_rel_by_node_type(
                ctx.instance,
                VPC_TYPE_DEPRECATED)

        # Attempt to use the VPC ID from parameters.
        # Fallback to connected VPC.
        params[VPC_ID] = \
            vpc_id or \
            targ.target.instance.runtime_properties.get(
                EXTERNAL_RESOURCE_ID)
        # Attempt to use the CIDR Block from parameters.
        # Fallback to connected VPC.
        params[CIDR_BLOCK] = \
            cidr_block or \
            targ.instance.runtime_properties.get(
                'resource_config', {}).get(CIDR_BLOCK)

    # Actually create the resource
    create_response = iface.create(params)
    ctx.instance.runtime_properties['create_response'] = \
        utils.JsonCleanuper(create_response).to_dict()
    subnet_id = create_response.get(SUBNET_ID)
    iface.update_resource_id(subnet_id)
    utils.update_resource_id(ctx.instance, subnet_id)
예제 #22
0
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)