Add support kuryr IPv6 subnet
This patch add IPv6 subnet when calling NetworkDriver.CreateNetwork. NOTE: Fullstack test and docs will land in separate patches. Change-Id: I0721f5896710e221ae028c62e69768b51014d0af Partially-Implements: blueprint ipv6-subnet
This commit is contained in:
parent
21083ce51c
commit
5188ec26c8
|
@ -40,6 +40,7 @@ NETWORK_GENERIC_OPTIONS = 'com.docker.network.generic'
|
|||
NEUTRON_NAME_OPTION = 'neutron.net.name'
|
||||
NEUTRON_POOL_NAME_OPTION = 'neutron.pool.name'
|
||||
NEUTRON_POOL_UUID_OPTION = 'neutron.pool.uuid'
|
||||
NEUTRON_V6_POOL_NAME_OPTION = 'neutron.pool.v6.name'
|
||||
NEUTRON_UUID_OPTION = 'neutron.net.uuid'
|
||||
REQUEST_ADDRESS_TYPE = 'RequestAddressType'
|
||||
KURYR_UNBOUND_PORT = 'kuryr-unbound-port'
|
||||
|
|
|
@ -509,6 +509,22 @@ def revoke_expose_ports(port_id):
|
|||
"Neutron security group: {0}").format(ex))
|
||||
|
||||
|
||||
def _create_kuryr_subnet(pool_cidr, subnet_cidr, pool_id, network_id, gateway):
|
||||
new_kuryr_subnet = [{
|
||||
'name': utils.make_subnet_name(pool_cidr),
|
||||
'network_id': network_id,
|
||||
'ip_version': subnet_cidr.version,
|
||||
'cidr': six.text_type(subnet_cidr),
|
||||
'enable_dhcp': app.enable_dhcp,
|
||||
}]
|
||||
new_kuryr_subnet[0]['subnetpool_id'] = pool_id
|
||||
if gateway:
|
||||
new_kuryr_subnet[0]['gateway_ip'] = gateway
|
||||
|
||||
app.neutron.create_subnet({'subnets': new_kuryr_subnet})
|
||||
LOG.debug("Created kuryr subnet %s", new_kuryr_subnet)
|
||||
|
||||
|
||||
@app.route('/Plugin.Activate', methods=['POST'])
|
||||
def plugin_activate():
|
||||
"""Returns the list of the implemented drivers.
|
||||
|
@ -620,41 +636,73 @@ def network_driver_create_network():
|
|||
jsonschema.validate(json_data, schemata.NETWORK_CREATE_SCHEMA)
|
||||
container_net_id = json_data['NetworkID']
|
||||
neutron_network_name = utils.make_net_name(container_net_id, tags=app.tag)
|
||||
pool_cidr = json_data['IPv4Data'][0]['Pool']
|
||||
gateway_ip = ''
|
||||
if 'Gateway' in json_data['IPv4Data'][0]:
|
||||
gateway_cidr = json_data['IPv4Data'][0]['Gateway']
|
||||
gateway_ip = gateway_cidr.split('/')[0]
|
||||
LOG.debug("gateway_cidr %(gateway_cidr)s, "
|
||||
"gateway_ip %(gateway_ip)s",
|
||||
{'gateway_cidr': gateway_cidr, 'gateway_ip': gateway_ip})
|
||||
v4_pool_cidr = None
|
||||
v6_pool_cidr = None
|
||||
v4_gateway_ip = ''
|
||||
v6_gateway_ip = ''
|
||||
|
||||
def _get_gateway_ip(ip_data):
|
||||
gateway_ip = ''
|
||||
if 'Gateway' in ip_data:
|
||||
gateway_cidr = ip_data['Gateway']
|
||||
gateway_ip = gateway_cidr.split('/')[0]
|
||||
return gateway_ip
|
||||
|
||||
if json_data['IPv4Data']:
|
||||
v4_pool_cidr = json_data['IPv4Data'][0]['Pool']
|
||||
v4_gateway_ip = _get_gateway_ip(json_data['IPv4Data'][0])
|
||||
|
||||
if json_data['IPv6Data']:
|
||||
v6_pool_cidr = json_data['IPv6Data'][0]['Pool']
|
||||
v6_gateway_ip = _get_gateway_ip(json_data['IPv6Data'][0])
|
||||
|
||||
neutron_uuid = None
|
||||
neutron_name = None
|
||||
pool_name = ''
|
||||
pool_id = ''
|
||||
existing_pool_id = ''
|
||||
v4_pool_name = ''
|
||||
v4_pool_id = ''
|
||||
v6_pool_name = ''
|
||||
v6_pool_id = ''
|
||||
options = json_data.get('Options')
|
||||
if options:
|
||||
generic_options = options.get(const.NETWORK_GENERIC_OPTIONS)
|
||||
if generic_options:
|
||||
neutron_uuid = generic_options.get(const.NEUTRON_UUID_OPTION)
|
||||
neutron_name = generic_options.get(const.NEUTRON_NAME_OPTION)
|
||||
pool_name = generic_options.get(const.NEUTRON_POOL_NAME_OPTION)
|
||||
pool_id = generic_options.get(const.NEUTRON_POOL_UUID_OPTION)
|
||||
v4_pool_name = generic_options.get(const.NEUTRON_POOL_NAME_OPTION)
|
||||
v6_pool_name = generic_options.get(
|
||||
const.NEUTRON_V6_POOL_NAME_OPTION)
|
||||
existing_pool_id = generic_options.get(
|
||||
const.NEUTRON_POOL_UUID_OPTION)
|
||||
|
||||
if pool_id:
|
||||
pools = _get_subnetpools_by_attrs(id=pool_id)
|
||||
elif pool_name:
|
||||
pools = _get_subnetpools_by_attrs(name=pool_name)
|
||||
def _get_pool_id(pool_name, pool_cidr):
|
||||
pool_id = ''
|
||||
if not pool_name and pool_cidr:
|
||||
pool_name = lib_utils.get_neutron_subnetpool_name(pool_cidr)
|
||||
if pool_name:
|
||||
pools = _get_subnetpools_by_attrs(name=pool_name)
|
||||
if pools:
|
||||
pool_id = pools[0]['id']
|
||||
else:
|
||||
raise exceptions.KuryrException(
|
||||
("Specified pool name({0}) does not "
|
||||
"exist.").format(pool_name))
|
||||
return pool_id
|
||||
|
||||
if existing_pool_id:
|
||||
pools = _get_subnetpools_by_attrs(id=existing_pool_id)
|
||||
if pools:
|
||||
existing_pool_id = pools[0]['id']
|
||||
else:
|
||||
raise exceptions.KuryrException(
|
||||
("Specified pool id({0}) does not "
|
||||
"exist.").format(existing_pool_id))
|
||||
|
||||
if existing_pool_id:
|
||||
v4_pool_id = existing_pool_id
|
||||
else:
|
||||
pool_name = lib_utils.get_neutron_subnetpool_name(pool_cidr)
|
||||
pools = _get_subnetpools_by_attrs(name=pool_name)
|
||||
|
||||
if not pools:
|
||||
raise exceptions.KuryrException(
|
||||
("Specified pool id/name({0}) does not "
|
||||
"exist.").format(pool_id or pool_name))
|
||||
pool_id = pools[0]['id']
|
||||
v4_pool_id = _get_pool_id(v4_pool_name, v4_pool_cidr)
|
||||
v6_pool_id = _get_pool_id(v6_pool_name, v6_pool_cidr)
|
||||
|
||||
# let the user override the driver default
|
||||
if not neutron_uuid and not neutron_name:
|
||||
|
@ -707,32 +755,40 @@ def network_driver_create_network():
|
|||
LOG.info(_LI("Using existing network %s "
|
||||
"successfully"), specified_network)
|
||||
|
||||
cidr = ipaddress.ip_network(six.text_type(pool_cidr))
|
||||
subnets = _get_subnets_by_attrs(network_id=network_id,
|
||||
cidr=six.text_type(cidr))
|
||||
if len(subnets) > 1:
|
||||
raise exceptions.DuplicatedResourceException(
|
||||
"Multiple Neutron subnets exist for the network_id={0}"
|
||||
"and cidr={1}".format(network_id, cidr))
|
||||
def _get_existing_neutron_subnets(pool_cidr, network_id):
|
||||
cidr = None
|
||||
subnets = []
|
||||
if pool_cidr:
|
||||
cidr = ipaddress.ip_network(six.text_type(pool_cidr))
|
||||
subnets = _get_subnets_by_attrs(network_id=network_id,
|
||||
cidr=six.text_type(cidr))
|
||||
if len(subnets) > 1:
|
||||
raise exceptions.DuplicatedResourceException(
|
||||
"Multiple Neutron subnets exist for the network_id={0}"
|
||||
"and cidr={1}".format(network_id, cidr))
|
||||
return cidr, subnets
|
||||
|
||||
v4_cidr, v4_subnets = _get_existing_neutron_subnets(v4_pool_cidr,
|
||||
network_id)
|
||||
v6_cidr, v6_subnets = _get_existing_neutron_subnets(v6_pool_cidr,
|
||||
network_id)
|
||||
|
||||
def _add_tag_for_existing_subnet(subnet, pool_id):
|
||||
if len(subnet) == 1:
|
||||
_neutron_subnet_add_tag(subnet[0]['id'], pool_id)
|
||||
|
||||
# This will add a subnetpool_id(created by kuryr) tag
|
||||
# for existing Neutron subnet.
|
||||
if app.tag and len(subnets) == 1:
|
||||
_neutron_subnet_add_tag(subnets[0]['id'], pool_id)
|
||||
# for existing Neutron subnets.
|
||||
if app.tag:
|
||||
_add_tag_for_existing_subnet(v4_subnets, v4_pool_id)
|
||||
_add_tag_for_existing_subnet(v6_subnets, v6_pool_id)
|
||||
|
||||
if not subnets:
|
||||
new_subnets = [{
|
||||
'name': utils.make_subnet_name(pool_cidr),
|
||||
'network_id': network_id,
|
||||
'ip_version': cidr.version,
|
||||
'cidr': six.text_type(cidr),
|
||||
'enable_dhcp': app.enable_dhcp,
|
||||
}]
|
||||
new_subnets[0]['subnetpool_id'] = pool_id
|
||||
if gateway_ip:
|
||||
new_subnets[0]['gateway_ip'] = gateway_ip
|
||||
|
||||
app.neutron.create_subnet({'subnets': new_subnets})
|
||||
if not v4_subnets and v4_pool_cidr:
|
||||
_create_kuryr_subnet(v4_pool_cidr, v4_cidr, v4_pool_id,
|
||||
network_id, v4_gateway_ip)
|
||||
if not v6_subnets and v6_pool_cidr:
|
||||
_create_kuryr_subnet(v6_pool_cidr, v6_cidr, v6_pool_id,
|
||||
network_id, v6_gateway_ip)
|
||||
|
||||
return flask.jsonify(const.SCHEMA['SUCCESS'])
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -83,13 +83,21 @@ class TestKuryrNetworkPreExisting(base.TestKuryrBase):
|
|||
}
|
||||
}
|
||||
|
||||
fake_subnetpool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
fake_kuryr_v4_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v4_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv4Data'][0]['Pool'])
|
||||
kuryr_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_subnetpool_id, name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.return_value = {
|
||||
'subnetpools': kuryr_subnetpools['subnetpools']}
|
||||
kuryr_v4_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_v4_subnetpool_id, name=fake_v4_pool_name)
|
||||
|
||||
fake_kuryr_v6_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v6_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv6Data'][0]['Pool'])
|
||||
kuryr_v6_subnetpools = self._get_fake_v6_subnetpools(
|
||||
fake_kuryr_v6_subnetpool_id, name=fake_v6_pool_name)
|
||||
mock_list_subnetpools.side_effect = [
|
||||
{'subnetpools': kuryr_v4_subnetpools['subnetpools']},
|
||||
{'subnetpools': kuryr_v6_subnetpools['subnetpools']}
|
||||
]
|
||||
mock_list_networks.return_value = fake_response
|
||||
|
||||
fake_existing_subnets_response = {
|
||||
|
@ -98,7 +106,7 @@ class TestKuryrNetworkPreExisting(base.TestKuryrBase):
|
|||
fake_cidr_v4 = '192.168.42.0/24'
|
||||
mock_list_subnets.return_value = fake_existing_subnets_response
|
||||
|
||||
fake_subnet_request = {
|
||||
fake_v4_subnet_request = {
|
||||
"subnets": [{
|
||||
'name': utils.make_subnet_name(fake_cidr_v4),
|
||||
'network_id': fake_neutron_net_id,
|
||||
|
@ -106,7 +114,7 @@ class TestKuryrNetworkPreExisting(base.TestKuryrBase):
|
|||
'cidr': fake_cidr_v4,
|
||||
'enable_dhcp': mock_tag.enable_dhcp,
|
||||
'gateway_ip': '192.168.42.1',
|
||||
'subnetpool_id': fake_kuryr_subnetpool_id
|
||||
'subnetpool_id': fake_kuryr_v4_subnetpool_id
|
||||
}]
|
||||
}
|
||||
subnet_v4_id = uuidutils.generate_uuid()
|
||||
|
@ -114,24 +122,47 @@ class TestKuryrNetworkPreExisting(base.TestKuryrBase):
|
|||
fake_neutron_net_id, subnet_v4_id,
|
||||
fake_kuryr_subnetpool_id,
|
||||
name=fake_cidr_v4, cidr=fake_cidr_v4)
|
||||
fake_subnet_response = {
|
||||
fake_cidr_v6 = 'fe80::/64'
|
||||
fake_v6_subnet_request = {
|
||||
"subnets": [{
|
||||
'name': utils.make_subnet_name(fake_cidr_v6),
|
||||
'network_id': fake_neutron_net_id,
|
||||
'ip_version': 6,
|
||||
'cidr': fake_cidr_v6,
|
||||
'enable_dhcp': mock_tag.enable_dhcp,
|
||||
'gateway_ip': 'fe80::f816:3eff:fe20:57c3',
|
||||
'subnetpool_id': fake_kuryr_v6_subnetpool_id
|
||||
}]
|
||||
}
|
||||
|
||||
subnet_v6_id = uuidutils.generate_uuid()
|
||||
fake_v6_subnet = self._get_fake_v6_subnet(
|
||||
fake_neutron_net_id, subnet_v6_id,
|
||||
fake_kuryr_v6_subnetpool_id,
|
||||
name=fake_cidr_v6, cidr=fake_cidr_v6)
|
||||
fake_v4_v6_subnets_response = {
|
||||
'subnets': [
|
||||
fake_v4_subnet['subnet']
|
||||
fake_v4_subnet['subnet'],
|
||||
fake_v6_subnet['subnet']
|
||||
]
|
||||
}
|
||||
mock_create_subnet.return_value = fake_subnet_response
|
||||
mock_create_subnet.return_value = fake_v4_v6_subnets_response
|
||||
|
||||
response = self.app.post('/NetworkDriver.CreateNetwork',
|
||||
content_type='application/json',
|
||||
data=jsonutils.dumps(network_request))
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
mock_list_subnetpools.assert_called_with(name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v4_pool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v6_pool_name)
|
||||
mock_list_networks.assert_called_with(id=fake_neutron_net_id)
|
||||
mock_list_subnets.assert_called_with(
|
||||
mock_list_subnets.assert_any_call(
|
||||
network_id=fake_neutron_net_id,
|
||||
cidr=fake_cidr_v4)
|
||||
mock_create_subnet.assert_called_with(fake_subnet_request)
|
||||
mock_list_subnets.assert_any_call(network_id=fake_neutron_net_id,
|
||||
cidr=fake_cidr_v6)
|
||||
mock_create_subnet.assert_any_call(fake_v4_subnet_request)
|
||||
mock_create_subnet.assert_any_call(fake_v6_subnet_request)
|
||||
if mock_tag.tag:
|
||||
tags = utils.create_net_tags(docker_network_id)
|
||||
for tag in tags:
|
||||
|
@ -191,31 +222,47 @@ class TestKuryrNetworkPreExisting(base.TestKuryrBase):
|
|||
}
|
||||
}
|
||||
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_subnetpool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
fake_kuryr_v4_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v4_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv4Data'][0]['Pool'])
|
||||
kuryr_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_subnetpool_id, name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.return_value = {
|
||||
'subnetpools': kuryr_subnetpools['subnetpools']}
|
||||
kuryr_v4_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_v4_subnetpool_id, name=fake_v4_pool_name)
|
||||
|
||||
fake_kuryr_v6_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v6_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv6Data'][0]['Pool'])
|
||||
kuryr_v6_subnetpools = self._get_fake_v6_subnetpools(
|
||||
fake_kuryr_v6_subnetpool_id, name=fake_v6_pool_name)
|
||||
mock_list_subnetpools.side_effect = [
|
||||
{'subnetpools': kuryr_v4_subnetpools['subnetpools']},
|
||||
{'subnetpools': kuryr_v6_subnetpools['subnetpools']}
|
||||
]
|
||||
|
||||
subnet_v4_id = uuidutils.generate_uuid()
|
||||
subnet_v6_id = uuidutils.generate_uuid()
|
||||
fake_cidr_v4 = '192.168.42.0/24'
|
||||
fake_cidr_v6 = 'fe80::/64'
|
||||
fake_v4_subnet = self._get_fake_v4_subnet(
|
||||
fake_neutron_net_id,
|
||||
docker_endpoint_id="fake_id",
|
||||
subnet_v4_id=subnet_v4_id,
|
||||
subnetpool_id=fake_kuryr_subnetpool_id,
|
||||
subnetpool_id=fake_kuryr_v4_subnetpool_id,
|
||||
cidr=fake_cidr_v4)
|
||||
fake_v6_subnet = self._get_fake_v6_subnet(
|
||||
fake_neutron_net_id,
|
||||
docker_endpoint_id="fake_id",
|
||||
subnet_v6_id=subnet_v6_id,
|
||||
subnetpool_id=fake_kuryr_v6_subnetpool_id,
|
||||
cidr=fake_cidr_v6)
|
||||
|
||||
fake_existing_subnets_response = {
|
||||
'subnets': [
|
||||
fake_v4_subnet['subnet']
|
||||
]
|
||||
}
|
||||
mock_list_subnets.return_value = fake_existing_subnets_response
|
||||
fake_existing_subnets_response = [
|
||||
{'subnets': [fake_v4_subnet['subnet']]},
|
||||
{'subnets': [fake_v6_subnet['subnet']]}
|
||||
]
|
||||
|
||||
mock_list_subnets.side_effect = fake_existing_subnets_response
|
||||
fake_response['networks'][0]['subnets'].append(subnet_v4_id)
|
||||
fake_response['networks'][0]['subnets'].append(subnet_v6_id)
|
||||
mock_list_networks.return_value = fake_response
|
||||
|
||||
def mock_exception(*args, **kwargs):
|
||||
|
@ -228,11 +275,15 @@ class TestKuryrNetworkPreExisting(base.TestKuryrBase):
|
|||
data=jsonutils.dumps(network_request))
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
mock_list_subnetpools.assert_called_with(name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v4_pool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v6_pool_name)
|
||||
mock_list_networks.assert_called_with(id=fake_neutron_net_id)
|
||||
mock_list_subnets.assert_called_with(
|
||||
mock_list_subnets.assert_any_call(
|
||||
network_id=fake_neutron_net_id,
|
||||
cidr=fake_cidr_v4)
|
||||
mock_list_subnets.assert_any_call(
|
||||
network_id=fake_neutron_net_id,
|
||||
cidr=fake_cidr_v6)
|
||||
|
||||
if mock_tag.tag:
|
||||
tags = utils.create_net_tags(docker_network_id)
|
||||
|
@ -241,9 +292,12 @@ class TestKuryrNetworkPreExisting(base.TestKuryrBase):
|
|||
'networks', fake_neutron_net_id, tag)
|
||||
mock_add_tag.assert_any_call('networks', fake_neutron_net_id,
|
||||
const.KURYR_EXISTING_NEUTRON_NET)
|
||||
mock_add_tag.assert_called_with('subnets',
|
||||
subnet_v4_id,
|
||||
fake_kuryr_subnetpool_id)
|
||||
mock_add_tag.assert_any_call('subnets',
|
||||
subnet_v4_id,
|
||||
fake_kuryr_v4_subnetpool_id)
|
||||
mock_add_tag.assert_any_call('subnets',
|
||||
subnet_v6_id,
|
||||
fake_kuryr_v6_subnetpool_id)
|
||||
else:
|
||||
mock_update_network.assert_called_with(
|
||||
fake_neutron_net_id, {'network':
|
||||
|
|
|
@ -60,13 +60,21 @@ class TestKuryrNetworkCreateFailures(base.TestKuryrFailures):
|
|||
'Options': {}
|
||||
}
|
||||
|
||||
fake_subnetpool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
fake_kuryr_v4_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v4_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv4Data'][0]['Pool'])
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
kuryr_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_subnetpool_id, name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.return_value = {
|
||||
'subnetpools': kuryr_subnetpools['subnetpools']}
|
||||
kuryr_v4_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_v4_subnetpool_id, name=fake_v4_pool_name)
|
||||
|
||||
fake_kuryr_v6_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v6_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv6Data'][0]['Pool'])
|
||||
kuryr_v6_subnetpools = self._get_fake_v6_subnetpools(
|
||||
fake_kuryr_v6_subnetpool_id, name=fake_v6_pool_name)
|
||||
mock_list_subnetpools.side_effect = [
|
||||
{'subnetpools': kuryr_v4_subnetpools['subnetpools']},
|
||||
{'subnetpools': kuryr_v6_subnetpools['subnetpools']}
|
||||
]
|
||||
|
||||
fake_request = {
|
||||
"network": {
|
||||
|
@ -78,7 +86,8 @@ class TestKuryrNetworkCreateFailures(base.TestKuryrFailures):
|
|||
response = self._invoke_create_request(network_request)
|
||||
self.assertEqual(401, response.status_code)
|
||||
decoded_json = jsonutils.loads(response.data)
|
||||
mock_list_subnetpools.assert_called_with(name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v4_pool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v6_pool_name)
|
||||
mock_create_network.assert_called_with(fake_request)
|
||||
self.assertIn('Err', decoded_json)
|
||||
self.assertEqual(
|
||||
|
@ -107,19 +116,28 @@ class TestKuryrNetworkCreateFailures(base.TestKuryrFailures):
|
|||
'Options': {}
|
||||
}
|
||||
|
||||
fake_subnetpool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
fake_kuryr_v4_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v4_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv4Data'][0]['Pool'])
|
||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||
kuryr_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_subnetpool_id, name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.return_value = {
|
||||
'subnetpools': kuryr_subnetpools['subnetpools']}
|
||||
kuryr_v4_subnetpools = self._get_fake_v4_subnetpools(
|
||||
fake_kuryr_v4_subnetpool_id, name=fake_v4_pool_name)
|
||||
|
||||
fake_kuryr_v6_subnetpool_id = uuidutils.generate_uuid()
|
||||
fake_v6_pool_name = lib_utils.get_neutron_subnetpool_name(
|
||||
network_request['IPv6Data'][0]['Pool'])
|
||||
kuryr_v6_subnetpools = self._get_fake_v6_subnetpools(
|
||||
fake_kuryr_v6_subnetpool_id, name=fake_v6_pool_name)
|
||||
mock_list_subnetpools.side_effect = [
|
||||
{'subnetpools': kuryr_v4_subnetpools['subnetpools']},
|
||||
{'subnetpools': kuryr_v6_subnetpools['subnetpools']}
|
||||
]
|
||||
|
||||
mock_get_default_network_id.side_effect = exceptions.Unauthorized
|
||||
response = self._invoke_create_request(network_request)
|
||||
self.assertEqual(401, response.status_code)
|
||||
decoded_json = jsonutils.loads(response.data)
|
||||
mock_list_subnetpools.assert_called_with(name=fake_subnetpool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v4_pool_name)
|
||||
mock_list_subnetpools.assert_any_call(name=fake_v6_pool_name)
|
||||
mock_get_default_network_id.assert_called()
|
||||
self.assertIn('Err', decoded_json)
|
||||
self.assertEqual(
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
features:
|
||||
- |
|
||||
Support creating an IPv6 subnet from Docker client. Users can pass --ipv6 and
|
||||
IPv6 subnet attribute in CLI.
|
||||
issues:
|
||||
- |
|
||||
Docker version 1.12 and 1.13 have problem to pass ipv6 tag [1], according to
|
||||
this limitation, current support is for dual-stack only.
|
||||
[1] https://github.com/docker/docker/issues/28055
|
Loading…
Reference in New Issue