コード例 #1
0
def connect_floatingip(nova_client, fixed_ip, **kwargs):
    server_id = get_openstack_id(ctx.source)
    floating_ip_id = get_openstack_id(ctx.target)

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external floatingip and server '
                        'are associated')
        if nova_client.floating_ips.get(floating_ip_id).instance_id ==\
                server_id:
            return
        raise NonRecoverableError(
            'Expected external resources server {0} and floating-ip {1} to be '
            'connected'.format(server_id, floating_ip_id))

    floating_ip_address = ctx.target.instance.runtime_properties[
        IP_ADDRESS_PROPERTY]
    server = nova_client.servers.get(server_id)
    server.add_floating_ip(floating_ip_address, fixed_ip or None)

    server = nova_client.servers.get(server_id)
    all_server_ips = reduce(operator.add, server.networks.values())
    if floating_ip_address not in all_server_ips:
        return ctx.operation.retry(message='Failed to assign floating ip {0}'
                                           ' to machine {1}.'
                                   .format(floating_ip_address, server_id))
コード例 #2
0
def connect_security_group(neutron_client, **kwargs):
    port_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    security_group_id = ctx.target.instance.runtime_properties[
        OPENSTACK_ID_PROPERTY]

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external port and security-group are '
                        'connected')
        if any(sg for sg in neutron_client.show_port(port_id)['port'].get(
                'security_groups', []) if sg == security_group_id):
            return
        raise NonRecoverableError(
            'Expected external resources port {0} and security-group {1} to '
            'be connected'.format(port_id, security_group_id))

    # WARNING: non-atomic operation
    port = neutron_client.cosmo_get('port', id=port_id)
    ctx.logger.info(
        "connect_security_group(): source_id={0} target={1}".format(
            port_id, ctx.target.instance.runtime_properties))
    sgs = port['security_groups'] + [security_group_id]
    neutron_client.update_port(port_id, {'port': {'security_groups': sgs}})

    # Double check if SG has been actually updated (a race-condition
    # in OpenStack):
    port_info = neutron_client.show_port(port_id)['port']
    port_security_groups = port_info.get('security_groups', [])
    if security_group_id not in port_security_groups:
        return ctx.operation.retry(
            message='Security group connection (`{0}\' -> `{1}\')'
                    ' has not been established!'.format(port_id,
                                                        security_group_id),
            retry_after=NO_SG_PORT_CONNECTION_RETRY_INTERVAL
        )
コード例 #3
0
def connect_security_group(nova_client, **kwargs):
    server_id = get_openstack_id(ctx.source)
    security_group_id = get_openstack_id(ctx.target)
    security_group_name = ctx.target.instance.runtime_properties[
        OPENSTACK_NAME_PROPERTY]

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external security group and server '
                        'are associated')
        server = nova_client.servers.get(server_id)
        if [sg for sg in server.list_security_group() if sg.id ==
                security_group_id]:
            return
        raise NonRecoverableError(
            'Expected external resources server {0} and security-group {1} to '
            'be connected'.format(server_id, security_group_id))

    server = nova_client.servers.get(server_id)
    for security_group in server.list_security_group():
        # Since some security groups are already attached in
        # create this will ensure that they are not attached twice.
        if security_group_id != security_group.id and \
                security_group_name != security_group.name:
            # to support nova security groups as well,
            # we connect the security group by name
            # (as connecting by id
            # doesn't seem to work well for nova SGs)
            server.add_security_group(security_group_name)

    _validate_security_group_and_server_connection_status(nova_client,
                                                          server_id,
                                                          security_group_id,
                                                          security_group_name,
                                                          is_connected=True)
コード例 #4
0
def connect_security_group(nova_client, **kwargs):
    server_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    security_group_id = ctx.target.instance.runtime_properties[
        OPENSTACK_ID_PROPERTY]
    security_group_name = ctx.target.instance.runtime_properties[
        OPENSTACK_NAME_PROPERTY]

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external security group and server '
                        'are associated')
        server = nova_client.servers.get(server_id)
        if [sg for sg in server.list_security_group() if sg.id ==
                security_group_id]:
            return
        raise NonRecoverableError(
            'Expected external resources server {0} and security-group {1} to '
            'be connected'.format(server_id, security_group_id))

    server = nova_client.servers.get(server_id)
    for security_group in server.list_security_group():
        # Since some security groups are already attached in
        # create this will ensure that they are not attached twice.
        if security_group_id != security_group.id and \
                security_group_name != security_group.name:
            # to support nova security groups as well,
            # we connect the security group by name
            # (as connecting by id
            # doesn't seem to work well for nova SGs)
            server.add_security_group(security_group_name)

    _validate_security_group_and_server_connection_status(nova_client,
                                                          server_id,
                                                          security_group_id,
                                                          security_group_name,
                                                          is_connected=True)
コード例 #5
0
def connect_floatingip(nova_client, fixed_ip, **kwargs):
    server_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    floating_ip_id = ctx.target.instance.runtime_properties[
        OPENSTACK_ID_PROPERTY]

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external floatingip and server '
                        'are associated')
        if nova_client.floating_ips.get(floating_ip_id).instance_id ==\
                server_id:
            return
        raise NonRecoverableError(
            'Expected external resources server {0} and floating-ip {1} to be '
            'connected'.format(server_id, floating_ip_id))

    floating_ip_address = ctx.target.instance.runtime_properties[
        IP_ADDRESS_PROPERTY]
    server = nova_client.servers.get(server_id)
    server.add_floating_ip(floating_ip_address, fixed_ip or None)

    server = nova_client.servers.get(server_id)
    all_server_ips = reduce(operator.add, server.networks.values())
    if floating_ip_address not in all_server_ips:
        return ctx.operation.retry(message='Failed to assign floating ip {0}'
                                           ' to machine {1}.'
                                   .format(floating_ip_address, server_id))
コード例 #6
0
def connect_security_group(nova_client, **kwargs):
    server_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    security_group_id = ctx.target.instance.runtime_properties[
        OPENSTACK_ID_PROPERTY]
    security_group_name = ctx.target.instance.runtime_properties[
        OPENSTACK_NAME_PROPERTY]

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external security group and server '
                        'are associated')
        server = nova_client.servers.get(server_id)
        if [
                sg for sg in server.list_security_group()
                if sg.id == security_group_id
        ]:
            return
        raise NonRecoverableError(
            'Expected external resources server {0} and security-group {1} to '
            'be connected'.format(server_id, security_group_id))

    server = nova_client.servers.get(server_id)
    # to support nova security groups as well, we connect the security group
    # by name (as connecting by id doesn't seem to work well for nova SGs)
    server.add_security_group(security_group_name)

    _validate_security_group_and_server_connection_status(nova_client,
                                                          server_id,
                                                          security_group_id,
                                                          security_group_name,
                                                          is_connected=True)
コード例 #7
0
def attach_volume(nova_client, cinder_client, status_attempts,
                  status_timeout, **kwargs):
    server_id = get_openstack_id(ctx.target)
    volume_id = get_openstack_id(ctx.source)

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external volume and server '
                        'are connected')
        attachment = volume.get_attachment(cinder_client=cinder_client,
                                           volume_id=volume_id,
                                           server_id=server_id)
        if attachment:
            return
        else:
            raise NonRecoverableError(
                'Expected external resources server {0} and volume {1} to be '
                'connected'.format(server_id, volume_id))

    # Note: The 'device_name' property should actually be a property of the
    # relationship between a server and a volume; It'll move to that
    # relationship type once relationship properties are better supported.
    device = ctx.source.node.properties[volume.DEVICE_NAME_PROPERTY]
    nova_client.volumes.create_server_volume(
        server_id,
        volume_id,
        device if device != 'auto' else None)
    try:
        vol, wait_succeeded = volume.wait_until_status(
            cinder_client=cinder_client,
            volume_id=volume_id,
            status=volume.VOLUME_STATUS_IN_USE,
            num_tries=status_attempts,
            timeout=status_timeout
        )
        if not wait_succeeded:
            raise RecoverableError(
                'Waiting for volume status {0} failed - detaching volume and '
                'retrying..'.format(volume.VOLUME_STATUS_IN_USE))
        if device == 'auto':
            # The device name was assigned automatically so we
            # query the actual device name
            attachment = volume.get_attachment(
                cinder_client=cinder_client,
                volume_id=volume_id,
                server_id=server_id
            )
            device_name = attachment['device']
            ctx.logger.info('Detected device name for attachment of volume '
                            '{0} to server {1}: {2}'
                            .format(volume_id, server_id, device_name))
            ctx.source.instance.runtime_properties[
                volume.DEVICE_NAME_PROPERTY] = device_name
    except Exception, e:
        if not isinstance(e, NonRecoverableError):
            _prepare_attach_volume_to_be_repeated(
                nova_client, cinder_client, server_id, volume_id,
                status_attempts, status_timeout)
        raise
コード例 #8
0
def attach_volume(nova_client, cinder_client, status_attempts,
                  status_timeout, **kwargs):
    server_id = ctx.target.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    volume_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external volume and server '
                        'are connected')
        attachment = volume.get_attachment(cinder_client=cinder_client,
                                           volume_id=volume_id,
                                           server_id=server_id)
        if attachment:
            return
        else:
            raise NonRecoverableError(
                'Expected external resources server {0} and volume {1} to be '
                'connected'.format(server_id, volume_id))

    # Note: The 'device_name' property should actually be a property of the
    # relationship between a server and a volume; It'll move to that
    # relationship type once relationship properties are better supported.
    device = ctx.source.node.properties[volume.DEVICE_NAME_PROPERTY]
    nova_client.volumes.create_server_volume(
        server_id,
        volume_id,
        device if device != 'auto' else None)
    try:
        vol, wait_succeeded = volume.wait_until_status(
            cinder_client=cinder_client,
            volume_id=volume_id,
            status=volume.VOLUME_STATUS_IN_USE,
            num_tries=status_attempts,
            timeout=status_timeout
        )
        if not wait_succeeded:
            raise RecoverableError(
                'Waiting for volume status {0} failed - detaching volume and '
                'retrying..'.format(volume.VOLUME_STATUS_IN_USE))
        if device == 'auto':
            # The device name was assigned automatically so we
            # query the actual device name
            attachment = volume.get_attachment(
                cinder_client=cinder_client,
                volume_id=volume_id,
                server_id=server_id
            )
            device_name = attachment['device']
            ctx.logger.info('Detected device name for attachment of volume '
                            '{0} to server {1}: {2}'
                            .format(volume_id, server_id, device_name))
            ctx.source.instance.runtime_properties[
                volume.DEVICE_NAME_PROPERTY] = device_name
    except Exception, e:
        if not isinstance(e, NonRecoverableError):
            _prepare_attach_volume_to_be_repeated(
                nova_client, cinder_client, server_id, volume_id,
                status_attempts, status_timeout)
        raise
コード例 #9
0
def connect_port(neutron_client, **kwargs):
    if is_external_relationship_not_conditionally_created(ctx):
        return

    port_id = get_openstack_id(ctx.source)
    floating_ip_id = get_openstack_id(ctx.target)
    fip = {'port_id': port_id}
    neutron_client.update_floatingip(floating_ip_id,
                                     {FLOATINGIP_OPENSTACK_TYPE: fip})
コード例 #10
0
def connect_port(neutron_client, **kwargs):
    if is_external_relationship_not_conditionally_created(ctx):
        return

    port_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    floating_ip_id = ctx.target.instance.runtime_properties[
        OPENSTACK_ID_PROPERTY]
    fip = {'port_id': port_id}
    neutron_client.update_floatingip(floating_ip_id, {'floatingip': fip})
コード例 #11
0
def connect_port(neutron_client, **kwargs):
    if is_external_relationship_not_conditionally_created(ctx):
        return

    port_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    floating_ip_id = ctx.target.instance.runtime_properties[
        OPENSTACK_ID_PROPERTY]
    fip = {'port_id': port_id}
    neutron_client.update_floatingip(floating_ip_id, {'floatingip': fip})
コード例 #12
0
def connect_subnet(neutron_client, **kwargs):
    router_id = get_openstack_id(ctx.target)
    subnet_id = get_openstack_id(ctx.source)

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external subnet and router '
                        'are associated')
        for port in neutron_client.list_ports(device_id=router_id)['ports']:
            for fixed_ip in port.get('fixed_ips', []):
                if fixed_ip.get('subnet_id') == subnet_id:
                    return
        raise NonRecoverableError(
            'Expected external resources router {0} and subnet {1} to be '
            'connected'.format(router_id, subnet_id))

    neutron_client.add_interface_router(router_id, {'subnet_id': subnet_id})
コード例 #13
0
def connect_subnet(neutron_client, **kwargs):
    router_id = ctx.target.instance.runtime_properties[OPENSTACK_ID_PROPERTY]
    subnet_id = ctx.source.instance.runtime_properties[OPENSTACK_ID_PROPERTY]

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external subnet and router '
                        'are associated')
        for port in neutron_client.list_ports(device_id=router_id)['ports']:
            for fixed_ip in port.get('fixed_ips', []):
                if fixed_ip.get('subnet_id') == subnet_id:
                    return
        raise NonRecoverableError(
            'Expected external resources router {0} and subnet {1} to be '
            'connected'.format(router_id, subnet_id))

    neutron_client.add_interface_router(router_id, {'subnet_id': subnet_id})
コード例 #14
0
def connect_security_group(neutron_client, **kwargs):
    port_id = get_openstack_id(ctx.source)
    security_group_id = get_openstack_id(ctx.target)

    if is_external_relationship_not_conditionally_created(ctx):
        ctx.logger.info('Validating external port and security-group are '
                        'connected')
        if any(sg for sg in neutron_client.show_port(port_id)['port'].get(
                'security_groups', []) if sg == security_group_id):
            return
        raise NonRecoverableError(
            'Expected external resources port {0} and security-group {1} to '
            'be connected'.format(port_id, security_group_id))

    # WARNING: non-atomic operation
    port = neutron_client.cosmo_get(PORT_OPENSTACK_TYPE, id=port_id)
    ctx.logger.info(
        "connect_security_group(): source_id={0} target={1}".format(
            port_id, ctx.target.instance.runtime_properties))
    # We could just pass the port['security_groups']
    # dict here with a new element, however we need to test
    # a race condition in Openstack so we need to copy the security
    # group list.
    sgs = port['security_groups'][:]
    if security_group_id not in port['security_groups']:
        sgs.append(security_group_id)
    neutron_client.update_port(port_id,
                               {PORT_OPENSTACK_TYPE: {
                                   'security_groups': sgs
                               }})

    # Double check if SG has been actually updated (a race-condition
    # in OpenStack):
    port_info = neutron_client.show_port(port_id)['port']
    port_security_groups = port_info.get('security_groups', [])
    if security_group_id not in port_security_groups:
        return ctx.operation.retry(
            message='Security group connection (`{0}\' -> `{1}\')'
            ' has not been established!'.format(port_id, security_group_id),
            retry_after=NO_SG_PORT_CONNECTION_RETRY_INTERVAL)