Support shared kuryr subnetpool
Subnetpools related to the shared neutron network should be shared as well. Change-Id: I7a0907a6af91b27c4dcc2b543346814182e94ddb Needed-By: I9e84acc294ac891f3d4e65866dd2cf415309ed01 Implements: blueprint shared-kuryr-subnetpool
This commit is contained in:
parent
c2e95fd203
commit
66729d4195
|
@ -40,6 +40,7 @@ KURYR_EXISTING_NEUTRON_PORT = 'kuryr.port.existing'
|
|||
NETWORK_GATEWAY_OPTIONS = 'com.docker.network.gateway'
|
||||
NETWORK_GENERIC_OPTIONS = 'com.docker.network.generic'
|
||||
NEUTRON_NAME_OPTION = 'neutron.net.name'
|
||||
NEUTRON_SHARED_OPTION = 'neutron.net.shared'
|
||||
NEUTRON_SUBNET_NAME_OPTION = 'neutron.subnet.name'
|
||||
NEUTRON_SUBNET_UUID_OPTION = 'neutron.subnet.uuid'
|
||||
NEUTRON_V6_SUBNET_NAME_OPTION = 'neutron.subnet.v6.name'
|
||||
|
|
|
@ -25,6 +25,7 @@ from oslo_concurrency import processutils
|
|||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
from oslo_utils import excutils
|
||||
from oslo_utils import strutils
|
||||
|
||||
from kuryr.lib import constants as lib_const
|
||||
from kuryr.lib import exceptions
|
||||
|
@ -563,7 +564,7 @@ def _create_kuryr_subnet(pool_cidr, subnet_cidr, pool_id, network_id, gateway):
|
|||
LOG.debug("Created kuryr subnet %s", new_kuryr_subnet)
|
||||
|
||||
|
||||
def _create_kuryr_subnetpool(pool_cidr, pool_tag):
|
||||
def _create_kuryr_subnetpool(pool_cidr, pool_tag, shared):
|
||||
pool_name = lib_utils.get_neutron_subnetpool_name(pool_cidr)
|
||||
|
||||
kwargs = {'name': pool_name}
|
||||
|
@ -579,7 +580,9 @@ def _create_kuryr_subnetpool(pool_cidr, pool_tag):
|
|||
new_subnetpool = {
|
||||
'name': pool_name,
|
||||
'default_prefixlen': cidr.prefixlen,
|
||||
'prefixes': [pool_cidr]}
|
||||
'prefixes': [pool_cidr],
|
||||
'shared': shared
|
||||
}
|
||||
LOG.info("Creating subnetpool with the given pool CIDR")
|
||||
created_subnetpool_response = app.neutron.create_subnetpool(
|
||||
{'subnetpool': new_subnetpool})
|
||||
|
@ -769,6 +772,7 @@ def network_driver_create_network():
|
|||
v4_subnet_id = ''
|
||||
v6_subnet_name = ''
|
||||
v6_subnet_id = ''
|
||||
shared = False
|
||||
options = json_data.get('Options')
|
||||
if options:
|
||||
generic_options = options.get(const.NETWORK_GENERIC_OPTIONS)
|
||||
|
@ -790,6 +794,8 @@ def network_driver_create_network():
|
|||
const.NEUTRON_POOL_UUID_OPTION)
|
||||
v6_pool_id = generic_options.get(
|
||||
const.NEUTRON_V6_POOL_UUID_OPTION)
|
||||
shared = strutils.bool_from_string(generic_options.get(
|
||||
const.NEUTRON_SHARED_OPTION, 'False'))
|
||||
|
||||
def _get_pool_id(pool_name, pool_cidr, pool_tags):
|
||||
pool_id = ''
|
||||
|
@ -843,7 +849,8 @@ def network_driver_create_network():
|
|||
if not neutron_uuid and not neutron_name:
|
||||
network = app.neutron.create_network(
|
||||
{'network': {'name': neutron_network_name,
|
||||
"admin_state_up": True}})
|
||||
"admin_state_up": True,
|
||||
'shared': shared}})
|
||||
network_id = network['network']['id']
|
||||
_neutron_net_add_tags(network['network']['id'], container_net_id,
|
||||
tags=app.tag)
|
||||
|
@ -865,6 +872,7 @@ def network_driver_create_network():
|
|||
("Specified network id/name({0}) does not "
|
||||
"exist.").format(specified_network))
|
||||
network_id = networks[0]['id']
|
||||
network_shared = networks[0]['shared']
|
||||
except n_exceptions.NeutronClientException as ex:
|
||||
LOG.error("Error happened during listing "
|
||||
"Neutron networks: %s", ex)
|
||||
|
@ -880,6 +888,19 @@ def network_driver_create_network():
|
|||
"%(neutron_network_name)s successfully: %(network)s",
|
||||
{'neutron_network_name': neutron_network_name,
|
||||
'network': network})
|
||||
if network_shared != shared:
|
||||
# NOTE(kiennt): Use generic KuryrException to unblock
|
||||
# patch 516228 for merging. Will change
|
||||
# it to ConflictOption exception in the
|
||||
# follow-up.
|
||||
raise exceptions.KuryrException(
|
||||
'Network %(network_id)s had option '
|
||||
'shared=%(network_shared)s, conflict with the given option '
|
||||
'shared=%(shared)s', {
|
||||
'network_id': network_id,
|
||||
'network_shared': network_shared,
|
||||
'shared': shared
|
||||
})
|
||||
LOG.info("Using existing network %s "
|
||||
"successfully", specified_network)
|
||||
|
||||
|
@ -1472,8 +1493,11 @@ def ipam_request_pool():
|
|||
pool_id = ''
|
||||
subnet_id = ''
|
||||
subnet_name = ''
|
||||
shared = False
|
||||
options = json_data.get('Options')
|
||||
if options:
|
||||
shared = strutils.bool_from_string(options.get(
|
||||
const.NEUTRON_SHARED_OPTION, 'False'))
|
||||
if v6:
|
||||
subnet_name = options.get(const.NEUTRON_V6_SUBNET_NAME_OPTION)
|
||||
subnet_id = options.get(const.NEUTRON_V6_SUBNET_UUID_OPTION)
|
||||
|
@ -1500,7 +1524,8 @@ def ipam_request_pool():
|
|||
"in Options.")
|
||||
if not pool_name and not pool_id:
|
||||
pool_id = _create_kuryr_subnetpool(subnet_cidr,
|
||||
subnet_id)['id']
|
||||
subnet_id,
|
||||
shared)['id']
|
||||
else:
|
||||
if pool_id:
|
||||
existing_pools = _get_subnetpools_by_attrs(id=pool_id)
|
||||
|
@ -1518,11 +1543,22 @@ def ipam_request_pool():
|
|||
prefixes = existing_pools[0]['prefixes']
|
||||
pool_cidr = ipaddress.ip_network(six.text_type(prefixes[0]))
|
||||
if pool_cidr == cidr:
|
||||
if shared != existing_pools[0]['shared']:
|
||||
# NOTE(kiennt): Use generic KuryrException to unblock
|
||||
# patch 516228 for merging. Will change
|
||||
# it to ConflictOption exception in the
|
||||
# follow-up.
|
||||
raise exceptions.KuryrException(
|
||||
'There is already existing subnet pool '
|
||||
'with %(cidr)s but with shared = %(shared)s',
|
||||
{'cidr': cidr,
|
||||
'shared': existing_pools[0]['shared']})
|
||||
LOG.info("Using existing Neutron subnetpool %s successfully",
|
||||
pool_id)
|
||||
else:
|
||||
pool_id = _create_kuryr_subnetpool(subnet_cidr,
|
||||
subnet_id)['id']
|
||||
subnet_id,
|
||||
shared)['id']
|
||||
else:
|
||||
if v6:
|
||||
default_pool_list = SUBNET_POOLS_V6
|
||||
|
|
|
@ -50,7 +50,8 @@ class TestIpamRequestPoolFailures(base.TestKuryrFailures):
|
|||
new_subnetpool = {
|
||||
'name': pool_name,
|
||||
'default_prefixlen': 16,
|
||||
'prefixes': ['10.0.0.0/16']}
|
||||
'prefixes': ['10.0.0.0/16'],
|
||||
'shared': False}
|
||||
|
||||
fake_subnet = {"subnets": []}
|
||||
mock_list_subnets.return_value = fake_subnet
|
||||
|
|
|
@ -115,7 +115,8 @@ class TestKuryr(base.TestKuryrBase):
|
|||
fake_create_network_request = {
|
||||
"network": {
|
||||
"name": utils.make_net_name(docker_network_id),
|
||||
"admin_state_up": True
|
||||
"admin_state_up": True,
|
||||
"shared": False
|
||||
}
|
||||
}
|
||||
fake_network['name'] = utils.make_net_name(docker_network_id)
|
||||
|
@ -241,7 +242,8 @@ class TestKuryr(base.TestKuryrBase):
|
|||
fake_create_network_request = {
|
||||
"network": {
|
||||
"name": utils.make_net_name(docker_network_id),
|
||||
"admin_state_up": True
|
||||
"admin_state_up": True,
|
||||
"shared": False
|
||||
}
|
||||
}
|
||||
fake_network['name'] = utils.make_net_name(docker_network_id)
|
||||
|
@ -379,7 +381,8 @@ class TestKuryr(base.TestKuryrBase):
|
|||
fake_create_network_request = {
|
||||
"network": {
|
||||
"name": utils.make_net_name(docker_network_id),
|
||||
"admin_state_up": True
|
||||
"admin_state_up": True,
|
||||
"shared": False
|
||||
}
|
||||
}
|
||||
fake_network['name'] = utils.make_net_name(docker_network_id)
|
||||
|
@ -821,7 +824,8 @@ class TestKuryr(base.TestKuryrBase):
|
|||
fake_create_network_request = {
|
||||
"network": {
|
||||
"name": utils.make_net_name(docker_network_id),
|
||||
"admin_state_up": True
|
||||
"admin_state_up": True,
|
||||
"shared": False
|
||||
}
|
||||
}
|
||||
fake_network['name'] = utils.make_net_name(docker_network_id)
|
||||
|
@ -986,7 +990,8 @@ class TestKuryr(base.TestKuryrBase):
|
|||
fake_create_network_request = {
|
||||
"network": {
|
||||
"name": utils.make_net_name(docker_network_id),
|
||||
"admin_state_up": True
|
||||
"admin_state_up": True,
|
||||
"shared": False
|
||||
}
|
||||
}
|
||||
fake_network['name'] = utils.make_net_name(docker_network_id)
|
||||
|
@ -1147,7 +1152,8 @@ class TestKuryr(base.TestKuryrBase):
|
|||
fake_create_network_request = {
|
||||
"network": {
|
||||
"name": utils.make_net_name(docker_network_id),
|
||||
"admin_state_up": True
|
||||
"admin_state_up": True,
|
||||
"shared": False
|
||||
}
|
||||
}
|
||||
# The following fake response is retrieved from the Neutron doc:
|
||||
|
|
|
@ -75,7 +75,8 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||
new_subnetpool = {
|
||||
'name': pool_name,
|
||||
'default_prefixlen': prefixlen,
|
||||
'prefixes': [pool_cidr]}
|
||||
'prefixes': [pool_cidr],
|
||||
'shared': False}
|
||||
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_name = pool_name
|
||||
|
@ -117,6 +118,64 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||
decoded_json = jsonutils.loads(response.data)
|
||||
self.assertEqual(fake_kuryr_subnetpool_id, decoded_json['PoolID'])
|
||||
|
||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.add_tag')
|
||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.create_subnetpool')
|
||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnetpools')
|
||||
@ddt.data((FAKE_IP4_CIDR), (FAKE_IP6_CIDR))
|
||||
def test_ipam_driver_request_pool_with_existing_subnet_id_and_shared(self,
|
||||
pool_cidr, mock_list_subnetpools,
|
||||
mock_create_subnetpool, mock_add_tag):
|
||||
neutron_subnet_v4_id = uuidutils.generate_uuid()
|
||||
|
||||
pool_name = lib_utils.get_neutron_subnetpool_name(pool_cidr)
|
||||
prefixlen = ipaddress.ip_network(six.text_type(pool_cidr)).prefixlen
|
||||
new_subnetpool = {
|
||||
'name': pool_name,
|
||||
'default_prefixlen': prefixlen,
|
||||
'prefixes': [pool_cidr],
|
||||
'shared': True}
|
||||
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_name = pool_name
|
||||
if pool_cidr == FAKE_IP4_CIDR:
|
||||
kuryr_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_subnetpool_id, prefixes=[pool_cidr],
|
||||
name=fake_name)
|
||||
else:
|
||||
kuryr_subnetpools = self._get_fake_v6_subnetpools(
|
||||
fake_kuryr_subnetpool_id, prefixes=[pool_cidr],
|
||||
name=fake_name)
|
||||
mock_list_subnetpools.return_value = {'subnetpools': []}
|
||||
fake_subnetpool_response = {
|
||||
'subnetpool': kuryr_subnetpools['subnetpools'][0]
|
||||
}
|
||||
|
||||
mock_create_subnetpool.return_value = fake_subnetpool_response
|
||||
|
||||
fake_request = {
|
||||
'AddressSpace': '',
|
||||
'Pool': pool_cidr,
|
||||
'SubPool': '', # In the case --ip-range is not given
|
||||
'Options': {
|
||||
'neutron.subnet.uuid': neutron_subnet_v4_id,
|
||||
'neutron.net.shared': True
|
||||
},
|
||||
'V6': False
|
||||
}
|
||||
response = self.app.post('/IpamDriver.RequestPool',
|
||||
content_type='application/json',
|
||||
data=jsonutils.dumps(fake_request))
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
mock_list_subnetpools.assert_called_with(
|
||||
name=pool_name, tags=[str(neutron_subnet_v4_id)])
|
||||
mock_create_subnetpool.assert_called_with(
|
||||
{'subnetpool': new_subnetpool})
|
||||
mock_add_tag.assert_called_once_with(
|
||||
'subnetpools', fake_kuryr_subnetpool_id, neutron_subnet_v4_id)
|
||||
decoded_json = jsonutils.loads(response.data)
|
||||
self.assertEqual(fake_kuryr_subnetpool_id, decoded_json['PoolID'])
|
||||
|
||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.add_tag')
|
||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.create_subnetpool')
|
||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnetpools')
|
||||
|
@ -149,7 +208,8 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||
new_subnetpool = {
|
||||
'name': pool_name,
|
||||
'default_prefixlen': prefixlen,
|
||||
'prefixes': [pool_cidr]}
|
||||
'prefixes': [pool_cidr],
|
||||
'shared': False}
|
||||
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_name = pool_name
|
||||
|
@ -205,7 +265,8 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||
new_subnetpool = {
|
||||
'name': pool_name,
|
||||
'default_prefixlen': prefixlen,
|
||||
'prefixes': [pool_cidr]}
|
||||
'prefixes': [pool_cidr],
|
||||
'shared': False}
|
||||
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_name = pool_name
|
||||
|
@ -369,7 +430,8 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||
new_subnetpool = {
|
||||
'name': pool_name,
|
||||
'default_prefixlen': prefixlen,
|
||||
'prefixes': [subnet_cidr]}
|
||||
'prefixes': [subnet_cidr],
|
||||
'shared': False}
|
||||
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_existing_subnetpool_id = uuidutils.generate_uuid()
|
||||
|
|
|
@ -81,7 +81,8 @@ class TestKuryrNetworkCreateFailures(base.TestKuryrFailures):
|
|||
fake_request = {
|
||||
"network": {
|
||||
"name": utils.make_net_name(docker_network_id),
|
||||
"admin_state_up": True
|
||||
"admin_state_up": True,
|
||||
"shared": False
|
||||
}
|
||||
}
|
||||
mock_create_network.side_effect = exceptions.Unauthorized
|
||||
|
|
Loading…
Reference in New Issue