Exemple #1
0
def ipam_release_pool():
    """Deletes a new Neutron subnetpool from the given reuest.

    This function takes the following JSON data and delegates the subnetpool
    deletion to the Neutron client. ::

       {
           "PoolID": string
       }

    Then the following JSON response is returned. ::

       {}

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/ipam.md#releasepool  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for /IpamDriver.ReleasePool"
                     .format(json_data))
    jsonschema.validate(json_data, schemata.RELEASE_POOL_SCHEMA)
    pool_id = json_data['PoolID']
    try:
        app.neutron.delete_subnetpool(pool_id)
    except n_exceptions.Conflict as ex:
        app.logger.info(_LI("The subnetpool with ID {0} is still in use."
                        " It can't be deleted for now.").format(pool_id))
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(_LE("Error happend during deleting a "
                             "Neutron subnetpool: {0}").format(ex))
        raise

    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemple #2
0
def ipam_release_pool():
    """Deletes a new Neutron subnetpool from the given reuest.

    This function takes the following JSON data and delegates the subnetpool
    deletion to the Neutron client. ::

       {
           "PoolID": string
       }

    Then the following JSON response is returned. ::

       {}

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/ipam.md#releasepool  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug(
        "Received JSON data {0} for /IpamDriver.ReleasePool".format(json_data))
    jsonschema.validate(json_data, schemata.RELEASE_POOL_SCHEMA)
    pool_id = json_data['PoolID']
    try:
        app.neutron.delete_subnetpool(pool_id)
    except n_exceptions.Conflict as ex:
        app.logger.info(
            _LI("The subnetpool with ID {0} is still in use."
                " It can't be deleted for now.").format(pool_id))
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(
            _LE("Error happend during deleting a "
                "Neutron subnetpool: {0}").format(ex))
        raise

    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemple #3
0
def ipam_request_pool():
    """Creates a new Neutron subnetpool from the given request.

    This funciton takes the following JSON data and delegates the subnetpool
    creation to the Neutron client. ::

        {
            "AddressSpace": string
            "Pool":         string
            "SubPool":      string
            "Options":      map[string]string
            "V6":           bool
        }

    Then the following JSON response is returned. ::

        {
            "PoolID": string
            "Pool":   string
            "Data":   map[string]string
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/ipam.md#requestpool  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug(
        "Received JSON data {0} for /IpamDriver.RequestPool".format(json_data))
    jsonschema.validate(json_data, schemata.REQUEST_POOL_SCHEMA)
    requested_pool = json_data['Pool']
    requested_subpool = json_data['SubPool']
    v6 = json_data['V6']
    pool_id = ''
    subnet_cidr = ''
    if requested_pool:
        app.logger.info(_LI("Creating subnetpool with the given pool CIDR"))
        if requested_subpool:
            cidr = netaddr.IPNetwork(requested_subpool)
        else:
            cidr = netaddr.IPNetwork(requested_pool)
        subnet_cidr = _get_subnet_cidr_using_cidr(cidr)
        pool_name = utils.get_neutron_subnetpool_name(subnet_cidr)
        # Check if requested pool already exist
        pools = _get_subnetpools_by_attrs(name=pool_name)
        if pools:
            pool_id = pools[0]['id']
        if not pools:
            new_subnetpool = {
                'name': pool_name,
                'default_prefixlen': cidr.prefixlen,
                'prefixes': [subnet_cidr]
            }
            created_subnetpool_response = app.neutron.create_subnetpool(
                {'subnetpool': new_subnetpool})
            pool = created_subnetpool_response['subnetpool']
            pool_id = pool['id']
    else:
        if v6:
            default_pool_list = SUBNET_POOLS_V6
        else:
            default_pool_list = SUBNET_POOLS_V4
        pool_name = default_pool_list[0]
        pools = _get_subnetpools_by_attrs(name=pool_name)
        if pools:
            pool = pools[0]
            pool_id = pool['id']
            prefixes = pool['prefixes']
            if len(prefixes) > 1:
                app.logger.warning(
                    _LW("More than one prefixes present. "
                        "Picking first one."))
            cidr = netaddr.IPNetwork(prefixes[0])
            subnet_cidr = _get_subnet_cidr_using_cidr(cidr)
        else:
            app.logger.error(_LE("Default neutron pools not found."))
    req_pool_res = {'PoolID': pool_id, 'Pool': subnet_cidr}
    return flask.jsonify(req_pool_res)
Exemple #4
0
def network_driver_delete_network():
    """Delete the Neutron Network with name as the given NetworkID.

    This function takes the following JSON data and delegates the actual
    network deletion to the Neutron client. ::

        {
            "NetworkID": string
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/remote.md#delete-network  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.DeleteNetwork".format(json_data))
    jsonschema.validate(json_data, schemata.NETWORK_DELETE_SCHEMA)

    container_net_id = json_data['NetworkID']
    neutron_network_tags = utils.make_net_tags(container_net_id)
    existing_network_tags = neutron_network_tags + ','
    existing_network_tags += const.KURYR_EXISTING_NEUTRON_NET
    try:
        existing_networks = _get_networks_by_attrs(tags=existing_network_tags)
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(
            _LE("Error happened during listing "
                "Neutron networks: {0}").format(ex))
        raise

    if existing_networks:
        app.logger.warn(
            _LW("Network is a pre existing Neutron network, "
                "not deleting in Neutron. removing tags: {0}").format(
                    existing_network_tags))
        neutron_net_id = existing_networks[0]['id']
        _neutron_net_remove_tags(neutron_net_id, container_net_id)
        _neutron_net_remove_tag(neutron_net_id,
                                const.KURYR_EXISTING_NEUTRON_NET)
        return flask.jsonify(const.SCHEMA['SUCCESS'])

    try:
        filtered_networks = _get_networks_by_attrs(tags=neutron_network_tags)
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(
            _LE("Error happened during listing "
                "Neutron networks: {0}").format(ex))
        raise

    if not filtered_networks:
        app.logger.warn(
            _LW("Network with tags {0} cannot be found").format(
                neutron_network_tags))
    else:
        neutron_network_id = filtered_networks[0]['id']
        filtered_subnets = _get_subnets_by_attrs(network_id=neutron_network_id)
        for subnet in filtered_subnets:
            try:
                subnetpool_id = subnet.get('subnetpool_id', None)

                _cache_default_subnetpool_ids(app)

                if subnetpool_id not in app.DEFAULT_POOL_IDS:
                    # If the subnet to be deleted has any port, when some ports
                    # are referring to the subnets in other words,
                    # delete_subnet throws an exception, SubnetInUse that
                    # extends Conflict. This can happen when the multiple
                    # Docker endpoints are created with the same subnet CIDR
                    # and it's totally the normal case. So we'd just log that
                    # and continue to proceed.
                    app.neutron.delete_subnet(subnet['id'])
            except n_exceptions.Conflict as ex:
                app.logger.error(
                    _LE("Subnet, {0}, is in use. Network cant be deleted.").
                    format(subnet['id']))
                raise
            except n_exceptions.NeutronClientException as ex:
                app.logger.error(
                    _LE("Error happened during deleting a "
                        "Neutron subnets: {0}").format(ex))
                raise

        try:
            app.neutron.delete_network(neutron_network_id)
        except n_exceptions.NeutronClientException as ex:
            app.logger.error(
                _LE("Error happened during deleting a "
                    "Neutron network: {0}").format(ex))
            raise
        app.logger.info(
            _LI("Deleted the network with ID {0} successfully").format(
                neutron_network_id))
    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemple #5
0
def network_driver_create_network():
    """Creates a new Neutron Network which name is the given NetworkID.

    This function takes the following JSON data and delegates the actual
    network creation to the Neutron client. libnetwork's NetworkID is used as
    the name of Network in Neutron. ::

        {
            "NetworkID": string,
            "IPv4Data" : [{
                "AddressSpace": string,
                "Pool": ipv4-cidr-string,
                "Gateway" : ipv4-address,
                "AuxAddresses": {
                    "<identifier1>" : "<ipv4-address1>",
                    "<identifier2>" : "<ipv4-address2>",
                    ...
                }
            }, ...],
            "IPv6Data" : [{
                "AddressSpace": string,
                "Pool": ipv6-cidr-string,
                "Gateway" : ipv6-address,
                "AuxAddresses": {
                    "<identifier1>" : "<ipv6-address1>",
                    "<identifier2>" : "<ipv6-address2>",
                    ...
                }
            }, ...],
            "Options": {
                ...
            }
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/remote.md#create-network  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.CreateNetwork".format(json_data))
    jsonschema.validate(json_data, schemata.NETWORK_CREATE_SCHEMA)

    container_net_id = json_data['NetworkID']
    neutron_network_name = utils.make_net_name(container_net_id)
    pool_cidr = json_data['IPv4Data'][0]['Pool']
    gateway_ip = ''
    if 'Gateway' in json_data['IPv4Data'][0]:
        gateway_cidr = json_data['IPv4Data'][0]['Gateway']
        gateway_ip = gateway_cidr.split('/')[0]
        app.logger.debug("gateway_cidr {0}, gateway_ip {1}".format(
            gateway_cidr, gateway_ip))

    neutron_uuid = None
    neutron_name = None
    options = json_data.get('Options')
    if options:
        generic_options = options.get(const.NETWORK_GENERIC_OPTIONS)
        if generic_options:
            neutron_uuid = generic_options.get(const.NEUTRON_UUID_OPTION)
            neutron_name = generic_options.get(const.NEUTRON_NAME_OPTION)

    if not neutron_uuid and not neutron_name:
        network = app.neutron.create_network({
            'network': {
                'name': neutron_network_name,
                "admin_state_up": True
            }
        })
        network_id = network['network']['id']
        _neutron_net_add_tags(network['network']['id'], container_net_id)

        app.logger.info(
            _LI("Created a new network with name {0}"
                " successfully: {1}").format(neutron_network_name, network))
    else:
        try:
            if neutron_uuid:
                networks = _get_networks_by_attrs(id=neutron_uuid)
            else:
                networks = _get_networks_by_attrs(name=neutron_name)
            network_id = networks[0]['id']
        except n_exceptions.NeutronClientException as ex:
            app.logger.error(
                _LE("Error happened during listing "
                    "Neutron networks: {0}").format(ex))
            raise
        _neutron_net_add_tags(network_id, container_net_id)
        _neutron_net_add_tag(network_id, const.KURYR_EXISTING_NEUTRON_NET)
        app.logger.info(
            _LI("Using existing network {0} successfully").format(
                neutron_uuid))

    cidr = netaddr.IPNetwork(pool_cidr)
    subnet_network = str(cidr.network)
    subnet_cidr = '/'.join([subnet_network, str(cidr.prefixlen)])
    subnets = _get_subnets_by_attrs(network_id=network_id, cidr=subnet_cidr)
    if not subnets:
        new_subnets = [{
            'name': pool_cidr,
            'network_id': network_id,
            'ip_version': cidr.version,
            'cidr': subnet_cidr,
            'enable_dhcp': app.enable_dhcp,
        }]
        if gateway_ip:
            new_subnets[0]['gateway_ip'] = gateway_ip

        app.neutron.create_subnet({'subnets': new_subnets})

    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemple #6
0
def ipam_request_pool():
    """Creates a new Neutron subnetpool from the given request.

    This funciton takes the following JSON data and delegates the subnetpool
    creation to the Neutron client. ::

        {
            "AddressSpace": string
            "Pool":         string
            "SubPool":      string
            "Options":      map[string]string
            "V6":           bool
        }

    Then the following JSON response is returned. ::

        {
            "PoolID": string
            "Pool":   string
            "Data":   map[string]string
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/ipam.md#requestpool  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for /IpamDriver.RequestPool"
                     .format(json_data))
    jsonschema.validate(json_data, schemata.REQUEST_POOL_SCHEMA)
    requested_pool = json_data['Pool']
    requested_subpool = json_data['SubPool']
    v6 = json_data['V6']
    pool_id = ''
    subnet_cidr = ''
    if requested_pool:
        app.logger.info(_LI("Creating subnetpool with the given pool CIDR"))
        if requested_subpool:
            cidr = netaddr.IPNetwork(requested_subpool)
        else:
            cidr = netaddr.IPNetwork(requested_pool)
        subnet_cidr = _get_subnet_cidr_using_cidr(cidr)
        pool_name = utils.get_neutron_subnetpool_name(subnet_cidr)
        # Check if requested pool already exist
        pools = _get_subnetpools_by_attrs(name=pool_name)
        if pools:
            pool_id = pools[0]['id']
        if not pools:
            new_subnetpool = {
                'name': pool_name,
                'default_prefixlen': cidr.prefixlen,
                'prefixes': [subnet_cidr]}
            created_subnetpool_response = app.neutron.create_subnetpool(
                {'subnetpool': new_subnetpool})
            pool = created_subnetpool_response['subnetpool']
            pool_id = pool['id']
    else:
        if v6:
            default_pool_list = SUBNET_POOLS_V6
        else:
            default_pool_list = SUBNET_POOLS_V4
        pool_name = default_pool_list[0]
        pools = _get_subnetpools_by_attrs(name=pool_name)
        if pools:
            pool = pools[0]
            pool_id = pool['id']
            prefixes = pool['prefixes']
            if len(prefixes) > 1:
                app.logger.warning(_LW("More than one prefixes present. "
                                     "Picking first one."))
            cidr = netaddr.IPNetwork(prefixes[0])
            subnet_cidr = _get_subnet_cidr_using_cidr(cidr)
        else:
            app.logger.error(_LE("Default neutron pools not found."))
    req_pool_res = {'PoolID': pool_id,
                    'Pool': subnet_cidr}
    return flask.jsonify(req_pool_res)
Exemple #7
0
def network_driver_delete_network():
    """Delete the Neutron Network with name as the given NetworkID.

    This function takes the following JSON data and delegates the actual
    network deletion to the Neutron client. ::

        {
            "NetworkID": string
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/remote.md#delete-network  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.DeleteNetwork".format(json_data))
    jsonschema.validate(json_data, schemata.NETWORK_DELETE_SCHEMA)

    container_net_id = json_data['NetworkID']
    neutron_network_identifier = _make_net_identifier(container_net_id,
                                                      tags=app.tag)
    if app.tag:
        existing_network_identifier = neutron_network_identifier + ','
        existing_network_identifier += const.KURYR_EXISTING_NEUTRON_NET
        try:
            existing_networks = _get_networks_by_identifier(
                existing_network_identifier)
        except n_exceptions.NeutronClientException as ex:
            app.logger.error(_LE("Error happened during listing "
                                 "Neutron networks: {0}").format(ex))
            raise

        if existing_networks:
            app.logger.warn(_LW("Network is a pre existing Neutron network, "
                                "not deleting in Neutron. removing tags: {0}")
                            .format(existing_network_identifier))
            neutron_net_id = existing_networks[0]['id']
            _neutron_net_remove_tags(neutron_net_id, container_net_id)
            _neutron_net_remove_tag(neutron_net_id,
                                    const.KURYR_EXISTING_NEUTRON_NET)
            return flask.jsonify(const.SCHEMA['SUCCESS'])

    try:
        filtered_networks = _get_networks_by_identifier(
            neutron_network_identifier)
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(_LE("Error happened during listing "
                             "Neutron networks: {0}").format(ex))
        raise

    if not filtered_networks:
        app.logger.warn(_LW("Network with identifier {0} cannot be found")
                        .format(neutron_network_identifier))
    else:
        neutron_network_id = filtered_networks[0]['id']
        filtered_subnets = _get_subnets_by_attrs(
            network_id=neutron_network_id)
        for subnet in filtered_subnets:
            try:
                subnetpool_id = subnet.get('subnetpool_id', None)

                _cache_default_subnetpool_ids(app)

                if subnetpool_id not in app.DEFAULT_POOL_IDS:
                    # If the subnet to be deleted has any port, when some ports
                    # are referring to the subnets in other words,
                    # delete_subnet throws an exception, SubnetInUse that
                    # extends Conflict. This can happen when the multiple
                    # Docker endpoints are created with the same subnet CIDR
                    # and it's totally the normal case. So we'd just log that
                    # and continue to proceed.
                    app.neutron.delete_subnet(subnet['id'])
            except n_exceptions.Conflict as ex:
                app.logger.error(_LE(
                    "Subnet, {0}, is in use. Network cant be deleted.").format(
                        subnet['id']))
                raise
            except n_exceptions.NeutronClientException as ex:
                app.logger.error(_LE("Error happened during deleting a "
                                     "Neutron subnets: {0}").format(ex))
                raise

        try:
            app.neutron.delete_network(neutron_network_id)
        except n_exceptions.NeutronClientException as ex:
            app.logger.error(_LE("Error happened during deleting a "
                                 "Neutron network: {0}").format(ex))
            raise
        app.logger.info(_LI("Deleted the network with ID {0} successfully")
                        .format(neutron_network_id))
    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemple #8
0
def network_driver_create_network():
    """Creates a new Neutron Network which name is the given NetworkID.

    This function takes the following JSON data and delegates the actual
    network creation to the Neutron client. libnetwork's NetworkID is used as
    the name of Network in Neutron. ::

        {
            "NetworkID": string,
            "IPv4Data" : [{
                "AddressSpace": string,
                "Pool": ipv4-cidr-string,
                "Gateway" : ipv4-address,
                "AuxAddresses": {
                    "<identifier1>" : "<ipv4-address1>",
                    "<identifier2>" : "<ipv4-address2>",
                    ...
                }
            }, ...],
            "IPv6Data" : [{
                "AddressSpace": string,
                "Pool": ipv6-cidr-string,
                "Gateway" : ipv6-address,
                "AuxAddresses": {
                    "<identifier1>" : "<ipv6-address1>",
                    "<identifier2>" : "<ipv6-address2>",
                    ...
                }
            }, ...],
            "Options": {
                ...
            }
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/remote.md#create-network  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.CreateNetwork".format(json_data))
    jsonschema.validate(json_data, schemata.NETWORK_CREATE_SCHEMA)
    container_net_id = json_data['NetworkID']
    neutron_network_name = utils.make_net_name(container_net_id, tags=app.tag)
    pool_cidr = json_data['IPv4Data'][0]['Pool']
    gateway_ip = ''
    if 'Gateway' in json_data['IPv4Data'][0]:
        gateway_cidr = json_data['IPv4Data'][0]['Gateway']
        gateway_ip = gateway_cidr.split('/')[0]
        app.logger.debug("gateway_cidr {0}, gateway_ip {1}"
            .format(gateway_cidr, gateway_ip))

    neutron_uuid = None
    neutron_name = None
    options = json_data.get('Options')
    if options:
        generic_options = options.get(const.NETWORK_GENERIC_OPTIONS)
        if generic_options:
            neutron_uuid = generic_options.get(const.NEUTRON_UUID_OPTION)
            neutron_name = generic_options.get(const.NEUTRON_NAME_OPTION)

    if not neutron_uuid and not neutron_name:
        network = app.neutron.create_network(
            {'network': {'name': neutron_network_name,
                         "admin_state_up": True}})
        network_id = network['network']['id']
        _neutron_net_add_tags(network['network']['id'], container_net_id,
                              tags=app.tag)

        app.logger.info(_LI("Created a new network with name {0}"
                            " successfully: {1}")
                        .format(neutron_network_name, network))
    else:
        try:
            if neutron_uuid:
                networks = _get_networks_by_attrs(id=neutron_uuid)
            else:
                networks = _get_networks_by_attrs(name=neutron_name)
            network_id = networks[0]['id']
        except n_exceptions.NeutronClientException as ex:
            app.logger.error(_LE("Error happened during listing "
                                 "Neutron networks: {0}").format(ex))
            raise
        if app.tag:
            _neutron_net_add_tags(network_id, container_net_id, tags=app.tag)
            _neutron_net_add_tag(network_id, const.KURYR_EXISTING_NEUTRON_NET)
        else:
            network = app.neutron.update_network(
                neutron_uuid, {'network': {'name': neutron_network_name}})
            app.logger.info(_LI("Updated the network with new name {0}"
                                " successfully: {1}")
                            .format(neutron_network_name, network))
        app.logger.info(_LI("Using existing network {0} successfully")
                        .format(neutron_uuid))

    cidr = netaddr.IPNetwork(pool_cidr)
    subnet_network = str(cidr.network)
    subnet_cidr = '/'.join([subnet_network, str(cidr.prefixlen)])
    subnets = _get_subnets_by_attrs(
        network_id=network_id, cidr=subnet_cidr)
    if not subnets:
        new_subnets = [{
            'name': pool_cidr,
            'network_id': network_id,
            'ip_version': cidr.version,
            'cidr': subnet_cidr,
            'enable_dhcp': app.enable_dhcp,
        }]
        if gateway_ip:
            new_subnets[0]['gateway_ip'] = gateway_ip

        app.neutron.create_subnet({'subnets': new_subnets})

    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemple #9
0
def network_driver_delete_network():
    """Delete the Neutron Network with name as the given NetworkID.

    This function takes the following JSON data and delegates the actual
    network deletion to the Neutron client. ::

        {
            "NetworkID": string
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/remote.md#delete-network  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.DeleteNetwork".format(json_data))
    jsonschema.validate(json_data, schemata.NETWORK_DELETE_SCHEMA)

    neutron_network_name = json_data['NetworkID']
    try:
        filtered_networks = _get_networks_by_attrs(name=neutron_network_name)
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(_LE("Error happened during listing "
                             "Neutron networks: {0}").format(ex))
        raise
    # We assume Neutron's Network names are not conflicted in Kuryr because
    # they are Docker IDs, 256 bits hashed values, which are rarely conflicted.
    # However, if there're multiple networks associated with the single
    # NetworkID, it raises DuplicatedResourceException and stops processes.
    # See the following doc for more details about Docker's IDs:
    #   https://github.com/docker/docker/blob/master/docs/terms/container.md#container-ids  # noqa
    if not filtered_networks:
        app.logger.warn("Network with name {0} cannot be found"
                        .format(neutron_network_name))
    else:
        neutron_network_id = filtered_networks[0]['id']
        filtered_subnets = _get_subnets_by_attrs(
            network_id=neutron_network_id)
        for subnet in filtered_subnets:
            try:
                subnetpool_id = subnet.get('subnetpool_id', None)

                _cache_default_subnetpool_ids(app)

                if subnetpool_id not in app.DEFAULT_POOL_IDS:
                    # If the subnet to be deleted has any port, when some ports
                    # are referring to the subnets in other words,
                    # delete_subnet throws an exception, SubnetInUse that
                    # extends Conflict. This can happen when the multiple
                    # Docker endpoints are created with the same subnet CIDR
                    # and it's totally the normal case. So we'd just log that
                    # and continue to proceed.
                    app.neutron.delete_subnet(subnet['id'])
            except n_exceptions.Conflict as ex:
                app.logger.error(_LE(
                    "Subnet, {0}, is in use. Network cant be deleted.").format(
                        subnet['id']))
                raise
            except n_exceptions.NeutronClientException as ex:
                app.logger.error(_LE("Error happened during deleting a "
                                     "Neutron subnets: {0}").format(ex))
                raise

        try:
            app.neutron.delete_network(neutron_network_id)
        except n_exceptions.NeutronClientException as ex:
            app.logger.error(_LE("Error happened during deleting a "
                                 "Neutron network: {0}").format(ex))
            raise
        app.logger.info(_LI("Deleted the network with ID {0} successfully")
                        .format(neutron_network_id))
    return flask.jsonify(constants.SCHEMA['SUCCESS'])
Exemple #10
0
def network_driver_create_network():
    """Creates a new Neutron Network which name is the given NetworkID.

    This function takes the following JSON data and delegates the actual
    network creation to the Neutron client. libnetwork's NetworkID is used as
    the name of Network in Neutron. ::

        {
            "NetworkID": string,
            "IPv4Data" : [{
                "AddressSpace": string,
                "Pool": ipv4-cidr-string,
                "Gateway" : ipv4-address,
                "AuxAddresses": {
                    "<identifier1>" : "<ipv4-address1>",
                    "<identifier2>" : "<ipv4-address2>",
                    ...
                }
            }, ...],
            "IPv6Data" : [{
                "AddressSpace": string,
                "Pool": ipv6-cidr-string,
                "Gateway" : ipv6-address,
                "AuxAddresses": {
                    "<identifier1>" : "<ipv6-address1>",
                    "<identifier2>" : "<ipv6-address2>",
                    ...
                }
            }, ...],
            "Options": {
                ...
            }
        }

    See the following link for more details about the spec:

      https://github.com/docker/libnetwork/blob/master/docs/remote.md#create-network  # noqa
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.CreateNetwork".format(json_data))
    jsonschema.validate(json_data, schemata.NETWORK_CREATE_SCHEMA)

    neutron_network_name = json_data['NetworkID']
    pool_cidr = json_data['IPv4Data'][0]['Pool']
    gateway_ip = ''
    if 'Gateway' in json_data['IPv4Data'][0]:
        gateway_cidr = json_data['IPv4Data'][0]['Gateway']
        gateway_ip = gateway_cidr.split('/')[0]
        app.logger.debug("gateway_cidr {0}, gateway_ip {1}"
            .format(gateway_cidr, gateway_ip))

    network = app.neutron.create_network(
        {'network': {'name': neutron_network_name, "admin_state_up": True}})

    app.logger.info(_LI("Created a new network with name {0}"
                      " successfully: {1}")
                    .format(neutron_network_name, network))

    cidr = netaddr.IPNetwork(pool_cidr)
    subnet_network = str(cidr.network)
    subnet_cidr = '/'.join([subnet_network, str(cidr.prefixlen)])
    subnets = _get_subnets_by_attrs(
        network_id=network['network']['id'], cidr=subnet_cidr)
    if not subnets:
        new_subnets = [{
            'name': pool_cidr,
            'network_id': network['network']['id'],
            'ip_version': cidr.version,
            'cidr': subnet_cidr,
            'enable_dhcp': app.enable_dhcp,
        }]
        if gateway_ip:
            new_subnets[0]['gateway_ip'] = gateway_ip

        app.neutron.create_subnet({'subnets': new_subnets})

    return flask.jsonify(constants.SCHEMA['SUCCESS'])