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 _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']
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']
def test_ipam_driver_request_address(self): # faking list_subnetpools self.mox.StubOutWithMock(app.neutron, 'list_subnetpools') fake_kuryr_subnetpool_id = str(uuid.uuid4()) fake_name = utils.get_neutron_subnetpool_name(FAKE_IP4_CIDR) kuryr_subnetpools = self._get_fake_v4_subnetpools( fake_kuryr_subnetpool_id, prefixes=[FAKE_IP4_CIDR], name=fake_name) app.neutron.list_subnetpools(id=fake_kuryr_subnetpool_id).AndReturn( kuryr_subnetpools) # faking list_subnets docker_endpoint_id = hashlib.sha256( utils.getrandbits(256)).hexdigest() neutron_network_id = str(uuid.uuid4()) subnet_v4_id = str(uuid.uuid4()) fake_v4_subnet = self._get_fake_v4_subnet( neutron_network_id, docker_endpoint_id, subnet_v4_id, subnetpool_id=fake_kuryr_subnetpool_id, cidr=FAKE_IP4_CIDR) fake_subnet_response = { 'subnets': [ fake_v4_subnet['subnet'] ] } self.mox.StubOutWithMock(app.neutron, 'list_subnets') app.neutron.list_subnets(cidr=FAKE_IP4_CIDR).AndReturn( fake_subnet_response) # faking create_port fake_neutron_port_id = str(uuid.uuid4()) fake_port = base.TestKuryrBase._get_fake_port( docker_endpoint_id, neutron_network_id, fake_neutron_port_id, subnet_v4_id, neutron_subnet_v4_address="10.0.0.5") port_request = { 'name': 'kuryr-unbound-port', 'admin_state_up': True, 'network_id': neutron_network_id, 'binding:host_id': utils.get_hostname(), } fixed_ips = port_request['fixed_ips'] = [] fixed_ip = {'subnet_id': subnet_v4_id} fixed_ips.append(fixed_ip) self.mox.StubOutWithMock(app.neutron, 'create_port') app.neutron.create_port({'port': port_request}).AndReturn(fake_port) # Apply mocks self.mox.ReplayAll() # Testing container ip allocation fake_request = { 'PoolID': fake_kuryr_subnetpool_id, 'Address': '', # Querying for container address 'Options': {} } response = self.app.post('/IpamDriver.RequestAddress', content_type='application/json', data=jsonutils.dumps(fake_request)) self.assertEqual(200, response.status_code) decoded_json = jsonutils.loads(response.data) self.assertEqual('10.0.0.5/16', decoded_json['Address'])
def ipam_request_address(): """Allocates the IP address in the given request. This function takes the following JSON data and add the given IP address in the allocation_pools attribute of the subnet. :: { "PoolID": string "Address": string "Options": map[string]string } Then the following response is returned. :: { "Address": string "Data": map[string]string } See the following link for more details about the spec: https://github.com/docker/libnetwork/blob/master/docs/ipam.md#requestaddress # noqa """ json_data = flask.request.get_json(force=True) app.logger.debug( "Received JSON data {0} for /IpamDriver.RequestAddress".format( json_data)) jsonschema.validate(json_data, schemata.REQUEST_ADDRESS_SCHEMA) pool_id = json_data['PoolID'] req_address = json_data['Address'] allocated_address = '' subnet_cidr = '' pool_prefix_len = '' pools = _get_subnetpools_by_attrs(id=pool_id) if pools: pool = pools[0] prefixes = pool['prefixes'] if len(prefixes) > 1: app.logger.warning( _LW("More than one prefixes present. Picking " "first one.")) for prefix in prefixes: cidr = netaddr.IPNetwork(prefix) pool_prefix_len = str(cidr.prefixlen) subnet_network = str(cidr.network) subnet_cidr = '/'.join([subnet_network, pool_prefix_len]) break else: raise exceptions.NoResourceException( "No subnetpools with id {0} is found.".format(pool_id)) # check if any subnet with matching cidr is present subnets = _get_subnets_by_attrs(cidr=subnet_cidr) if subnets: subnet = subnets[0] # allocating address for container port neutron_network_id = subnet['network_id'] try: port = { 'name': 'kuryr-unbound-port', 'admin_state_up': True, 'network_id': neutron_network_id, 'binding:host_id': utils.get_hostname(), } fixed_ips = port['fixed_ips'] = [] fixed_ip = {'subnet_id': subnet['id']} if req_address: fixed_ip['ip_address'] = req_address fixed_ips.append(fixed_ip) created_port_resp = app.neutron.create_port({'port': port}) created_port = created_port_resp['port'] allocated_address = created_port['fixed_ips'][0]['ip_address'] allocated_address = '/'.join( [allocated_address, str(cidr.prefixlen)]) except n_exceptions.NeutronClientException as ex: app.logger.error( _LE("Error happend during ip allocation on" "Neutron side: {0}").format(ex)) raise else: # Auxiliary address or gw_address is received at network creation time. # This address cannot be reserved with neutron at this time as subnet # is not created yet. In /NetworkDriver.CreateNetwork this address will # be reserved with neutron. if req_address: allocated_address = '/'.join([req_address, pool_prefix_len]) return flask.jsonify({'Address': allocated_address})
def test_ipam_driver_request_address(self): # faking list_subnetpools self.mox.StubOutWithMock(app.neutron, 'list_subnetpools') fake_kuryr_subnetpool_id = str(uuid.uuid4()) fake_name = utils.get_neutron_subnetpool_name(FAKE_IP4_CIDR) kuryr_subnetpools = self._get_fake_v4_subnetpools( fake_kuryr_subnetpool_id, prefixes=[FAKE_IP4_CIDR], name=fake_name) app.neutron.list_subnetpools( id=fake_kuryr_subnetpool_id).AndReturn(kuryr_subnetpools) # faking list_subnets docker_endpoint_id = hashlib.sha256(utils.getrandbits(256)).hexdigest() neutron_network_id = str(uuid.uuid4()) subnet_v4_id = str(uuid.uuid4()) fake_v4_subnet = self._get_fake_v4_subnet( neutron_network_id, docker_endpoint_id, subnet_v4_id, subnetpool_id=fake_kuryr_subnetpool_id, cidr=FAKE_IP4_CIDR) fake_subnet_response = {'subnets': [fake_v4_subnet['subnet']]} self.mox.StubOutWithMock(app.neutron, 'list_subnets') app.neutron.list_subnets( cidr=FAKE_IP4_CIDR).AndReturn(fake_subnet_response) # faking create_port fake_neutron_port_id = str(uuid.uuid4()) fake_port = base.TestKuryrBase._get_fake_port( docker_endpoint_id, neutron_network_id, fake_neutron_port_id, subnet_v4_id, neutron_subnet_v4_address="10.0.0.5") port_request = { 'name': 'kuryr-unbound-port', 'admin_state_up': True, 'network_id': neutron_network_id, 'binding:host_id': utils.get_hostname(), } fixed_ips = port_request['fixed_ips'] = [] fixed_ip = {'subnet_id': subnet_v4_id} fixed_ips.append(fixed_ip) self.mox.StubOutWithMock(app.neutron, 'create_port') app.neutron.create_port({'port': port_request}).AndReturn(fake_port) # Apply mocks self.mox.ReplayAll() # Testing container ip allocation fake_request = { 'PoolID': fake_kuryr_subnetpool_id, 'Address': '', # Querying for container address 'Options': {} } response = self.app.post('/IpamDriver.RequestAddress', content_type='application/json', data=jsonutils.dumps(fake_request)) self.assertEqual(200, response.status_code) decoded_json = jsonutils.loads(response.data) self.assertEqual('10.0.0.5/16', decoded_json['Address'])
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)
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'])
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'])
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
def ipam_request_address(): """Allocates the IP address in the given request. This function takes the following JSON data and add the given IP address in the allocation_pools attribute of the subnet. :: { "PoolID": string "Address": string "Options": map[string]string } Then the following response is returned. :: { "Address": string "Data": map[string]string } See the following link for more details about the spec: https://github.com/docker/libnetwork/blob/master/docs/ipam.md#requestaddress # noqa """ json_data = flask.request.get_json(force=True) app.logger.debug("Received JSON data {0} for /IpamDriver.RequestAddress" .format(json_data)) jsonschema.validate(json_data, schemata.REQUEST_ADDRESS_SCHEMA) pool_id = json_data['PoolID'] req_address = json_data['Address'] allocated_address = '' subnet_cidr = '' pool_prefix_len = '' pools = _get_subnetpools_by_attrs(id=pool_id) if pools: pool = pools[0] prefixes = pool['prefixes'] if len(prefixes) > 1: app.logger.warning(_LW("More than one prefixes present. Picking " "first one.")) for prefix in prefixes: cidr = netaddr.IPNetwork(prefix) pool_prefix_len = str(cidr.prefixlen) subnet_network = str(cidr.network) subnet_cidr = '/'.join([subnet_network, pool_prefix_len]) break else: raise exceptions.NoResourceException( "No subnetpools with id {0} is found." .format(pool_id)) # check if any subnet with matching cidr is present subnets = _get_subnets_by_attrs(cidr=subnet_cidr) if subnets: subnet = subnets[0] # allocating address for container port neutron_network_id = subnet['network_id'] try: port = { 'name': 'kuryr-unbound-port', 'admin_state_up': True, 'network_id': neutron_network_id, 'binding:host_id': utils.get_hostname(), } fixed_ips = port['fixed_ips'] = [] fixed_ip = {'subnet_id': subnet['id']} if req_address: fixed_ip['ip_address'] = req_address fixed_ips.append(fixed_ip) created_port_resp = app.neutron.create_port({'port': port}) created_port = created_port_resp['port'] allocated_address = created_port['fixed_ips'][0]['ip_address'] allocated_address = '/'.join( [allocated_address, str(cidr.prefixlen)]) except n_exceptions.NeutronClientException as ex: app.logger.error(_LE("Error happend during ip allocation on" "Neutron side: {0}").format(ex)) raise else: # Auxiliary address or gw_address is received at network creation time. # This address cannot be reserved with neutron at this time as subnet # is not created yet. In /NetworkDriver.CreateNetwork this address will # be reserved with neutron. if req_address: allocated_address = '/'.join([req_address, pool_prefix_len]) return flask.jsonify({'Address': allocated_address})