Merge "RequestAddress when subnet has not been created"
This commit is contained in:
commit
20456034fe
|
@ -1323,8 +1323,8 @@ def ipam_request_address():
|
||||||
else:
|
else:
|
||||||
subnet = subnets_by_cidr[0]
|
subnet = subnets_by_cidr[0]
|
||||||
|
|
||||||
if is_gateway:
|
if any(subnet):
|
||||||
if any(subnet):
|
if is_gateway:
|
||||||
# check if request gateway ip same with existed gateway ip
|
# check if request gateway ip same with existed gateway ip
|
||||||
existed_gateway_ip = subnet.get('gateway_ip', '')
|
existed_gateway_ip = subnet.get('gateway_ip', '')
|
||||||
if req_address == existed_gateway_ip:
|
if req_address == existed_gateway_ip:
|
||||||
|
@ -1336,59 +1336,65 @@ def ipam_request_address():
|
||||||
"gateway {1} in existed "
|
"gateway {1} in existed "
|
||||||
"network.".format(req_address, existed_gateway_ip))
|
"network.".format(req_address, existed_gateway_ip))
|
||||||
else:
|
else:
|
||||||
allocated_address = '/'.join([req_address, pool_prefix_len])
|
# allocating address for container port
|
||||||
else:
|
neutron_network_id = subnet['network_id']
|
||||||
# allocating address for container port
|
try:
|
||||||
neutron_network_id = subnet['network_id']
|
port = {
|
||||||
try:
|
'name': 'kuryr-unbound-port',
|
||||||
port = {
|
'admin_state_up': True,
|
||||||
'name': 'kuryr-unbound-port',
|
'network_id': neutron_network_id,
|
||||||
'admin_state_up': True,
|
'binding:host_id': utils.get_hostname(),
|
||||||
'network_id': neutron_network_id,
|
}
|
||||||
'binding:host_id': utils.get_hostname(),
|
fixed_ips = port['fixed_ips'] = []
|
||||||
}
|
fixed_ip = {'subnet_id': subnet['id']}
|
||||||
fixed_ips = port['fixed_ips'] = []
|
num_ports = 0
|
||||||
fixed_ip = {'subnet_id': subnet['id']}
|
if req_address:
|
||||||
num_ports = 0
|
fixed_ip['ip_address'] = req_address
|
||||||
if req_address:
|
fixed_ip_existing = [('subnet_id=%s' % subnet['id'])]
|
||||||
fixed_ip['ip_address'] = req_address
|
fixed_ip_existing.append('ip_address='
|
||||||
fixed_ip_existing = [('subnet_id=%s' % subnet['id'])]
|
'%s' % str(req_address))
|
||||||
fixed_ip_existing.append('ip_address=%s' % str(req_address))
|
filtered_ports = app.neutron.list_ports(
|
||||||
filtered_ports = app.neutron.list_ports(
|
fixed_ips=fixed_ip_existing)
|
||||||
fixed_ips=fixed_ip_existing)
|
num_ports = len(filtered_ports.get('ports', []))
|
||||||
num_ports = len(filtered_ports.get('ports', []))
|
fixed_ips.append(fixed_ip)
|
||||||
fixed_ips.append(fixed_ip)
|
|
||||||
|
|
||||||
if num_ports:
|
if num_ports:
|
||||||
existing_port = filtered_ports['ports'][0]
|
existing_port = filtered_ports['ports'][0]
|
||||||
created_port_resp = {'port': existing_port}
|
created_port_resp = {'port': existing_port}
|
||||||
host = existing_port.get('binding:host_id')
|
host = existing_port.get('binding:host_id')
|
||||||
vif_type = existing_port.get('binding:vif_type')
|
vif_type = existing_port.get('binding:vif_type')
|
||||||
if not host and vif_type == 'unbound':
|
if not host and vif_type == 'unbound':
|
||||||
updated_port = {
|
updated_port = {
|
||||||
'admin_state_up': True,
|
'admin_state_up': True,
|
||||||
'binding:host_id': utils.get_hostname(),
|
'binding:host_id': utils.get_hostname(),
|
||||||
}
|
}
|
||||||
created_port_resp = app.neutron.update_port(
|
created_port_resp = app.neutron.update_port(
|
||||||
existing_port['id'],
|
existing_port['id'],
|
||||||
{'port': updated_port})
|
{'port': updated_port})
|
||||||
|
else:
|
||||||
|
raise exceptions.AddressInUseException(
|
||||||
|
"Requested ip address {0} already belongs to a "
|
||||||
|
"bound Neutron port: {1}".format(fixed_ip,
|
||||||
|
existing_port['id']))
|
||||||
else:
|
else:
|
||||||
raise exceptions.AddressInUseException(
|
created_port_resp = app.neutron.create_port({'port': port})
|
||||||
"Requested ip address {0} already belongs to a bound "
|
|
||||||
"Neutron port: {1}".format(fixed_ip,
|
|
||||||
existing_port['id']))
|
|
||||||
else:
|
|
||||||
created_port_resp = app.neutron.create_port({'port': port})
|
|
||||||
|
|
||||||
created_port = created_port_resp['port']
|
created_port = created_port_resp['port']
|
||||||
app.logger.debug("created port %s", created_port)
|
app.logger.debug("created port %s", created_port)
|
||||||
allocated_address = created_port['fixed_ips'][0]['ip_address']
|
allocated_address = created_port['fixed_ips'][0]['ip_address']
|
||||||
allocated_address = '/'.join(
|
allocated_address = '/'.join(
|
||||||
[allocated_address, str(cidr.prefixlen)])
|
[allocated_address, str(cidr.prefixlen)])
|
||||||
except n_exceptions.NeutronClientException as ex:
|
except n_exceptions.NeutronClientException as ex:
|
||||||
app.logger.error(_LE("Error happened during ip allocation on "
|
app.logger.error(_LE("Error happened during ip allocation on "
|
||||||
"Neutron side: %s"), ex)
|
"Neutron side: %s"), ex)
|
||||||
raise
|
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})
|
return flask.jsonify({'Address': allocated_address})
|
||||||
|
|
||||||
|
|
|
@ -238,6 +238,41 @@ class TestKuryrIpam(base.TestKuryrBase):
|
||||||
decoded_json = jsonutils.loads(response.data)
|
decoded_json = jsonutils.loads(response.data)
|
||||||
self.assertEqual('10.0.0.5/16', decoded_json['Address'])
|
self.assertEqual('10.0.0.5/16', decoded_json['Address'])
|
||||||
|
|
||||||
|
def test_ipam_driver_request_address_when_subnet_not_exist(self):
|
||||||
|
requested_address = '10.0.0.5'
|
||||||
|
# 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
|
||||||
|
fake_subnet_response = {'subnets': []}
|
||||||
|
self.mox.StubOutWithMock(app.neutron, 'list_subnets')
|
||||||
|
app.neutron.list_subnets(cidr=FAKE_IP4_CIDR).AndReturn(
|
||||||
|
fake_subnet_response)
|
||||||
|
|
||||||
|
# Apply mocks
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
# Testing container ip allocation
|
||||||
|
fake_request = {
|
||||||
|
'PoolID': fake_kuryr_subnetpool_id,
|
||||||
|
'Address': requested_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(requested_address + '/16', decoded_json['Address'])
|
||||||
|
|
||||||
@ddt.data((False), (True))
|
@ddt.data((False), (True))
|
||||||
def test_ipam_driver_request_specific_address(self, existing_port):
|
def test_ipam_driver_request_specific_address(self, existing_port):
|
||||||
requested_address = '10.0.0.5'
|
requested_address = '10.0.0.5'
|
||||||
|
|
Loading…
Reference in New Issue