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()
    def test_leave_unbinding_failure(self, GivenException):
        fake_docker_network_id = utils.get_hash()
        fake_docker_endpoint_id = utils.get_hash()

        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, const.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]

        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'])
示例#3
0
 def _get_fake_port_request(neutron_network_id, docker_endpoint_id,
                            neutron_subnetv4_id, neutron_subnetv6_id):
     fake_port_request = {
         'port': {
             'name':
             utils.get_neutron_port_name(docker_endpoint_id),
             'admin_state_up':
             True,
             "binding:host_id":
             lib_utils.get_hostname(),
             'device_owner':
             lib_const.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
         }
     }
     return fake_port_request
    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)
示例#5
0
 def _get_fake_port_map(
         neutron_network_id, docker_endpoint_id,
         neutron_subnetv4_id, neutron_subnetv6_id):
     fake_port = {
         "port": {
             "status": "DOWN",
             "name": utils.get_neutron_port_name(docker_endpoint_id),
             "allowed_address_pairs": [],
             "admin_state_up": True,
             "binding:host_id": lib_utils.get_hostname(),
             "network_id": neutron_network_id,
             "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
             'device_owner': lib_const.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": [],
         }
     }
     return fake_port
示例#6
0
    def update_port(self, port, endpoint_id, interface_mac):
        """Updates port information and performs extra driver-specific actions.

        It returns the updated port dictionary after the required actions
        performed depending on the binding driver.

        :param port: a neutron port dictionary returned from
                             python-neutronclient
        :param endpoint_id:  the ID of the endpoint as string
        :param interface_mac: the MAC address of the endpoint
        :returns: the updated Neutron port id dictionary as returned by
                  python-neutronclient
        """
        port['name'] = libnet_utils.get_neutron_port_name(endpoint_id)
        try:
            updated_port = {
                'name': port['name'],
                'device_owner': lib_const.DEVICE_OWNER,
                'binding:host_id': lib_utils.get_hostname(),
            }
            if not port.get('device_id'):
                updated_port['device_id'] = endpoint_id
            if interface_mac:
                updated_port['mac_address'] = interface_mac
            response_port = app.neutron.update_port(port['id'],
                                                    {'port': updated_port})
        except n_exceptions.NeutronClientException as ex:
            LOG.error("Error happened during updating a "
                      "Neutron port: %s", ex)
            raise
        return response_port['port']
示例#7
0
    def _get_fake_port(docker_endpoint_id,
                       neutron_network_id,
                       neutron_port_id,
                       neutron_port_status=lib_const.PORT_STATUS_DOWN,
                       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",
                       neutron_mac_address="fa:16:3e:20:57:c3",
                       device_owner=None,
                       neutron_trunk_id=None,
                       tags=None,
                       name=None,
                       binding_profile=None):
        # The following fake response is retrieved from the Neutron doc:
        #   http://developer.openstack.org/api-ref-networking-v2.html#createPort  # noqa
        if not name:
            name = utils.get_neutron_port_name(docker_endpoint_id)
        fake_port = {
            'port': {
                "status": neutron_port_status,
                "name": name,
                "allowed_address_pairs": [],
                "admin_state_up": True,
                "network_id": neutron_network_id,
                "tenant_id": "d6700c0c9ffa4f1cb322cd4a1f3906fa",
                "device_owner": device_owner,
                "mac_address": neutron_mac_address,
                "fixed_ips": [],
                "id": neutron_port_id,
                "security_groups": [],
                "device_id": docker_endpoint_id,
                "tags": tags
            }
        }

        if binding_profile is not None:
            fake_port['port']['binding:profile'] = binding_profile

        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
            })
        if neutron_trunk_id:
            fake_port['port']['trunk_details'] = {'trunk_id': neutron_trunk_id}

        return fake_port
示例#8
0
    def test_delete_endpoint_delete_host_iface_failure(self, GivenException,
                                                       mock_list_networks,
                                                       mock_list_ports,
                                                       mock_delete_host_iface):
        fake_docker_network_id = lib_utils.get_hash()
        fake_docker_endpoint_id = lib_utils.get_hash()

        fake_neutron_network_id = uuidutils.generate_uuid()
        fake_neutron_port_id = uuidutils.generate_uuid()
        fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
        fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
        t = utils.make_net_tags(fake_docker_network_id)
        mock_list_networks.return_value = self._get_fake_list_network(
            fake_neutron_network_id)
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        mock_list_ports.return_value = fake_neutron_ports_response
        fake_neutron_port = fake_neutron_ports_response['ports'][0]

        fake_message = "fake message"
        if GivenException == n_exceptions.NeutronClientException:
            fake_exception = GivenException(fake_message, status_code=500)
        else:
            fake_exception = GivenException(fake_message)
        mock_delete_host_iface.side_effect = fake_exception
        response = self._invoke_delete_request(fake_docker_network_id,
                                               fake_docker_endpoint_id)

        self.assertEqual(w_exceptions.InternalServerError.code,
                         response.status_code)
        mock_list_networks.assert_called_with(tags=t)
        mock_list_ports.assert_called_with(name=neutron_port_name)
        mock_delete_host_iface.assert_called_with(fake_docker_endpoint_id,
                                                  fake_neutron_port)
        decoded_json = jsonutils.loads(response.data)
        self.assertIn('Err', decoded_json)
        self.assertIn(fake_message, decoded_json['Err'])
示例#9
0
    def update_port(self, port, endpoint_id, interface_mac, tags=True):
        """Updates port information and performs extra driver-specific actions.

        It returns the updated port dictionary after the required actions
        performed depending on the binding driver.

        :param port: a neutron port dictionary returned from
                             python-neutronclient
        :param endpoint_id:  the ID of the endpoint as string
        :param interface_mac: the MAC address of the endpoint
        :returns: the updated Neutron port id dictionary as returned by
                  python-neutronclient
        """
        try:
            updated_port = {}
            hostname = lib_utils.get_hostname()
            if port['binding:host_id'] != hostname:
                updated_port['binding:host_id'] = hostname
                updated_port['device_owner'] = lib_const.DEVICE_OWNER
            if port['admin_state_up'] is not True:
                updated_port['admin_state_up'] = True
            if not tags:
                # rename the port if tagging is not supported
                updated_port['name'] = libnet_utils.get_neutron_port_name(
                    endpoint_id)
            if not port.get('device_id'):
                updated_port['device_id'] = endpoint_id
            if interface_mac and port['mac_address'] != interface_mac:
                updated_port['mac_address'] = interface_mac
            if updated_port:
                port = app.neutron.update_port(port['id'],
                                               {'port': updated_port})['port']
        except n_exceptions.NeutronClientException as ex:
            LOG.error("Error happened during updating a "
                      "Neutron port: %s", ex)
            raise
        return port
示例#10
0
    def _get_fake_port(docker_endpoint_id, neutron_network_id,
                       neutron_port_id,
                       neutron_port_status=const.PORT_STATUS_DOWN,
                       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": neutron_port_status,
                "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
示例#11
0
    def update_port(self, port, endpoint_id, interface_mac, tags=True):
        """Updates port information and performs extra driver-specific actions.

        It returns the updated port dictionary after the required actions
        performed depending on the binding driver.

        :param port: a neutron port dictionary returned from
                             python-neutronclient
        :param endpoint_id:  the ID of the endpoint as string
        :param interface_mac: the MAC address of the endpoint
        :returns: the updated Neutron port id dictionary as returned by
                  python-neutronclient
        """
        try:
            updated_port = {}
            hostname = lib_utils.get_hostname()
            if port['binding:host_id'] != hostname:
                updated_port['binding:host_id'] = hostname
                updated_port['device_owner'] = lib_const.DEVICE_OWNER
            if port['admin_state_up'] is not True:
                updated_port['admin_state_up'] = True
            if not tags:
                # rename the port if tagging is not supported
                updated_port['name'] = libnet_utils.get_neutron_port_name(
                    endpoint_id)
            if not port.get('device_id'):
                updated_port['device_id'] = endpoint_id
            if interface_mac and port['mac_address'] != interface_mac:
                updated_port['mac_address'] = interface_mac
            if updated_port:
                port = app.neutron.update_port(port['id'],
                                               {'port': updated_port})['port']
        except n_exceptions.NeutronClientException as ex:
            LOG.error("Error happened during updating a "
                      "Neutron port: %s", ex)
            raise
        return port
示例#12
0
    def test_container_ipam_request_address_with_existing_port(self):
        # pre-created Neutron network and subnet and port
        neutron_net_name = lib_utils.get_random_string(8)
        neutron_network = self.neutron_client.create_network(
            {'network': {'name': neutron_net_name,
                         "admin_state_up": True}})
        neutron_subnet_name = lib_utils.get_random_string(8)
        subnet_param = [{
            'name': neutron_subnet_name,
            'network_id': neutron_network['network']['id'],
            'ip_version': 4,
            'cidr': "10.14.0.0/24",
        }]
        neutron_subnet = self.neutron_client.create_subnet(
            {'subnets': subnet_param})
        neutron_v6_subnet_name = lib_utils.get_random_string(8)
        v6_subnet_param = [{
            'name': neutron_v6_subnet_name,
            'network_id': neutron_network['network']['id'],
            'ip_version': 6,
            'cidr': "fe81::/64",
        }]
        neutron_v6_subnet = self.neutron_client.create_subnet(
            {'subnets': v6_subnet_param})
        existing_neutron_port = self.neutron_client.create_port(
            {'port': {'network_id': neutron_network['network']['id']}})
        fixed_ips = {fip['subnet_id']: fip['ip_address']
                     for fip in existing_neutron_port['port']['fixed_ips']}
        ipv4_address = fixed_ips[neutron_subnet['subnets'][0]['id']]
        ipv6_address = fixed_ips[neutron_v6_subnet['subnets'][0]['id']]

        fake_ipam = {
            "Driver": "kuryr",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.14.0.0/24",
                    "Gateway": "10.14.0.1"
                },
                {
                    "Subnet": "fe81::/64",
                    "Gateway": "fe81::1"
                },
            ]
        }

        # Create docker network using existing Neutron network
        options = {'neutron.net.name': neutron_net_name}
        container_net_name = lib_utils.get_random_string(8)
        container_net = self.docker_client.create_network(
            name=container_net_name,
            driver='kuryr',
            enable_ipv6=True,
            options=options,
            ipam=fake_ipam)
        container_net_id = container_net.get('Id')
        try:
            networks = self.neutron_client.list_networks(
                tags=utils.make_net_tags(container_net_id))
        except Exception as e:
            self.docker_client.remove_network(container_net_id)
            message = ("Failed to list neutron networks: %s")
            self.fail(message % e.args[0])
        self.assertEqual(1, len(networks['networks']))

        # Boot a container, and connect to the docker network.
        container_name = lib_utils.get_random_string(8)
        container = self.docker_client.create_container(
            image='kuryr/busybox',
            command='/bin/sleep 600',
            hostname='kuryr_test_container',
            name=container_name)
        warn_msg = container.get('Warning')
        container_id = container.get('Id')
        self.assertIsNone(warn_msg, 'Warn in creating container')
        self.assertIsNotNone(container_id, 'Create container id must not '
                                           'be None')
        self.docker_client.start(container=container_id)
        self.docker_client.connect_container_to_network(
            container_id, container_net_id, ipv4_address=ipv4_address,
            ipv6_address=ipv6_address)
        try:
            ports = self.neutron_client.list_ports(
                network_id=neutron_network['network']['id'])
        except Exception as e:
            self.docker_client.disconnect_container_from_network(
                container_id,
                container_net_id)
            message = ("Failed to list neutron ports: %s")
            self.fail(message % e.args[0])

        # A dhcp port gets created as well; dhcp is enabled by default
        self.assertEqual(2, len(ports['ports']))
        # Find the existing neutron port
        neutron_port_param = {"network_id": neutron_network['network']['id']}
        neutron_ports = self.neutron_client.list_ports(
            **neutron_port_param)
        neutron_port = [port for port in neutron_ports['ports'] if
                        (const.KURYR_EXISTING_NEUTRON_PORT in port['tags'] or
                         port['name'] ==
                         utils.get_neutron_port_name(port['device_id']))]
        self.assertEqual(1, len(neutron_port))
        # Disconnect container from network.
        self.docker_client.disconnect_container_from_network(container_id,
                                                             container_net_id)
        ports = self.neutron_client.list_ports(
            network_id=neutron_network['network']['id'])
        self.assertEqual(2, len(ports['ports']))
        neutron_ports = self.neutron_client.list_ports(
            **neutron_port_param)
        neutron_port = [port for port in neutron_ports['ports'] if
                        (const.KURYR_EXISTING_NEUTRON_PORT in port['tags'] or
                         port['name'] ==
                         utils.get_neutron_port_name(port['device_id']))]
        self.assertEqual(0, len(neutron_port))

        # Cleanup resources
        self.docker_client.stop(container=container_id)
        self.docker_client.remove_network(container_net_id)
        self.neutron_client.delete_port(existing_neutron_port['port']['id'])
        self.neutron_client.delete_subnet(neutron_subnet['subnets'][0]['id'])
        self.neutron_client.delete_subnet(
            neutron_v6_subnet['subnets'][0]['id'])
        self.neutron_client.delete_network(neutron_network['network']['id'])
示例#13
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)
示例#14
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)
示例#15
0
    def test_create_host_iface_failures(self, GivenException,
            mock_list_networks, mock_list_ports, mock_list_subnets,
            mock_update_port, mock_create_host_iface):
        fake_docker_network_id = lib_utils.get_hash()
        fake_docker_endpoint_id = lib_utils.get_hash()
        fake_neutron_network_id = uuidutils.generate_uuid()

        fake_neutron_network = self._get_fake_list_network(
            fake_neutron_network_id)
        t = utils.make_net_tags(fake_docker_network_id)
        mock_list_networks.return_value = fake_neutron_network

        fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
        fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
        fake_v4_subnet = self._get_fake_v4_subnet(fake_docker_network_id,
                                                  fake_docker_endpoint_id,
                                                  fake_neutron_v4_subnet_id)
        fake_v6_subnet = self._get_fake_v6_subnet(fake_docker_network_id,
                                                  fake_docker_endpoint_id,
                                                  fake_neutron_v6_subnet_id)
        fake_v4_subnet_response = {
            "subnets": [
                fake_v4_subnet['subnet']
            ]
        }
        fake_v6_subnet_response = {
            "subnets": [
                fake_v6_subnet['subnet']
            ]
        }

        def fake_subnet_response(network_id, cidr):
            if cidr == '192.168.1.0/24':
                return fake_v4_subnet_response
            elif cidr == 'fe80::/64':
                return fake_v6_subnet_response
            else:
                return {'subnets': []}

        mock_list_subnets.side_effect = fake_subnet_response

        fake_neutron_port_id = uuidutils.generate_uuid()
        fake_fixed_ips = ['subnet_id=%s' % fake_neutron_v4_subnet_id,
                          'ip_address=192.168.1.2',
                          'subnet_id=%s' % fake_neutron_v6_subnet_id,
                          'ip_address=fe80::f816:3eff:fe20:57c4']
        fake_port_response = self._get_fake_port(
            fake_docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        fake_ports_response = {
            "ports": [
                fake_port_response['port']
            ]
        }
        mock_list_ports.return_value = fake_ports_response
        fake_updated_port = fake_port_response['port']
        fake_updated_port['name'] = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        mock_update_port.return_value = fake_port_response['port']

        fake_neutron_subnets = [fake_v4_subnet['subnet'],
                                fake_v6_subnet['subnet']]

        fake_message = "fake message"
        if GivenException == n_exceptions.NeutronClientException:
            fake_exception = GivenException(fake_message, status_code=500)
        else:
            fake_exception = GivenException(fake_message)
        mock_create_host_iface.side_effect = fake_exception

        response = self._invoke_create_request(
            fake_docker_network_id, fake_docker_endpoint_id)

        self.assertEqual(
            w_exceptions.InternalServerError.code, response.status_code)
        mock_list_networks.assert_called_with(tags=t)
        expect_calls = [mock.call(cidr='192.168.1.0/24',
            network_id=fake_neutron_network_id),
            mock.call(cidr='fe80::/64', network_id=fake_neutron_network_id)]
        mock_list_subnets.assert_has_calls(expect_calls, any_order=True)
        mock_list_ports.assert_called_with(fixed_ips=fake_fixed_ips)
        mock_update_port.assert_called_with(fake_port_response['port'],
                                            fake_docker_endpoint_id,
                                            "fa:16:3e:20:57:c3")
        mock_create_host_iface.assert_called_with(
            fake_docker_endpoint_id, fake_updated_port, fake_neutron_subnets,
            fake_neutron_network['networks'][0])

        decoded_json = jsonutils.loads(response.data)
        self.assertIn('Err', decoded_json)
        self.assertIn(fake_message, decoded_json['Err'])
    def test_network_driver_program_external_connectivity(self, existing_sg,
                                                          num_ports):
        fake_docker_net_id = utils.get_hash()
        fake_docker_endpoint_id = utils.get_hash()

        fake_neutron_net_id = str(uuid.uuid4())
        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)
        if existing_sg:
            fake_neutron_existing_sec_group_id = str(uuid.uuid4())
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_existing_sec_group_id]

        app.neutron.list_ports(name=neutron_port_name).AndReturn(
            fake_neutron_ports_response)

        sec_group = {
            'name': utils.get_sg_expose_name(fake_neutron_port_id),
            'description': 'Docker exposed ports created by Kuryr.'
        }
        self.mox.StubOutWithMock(app.neutron, 'create_security_group')
        fake_neutron_sec_group_id = utils.get_hash()
        fake_neutron_sec_group_response = {'security_group':
                                           {'id': fake_neutron_sec_group_id}}
        app.neutron.create_security_group({'security_group':
                                           sec_group}).AndReturn(
                                           fake_neutron_sec_group_response)

        self.mox.StubOutWithMock(app.neutron, 'create_security_group_rule')
        for i in range(num_ports):
            sec_group_rule = {
                'security_group_id': fake_neutron_sec_group_id,
                'direction': 'ingress',
                'port_range_min': PORT + i,
                'port_range_max': PORT + i,
                'protocol': constants.PROTOCOLS[PROTOCOL]
            }
            app.neutron.create_security_group_rule({'security_group_rule':
                                                    sec_group_rule})

        sgs = [fake_neutron_sec_group_id]
        if existing_sg:
            sgs.append(fake_neutron_existing_sec_group_id)
        self.mox.StubOutWithMock(app.neutron, 'show_port')
        app.neutron.show_port(fake_neutron_port_id).AndReturn(
            {'port': fake_neutron_ports_response['ports'][0]})

        self.mox.StubOutWithMock(app.neutron, 'update_port')
        app.neutron.update_port(fake_neutron_port_id,
                                {'port': {'security_groups': sgs}})

        self.mox.ReplayAll()

        port_opt = []
        for i in range(num_ports):
            port_opt.append({u'Port': PORT + i, u'Proto': PROTOCOL})
        options = {'com.docker.network.endpoint.exposedports':
                   port_opt,
                   'com.docker.network.portmap':
                   []}
        data = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
            'Options': options,
        }
        response = self.app.post('/NetworkDriver.ProgramExternalConnectivity',
                                 content_type='application/json',
                                 data=jsonutils.dumps(data))

        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
示例#17
0
    def test_container_ipam_release_address_with_existing_network(self):
        # pre-created Neutron network and subnet
        neutron_net_name = lib_utils.get_random_string(8)
        neutron_network = self.neutron_client.create_network(
            {'network': {
                'name': neutron_net_name,
                "admin_state_up": True
            }})
        neutron_subnet_name = lib_utils.get_random_string(8)
        subnet_param = [{
            'name': neutron_subnet_name,
            'network_id': neutron_network['network']['id'],
            'ip_version': 4,
            'cidr': "10.10.0.0/24",
            'enable_dhcp': True,
        }]
        self.neutron_client.create_subnet({'subnets': subnet_param})

        fake_ipam = {
            "Driver":
            "kuryr",
            "Options": {},
            "Config": [{
                "Subnet": "10.10.0.0/16",
                "IPRange": "10.10.0.0/24",
                "Gateway": "10.10.0.1"
            }]
        }

        # Create docker network using existing Neutron network
        options = {'neutron.net.name': neutron_net_name}
        container_net_name = lib_utils.get_random_string(8)
        container_net = self.docker_client.create_network(
            name=container_net_name,
            driver='kuryr',
            options=options,
            ipam=fake_ipam)
        container_net_id = container_net.get('Id')
        try:
            networks = self.neutron_client.list_networks(
                tags=utils.make_net_tags(container_net_id))
        except Exception as e:
            self.docker_client.remove_network(container_net_id)
            message = ("Failed to list neutron networks: %s")
            self.fail(message % e.args[0])
        self.assertEqual(1, len(networks['networks']))

        # Boot a container, and connect to the docker network.
        container_name = lib_utils.get_random_string(8)
        container = self.docker_client.create_container(
            image='kuryr/busybox',
            command='/bin/sleep 600',
            hostname='kuryr_test_container',
            name=container_name)
        warn_msg = container.get('Warning')
        container_id = container.get('Id')
        self.assertIsNone(warn_msg, 'Warn in creating container')
        self.assertIsNotNone(container_id, 'Create container id must not '
                             'be None')
        self.docker_client.start(container=container_id)
        self.docker_client.connect_container_to_network(
            container_id, container_net_id)
        try:
            ports = self.neutron_client.list_ports(
                network_id=neutron_network['network']['id'])
        except Exception as e:
            self.docker_client.disconnect_container_from_network(
                container_id, container_net_id)
            message = ("Failed to list neutron ports: %s")
            self.fail(message % e.args[0])

        # A dhcp port gets created as well; dhcp is enabled by default
        self.assertEqual(2, len(ports['ports']))
        # Find the kuryr port
        kuryr_port_param = {"network_id": neutron_network['network']['id']}
        kuryr_ports = self.neutron_client.list_ports(**kuryr_port_param)
        kuryr_port = [
            port for port in kuryr_ports['ports']
            if (lib_const.DEVICE_OWNER in port['tags'] or port['name'] ==
                utils.get_neutron_port_name(port['device_id']))
        ]
        self.assertEqual(1, len(kuryr_port))
        # Disconnect container from network, this release ip address.
        self.docker_client.disconnect_container_from_network(
            container_id, container_net_id)
        ports = self.neutron_client.list_ports(
            network_id=neutron_network['network']['id'])
        self.assertEqual(1, len(ports['ports']))
        kuryr_ports = self.neutron_client.list_ports(**kuryr_port_param)
        kuryr_port = [
            port for port in kuryr_ports['ports']
            if (lib_const.DEVICE_OWNER in port['tags'] or port['name'] ==
                utils.get_neutron_port_name(port['device_id']))
        ]
        self.assertEqual(0, len(kuryr_port))

        # Cleanup resources
        self.docker_client.stop(container=container_id)
        self.docker_client.remove_network(container_net_id)
        self.neutron_client.delete_network(neutron_network['network']['id'])
示例#18
0
    def test_container_ipam_release_address_with_existing_network(self):
        # pre-created Neutron network and subnet
        neutron_net_name = lib_utils.get_random_string(8)
        neutron_network = self.neutron_client.create_network(
            {'network': {'name': neutron_net_name,
                         "admin_state_up": True}})
        neutron_subnet_name = lib_utils.get_random_string(8)
        subnet_param = [{
            'name': neutron_subnet_name,
            'network_id': neutron_network['network']['id'],
            'ip_version': 4,
            'cidr': "10.10.0.0/24",
            'enable_dhcp': True,
        }]
        self.neutron_client.create_subnet({'subnets': subnet_param})

        fake_ipam = {
            "Driver": "kuryr",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.10.0.0/16",
                    "IPRange": "10.10.0.0/24",
                    "Gateway": "10.10.0.1"
                }
            ]
        }

        # Create docker network using existing Neutron network
        options = {'neutron.net.name': neutron_net_name}
        container_net_name = lib_utils.get_random_string(8)
        container_net = self.docker_client.create_network(
            name=container_net_name,
            driver='kuryr',
            options=options,
            ipam=fake_ipam)
        container_net_id = container_net.get('Id')
        try:
            networks = self.neutron_client.list_networks(
                tags=utils.make_net_tags(container_net_id))
        except Exception as e:
            self.docker_client.remove_network(container_net_id)
            message = ("Failed to list neutron networks: %s")
            self.fail(message % e.args[0])
        self.assertEqual(1, len(networks['networks']))

        # Boot a container, and connect to the docker network.
        container_name = lib_utils.get_random_string(8)
        container = self.docker_client.create_container(
            image='kuryr/busybox',
            command='/bin/sleep 600',
            hostname='kuryr_test_container',
            name=container_name)
        warn_msg = container.get('Warning')
        container_id = container.get('Id')
        self.assertIsNone(warn_msg, 'Warn in creating container')
        self.assertIsNotNone(container_id, 'Create container id must not '
                                           'be None')
        self.docker_client.start(container=container_id)
        self.docker_client.connect_container_to_network(container_id,
                                                        container_net_id)
        try:
            ports = self.neutron_client.list_ports(
                network_id=neutron_network['network']['id'])
        except Exception as e:
            self.docker_client.disconnect_container_from_network(
                container_id,
                container_net_id)
            message = ("Failed to list neutron ports: %s")
            self.fail(message % e.args[0])

        # A dhcp port gets created as well; dhcp is enabled by default
        self.assertEqual(2, len(ports['ports']))
        # Find the kuryr port
        kuryr_port_param = {"network_id": neutron_network['network']['id']}
        kuryr_ports = self.neutron_client.list_ports(
            **kuryr_port_param)
        kuryr_port = [port for port in kuryr_ports['ports'] if
                      (lib_const.DEVICE_OWNER in port['tags'] or
                       port['name'] ==
                       utils.get_neutron_port_name(port['device_id']))]
        self.assertEqual(1, len(kuryr_port))
        # Disconnect container from network, this release ip address.
        self.docker_client.disconnect_container_from_network(container_id,
                                                             container_net_id)
        ports = self.neutron_client.list_ports(
            network_id=neutron_network['network']['id'])
        self.assertEqual(1, len(ports['ports']))
        kuryr_ports = self.neutron_client.list_ports(
            **kuryr_port_param)
        kuryr_port = [port for port in kuryr_ports['ports'] if
                      (lib_const.DEVICE_OWNER in port['tags'] or
                       port['name'] ==
                       utils.get_neutron_port_name(port['device_id']))]
        self.assertEqual(0, len(kuryr_port))

        # Cleanup resources
        self.docker_client.stop(container=container_id)
        self.docker_client.remove_network(container_net_id)
        self.neutron_client.delete_network(neutron_network['network']['id'])
示例#19
0
    def test_container_ipam_request_address(self):
        fake_ipam = {
            "Driver":
            "kuryr",
            "Options": {},
            "Config": [{
                "Subnet": "10.12.0.0/16",
                "IPRange": "10.12.0.0/24",
                "Gateway": "10.12.0.1"
            }]
        }

        container_net_name = lib_utils.get_random_string(8)
        container_net = self.docker_client.create_network(
            name=container_net_name, driver='kuryr', ipam=fake_ipam)
        container_net_id = container_net.get('Id')
        try:
            networks = self.neutron_client.list_networks(
                tags=utils.make_net_tags(container_net_id))
        except Exception as e:
            self.docker_client.remove_network(container_net_id)
            message = ("Failed to list neutron networks: %s")
            self.fail(message % e.args[0])

        # Currently we cannot get IPAM pool from docker client.
        pool_name = "kuryrPool-" + "10.12.0.0/24"
        subnetpools = self.neutron_client.list_subnetpools(name=pool_name)
        self.assertEqual(1, len(subnetpools['subnetpools']))

        subnets = self.neutron_client.list_subnets(
            network_id=networks['networks'][0]['id'], cidr="10.12.0.0/24")
        self.assertEqual(1, len(subnets['subnets']))

        # Boot a container, and connect to the docker network.
        container_name = lib_utils.get_random_string(8)
        container = self.docker_client.create_container(
            image='kuryr/busybox',
            command='/bin/sleep 600',
            hostname='kuryr_test_container',
            name=container_name)
        warn_msg = container.get('Warning')
        container_id = container.get('Id')
        self.assertIsNone(warn_msg, 'Warn in creating container')
        self.assertIsNotNone(container_id, 'Create container id must not '
                             'be None')
        self.docker_client.start(container=container_id)
        self.docker_client.connect_container_to_network(
            container_id, container_net_id)
        try:
            ports = self.neutron_client.list_ports(
                network_id=networks['networks'][0]['id'])
        except Exception as e:
            self.docker_client.disconnect_container_from_network(
                container_id, container_net_id)
            message = ("Failed to list neutron ports: %s")
            self.fail(message % e.args[0])

        # DHCP port and container endpoint
        self.assertEqual(2, len(ports['ports']))
        # Find the kuryr port
        kuryr_port_param = {"network_id": networks['networks'][0]['id']}
        kuryr_ports = self.neutron_client.list_ports(**kuryr_port_param)
        kuryr_port = [
            port for port in kuryr_ports['ports']
            if (lib_const.DEVICE_OWNER in port['tags'] or port['name'] ==
                utils.get_neutron_port_name(port['device_id']))
        ]
        self.assertEqual(1, len(kuryr_port))

        # Disconnect container from network, this release ip address.
        self.docker_client.disconnect_container_from_network(
            container_id, container_net_id)
        # Cleanup resources
        self.docker_client.stop(container=container_id)
        self.docker_client.remove_network(container_net_id)
    def test_network_driver_revoke_external_connectivity(self, existing_sg,
            removing_sg, mock_list_ports, mock_list_security_groups,
            mock_delete_security_groups, mock_show_port,
            mock_update_port):
        config.CONF.set_override('process_external_connectivity', True)
        fake_docker_net_id = lib_utils.get_hash()
        fake_docker_endpoint_id = lib_utils.get_hash()

        fake_neutron_net_id = uuidutils.generate_uuid()
        fake_neutron_port_id = uuidutils.generate_uuid()
        fake_neutron_sec_group_id = lib_utils.get_hash()
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
        fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id,
            fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        if existing_sg:
            fake_neutron_existing_sec_group_id = uuidutils.generate_uuid()
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_sec_group_id, fake_neutron_existing_sec_group_id]
        else:
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_sec_group_id]
        if removing_sg:
            fake_neutron_sec_group_response = {
                'security_groups': [{'id': fake_neutron_sec_group_id}]}
        else:
            fake_neutron_sec_group_response = {
                'security_groups': []}

        mock_list_ports.return_value = fake_neutron_ports_response
        mock_list_security_groups.return_value = (
            fake_neutron_sec_group_response)
        mock_show_port.return_value = {'port':
            fake_neutron_ports_response['ports'][0]}

        if existing_sg:
            sgs = [fake_neutron_existing_sec_group_id]
        else:
            sgs = []
        data = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
        }
        response = self.app.post('/NetworkDriver.RevokeExternalConnectivity',
                                 content_type='application/json',
                                 data=jsonutils.dumps(data))

        self.assertEqual(200, response.status_code)
        mock_list_ports.assert_called_with(name=neutron_port_name)
        if removing_sg:
            mock_list_security_groups.assert_called_with(
                name=utils.get_sg_expose_name(fake_neutron_port_id))
            mock_delete_security_groups.assert_called_with(
                fake_neutron_sec_group_id)
            mock_show_port.assert_called_with(fake_neutron_port_id)
            mock_update_port.assert_called_with(fake_neutron_port_id,
                            {'port': {'security_groups': sgs}})
        else:
            mock_list_security_groups.assert_called_with(
                name=utils.get_sg_expose_name(fake_neutron_port_id))
            mock_delete_security_groups.assert_not_called()
            mock_show_port.assert_not_called()
            mock_update_port.assert_not_called()
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
示例#21
0
    def test_network_driver_revoke_external_connectivity(
            self, existing_sg, removing_sg, mock_list_ports,
            mock_list_security_groups, mock_delete_security_groups,
            mock_show_port, mock_update_port):
        fake_docker_net_id = lib_utils.get_hash()
        fake_docker_endpoint_id = lib_utils.get_hash()

        fake_neutron_net_id = uuidutils.generate_uuid()
        fake_neutron_port_id = uuidutils.generate_uuid()
        fake_neutron_sec_group_id = lib_utils.get_hash()
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
        fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id, fake_neutron_port_id,
            lib_const.PORT_STATUS_ACTIVE, fake_neutron_v4_subnet_id,
            fake_neutron_v6_subnet_id)
        if existing_sg:
            fake_neutron_existing_sec_group_id = uuidutils.generate_uuid()
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_sec_group_id, fake_neutron_existing_sec_group_id
            ]
        else:
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_sec_group_id
            ]
        if removing_sg:
            fake_neutron_sec_group_response = {
                'security_groups': [{
                    'id': fake_neutron_sec_group_id
                }]
            }
        else:
            fake_neutron_sec_group_response = {'security_groups': []}

        mock_list_ports.return_value = fake_neutron_ports_response
        mock_list_security_groups.return_value = (
            fake_neutron_sec_group_response)
        mock_show_port.return_value = {
            'port': fake_neutron_ports_response['ports'][0]
        }

        if existing_sg:
            sgs = [fake_neutron_existing_sec_group_id]
        else:
            sgs = []
        data = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
        }
        response = self.app.post('/NetworkDriver.RevokeExternalConnectivity',
                                 content_type='application/json',
                                 data=jsonutils.dumps(data))

        self.assertEqual(200, response.status_code)
        mock_list_ports.assert_called_with(name=neutron_port_name)
        if removing_sg:
            mock_list_security_groups.assert_called_with(
                name=utils.get_sg_expose_name(fake_neutron_port_id))
            mock_delete_security_groups.assert_called_with(
                fake_neutron_sec_group_id)
            mock_show_port.assert_called_with(fake_neutron_port_id)
            mock_update_port.assert_called_with(
                fake_neutron_port_id, {'port': {
                    'security_groups': sgs
                }})
        else:
            mock_list_security_groups.assert_called_with(
                name=utils.get_sg_expose_name(fake_neutron_port_id))
            mock_delete_security_groups.assert_not_called()
            mock_show_port.assert_not_called()
            mock_update_port.assert_not_called()
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
示例#22
0
    def test_container_ipam_request_address(self):
        fake_ipam = {
            "Driver": "kuryr",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.12.0.0/16",
                    "IPRange": "10.12.0.0/24",
                    "Gateway": "10.12.0.1"
                }
            ]
        }

        container_net_name = lib_utils.get_random_string(8)
        container_net = self.docker_client.create_network(
            name=container_net_name,
            driver='kuryr',
            ipam=fake_ipam)
        container_net_id = container_net.get('Id')
        try:
            networks = self.neutron_client.list_networks(
                tags=utils.make_net_tags(container_net_id))
        except Exception as e:
            self.docker_client.remove_network(container_net_id)
            message = ("Failed to list neutron networks: %s")
            self.fail(message % e.args[0])

        # Currently we cannot get IPAM pool from docker client.
        pool_name = "kuryrPool-" + "10.12.0.0/24"
        subnetpools = self.neutron_client.list_subnetpools(name=pool_name)
        self.assertEqual(1, len(subnetpools['subnetpools']))

        subnets = self.neutron_client.list_subnets(
            network_id=networks['networks'][0]['id'],
            cidr="10.12.0.0/24")
        self.assertEqual(1, len(subnets['subnets']))

        # Boot a container, and connect to the docker network.
        container_name = lib_utils.get_random_string(8)
        container = self.docker_client.create_container(
            image='kuryr/busybox',
            command='/bin/sleep 600',
            hostname='kuryr_test_container',
            name=container_name)
        warn_msg = container.get('Warning')
        container_id = container.get('Id')
        self.assertIsNone(warn_msg, 'Warn in creating container')
        self.assertIsNotNone(container_id, 'Create container id must not '
                                           'be None')
        self.docker_client.start(container=container_id)
        self.docker_client.connect_container_to_network(container_id,
                                                        container_net_id)
        try:
            ports = self.neutron_client.list_ports(
                network_id=networks['networks'][0]['id'])
        except Exception as e:
            self.docker_client.disconnect_container_from_network(
                container_id,
                container_net_id)
            message = ("Failed to list neutron ports: %s")
            self.fail(message % e.args[0])

        # DHCP port and container endpoint
        self.assertEqual(2, len(ports['ports']))
        # Find the kuryr port
        kuryr_port_param = {"network_id": networks['networks'][0]['id']}
        kuryr_ports = self.neutron_client.list_ports(
            **kuryr_port_param)
        kuryr_port = [port for port in kuryr_ports['ports'] if
                      (lib_const.DEVICE_OWNER in port['tags'] or
                       port['name'] ==
                       utils.get_neutron_port_name(port['device_id']))]
        self.assertEqual(1, len(kuryr_port))

        # Disconnect container from network, this release ip address.
        self.docker_client.disconnect_container_from_network(container_id,
                                                             container_net_id)
        # Cleanup resources
        self.docker_client.stop(container=container_id)
        self.docker_client.remove_network(container_net_id)
示例#23
0
    def test_network_driver_program_external_connectivity(
            self, existing_sg, num_ports, mock_list_ports,
            mock_create_security_group, mock_create_security_group_rule,
            mock_show_port, mock_update_port):
        fake_docker_net_id = lib_utils.get_hash()
        fake_docker_endpoint_id = lib_utils.get_hash()

        fake_neutron_net_id = uuidutils.generate_uuid()
        fake_neutron_port_id = uuidutils.generate_uuid()
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
        fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id, fake_neutron_port_id,
            lib_const.PORT_STATUS_ACTIVE, fake_neutron_v4_subnet_id,
            fake_neutron_v6_subnet_id)
        if existing_sg:
            fake_neutron_existing_sec_group_id = uuidutils.generate_uuid()
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_existing_sec_group_id
            ]

        mock_list_ports.return_value = fake_neutron_ports_response

        sec_group = {
            'name': utils.get_sg_expose_name(fake_neutron_port_id),
            'description': 'Docker exposed ports created by Kuryr.'
        }
        fake_neutron_sec_group_id = lib_utils.get_hash()
        fake_neutron_sec_group_response = {
            'security_group': {
                'id': fake_neutron_sec_group_id
            }
        }
        mock_create_security_group.return_value = (
            fake_neutron_sec_group_response)

        proto_port_dict = defaultdict(list)
        for i in range(num_ports):
            proto_port_dict[constants.PROTOCOLS[PROTOCOL_TCP]].append(PORT + i)
            proto_port_dict[constants.PROTOCOLS[PROTOCOL_UDP]].append(PORT + i)
        proto_port_dict[constants.PROTOCOLS[PROTOCOL_UDP]].append(SINGLE_PORT)

        for proto, port_list in proto_port_dict.items():
            for key, group in groupby(enumerate(sorted(port_list)),
                                      lambda ix: ix[0] - ix[1]):
                port_range_list = list(map(itemgetter(1), group))

                port_range_min = min(port_range_list)
                port_range_max = max(port_range_list)
                sec_group_rule = {
                    'security_group_id': fake_neutron_sec_group_id,
                    'direction': 'ingress',
                    'port_range_min': port_range_min,
                    'port_range_max': port_range_max,
                    'protocol': proto
                }

        sgs = [fake_neutron_sec_group_id]
        if existing_sg:
            sgs.append(fake_neutron_existing_sec_group_id)
        mock_show_port.return_value = {
            'port': fake_neutron_ports_response['ports'][0]
        }

        port_opt = []
        for i in range(num_ports):
            port_opt.append({u'Port': PORT + i, u'Proto': PROTOCOL_TCP})
            port_opt.append({u'Port': PORT + i, u'Proto': PROTOCOL_UDP})
        port_opt.append({u'Port': SINGLE_PORT, u'Proto': PROTOCOL_UDP})
        options = {
            'com.docker.network.endpoint.exposedports': port_opt,
            'com.docker.network.portmap': []
        }
        data = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
            'Options': options,
        }
        response = self.app.post('/NetworkDriver.ProgramExternalConnectivity',
                                 content_type='application/json',
                                 data=jsonutils.dumps(data))

        self.assertEqual(200, response.status_code)
        mock_update_port.assert_called_with(fake_neutron_port_id,
                                            {'port': {
                                                'security_groups': sgs
                                            }})
        mock_show_port.assert_called_with(fake_neutron_port_id)
        mock_create_security_group_rule.assert_called_with(
            {'security_group_rule': sec_group_rule})
        mock_create_security_group.assert_called_with(
            {'security_group': sec_group})
        mock_list_ports.assert_called_with(name=neutron_port_name)
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
    def test_network_driver_revoke_external_connectivity(self, existing_sg):
        fake_docker_net_id = utils.get_hash()
        fake_docker_endpoint_id = utils.get_hash()

        fake_neutron_net_id = str(uuid.uuid4())
        fake_neutron_port_id = str(uuid.uuid4())
        fake_neutron_sec_group_id = utils.get_hash()
        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)
        if existing_sg:
            fake_neutron_existing_sec_group_id = str(uuid.uuid4())
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_sec_group_id, fake_neutron_existing_sec_group_id]
        else:
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_sec_group_id]

        app.neutron.list_ports(name=neutron_port_name).AndReturn(
            fake_neutron_ports_response)

        self.mox.StubOutWithMock(app.neutron, 'list_security_groups')
        fake_neutron_sec_group_response = {'security_groups':
                                           [{'id': fake_neutron_sec_group_id}]}
        app.neutron.list_security_groups(
            name=utils.get_sg_expose_name(fake_neutron_port_id)).AndReturn(
            fake_neutron_sec_group_response)

        if existing_sg:
            sgs = [fake_neutron_existing_sec_group_id]
        else:
            sgs = []
        self.mox.StubOutWithMock(app.neutron, 'show_port')
        app.neutron.show_port(fake_neutron_port_id).AndReturn(
            {'port': fake_neutron_ports_response['ports'][0]})

        self.mox.StubOutWithMock(app.neutron, 'update_port')
        app.neutron.update_port(fake_neutron_port_id,
                                {'port': {'security_groups': sgs}})

        self.mox.StubOutWithMock(app.neutron, 'delete_security_group')
        app.neutron.delete_security_group(fake_neutron_sec_group_id)
        self.mox.ReplayAll()

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

        self.assertEqual(200, response.status_code)
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
示例#25
0
    def test_container_ipam_request_address_with_existing_port(self):
        # pre-created Neutron network and subnet and port
        neutron_net_name = lib_utils.get_random_string(8)
        neutron_network = self.neutron_client.create_network(
            {'network': {
                'name': neutron_net_name,
                "admin_state_up": True
            }})
        neutron_subnet_name = lib_utils.get_random_string(8)
        subnet_param = [{
            'name': neutron_subnet_name,
            'network_id': neutron_network['network']['id'],
            'ip_version': 4,
            'cidr': "10.14.0.0/24",
        }]
        neutron_subnet = self.neutron_client.create_subnet(
            {'subnets': subnet_param})
        neutron_v6_subnet_name = lib_utils.get_random_string(8)
        v6_subnet_param = [{
            'name': neutron_v6_subnet_name,
            'network_id': neutron_network['network']['id'],
            'ip_version': 6,
            'cidr': "fe81::/64",
        }]
        neutron_v6_subnet = self.neutron_client.create_subnet(
            {'subnets': v6_subnet_param})
        existing_neutron_port = self.neutron_client.create_port(
            {'port': {
                'network_id': neutron_network['network']['id']
            }})
        fixed_ips = {
            fip['subnet_id']: fip['ip_address']
            for fip in existing_neutron_port['port']['fixed_ips']
        }
        ipv4_address = fixed_ips[neutron_subnet['subnets'][0]['id']]
        ipv6_address = fixed_ips[neutron_v6_subnet['subnets'][0]['id']]

        fake_ipam = {
            "Driver":
            "kuryr",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.14.0.0/24",
                    "Gateway": "10.14.0.1"
                },
                {
                    "Subnet": "fe81::/64",
                    "Gateway": "fe81::1"
                },
            ]
        }

        # Create docker network using existing Neutron network
        options = {'neutron.net.name': neutron_net_name}
        container_net_name = lib_utils.get_random_string(8)
        container_net = self.docker_client.create_network(
            name=container_net_name,
            driver='kuryr',
            enable_ipv6=True,
            options=options,
            ipam=fake_ipam)
        container_net_id = container_net.get('Id')
        try:
            networks = self.neutron_client.list_networks(
                tags=utils.make_net_tags(container_net_id))
        except Exception as e:
            self.docker_client.remove_network(container_net_id)
            message = ("Failed to list neutron networks: %s")
            self.fail(message % e.args[0])
        self.assertEqual(1, len(networks['networks']))

        # Boot a container, and connect to the docker network.
        container_name = lib_utils.get_random_string(8)
        container = self.docker_client.create_container(
            image='kuryr/busybox',
            command='/bin/sleep 600',
            hostname='kuryr_test_container',
            name=container_name)
        warn_msg = container.get('Warning')
        container_id = container.get('Id')
        self.assertIsNone(warn_msg, 'Warn in creating container')
        self.assertIsNotNone(container_id, 'Create container id must not '
                             'be None')
        self.docker_client.start(container=container_id)
        self.docker_client.connect_container_to_network(
            container_id,
            container_net_id,
            ipv4_address=ipv4_address,
            ipv6_address=ipv6_address)
        try:
            ports = self.neutron_client.list_ports(
                network_id=neutron_network['network']['id'])
        except Exception as e:
            self.docker_client.disconnect_container_from_network(
                container_id, container_net_id)
            message = ("Failed to list neutron ports: %s")
            self.fail(message % e.args[0])

        # A dhcp port gets created as well; dhcp is enabled by default
        self.assertEqual(2, len(ports['ports']))
        # Find the existing neutron port
        neutron_port_param = {"network_id": neutron_network['network']['id']}
        neutron_ports = self.neutron_client.list_ports(**neutron_port_param)
        neutron_port = [
            port for port in neutron_ports['ports']
            if (const.KURYR_EXISTING_NEUTRON_PORT in port['tags'] or
                port['name'] == utils.get_neutron_port_name(port['device_id']))
        ]
        self.assertEqual(1, len(neutron_port))
        # Disconnect container from network.
        self.docker_client.disconnect_container_from_network(
            container_id, container_net_id)
        ports = self.neutron_client.list_ports(
            network_id=neutron_network['network']['id'])
        self.assertEqual(2, len(ports['ports']))
        neutron_ports = self.neutron_client.list_ports(**neutron_port_param)
        neutron_port = [
            port for port in neutron_ports['ports']
            if (const.KURYR_EXISTING_NEUTRON_PORT in port['tags'] or
                port['name'] == utils.get_neutron_port_name(port['device_id']))
        ]
        self.assertEqual(0, len(neutron_port))

        # Cleanup resources
        self.docker_client.stop(container=container_id)
        self.docker_client.remove_network(container_net_id)
        self.neutron_client.delete_port(existing_neutron_port['port']['id'])
        self.neutron_client.delete_subnet(neutron_subnet['subnets'][0]['id'])
        self.neutron_client.delete_subnet(
            neutron_v6_subnet['subnets'][0]['id'])
        self.neutron_client.delete_network(neutron_network['network']['id'])
    def test_network_driver_program_external_connectivity(self, existing_sg,
            num_ports, mock_list_ports, mock_create_security_group,
            mock_create_security_group_rule, mock_show_port,
            mock_update_port):
        config.CONF.set_override('process_external_connectivity', True)
        fake_docker_net_id = lib_utils.get_hash()
        fake_docker_endpoint_id = lib_utils.get_hash()

        fake_neutron_net_id = uuidutils.generate_uuid()
        fake_neutron_port_id = uuidutils.generate_uuid()
        neutron_port_name = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
        fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
        fake_neutron_ports_response = self._get_fake_ports(
            fake_docker_endpoint_id, fake_neutron_net_id,
            fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id)
        if existing_sg:
            fake_neutron_existing_sec_group_id = uuidutils.generate_uuid()
            fake_neutron_ports_response['ports'][0]['security_groups'] = [
                fake_neutron_existing_sec_group_id]

        mock_list_ports.return_value = fake_neutron_ports_response

        sec_group = {
            'name': utils.get_sg_expose_name(fake_neutron_port_id),
            'description': 'Docker exposed ports created by Kuryr.'
        }
        fake_neutron_sec_group_id = lib_utils.get_hash()
        fake_neutron_sec_group_response = {'security_group':
                                           {'id': fake_neutron_sec_group_id}}
        mock_create_security_group.return_value = (
            fake_neutron_sec_group_response)

        proto_port_dict = defaultdict(list)
        for i in range(num_ports):
            proto_port_dict[constants.PROTOCOLS[PROTOCOL_TCP]].append(PORT + i)
            proto_port_dict[constants.PROTOCOLS[PROTOCOL_UDP]].append(PORT + i)
        proto_port_dict[constants.PROTOCOLS[PROTOCOL_UDP]].append(SINGLE_PORT)

        for proto, port_list in proto_port_dict.items():
            for key, group in groupby(enumerate(sorted(port_list)),
                                      lambda ix: ix[0] - ix[1]):
                port_range_list = list(map(itemgetter(1), group))

                port_range_min = min(port_range_list)
                port_range_max = max(port_range_list)
                sec_group_rule = {
                    'security_group_id': fake_neutron_sec_group_id,
                    'direction': 'ingress',
                    'port_range_min': port_range_min,
                    'port_range_max': port_range_max,
                    'protocol': proto
                }

        sgs = [fake_neutron_sec_group_id]
        if existing_sg:
            sgs.append(fake_neutron_existing_sec_group_id)
        mock_show_port.return_value = {'port':
            fake_neutron_ports_response['ports'][0]}

        port_opt = []
        for i in range(num_ports):
            port_opt.append({u'Port': PORT + i, u'Proto': PROTOCOL_TCP})
            port_opt.append({u'Port': PORT + i, u'Proto': PROTOCOL_UDP})
        port_opt.append({u'Port': SINGLE_PORT, u'Proto': PROTOCOL_UDP})
        options = {'com.docker.network.endpoint.exposedports':
                   port_opt,
                   'com.docker.network.portmap':
                   []}
        data = {
            'NetworkID': fake_docker_net_id,
            'EndpointID': fake_docker_endpoint_id,
            'Options': options,
        }
        response = self.app.post('/NetworkDriver.ProgramExternalConnectivity',
                                 content_type='application/json',
                                 data=jsonutils.dumps(data))

        self.assertEqual(200, response.status_code)
        mock_update_port.assert_called_with(fake_neutron_port_id,
                                {'port': {'security_groups': sgs}})
        mock_show_port.assert_called_with(fake_neutron_port_id)
        mock_create_security_group_rule.assert_called_with(
            {'security_group_rule': sec_group_rule})
        mock_create_security_group.assert_called_with(
            {'security_group': sec_group})
        mock_list_ports.assert_called_with(name=neutron_port_name)
        decoded_json = jsonutils.loads(response.data)
        self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)
    def test_create_host_iface_failures(self, GivenException,
            mock_list_networks, mock_list_ports, mock_list_subnets,
            mock_update_port, mock_create_host_iface):
        fake_docker_network_id = lib_utils.get_hash()
        fake_docker_endpoint_id = lib_utils.get_hash()
        fake_neutron_network_id = uuidutils.generate_uuid()

        fake_neutron_network = self._get_fake_list_network(
            fake_neutron_network_id)
        t = utils.make_net_tags(fake_docker_network_id)
        mock_list_networks.return_value = fake_neutron_network

        fake_neutron_v4_subnet_id = uuidutils.generate_uuid()
        fake_neutron_v6_subnet_id = uuidutils.generate_uuid()
        fake_v4_subnet = self._get_fake_v4_subnet(fake_docker_network_id,
                                                  fake_docker_endpoint_id,
                                                  fake_neutron_v4_subnet_id)
        fake_v6_subnet = self._get_fake_v6_subnet(fake_docker_network_id,
                                                  fake_docker_endpoint_id,
                                                  fake_neutron_v6_subnet_id)
        fake_v4_subnet_response = {
            "subnets": [
                fake_v4_subnet['subnet']
            ]
        }
        fake_v6_subnet_response = {
            "subnets": [
                fake_v6_subnet['subnet']
            ]
        }

        def fake_subnet_response(network_id, cidr):
            if cidr == '192.168.1.0/24':
                return fake_v4_subnet_response
            elif cidr == 'fe80::/64':
                return fake_v6_subnet_response
            else:
                return {'subnets': []}

        mock_list_subnets.side_effect = fake_subnet_response

        fake_neutron_port_id = uuidutils.generate_uuid()
        fake_fixed_ips = ['subnet_id=%s' % fake_neutron_v4_subnet_id,
                          'ip_address=192.168.1.2',
                          'subnet_id=%s' % fake_neutron_v6_subnet_id,
                          'ip_address=fe80::f816:3eff:fe20:57c4']
        fake_port_response = self._get_fake_port(
            fake_docker_endpoint_id, fake_neutron_network_id,
            fake_neutron_port_id, lib_const.PORT_STATUS_ACTIVE,
            fake_neutron_v4_subnet_id, fake_neutron_v6_subnet_id,
            tags=utils.create_port_tags(fake_docker_endpoint_id))
        fake_ports_response = {
            "ports": [
                fake_port_response['port']
            ]
        }
        mock_list_ports.return_value = fake_ports_response
        fake_updated_port = fake_port_response['port']
        fake_updated_port['name'] = utils.get_neutron_port_name(
            fake_docker_endpoint_id)
        mock_update_port.return_value = fake_port_response['port']

        fake_neutron_subnets = [fake_v4_subnet['subnet'],
                                fake_v6_subnet['subnet']]

        fake_message = "fake message"
        if GivenException == n_exceptions.NeutronClientException:
            fake_exception = GivenException(fake_message, status_code=500)
        else:
            fake_exception = GivenException(fake_message)
        mock_create_host_iface.side_effect = fake_exception

        response = self._invoke_create_request(
            fake_docker_network_id, fake_docker_endpoint_id)

        self.assertEqual(
            w_exceptions.InternalServerError.code, response.status_code)
        mock_list_networks.assert_called_with(tags=t)
        expect_calls = [mock.call(cidr='192.168.1.0/24',
            network_id=fake_neutron_network_id),
            mock.call(cidr='fe80::/64', network_id=fake_neutron_network_id)]
        mock_list_subnets.assert_has_calls(expect_calls, any_order=True)
        mock_list_ports.assert_called_with(fixed_ips=fake_fixed_ips)
        mock_update_port.assert_called_with(fake_port_response['port'],
                                            fake_docker_endpoint_id,
                                            "fa:16:3e:20:57:c3",
                                            tags=True)
        mock_create_host_iface.assert_called_with(
            fake_docker_endpoint_id, fake_updated_port, fake_neutron_subnets,
            fake_neutron_network['networks'][0])

        decoded_json = jsonutils.loads(response.data)
        self.assertIn('Err', decoded_json)
        self.assertIn(fake_message, decoded_json['Err'])
示例#28
0
 def test_get_port_name(self):
     fake_docker_endpoint_id = lib_utils.get_hash()
     generated_neutron_port_name = utils.get_neutron_port_name(
         fake_docker_endpoint_id)
     self.assertIn(lib_utils.PORT_POSTFIX, generated_neutron_port_name)
     self.assertIn(fake_docker_endpoint_id, generated_neutron_port_name)