Exemplo n.º 1
0
    def test_create_network_with_same_name(self):
        """Create docker network with same name

           Create two docker networks with same name,
           delete them and see that neutron networks are
           deleted as well
        """
        res = self.docker_client.create_network(name='fakenet', driver='kuryr')
        net_id1 = res['Id']
        res = self.docker_client.create_network(name='fakenet', driver='kuryr')
        net_id2 = res['Id']
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id1))
        self.assertEqual(1, len(network['networks']))
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id2))
        self.assertEqual(1, len(network['networks']))
        self.docker_client.remove_network(net_id1)
        self.docker_client.remove_network(net_id2)
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id1))
        self.assertEqual(0, len(network['networks']))
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id2))
        self.assertEqual(0, len(network['networks']))
Exemplo n.º 2
0
    def test_create_network_with_same_name(self):
        """Create docker network with same name

           Create two docker networks with same name,
           delete them and see that neutron networks are
           deleted as well
        """
        res = self.docker_client.create_network(name='fakenet', driver='kuryr')
        net_id1 = res['Id']
        res = self.docker_client.create_network(name='fakenet', driver='kuryr')
        net_id2 = res['Id']
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id1))
        self.assertEqual(1, len(network['networks']))
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id2))
        self.assertEqual(1, len(network['networks']))
        self.docker_client.remove_network(net_id1)
        self.docker_client.remove_network(net_id2)
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id1))
        self.assertEqual(0, len(network['networks']))
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id2))
        self.assertEqual(0, len(network['networks']))
Exemplo n.º 3
0
Arquivo: base.py Projeto: fkautz/kuryr
    def _mock_out_network(self,
                          neutron_network_id,
                          docker_network_id,
                          check_existing=False):
        no_networks_response = {"networks": []}
        fake_list_response = {
            "networks": [{
                "status": "ACTIVE",
                "subnets": [],
                "admin_state_up": True,
                "tenant_id": "9bacb3c5d39d41a79512987f338cf177",
                "router:external": False,
                "segments": [],
                "shared": False,
                "id": neutron_network_id
            }]
        }
        self.mox.StubOutWithMock(app.neutron, 'list_networks')
        t = utils.make_net_tags(docker_network_id)
        if check_existing:
            te = t + ',' + const.KURYR_EXISTING_NEUTRON_NET
            app.neutron.list_networks(tags=te).AndReturn(no_networks_response)
        app.neutron.list_networks(tags=t).AndReturn(fake_list_response)

        self.mox.ReplayAll()
        return neutron_network_id
    def setUp(self):
        super(ContainerTest, self).setUp()
        self.docker_client.pull(repository='busybox', tag='1')

        fake_ipam = {
            "Driver": "kuryr",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.3.0.0/16",
                    "IPRange": "10.3.0.0/24",
                    "Gateway": "10.3.0.1"
                }
            ]
        }
        net_name = utils.get_random_string(8)
        res = self.docker_client.create_network(name=net_name,
                                                driver='kuryr',
                                                ipam=fake_ipam)
        self.net_id = res.get('Id')

        networks = self.neutron_client.list_networks(
            tags=utils.make_net_tags(self.net_id))
        self.assertEqual(1, len(networks['networks']))
        self.neutron_net_id = networks['networks'][0]['id']
Exemplo n.º 5
0
    def _mock_out_network(self, neutron_network_id, docker_network_id, check_existing=False):
        no_networks_response = {"networks": []}
        fake_list_response = {
            "networks": [
                {
                    "status": "ACTIVE",
                    "subnets": [],
                    "admin_state_up": True,
                    "tenant_id": "9bacb3c5d39d41a79512987f338cf177",
                    "router:external": False,
                    "segments": [],
                    "shared": False,
                    "id": neutron_network_id,
                }
            ]
        }
        self.mox.StubOutWithMock(app.neutron, "list_networks")
        t = utils.make_net_tags(docker_network_id)
        if check_existing:
            te = t + "," + const.KURYR_EXISTING_NEUTRON_NET
            app.neutron.list_networks(tags=te).AndReturn(no_networks_response)
        app.neutron.list_networks(tags=t).AndReturn(fake_list_response)

        self.mox.ReplayAll()
        return neutron_network_id
Exemplo n.º 6
0
    def test_delete_network_pre_existing(self):
        docker_network_id, fake_neutron_net_id, fake_response = self._ids()

        self.mox.StubOutWithMock(app.neutron, 'list_networks')
        t = utils.make_net_tags(docker_network_id)
        te = t + ',' + const.KURYR_EXISTING_NEUTRON_NET
        app.neutron.list_networks(tags=te).AndReturn(
            fake_response)

        self.mox.StubOutWithMock(app.neutron, "remove_tag")
        tags = utils.create_net_tags(docker_network_id)
        for tag in tags:
            app.neutron.remove_tag('networks', fake_neutron_net_id, tag)
        app.neutron.remove_tag('networks', fake_neutron_net_id,
                               const.KURYR_EXISTING_NEUTRON_NET)

        self.mox.ReplayAll()
        data = {'NetworkID': docker_network_id}
        response = self.app.post('/NetworkDriver.DeleteNetwork',
                                 content_type='application/json',
                                 data=jsonutils.dumps(data))

        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(const.SCHEMA['SUCCESS'], decoded_json)
Exemplo n.º 7
0
    def test_create_delete_network_with_kuryr_driver(self):
        """Create and Delete docker network with Kuryr

           This method creates a docker network with Kuryr driver
           and tests it was created in Neutron.
           It then deletes the docker network and tests that it was
           deleted from Neutron.
        """
        res = self.docker_client.create_network(name='fakenet', driver='kuryr')
        net_id = res['Id']
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id))
        self.assertEqual(1, len(network['networks']))
        self.docker_client.remove_network(net_id)
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id))
        self.assertEqual(0, len(network['networks']))
Exemplo n.º 8
0
    def test_create_delete_network_with_kuryr_driver(self):
        """Create and Delete docker network with Kuryr

           This method creates a docker network with Kuryr driver
           and tests it was created in Neutron.
           It then deletes the docker network and tests that it was
           deleted from Neutron.
        """
        res = self.docker_client.create_network(name='fakenet', driver='kuryr')
        net_id = res['Id']
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id))
        self.assertEqual(1, len(network['networks']))
        self.docker_client.remove_network(net_id)
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id))
        self.assertEqual(0, len(network['networks']))
Exemplo n.º 9
0
    def _delete_network_with_exception(self, network_id, ex):
        fake_neutron_network_id = "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
        no_networks_response = {"networks": []}
        if ex == exceptions.NotFound:
            fake_networks_response = no_networks_response
        else:
            fake_networks_response = {
                "networks": [{
                    "status": "ACTIVE",
                    "subnets": [],
                    "name": network_id,
                    "admin_state_up": True,
                    "tenant_id": "9bacb3c5d39d41a79512987f338cf177",
                    "router:external": False,
                    "segments": [],
                    "shared": False,
                    "id": fake_neutron_network_id
                }]
            }
        self.mox.StubOutWithMock(app.neutron, 'list_networks')
        t = utils.make_net_tags(network_id)
        te = t + ',' + const.KURYR_EXISTING_NEUTRON_NET
        app.neutron.list_networks(tags=te).AndReturn(no_networks_response)
        app.neutron.list_networks(tags=t).AndReturn(fake_networks_response)
        subnet_v4_id = "9436e561-47bf-436a-b1f1-fe23a926e031"
        subnet_v6_id = "64dd4a98-3d7a-4bfd-acf4-91137a8d2f51"

        docker_network_id = hashlib.sha256(utils.getrandbits(256)).hexdigest()
        docker_endpoint_id = hashlib.sha256(utils.getrandbits(256)).hexdigest()

        fake_v4_subnet = self._get_fake_v4_subnet(docker_network_id,
                                                  docker_endpoint_id,
                                                  subnet_v4_id)
        fake_v6_subnet = self._get_fake_v6_subnet(docker_network_id,
                                                  docker_endpoint_id,
                                                  subnet_v6_id)
        fake_subnets_response = {
            "subnets": [fake_v4_subnet['subnet'], fake_v6_subnet['subnet']]
        }

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        app.neutron.list_subnets(network_id=fake_neutron_network_id).AndReturn(
            fake_subnets_response)

        self.mox.StubOutWithMock(app.neutron, 'list_subnetpools')
        fake_subnetpools_response = {"subnetpools": []}
        app.neutron.list_subnetpools(
            name='kuryr').AndReturn(fake_subnetpools_response)
        app.neutron.list_subnetpools(
            name='kuryr6').AndReturn(fake_subnetpools_response)

        self.mox.StubOutWithMock(app.neutron, 'delete_subnet')
        app.neutron.delete_subnet(subnet_v4_id).AndReturn(None)
        app.neutron.delete_subnet(subnet_v6_id).AndReturn(None)

        self.mox.StubOutWithMock(app.neutron, 'delete_network')
        app.neutron.delete_network(fake_neutron_network_id).AndRaise(ex)
        self.mox.ReplayAll()
Exemplo n.º 10
0
    def _delete_network_with_subnet_exception(self, network_id, ex):
        fake_neutron_network_id = "4e8e5957-649f-477b-9e5b-f1f75b21c03c"
        no_networks_response = {
            "networks": []
        }
        fake_networks_response = {
            "networks": [{
                "status": "ACTIVE",
                "subnets": [],
                "name": network_id,
                "admin_state_up": True,
                "tenant_id": "9bacb3c5d39d41a79512987f338cf177",
                "router:external": False,
                "segments": [],
                "shared": False,
                "id": fake_neutron_network_id
            }]
        }
        self.mox.StubOutWithMock(app.neutron, 'list_networks')
        t = utils.make_net_tags(network_id)
        te = t + ',' + const.KURYR_EXISTING_NEUTRON_NET
        app.neutron.list_networks(tags=te).AndReturn(no_networks_response)
        app.neutron.list_networks(tags=t).AndReturn(fake_networks_response)
        subnet_v4_id = "9436e561-47bf-436a-b1f1-fe23a926e031"
        subnet_v6_id = "64dd4a98-3d7a-4bfd-acf4-91137a8d2f51"

        docker_network_id = hashlib.sha256(
            utils.getrandbits(256)).hexdigest()
        docker_endpoint_id = hashlib.sha256(
            utils.getrandbits(256)).hexdigest()

        fake_v4_subnet = self._get_fake_v4_subnet(
            docker_network_id, docker_endpoint_id, subnet_v4_id)
        fake_v6_subnet = self._get_fake_v6_subnet(
            docker_network_id, docker_endpoint_id, subnet_v6_id)
        fake_subnets_response = {
            "subnets": [
                fake_v4_subnet['subnet'],
                fake_v6_subnet['subnet']
            ]
        }

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        app.neutron.list_subnets(network_id=fake_neutron_network_id).AndReturn(
            fake_subnets_response)

        self.mox.StubOutWithMock(app.neutron, 'list_subnetpools')
        fake_subnetpools_response = {"subnetpools": []}
        app.neutron.list_subnetpools(name='kuryr').AndReturn(
            fake_subnetpools_response)
        app.neutron.list_subnetpools(name='kuryr6').AndReturn(
            fake_subnetpools_response)

        self.mox.StubOutWithMock(app.neutron, 'delete_subnet')
        app.neutron.delete_subnet(subnet_v4_id).AndRaise(ex)
        self.mox.ReplayAll()
Exemplo n.º 11
0
def network_driver_leave():
    """Unbinds a Neutron Port to a network interface attached to a container.

    This function takes the following JSON data and delete the veth pair
    corresponding to the given info. ::

        {
            "NetworkID": string,
            "EndpointID": string
        }
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.DeleteEndpoint".format(json_data))
    jsonschema.validate(json_data, schemata.LEAVE_SCHEMA)

    neutron_network_tags = utils.make_net_tags(json_data['NetworkID'])
    endpoint_id = json_data['EndpointID']
    filtered_networks = _get_networks_by_attrs(tags=neutron_network_tags)

    if not filtered_networks:
        return flask.jsonify({
            'Err':
            "Neutron network associated with tags {0} doesn't exit.".format(
                neutron_network_tags)
        })
    else:
        neutron_port_name = utils.get_neutron_port_name(endpoint_id)
        filtered_ports = _get_ports_by_attrs(name=neutron_port_name)
        if not filtered_ports:
            raise exceptions.NoResourceException(
                "The port doesn't exist for the name {0}".format(
                    neutron_port_name))
        neutron_port = filtered_ports[0]
        try:
            stdout, stderr = binding.port_unbind(endpoint_id, neutron_port)
            app.logger.debug(stdout)
            if stderr:
                app.logger.error(stderr)
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                app.logger.error(
                    _LE('Could not unbind the Neutron port from the veth '
                        'endpoint.'))
        except exceptions.VethDeletionFailure:
            with excutils.save_and_reraise_exception():
                app.logger.error(_LE('Cleaning the veth pair up was failed.'))

    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemplo n.º 12
0
def network_driver_leave():
    """Unbinds a Neutron Port to a network interface attached to a container.

    This function takes the following JSON data and delete the veth pair
    corresponding to the given info. ::

        {
            "NetworkID": string,
            "EndpointID": string
        }
    """
    json_data = flask.request.get_json(force=True)
    app.logger.debug("Received JSON data {0} for"
                     " /NetworkDriver.DeleteEndpoint"
                     .format(json_data))
    jsonschema.validate(json_data, schemata.LEAVE_SCHEMA)

    neutron_network_tags = utils.make_net_tags(json_data['NetworkID'])
    endpoint_id = json_data['EndpointID']
    filtered_networks = _get_networks_by_attrs(tags=neutron_network_tags)

    if not filtered_networks:
        return flask.jsonify({
            'Err': "Neutron network associated with tags {0} doesn't exit."
            .format(neutron_network_tags)
        })
    else:
        neutron_port_name = utils.get_neutron_port_name(endpoint_id)
        filtered_ports = _get_ports_by_attrs(name=neutron_port_name)
        if not filtered_ports:
            raise exceptions.NoResourceException(
                "The port doesn't exist for the name {0}"
                .format(neutron_port_name))
        neutron_port = filtered_ports[0]
        try:
            stdout, stderr = binding.port_unbind(endpoint_id, neutron_port)
            app.logger.debug(stdout)
            if stderr:
                app.logger.error(stderr)
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                app.logger.error(_LE(
                    'Could not unbind the Neutron port from the veth '
                    'endpoint.'))
        except exceptions.VethDeletionFailure:
            with excutils.save_and_reraise_exception():
                app.logger.error(_LE('Cleaning the veth pair up was failed.'))

    return flask.jsonify(const.SCHEMA['SUCCESS'])
Exemplo n.º 13
0
    def test_create_delete_network_without_kuryr_driver(self):
        """Create and Delete docker network without Kuryr

           This method create a docker network with the default
           docker driver, It tests that it was created correctly, but
           not added to Neutron
        """
        res = self.docker_client.create_network(name='fakenet')
        net_id = res['Id']
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id))
        self.assertEqual(0, len(network['networks']))
        docker_networks = self.docker_client.networks()
        network_found = False
        for docker_net in docker_networks:
            if docker_net['Id'] == net_id:
                network_found = True
        self.assertTrue(network_found)
        self.docker_client.remove_network(net_id)
Exemplo n.º 14
0
    def test_create_delete_network_without_kuryr_driver(self):
        """Create and Delete docker network without Kuryr

           This method create a docker network with the default
           docker driver, It tests that it was created correctly, but
           not added to Neutron
        """
        res = self.docker_client.create_network(name='fakenet')
        net_id = res['Id']
        network = self.neutron_client.list_networks(
            tags=utils.make_net_tags(net_id))
        self.assertEqual(0, len(network['networks']))
        docker_networks = self.docker_client.networks()
        network_found = False
        for docker_net in docker_networks:
            if docker_net['Id'] == net_id:
                network_found = True
        self.assertTrue(network_found)
        self.docker_client.remove_network(net_id)
Exemplo n.º 15
0
def network_driver_join():
    """Binds a Neutron Port to a network interface attached to a container.

    This function takes the following JSON data, creates a veth pair, put one
    end inside of the container and binds another end to the Neutron Port
    specified in the request. ::

        {
            "NetworkID": string,
            "EndpointID": string,
            "SandboxKey": string,
            "Options": {
                ...
            }
        }

    If the binding is succeeded, the following JSON response is returned.::

        {
            "InterfaceName": {
                SrcName: string,
                DstPrefix: string
            },
            "Gateway": string,
            "GatewayIPv6": string,
            "StaticRoutes": [{
                "Destination": string,
                "RouteType": int,
                "NextHop": string,
            }, ...]
        }

    See the following link for more details about the spec:

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

    neutron_network_tags = utils.make_net_tags(json_data['NetworkID'])
    endpoint_id = json_data['EndpointID']
    filtered_networks = _get_networks_by_attrs(tags=neutron_network_tags)

    if not filtered_networks:
        return flask.jsonify({
            'Err':
            "Neutron network associated with tags {0} doesn't exit.".format(
                neutron_network_tags)
        })
    else:
        neutron_network_id = filtered_networks[0]['id']

        neutron_port_name = utils.get_neutron_port_name(endpoint_id)
        filtered_ports = _get_ports_by_attrs(name=neutron_port_name)
        if not filtered_ports:
            raise exceptions.NoResourceException(
                "The port doesn't exist for the name {0}".format(
                    neutron_port_name))
        neutron_port = filtered_ports[0]
        all_subnets = _get_subnets_by_attrs(network_id=neutron_network_id)

        try:
            ifname, peer_name, (stdout, stderr) = binding.port_bind(
                endpoint_id, neutron_port, all_subnets)
            app.logger.debug(stdout)
            if stderr:
                app.logger.error(stderr)
        except exceptions.VethCreationFailure as ex:
            with excutils.save_and_reraise_exception():
                app.logger.error(
                    _LE('Preparing the veth '
                        'pair was failed: {0}.').format(ex))
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                app.logger.error(
                    _LE('Could not bind the Neutron port to the veth endpoint.'
                        ))

        join_response = {
            "InterfaceName": {
                "SrcName": peer_name,
                "DstPrefix": config.CONF.binding.veth_dst_prefix
            },
            "StaticRoutes": []
        }

        for subnet in all_subnets:
            if subnet['ip_version'] == 4:
                join_response['Gateway'] = subnet.get('gateway_ip', '')
            else:
                join_response['GatewayIPv6'] = subnet.get('gateway_ip', '')
            host_routes = subnet.get('host_routes', [])

            for host_route in host_routes:
                static_route = {'Destination': host_route['destination']}
                if host_route.get('nexthop', None):
                    static_route['RouteType'] = const.TYPES['NEXTHOP']
                    static_route['NextHop'] = host_route['nexthop']
                else:
                    static_route['RouteType'] = const.TYPES['CONNECTED']
                join_response['StaticRoutes'].append(static_route)

        return flask.jsonify(join_response)
Exemplo n.º 16
0
def network_driver_create_endpoint():
    """Creates new Neutron Subnets and a Port with the given EndpointID.

    This function takes the following JSON data and delegates the actual
    endpoint creation to the Neutron client mapping it into Subnet and Port. ::

        {
            "NetworkID": string,
            "EndpointID": string,
            "Options": {
                ...
            },
            "Interface": {
                "Address": string,
                "AddressIPv6": string,
                "MacAddress": string
            }
        }

    Then the following JSON response is returned. ::

        {
            "Interface": {
                "Address": string,
                "AddressIPv6": string,
                "MacAddress": string
            }
        }

    See the following link for more details about the spec:

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

    neutron_network_tags = utils.make_net_tags(json_data['NetworkID'])
    endpoint_id = json_data['EndpointID']
    filtered_networks = _get_networks_by_attrs(tags=neutron_network_tags)

    if not filtered_networks:
        return flask.jsonify({
            'Err':
            "Neutron network associated with tags {0} doesn't exist.".format(
                neutron_network_tags)
        })
    else:
        neutron_network_id = filtered_networks[0]['id']
        interface = json_data['Interface'] or {}  # Workaround for null
        interface_cidrv4 = interface.get('Address', '')
        interface_cidrv6 = interface.get('AddressIPv6', '')
        interface_mac = interface.get('MacAddress', '')
        if not interface_cidrv4 and not interface_cidrv6:
            return flask.jsonify(
                {'Err': "Interface address v4 or v6 not provided."})
        response_interface = _create_or_update_port(neutron_network_id,
                                                    endpoint_id,
                                                    interface_cidrv4,
                                                    interface_cidrv6,
                                                    interface_mac)

        return flask.jsonify({'Interface': response_interface})
Exemplo n.º 17
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'])
Exemplo n.º 18
0
 def tearDown(self):
     self.docker_client.remove_network(self.net_id)
     networks = self.neutron_client.list_networks(
         tags=utils.make_net_tags(self.net_id))
     self.assertEqual(0, len(networks['networks']))
     super(ContainerTest, self).tearDown()
Exemplo n.º 19
0
def _make_net_identifier(network_id, tags=True):
    if tags:
        return utils.make_net_tags(network_id)
    return network_id
Exemplo n.º 20
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'])
Exemplo n.º 21
0
def network_driver_create_endpoint():
    """Creates new Neutron Subnets and a Port with the given EndpointID.

    This function takes the following JSON data and delegates the actual
    endpoint creation to the Neutron client mapping it into Subnet and Port. ::

        {
            "NetworkID": string,
            "EndpointID": string,
            "Options": {
                ...
            },
            "Interface": {
                "Address": string,
                "AddressIPv6": string,
                "MacAddress": string
            }
        }

    Then the following JSON response is returned. ::

        {
            "Interface": {
                "Address": string,
                "AddressIPv6": string,
                "MacAddress": string
            }
        }

    See the following link for more details about the spec:

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

    neutron_network_tags = utils.make_net_tags(json_data['NetworkID'])
    endpoint_id = json_data['EndpointID']
    filtered_networks = _get_networks_by_attrs(tags=neutron_network_tags)

    if not filtered_networks:
        return flask.jsonify({
            'Err': "Neutron network associated with tags {0} doesn't exist."
            .format(neutron_network_tags)
        })
    else:
        neutron_network_id = filtered_networks[0]['id']
        interface = json_data['Interface'] or {}  # Workaround for null
        interface_cidrv4 = interface.get('Address', '')
        interface_cidrv6 = interface.get('AddressIPv6', '')
        interface_mac = interface.get('MacAddress', '')
        if not interface_cidrv4 and not interface_cidrv6:
            return flask.jsonify({
                'Err': "Interface address v4 or v6 not provided."
            })
        response_interface = _create_or_update_port(
            neutron_network_id, endpoint_id, interface_cidrv4,
            interface_cidrv6, interface_mac)

        return flask.jsonify({'Interface': response_interface})
Exemplo n.º 22
0
def network_driver_join():
    """Binds a Neutron Port to a network interface attached to a container.

    This function takes the following JSON data, creates a veth pair, put one
    end inside of the container and binds another end to the Neutron Port
    specified in the request. ::

        {
            "NetworkID": string,
            "EndpointID": string,
            "SandboxKey": string,
            "Options": {
                ...
            }
        }

    If the binding is succeeded, the following JSON response is returned.::

        {
            "InterfaceName": {
                SrcName: string,
                DstPrefix: string
            },
            "Gateway": string,
            "GatewayIPv6": string,
            "StaticRoutes": [{
                "Destination": string,
                "RouteType": int,
                "NextHop": string,
            }, ...]
        }

    See the following link for more details about the spec:

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

    neutron_network_tags = utils.make_net_tags(json_data['NetworkID'])
    endpoint_id = json_data['EndpointID']
    filtered_networks = _get_networks_by_attrs(tags=neutron_network_tags)

    if not filtered_networks:
        return flask.jsonify({
            'Err': "Neutron network associated with tags {0} doesn't exit."
            .format(neutron_network_tags)
        })
    else:
        neutron_network_id = filtered_networks[0]['id']

        neutron_port_name = utils.get_neutron_port_name(endpoint_id)
        filtered_ports = _get_ports_by_attrs(name=neutron_port_name)
        if not filtered_ports:
            raise exceptions.NoResourceException(
                "The port doesn't exist for the name {0}"
                .format(neutron_port_name))
        neutron_port = filtered_ports[0]
        all_subnets = _get_subnets_by_attrs(network_id=neutron_network_id)

        try:
            ifname, peer_name, (stdout, stderr) = binding.port_bind(
                endpoint_id, neutron_port, all_subnets)
            app.logger.debug(stdout)
            if stderr:
                app.logger.error(stderr)
        except exceptions.VethCreationFailure as ex:
            with excutils.save_and_reraise_exception():
                app.logger.error(_LE('Preparing the veth '
                                     'pair was failed: {0}.')
                                 .format(ex))
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                app.logger.error(_LE(
                    'Could not bind the Neutron port to the veth endpoint.'))

        join_response = {
            "InterfaceName": {
                "SrcName": peer_name,
                "DstPrefix": config.CONF.binding.veth_dst_prefix
            },
            "StaticRoutes": []
        }

        for subnet in all_subnets:
            if subnet['ip_version'] == 4:
                join_response['Gateway'] = subnet.get('gateway_ip', '')
            else:
                join_response['GatewayIPv6'] = subnet.get('gateway_ip', '')
            host_routes = subnet.get('host_routes', [])

            for host_route in host_routes:
                static_route = {
                    'Destination': host_route['destination']
                }
                if host_route.get('nexthop', None):
                    static_route['RouteType'] = const.TYPES['NEXTHOP']
                    static_route['NextHop'] = host_route['nexthop']
                else:
                    static_route['RouteType'] = const.TYPES['CONNECTED']
                join_response['StaticRoutes'].append(static_route)

        return flask.jsonify(join_response)
Exemplo n.º 23
0
def _make_net_identifier(network_id, tags=True):
    if tags:
        return utils.make_net_tags(network_id)
    return network_id