def _create_port_with_exception(self, neutron_network_id,
                                 docker_endpoint_id, neutron_subnetv4_id,
                                 neutron_subnetv6_id, ex):
     self.mox.StubOutWithMock(app.neutron, 'create_port')
     fake_port_request = {
         'port': {
             'name': utils.get_neutron_port_name(docker_endpoint_id),
             'admin_state_up': True,
             "binding:host_id": utils.get_hostname(),
             'device_owner': constants.DEVICE_OWNER,
             'device_id': docker_endpoint_id,
             'fixed_ips': [{
                 'subnet_id': neutron_subnetv4_id,
                 'ip_address': '192.168.1.2'
             }, {
                 'subnet_id': neutron_subnetv6_id,
                 'ip_address': 'fe80::f816:3eff:fe20:57c4'
             }],
             'mac_address': "fa:16:3e:20:57:c3",
             'network_id': neutron_network_id
         }
     }
     # The following fake response is retrieved from the Neutron doc:
     #   http://developer.openstack.org/api-ref-networking-v2.html#createPort  # noqa
     fake_port = {
         "port": {
             "status": "DOWN",
             "name": utils.get_neutron_port_name(docker_endpoint_id),
             "allowed_address_pairs": [],
             "admin_state_up": True,
             "binding:host_id": utils.get_hostname(),
             "network_id": neutron_network_id,
             "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
             "device_owner": constants.DEVICE_OWNER,
             'device_id': docker_endpoint_id,
             "mac_address": "fa:16:3e:20:57:c3",
             'fixed_ips': [{
                 'subnet_id': neutron_subnetv4_id,
                 'ip_address': '192.168.1.2'
             }, {
                 'subnet_id': neutron_subnetv6_id,
                 'ip_address': 'fe80::f816:3eff:fe20:57c4'
             }],
             "id": "65c0ee9f-d634-4522-8954-51021b570b0d",
             "security_groups": [],
             "device_id": ""
         }
     }
     if ex:
         app.neutron.create_port(fake_port_request).AndRaise(ex)
     else:
         app.neutron.create_port(fake_port_request).AndReturn(fake_port)
     self.mox.ReplayAll()
Example #2
0
    def test_network_driver_leave(self):
        fake_docker_net_id = utils.get_hash()
        fake_docker_endpoint_id = utils.get_hash()

        fake_neutron_net_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_net_id, fake_docker_net_id)
        fake_neutron_port_id = str(uuid.uuid4())
        self.mox.StubOutWithMock(app.neutron, 'list_ports')
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = str(uuid.uuid4())
        fake_neutron_v6_subnet_id = str(uuid.uuid4())
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id,
            fake_neutron_port_id, constants.PORT_STATUS_ACTIVE,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_ports(name=neutron_port_name).AndReturn(
            fake_neutron_ports_response)

        fake_neutron_port = fake_neutron_ports_response['ports'][0]
        self._mock_out_unbinding(fake_docker_endpoint_id, fake_neutron_port)

        leave_request = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
        }
        response = self.app.post('/NetworkDriver.Leave',
                                 content_type='application/json',
                                 data=jsonutils.dumps(leave_request))

        self.mox.ReplayAll()
        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
Example #3
0
    def test_network_driver_leave(self):
        fake_docker_net_id = hashlib.sha256(utils.getrandbits(256)).hexdigest()
        fake_docker_endpoint_id = hashlib.sha256(
            utils.getrandbits(256)).hexdigest()

        fake_neutron_net_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_net_id, fake_docker_net_id)
        fake_neutron_port_id = str(uuid.uuid4())
        self.mox.StubOutWithMock(app.neutron, 'list_ports')
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = str(uuid.uuid4())
        fake_neutron_v6_subnet_id = str(uuid.uuid4())
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id, fake_neutron_port_id,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_ports(
            name=neutron_port_name).AndReturn(fake_neutron_ports_response)

        fake_neutron_port = fake_neutron_ports_response['ports'][0]
        self._mock_out_unbinding(fake_docker_endpoint_id, fake_neutron_port)

        leave_request = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
        }
        response = self.app.post('/NetworkDriver.Leave',
                                 content_type='application/json',
                                 data=jsonutils.dumps(leave_request))

        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
Example #4
0
 def test_get_port_name(self):
     fake_docker_endpoint_id = hashlib.sha256(
         utils.getrandbits(256)).hexdigest()
     generated_neutron_port_name = utils.get_neutron_port_name(
         fake_docker_endpoint_id)
     self.assertIn(utils.PORT_POSTFIX, generated_neutron_port_name)
     self.assertIn(fake_docker_endpoint_id, generated_neutron_port_name)
Example #5
0
    def test_leave_unbinding_failure(self, GivenException):
        fake_docker_network_id = hashlib.sha256(str(random.getrandbits(256))).hexdigest()
        fake_docker_endpoint_id = hashlib.sha256(str(random.getrandbits(256))).hexdigest()

        fake_neutron_network_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_network_id, fake_docker_network_id)
        fake_neutron_port_id = str(uuid.uuid4())
        self.mox.StubOutWithMock(app.neutron, "list_ports")
        neutron_port_name = utils.get_neutron_port_name(fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = str(uuid.uuid4())
        fake_neutron_v6_subnet_id = str(uuid.uuid4())
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id,
            fake_neutron_network_id,
            fake_neutron_port_id,
            fake_neutron_v4_subnet_id,
            fake_neutron_v6_subnet_id,
        )
        app.neutron.list_ports(name=neutron_port_name).AndReturn(fake_neutron_ports_response)
        fake_neutron_port = fake_neutron_ports_response["ports"][0]

        fake_message = "fake message"
        fake_exception = GivenException(fake_message)
        self._port_unbind_with_exception(fake_docker_endpoint_id, fake_neutron_port, fake_exception)

        response = self._invoke_leave_request(fake_docker_network_id, fake_docker_endpoint_id)

        self.assertEqual(w_exceptions.InternalServerError.code, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertTrue("Err" in decoded_json)
        self.assertTrue(fake_message in decoded_json["Err"])
Example #6
0
    def test_leave_unbinding_failure(self, GivenException):
        fake_docker_network_id = hashlib.sha256(
            utils.getrandbits(256)).hexdigest()
        fake_docker_endpoint_id = hashlib.sha256(
            utils.getrandbits(256)).hexdigest()

        fake_neutron_network_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_network_id, fake_docker_network_id)
        fake_neutron_port_id = str(uuid.uuid4())
        self.mox.StubOutWithMock(app.neutron, 'list_ports')
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = str(uuid.uuid4())
        fake_neutron_v6_subnet_id = str(uuid.uuid4())
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_port_id,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_ports(name=neutron_port_name).AndReturn(
            fake_neutron_ports_response)
        fake_neutron_port = fake_neutron_ports_response['ports'][0]

        fake_message = "fake message"
        fake_exception = GivenException(fake_message)
        self._port_unbind_with_exception(
            fake_docker_endpoint_id, fake_neutron_port, fake_exception)

        response = self._invoke_leave_request(
            fake_docker_network_id, fake_docker_endpoint_id)

        self.assertEqual(
            w_exceptions.InternalServerError.code, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertIn('Err', decoded_json)
        self.assertIn(fake_message, decoded_json['Err'])
Example #7
0
 def test_get_port_name(self):
     fake_docker_endpoint_id = hashlib.sha256(str(
         random.getrandbits(256))).hexdigest()
     generated_neutron_port_name = utils.get_neutron_port_name(
         fake_docker_endpoint_id)
     self.assertTrue(utils.PORT_POSTFIX in generated_neutron_port_name)
     self.assertTrue(fake_docker_endpoint_id in generated_neutron_port_name)
Example #8
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_identifier = _make_net_identifier(json_data['NetworkID'],
                                                      tags=app.tag)
    endpoint_id = json_data['EndpointID']
    filtered_networks = _get_networks_by_identifier(neutron_network_identifier)

    if not filtered_networks:
        return flask.jsonify({
            'Err': "Neutron net associated with identifier {0} doesn't exit."
            .format(neutron_network_identifier)
        })
    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'])
Example #9
0
def _update_port(port, endpoint_id):
    port['name'] = utils.get_neutron_port_name(endpoint_id)
    try:
        response_port = app.neutron.update_port(
                port['id'],
                {'port': {
                    'name': port['name'],
                    'device_owner': const.DEVICE_OWNER,
                    'device_id': endpoint_id}})
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(_LE("Error happend during creating a "
                             "Neutron port: {0}").format(ex))
        raise
    return response_port['port']
Example #10
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_name = json_data['NetworkID']
    endpoint_id = json_data['EndpointID']

    filtered_networks = _get_networks_by_attrs(name=neutron_network_name)

    if not filtered_networks:
        return flask.jsonify({
            'Err':
            "Neutron network associated with ID {0} doesn't exit.".format(
                neutron_network_name)
        })
    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(
                    'Could not unbind the Neutron port from the veth '
                    'endpoint.')
        except exceptions.VethDeletionFailure:
            with excutils.save_and_reraise_exception():
                app.logger.error('Cleaning the veth pair up was failed.')

    return flask.jsonify(constants.SCHEMA['SUCCESS'])
Example #11
0
def _update_port(port, endpoint_id):
    port['name'] = utils.get_neutron_port_name(endpoint_id)
    try:
        response_port = app.neutron.update_port(
            port['id'], {
                'port': {
                    'name': port['name'],
                    'device_owner': constants.DEVICE_OWNER,
                    'device_id': endpoint_id
                }
            })
    except n_exceptions.NeutronClientException as ex:
        app.logger.error("Error happened during creating a "
                         "Neutron port: {0}".format(ex))
        raise
    return response_port['port']
Example #12
0
    def test_join_veth_failures(self, GivenException):
        fake_docker_network_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()
        fake_docker_endpoint_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()
        fake_container_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()

        fake_neutron_network_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_network_id, fake_docker_network_id)
        fake_neutron_port_id = str(uuid.uuid4())
        self.mox.StubOutWithMock(app.neutron, 'list_ports')
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = str(uuid.uuid4())
        fake_neutron_v6_subnet_id = str(uuid.uuid4())
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_port_id,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_ports(name=neutron_port_name).AndReturn(
            fake_neutron_ports_response)

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        fake_neutron_subnets_response = self._get_fake_subnets(
            fake_docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_subnets(network_id=fake_neutron_network_id).AndReturn(
            fake_neutron_subnets_response)
        fake_neutron_port = fake_neutron_ports_response['ports'][0]
        fake_neutron_subnets = fake_neutron_subnets_response['subnets']

        fake_message = "fake message"
        fake_exception = GivenException(fake_message)
        self._port_bind_with_exeption(
            fake_docker_endpoint_id, fake_neutron_port,
            fake_neutron_subnets, fake_exception)
        self.mox.ReplayAll()

        response = self._invoke_join_request(
            fake_docker_network_id, fake_docker_endpoint_id, fake_container_id)

        self.assertEqual(
            w_exceptions.InternalServerError.code, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertTrue('Err' in decoded_json)
        self.assertTrue(fake_message in decoded_json['Err'])
Example #13
0
def _create_port(endpoint_id, neutron_network_id, interface_mac, fixed_ips):
    port = {
        'name': utils.get_neutron_port_name(endpoint_id),
        'admin_state_up': True,
        'network_id': neutron_network_id,
        'device_owner': constants.DEVICE_OWNER,
        'device_id': endpoint_id,
        'binding:host_id': utils.get_hostname(),
        'fixed_ips': fixed_ips
    }
    if interface_mac:
        port['mac_address'] = interface_mac
    try:
        rcvd_port = app.neutron.create_port({'port': port})
    except n_exceptions.NeutronClientException as ex:
        app.logger.error("Error happened during creating a "
                         "Neutron port: {0}".format(ex))
        raise
    return rcvd_port['port']
Example #14
0
def _create_port(endpoint_id, neutron_network_id, interface_mac, fixed_ips):
    port = {
        'name': utils.get_neutron_port_name(endpoint_id),
        'admin_state_up': True,
        'network_id': neutron_network_id,
        'device_owner': const.DEVICE_OWNER,
        'device_id': endpoint_id,
        'binding:host_id': utils.get_hostname(),
        'fixed_ips': fixed_ips
    }
    if interface_mac:
        port['mac_address'] = interface_mac
    try:
        rcvd_port = app.neutron.create_port({'port': port})
    except n_exceptions.NeutronClientException as ex:
        app.logger.error(_LE("Error happend during creating a"
                             " Neutron port: {0}").format(ex))
        raise
    return rcvd_port['port']
Example #15
0
    def _get_fake_port(docker_endpoint_id,
                       neutron_network_id,
                       neutron_port_id,
                       neutron_subnet_v4_id=None,
                       neutron_subnet_v6_id=None,
                       neutron_subnet_v4_address="192.168.1.2",
                       neutron_subnet_v6_address="fe80::f816:3eff:fe20:57c4"):
        # The following fake response is retrieved from the Neutron doc:
        #   http://developer.openstack.org/api-ref-networking-v2.html#createPort  # noqa
        fake_port = {
            'port': {
                "status": "DOWN",
                "name": utils.get_neutron_port_name(docker_endpoint_id),
                "allowed_address_pairs": [],
                "admin_state_up": True,
                "network_id": neutron_network_id,
                "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
                "device_owner": "",
                "mac_address": "fa:16:3e:20:57:c3",
                "fixed_ips": [],
                "id": neutron_port_id,
                "security_groups": [],
                "device_id": ""
            }
        }

        if neutron_subnet_v4_id:
            fake_port['port']['fixed_ips'].append({
                "subnet_id":
                neutron_subnet_v4_id,
                "ip_address":
                neutron_subnet_v4_address
            })
        if neutron_subnet_v6_id:
            fake_port['port']['fixed_ips'].append({
                "subnet_id":
                neutron_subnet_v6_id,
                "ip_address":
                neutron_subnet_v6_address
            })
        return fake_port
Example #16
0
    def _get_fake_port(
        docker_endpoint_id,
        neutron_network_id,
        neutron_port_id,
        neutron_subnet_v4_id=None,
        neutron_subnet_v6_id=None,
        neutron_subnet_v4_address="192.168.1.2",
        neutron_subnet_v6_address="fe80::f816:3eff:fe20:57c4",
    ):
        # The following fake response is retrieved from the Neutron doc:
        #   http://developer.openstack.org/api-ref-networking-v2.html#createPort  # noqa
        fake_port = {
            "port": {
                "status": "DOWN",
                "name": utils.get_neutron_port_name(docker_endpoint_id),
                "allowed_address_pairs": [],
                "admin_state_up": True,
                "network_id": neutron_network_id,
                "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
                "device_owner": "",
                "mac_address": "fa:16:3e:20:57:c3",
                "fixed_ips": [],
                "id": neutron_port_id,
                "security_groups": [],
                "device_id": "",
            }
        }

        if neutron_subnet_v4_id:
            fake_port["port"]["fixed_ips"].append(
                {"subnet_id": neutron_subnet_v4_id, "ip_address": neutron_subnet_v4_address}
            )
        if neutron_subnet_v6_id:
            fake_port["port"]["fixed_ips"].append(
                {"subnet_id": neutron_subnet_v6_id, "ip_address": neutron_subnet_v6_address}
            )
        return fake_port
Example #17
0
    def test_network_driver_create_endpoint_with_v4_subnetpool(self):
        docker_network_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()
        docker_endpoint_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()

        fake_neutron_network_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_network_id, docker_network_id)

        self.mox.StubOutWithMock(app.neutron, 'list_subnetpools')
        fake_kuryr_subnetpool_id = str(uuid.uuid4())
        kuryr_subnetpools = self._get_fake_v4_subnetpools(
            fake_kuryr_subnetpool_id)
        app.neutron.list_subnetpools(name='kuryr').AndReturn(kuryr_subnetpools)
        app.neutron.list_subnetpools(
            name='kuryr6').AndReturn({'subnetpools': []})

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        fake_existing_subnets_response = {
            "subnets": []
        }
        fake_cidr_v4 = '192.168.1.0/24'
        app.neutron.list_subnets(
            network_id=fake_neutron_network_id,
            cidr=fake_cidr_v4).AndReturn(fake_existing_subnets_response)

        self.mox.StubOutWithMock(app.neutron, 'create_subnet')
        fake_subnet_request = {
            "subnets": [{
                'name': '-'.join([docker_endpoint_id,
                                  '192.168.1.0']),
                'network_id': fake_neutron_network_id,
                'ip_version': 4,
                'subnetpool_id': fake_kuryr_subnetpool_id,
                'enable_dhcp': 'False'
            }]
        }
        subnet_v4_id = str(uuid.uuid4())
        fake_v4_subnet = self._get_fake_v4_subnet(
            docker_network_id, docker_endpoint_id, subnet_v4_id,
            subnetpool_id=fake_kuryr_subnetpool_id)
        fake_subnet_response = {
            'subnets': [
                fake_v4_subnet['subnet']
            ]
        }
        app.neutron.create_subnet(
            fake_subnet_request).AndReturn(fake_subnet_response)

        self.mox.StubOutWithMock(app.neutron, 'create_port')
        fake_mac_address = 'fa:16:3e:20:57:c3'
        fake_neutron_port_id = str(uuid.uuid4())
        fake_port_request = {
            'port': {
                'name': utils.get_neutron_port_name(docker_endpoint_id),
                'admin_state_up': True,
                "binding:host_id": utils.get_hostname(),
                'mac_address': fake_mac_address,
                'network_id': fake_neutron_network_id,
                'device_owner': constants.DEVICE_OWNER,
                'device_id': docker_endpoint_id,
                'fixed_ips': [{'subnet_id': subnet_v4_id}]
            }
        }
        fake_port_response = self._get_fake_port(
            docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_port_id,
            neutron_subnet_v4_id=subnet_v4_id,
            neutron_subnet_v4_address='192.168.1.2')
        app.neutron.create_port(
            fake_port_request).AndReturn(fake_port_response)

        self.mox.ReplayAll()

        request = {
            'NetworkID': docker_network_id,
            'EndpointID': docker_endpoint_id,
            'Options': {},
            'Interface': {
                'MacAddress': "fa:16:3e:20:57:c3"
            }
        }
        response = self.app.post('/NetworkDriver.CreateEndpoint',
                                 content_type='application/json',
                                 data=jsonutils.dumps(request))

        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        expected = {'Interface': request['Interface']}
        # Address and AddressIPv6, allocated by Neutron's IPAM automatically
        # should be contained in the response.
        self.assertNotEqual(expected, decoded_json)
        app.logger.debug(decoded_json)
        self.assertIn('Address', decoded_json['Interface'])
Example #18
0
 def _create_port_with_exception(self, neutron_network_id,
                                 docker_endpoint_id, neutron_subnetv4_id,
                                 neutron_subnetv6_id, ex):
     self.mox.StubOutWithMock(app.neutron, 'create_port')
     fake_port_request = {
         'port': {
             'name':
             utils.get_neutron_port_name(docker_endpoint_id),
             'admin_state_up':
             True,
             "binding:host_id":
             utils.get_hostname(),
             'device_owner':
             constants.DEVICE_OWNER,
             'device_id':
             docker_endpoint_id,
             'fixed_ips': [{
                 'subnet_id': neutron_subnetv4_id,
                 'ip_address': '192.168.1.2'
             }, {
                 'subnet_id': neutron_subnetv6_id,
                 'ip_address': 'fe80::f816:3eff:fe20:57c4'
             }],
             'mac_address':
             "fa:16:3e:20:57:c3",
             'network_id':
             neutron_network_id
         }
     }
     # The following fake response is retrieved from the Neutron doc:
     #   http://developer.openstack.org/api-ref-networking-v2.html#createPort  # noqa
     fake_port = {
         "port": {
             "status":
             "DOWN",
             "name":
             utils.get_neutron_port_name(docker_endpoint_id),
             "allowed_address_pairs": [],
             "admin_state_up":
             True,
             "binding:host_id":
             utils.get_hostname(),
             "network_id":
             neutron_network_id,
             "tenant_id":
             "d6700c0c9ffa4f1cb322cd4a1f3906fa",
             "device_owner":
             constants.DEVICE_OWNER,
             'device_id':
             docker_endpoint_id,
             "mac_address":
             "fa:16:3e:20:57:c3",
             'fixed_ips': [{
                 'subnet_id': neutron_subnetv4_id,
                 'ip_address': '192.168.1.2'
             }, {
                 'subnet_id': neutron_subnetv6_id,
                 'ip_address': 'fe80::f816:3eff:fe20:57c4'
             }],
             "id":
             "65c0ee9f-d634-4522-8954-51021b570b0d",
             "security_groups": [],
             "device_id":
             ""
         }
     }
     if ex:
         app.neutron.create_port(fake_port_request).AndRaise(ex)
     else:
         app.neutron.create_port(fake_port_request).AndReturn(fake_port)
     self.mox.ReplayAll()
Example #19
0
def _create_subnets_and_or_port(interface, neutron_network_id, endpoint_id):
    response_interface = {}
    existing_subnets = []
    created_subnets_response = {'subnets': []}
    # v4 and v6 Subnets for bulk creation.
    new_subnets = []

    interface_cidrv4 = interface.get('Address', '')
    interface_cidrv6 = interface.get('AddressIPv6', '')
    interface_mac = interface.get('MacAddress', '')

    if interface_cidrv4 or interface_cidrv6:
        created_subnets_response = _handle_explicit_allocation(
            neutron_network_id, endpoint_id, interface_cidrv4,
            interface_cidrv6, new_subnets, existing_subnets)
    else:
        app.logger.info("Retrieving or creating subnets with the default "
                        "subnetpool because Address and AddressIPv6 are "
                        "not given.")
        created_subnets_response = _handle_allocation_from_pools(
            neutron_network_id, endpoint_id, new_subnets, existing_subnets)

    try:
        port = {
            'name': utils.get_neutron_port_name(endpoint_id),
            'admin_state_up': True,
            "binding:host_id": utils.get_hostname(),
            'network_id': neutron_network_id,
            'device_owner': constants.DEVICE_OWNER,
            'device_id': endpoint_id,
        }
        if interface_mac:
            port['mac_address'] = interface_mac
        created_subnets = created_subnets_response.get('subnets', [])
        all_subnets = created_subnets + existing_subnets
        fixed_ips = port['fixed_ips'] = []
        for subnet in all_subnets:
            fixed_ip = {'subnet_id': subnet['id']}
            if interface_cidrv4 or interface_cidrv6:
                if subnet['ip_version'] == 4 and interface_cidrv4:
                    cidr = netaddr.IPNetwork(interface_cidrv4)
                elif subnet['ip_version'] == 6 and interface_cidrv6:
                    cidr = netaddr.IPNetwork(interface_cidrv6)
                subnet_cidr = '/'.join([str(cidr.network),
                                        str(cidr.prefixlen)])
                if subnet['cidr'] != subnet_cidr:
                    continue
                fixed_ip['ip_address'] = str(cidr.ip)
            fixed_ips.append(fixed_ip)
        created_port = app.neutron.create_port({'port': port})
        created_port = created_port['port']

        created_fixed_ips = created_port['fixed_ips']
        subnets_dict_by_id = {subnet['id']: subnet
                              for subnet in all_subnets}
        if not interface_mac:
            response_interface['MacAddress'] = created_port['mac_address']

        if not (interface_cidrv4 or interface_cidrv6):
            if 'ip_address' in created_port:
                _process_interface_address(
                    created_port, subnets_dict_by_id, response_interface)
            for fixed_ip in created_fixed_ips:
                _process_interface_address(
                    fixed_ip, subnets_dict_by_id, response_interface)
    except n_exceptions.NeutronClientException as ex:
        app.logger.error("Error happened during creating a "
                         "Neutron port: {0}".format(ex))
        # Rollback the subnets creation
        for subnet in created_subnets:
            app.neutron.delete_subnet(subnet['id'])
        raise
    return response_interface
Example #20
0
    def test_network_driver_join(self):
        fake_docker_net_id = hashlib.sha256(utils.getrandbits(256)).hexdigest()
        fake_docker_endpoint_id = hashlib.sha256(
            utils.getrandbits(256)).hexdigest()
        fake_container_id = hashlib.sha256(utils.getrandbits(256)).hexdigest()

        fake_neutron_net_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_net_id, fake_docker_net_id)
        fake_neutron_port_id = str(uuid.uuid4())
        self.mox.StubOutWithMock(app.neutron, 'list_ports')
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = str(uuid.uuid4())
        fake_neutron_v6_subnet_id = str(uuid.uuid4())
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id, fake_neutron_port_id,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_ports(
            name=neutron_port_name).AndReturn(fake_neutron_ports_response)

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        fake_neutron_subnets_response = self._get_fake_subnets(
            fake_docker_endpoint_id, fake_neutron_net_id,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_subnets(network_id=fake_neutron_net_id).AndReturn(
            fake_neutron_subnets_response)
        fake_neutron_port = fake_neutron_ports_response['ports'][0]
        fake_neutron_subnets = fake_neutron_subnets_response['subnets']
        _, fake_peer_name, _ = self._mock_out_binding(fake_docker_endpoint_id,
                                                      fake_neutron_port,
                                                      fake_neutron_subnets)
        self.mox.ReplayAll()

        fake_subnets_dict_by_id = {
            subnet['id']: subnet
            for subnet in fake_neutron_subnets
        }

        join_request = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
            'SandboxKey': utils.get_sandbox_key(fake_container_id),
            'Options': {},
        }
        response = self.app.post('/NetworkDriver.Join',
                                 content_type='application/json',
                                 data=jsonutils.dumps(join_request))

        self.assertEqual(200, response.status_code)

        decoded_json = jsonutils.loads(response.data)
        fake_neutron_v4_subnet = fake_subnets_dict_by_id[
            fake_neutron_v4_subnet_id]
        fake_neutron_v6_subnet = fake_subnets_dict_by_id[
            fake_neutron_v6_subnet_id]
        expected_response = {
            'Gateway': fake_neutron_v4_subnet['gateway_ip'],
            'GatewayIPv6': fake_neutron_v6_subnet['gateway_ip'],
            'InterfaceName': {
                'DstPrefix': config.CONF.binding.veth_dst_prefix,
                'SrcName': fake_peer_name,
            },
            'StaticRoutes': []
        }
        self.assertEqual(expected_response, decoded_json)
Example #21
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_name = json_data['NetworkID']
    endpoint_id = json_data['EndpointID']

    filtered_networks = _get_networks_by_attrs(name=neutron_network_name)

    if not filtered_networks:
        return flask.jsonify({
            'Err': "Neutron network associated with ID {0} doesn't exit."
            .format(neutron_network_name)
        })
    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('Preparing the veth pair was failed: {0}.'
                                 .format(ex))
        except processutils.ProcessExecutionError:
            with excutils.save_and_reraise_exception():
                app.logger.error(
                    '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'] = constants.TYPES['NEXTHOP']
                    static_route['NextHop'] = host_route['nexthop']
                else:
                    static_route['RouteType'] = constants.TYPES['CONNECTED']
                join_response['StaticRoutes'].append(static_route)

        return flask.jsonify(join_response)
Example #22
0
    def test_network_driver_create_endpoint(self):
        docker_network_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()
        docker_endpoint_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()

        fake_neutron_network_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_network_id, docker_network_id)

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        fake_existing_subnets_response = {
            "subnets": []
        }
        fake_cidr_v4 = '192.168.1.0/24'
        app.neutron.list_subnets(
            network_id=fake_neutron_network_id,
            cidr=fake_cidr_v4).AndReturn(fake_existing_subnets_response)

        fake_cidr_v6 = 'fe80::/64'
        app.neutron.list_subnets(
            network_id=fake_neutron_network_id,
            cidr=fake_cidr_v6).AndReturn(fake_existing_subnets_response)

        self.mox.StubOutWithMock(app.neutron, 'create_subnet')
        fake_subnet_request = {
            "subnets": [{
                'name': '-'.join([docker_endpoint_id,
                                  '192.168.1.0']),
                'network_id': fake_neutron_network_id,
                'ip_version': 4,
                "cidr": '192.168.1.0/24',
                'enable_dhcp': 'False'
            }, {
                'name': '-'.join([docker_endpoint_id,
                                  'fe80::']),
                'network_id': fake_neutron_network_id,
                'ip_version': 6,
                "cidr": 'fe80::/64',
                'enable_dhcp': 'False'
            }]
        }
        # The following fake response is retrieved from the Neutron doc:
        #   http://developer.openstack.org/api-ref-networking-v2.html#createSubnet  # noqa
        subnet_v4_id = "9436e561-47bf-436a-b1f1-fe23a926e031"
        subnet_v6_id = "64dd4a98-3d7a-4bfd-acf4-91137a8d2f51"
        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_subnet_response = {
            "subnets": [
                fake_v4_subnet['subnet'],
                fake_v6_subnet['subnet']
            ]
        }
        app.neutron.create_subnet(
            fake_subnet_request).AndReturn(fake_subnet_response)

        fake_ipv4cidr = '192.168.1.2/24'
        fake_ipv6cidr = 'fe80::f816:3eff:fe20:57c4/64'
        subnet_v4_address = fake_ipv4cidr.split('/')[0]
        subnet_v6_address = fake_ipv6cidr.split('/')[0]
        self.mox.StubOutWithMock(app.neutron, 'create_port')
        fake_port_request = {
            'port': {
                'name': utils.get_neutron_port_name(docker_endpoint_id),
                'admin_state_up': True,
                "binding:host_id": utils.get_hostname(),
                'device_owner': constants.DEVICE_OWNER,
                'device_id': docker_endpoint_id,
                'mac_address': "fa:16:3e:20:57:c3",
                'network_id': fake_neutron_network_id,
                'fixed_ips': [{
                    'subnet_id': subnet_v4_id,
                    'ip_address': subnet_v4_address
                }, {
                    'subnet_id': subnet_v6_id,
                    'ip_address': subnet_v6_address
                }]
            }
        }
        fake_port_id = str(uuid.uuid4())
        fake_port = self._get_fake_port(
            docker_endpoint_id, fake_neutron_network_id,
            fake_port_id,
            subnet_v4_id, subnet_v6_id)
        app.neutron.create_port(fake_port_request).AndReturn(fake_port)
        self.mox.ReplayAll()

        data = {
            'NetworkID': docker_network_id,
            'EndpointID': docker_endpoint_id,
            'Options': {},
            'Interface': {
                'Address': fake_ipv4cidr,
                'AddressIPv6': fake_ipv6cidr,
                'MacAddress': "fa:16:3e:20:57:c3"
            }
        }
        response = self.app.post('/NetworkDriver.CreateEndpoint',
                                 content_type='application/json',
                                 data=jsonutils.dumps(data))

        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        expected = {'Interface': {}}
        self.assertEqual(expected, decoded_json)
Example #23
0
    def test_network_driver_join(self, vif_plug_is_fatal):
        if vif_plug_is_fatal:
            self.mox.StubOutWithMock(app, "vif_plug_is_fatal")
            app.vif_plug_is_fatal = True

        fake_docker_net_id = utils.get_hash()
        fake_docker_endpoint_id = utils.get_hash()
        fake_container_id = utils.get_hash()

        fake_neutron_net_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_net_id, fake_docker_net_id)
        fake_neutron_port_id = str(uuid.uuid4())
        self.mox.StubOutWithMock(app.neutron, 'list_ports')
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = str(uuid.uuid4())
        fake_neutron_v6_subnet_id = str(uuid.uuid4())
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id,
            fake_neutron_port_id, constants.PORT_STATUS_DOWN,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_ports(name=neutron_port_name).AndReturn(
            fake_neutron_ports_response)

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        fake_neutron_subnets_response = self._get_fake_subnets(
            fake_docker_endpoint_id, fake_neutron_net_id,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        app.neutron.list_subnets(network_id=fake_neutron_net_id).AndReturn(
            fake_neutron_subnets_response)
        fake_neutron_port = fake_neutron_ports_response['ports'][0]
        fake_neutron_subnets = fake_neutron_subnets_response['subnets']
        _, fake_peer_name, _ = self._mock_out_binding(
            fake_docker_endpoint_id, fake_neutron_port, fake_neutron_subnets)

        if vif_plug_is_fatal:
            self.mox.StubOutWithMock(app.neutron, 'show_port')
            fake_neutron_ports_response_2 = self._get_fake_port(
                fake_docker_endpoint_id, fake_neutron_net_id,
                fake_neutron_port_id, constants.PORT_STATUS_ACTIVE,
                fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
            app.neutron.show_port(fake_neutron_port_id).AndReturn(
                fake_neutron_ports_response_2)

        self.mox.ReplayAll()

        fake_subnets_dict_by_id = {subnet['id']: subnet
                                   for subnet in fake_neutron_subnets}

        join_request = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
            'SandboxKey': utils.get_sandbox_key(fake_container_id),
            'Options': {},
        }
        response = self.app.post('/NetworkDriver.Join',
                                 content_type='application/json',
                                 data=jsonutils.dumps(join_request))

        self.assertEqual(200, response.status_code)

        decoded_json = jsonutils.loads(response.data)
        fake_neutron_v4_subnet = fake_subnets_dict_by_id[
            fake_neutron_v4_subnet_id]
        fake_neutron_v6_subnet = fake_subnets_dict_by_id[
            fake_neutron_v6_subnet_id]
        expected_response = {
            'Gateway': fake_neutron_v4_subnet['gateway_ip'],
            'GatewayIPv6': fake_neutron_v6_subnet['gateway_ip'],
            'InterfaceName': {
                'DstPrefix': config.CONF.binding.veth_dst_prefix,
                'SrcName': fake_peer_name,
            },
            'StaticRoutes': []
        }
        self.assertEqual(expected_response, decoded_json)
Example #24
0
    def test_network_driver_create_endpoint_with_subnetpools(self):
        docker_network_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()
        docker_endpoint_id = hashlib.sha256(
            str(random.getrandbits(256))).hexdigest()

        fake_neutron_network_id = str(uuid.uuid4())
        self._mock_out_network(fake_neutron_network_id, docker_network_id)

        self.mox.StubOutWithMock(app.neutron, 'list_subnetpools')
        fake_kuryr_subnetpool_id = str(uuid.uuid4())
        kuryr_subnetpools = self._get_fake_v4_subnetpools(
            fake_kuryr_subnetpool_id)
        app.neutron.list_subnetpools(name='kuryr').AndReturn(kuryr_subnetpools)

        fake_kuryr6_subnetpool_id = str(uuid.uuid4())
        kuryr6_subnetpools = self._get_fake_v6_subnetpools(
            fake_kuryr6_subnetpool_id)
        app.neutron.list_subnetpools(
            name='kuryr6').AndReturn(kuryr6_subnetpools)

        self.mox.StubOutWithMock(app.neutron, 'list_subnets')
        fake_existing_subnets_response = {
            "subnets": []
        }
        fake_cidr_v4 = '192.168.1.0/24'
        app.neutron.list_subnets(
            network_id=fake_neutron_network_id,
            cidr=fake_cidr_v4).AndReturn(fake_existing_subnets_response)

        fake_cidr_v6 = 'fe80::/64'
        app.neutron.list_subnets(
            network_id=fake_neutron_network_id,
            cidr=fake_cidr_v6).AndReturn(fake_existing_subnets_response)

        self.mox.StubOutWithMock(app.neutron, 'create_subnet')
        fake_subnet_request = {
            "subnets": [{
                'name': '-'.join([docker_endpoint_id,
                                  '192.168.1.0']),
                'network_id': fake_neutron_network_id,
                'ip_version': 4,
                'subnetpool_id': fake_kuryr_subnetpool_id,
                'enable_dhcp': 'False'
            }, {
                'name': '-'.join([docker_endpoint_id,
                                  'fe80::']),
                'network_id': fake_neutron_network_id,
                'ip_version': 6,
                'subnetpool_id': fake_kuryr6_subnetpool_id,
                'enable_dhcp': 'False'
            }]
        }
        # The following fake response is retrieved from the Neutron doc:
        #   http://developer.openstack.org/api-ref-networking-v2.html#createSubnet  # noqa
        subnet_v4_id = "9436e561-47bf-436a-b1f1-fe23a926e031"
        subnet_v6_id = "64dd4a98-3d7a-4bfd-acf4-91137a8d2f51"
        fake_subnet_response = super(self.__class__, self)._get_fake_subnets(
            docker_endpoint_id, fake_neutron_network_id,
            subnet_v4_id, subnet_v6_id)

        app.neutron.create_subnet(
            fake_subnet_request).AndReturn(fake_subnet_response)

        self.mox.StubOutWithMock(app.neutron, 'create_port')
        fake_mac_address = 'fa:16:3e:20:57:c3'
        fake_neutron_port_id = str(uuid.uuid4())
        fake_port_request = {
            'port': {
                'name': utils.get_neutron_port_name(docker_endpoint_id),
                'admin_state_up': True,
                "binding:host_id": utils.get_hostname(),
                'mac_address': fake_mac_address,
                'network_id': fake_neutron_network_id,
                'device_owner': constants.DEVICE_OWNER,
                'device_id': docker_endpoint_id,
                'fixed_ips': [
                    {'subnet_id': subnet_v4_id},
                    {'subnet_id': subnet_v6_id},
                ]
            }
        }
        fake_port_response = self._get_fake_port(
            docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_port_id,
            neutron_subnet_v4_id=subnet_v4_id,
            neutron_subnet_v6_id=subnet_v6_id,
            neutron_subnet_v4_address='192.168.1.2',
            neutron_subnet_v6_address="fe80::f816:3eff:fe20:57c4")
        app.neutron.create_port(
            fake_port_request).AndReturn(fake_port_response)

        self.mox.ReplayAll()

        request = {
            'NetworkID': docker_network_id,
            'EndpointID': docker_endpoint_id,
            'Options': {},
            'Interface': {
                'MacAddress': "fa:16:3e:20:57:c3"
            }
        }
        response = self.app.post('/NetworkDriver.CreateEndpoint',
                                 content_type='application/json',
                                 data=jsonutils.dumps(request))

        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        expected = {'Interface': request['Interface']}
        # Address and AddressIPv6, allocated by Neutron's IPAM automatically
        # should be contained in the response.
        self.assertNotEqual(expected, decoded_json)
        self.assertIn('Address', decoded_json['Interface'])
        self.assertIn('AddressIPv6', decoded_json['Interface'])
Example #25
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)
Example #26
0
 def test_get_port_name(self):
     fake_docker_endpoint_id = utils.get_hash()
     generated_neutron_port_name = utils.get_neutron_port_name(
         fake_docker_endpoint_id)
     self.assertIn(utils.PORT_POSTFIX, generated_neutron_port_name)
     self.assertIn(fake_docker_endpoint_id, generated_neutron_port_name)