Merge "Add subnetpool_id tag for existing Neutron subnet"
This commit is contained in:
commit
b895ee256d
@ -72,7 +72,7 @@ def check_for_neutron_ext_support():
|
|||||||
|
|
||||||
|
|
||||||
def check_for_neutron_ext_tag():
|
def check_for_neutron_ext_tag():
|
||||||
"""Validates for mandatory extension support availability in neutron."""
|
"""Validates for tags extension support availability in neutron."""
|
||||||
app.tag = True
|
app.tag = True
|
||||||
try:
|
try:
|
||||||
app.neutron.show_extension(TAG_NEUTRON_EXTENSION)
|
app.neutron.show_extension(TAG_NEUTRON_EXTENSION)
|
||||||
@ -287,6 +287,10 @@ def _neutron_net_remove_tags(netid, tag):
|
|||||||
_neutron_net_remove_tag(netid, tag)
|
_neutron_net_remove_tag(netid, tag)
|
||||||
|
|
||||||
|
|
||||||
|
def _neutron_subnet_add_tag(subnetid, tag):
|
||||||
|
app.neutron.add_tag('subnets', subnetid, tag)
|
||||||
|
|
||||||
|
|
||||||
def _make_net_identifier(network_id, tags=True):
|
def _make_net_identifier(network_id, tags=True):
|
||||||
if tags:
|
if tags:
|
||||||
return utils.make_net_tags(network_id)
|
return utils.make_net_tags(network_id)
|
||||||
@ -634,6 +638,18 @@ def network_driver_create_network():
|
|||||||
"Multiple Neutron subnets exist for the network_id={0}"
|
"Multiple Neutron subnets exist for the network_id={0}"
|
||||||
"and cidr={1}".format(network_id, cidr))
|
"and cidr={1}".format(network_id, cidr))
|
||||||
|
|
||||||
|
# This will add a subnetpool_id(created by kuryr) tag
|
||||||
|
# for existing Neutron subnet.
|
||||||
|
if app.tag and len(subnets) == 1:
|
||||||
|
try:
|
||||||
|
tag_extension = app.neutron.show_extension(TAG_NEUTRON_EXTENSION)
|
||||||
|
except n_exceptions.NeutronClientException as ex:
|
||||||
|
app.logger.error(_LE("Failed to show Neutron tags "
|
||||||
|
"extension: %s"), ex)
|
||||||
|
raise
|
||||||
|
if 'subnet' in tag_extension['extension']['description']:
|
||||||
|
_neutron_subnet_add_tag(subnets[0]['id'], pool_id)
|
||||||
|
|
||||||
if not subnets:
|
if not subnets:
|
||||||
new_subnets = [{
|
new_subnets = [{
|
||||||
'name': utils.make_subnet_name(pool_cidr),
|
'name': utils.make_subnet_name(pool_cidr),
|
||||||
@ -1315,8 +1331,21 @@ def ipam_request_address():
|
|||||||
if subnets_by_cidr:
|
if subnets_by_cidr:
|
||||||
if len(subnets_by_cidr) > 1:
|
if len(subnets_by_cidr) > 1:
|
||||||
for tmp_subnet in subnets_by_cidr:
|
for tmp_subnet in subnets_by_cidr:
|
||||||
if tmp_subnet.get('subnetpool_id', '') == pool_id:
|
subnet_name = tmp_subnet.get('name')
|
||||||
subnet = tmp_subnet
|
# Subnet created by Kuryr.
|
||||||
|
if str(subnet_name).startswith(const.SUBNET_NAME_PREFIX):
|
||||||
|
if tmp_subnet.get('subnetpool_id', '') == pool_id:
|
||||||
|
subnet = tmp_subnet
|
||||||
|
# Subnet created by Neutron.
|
||||||
|
else:
|
||||||
|
if tmp_subnet.get('tags') is not None:
|
||||||
|
if pool_id in tmp_subnet.get('tags'):
|
||||||
|
subnet = tmp_subnet
|
||||||
|
else:
|
||||||
|
app.logger.warning(_LW("subnetpool tag for Neutron "
|
||||||
|
"subnet %s is missing, cannot "
|
||||||
|
"gets the correct subnet."),
|
||||||
|
tmp_subnet['id'])
|
||||||
if not any(subnet) and not is_gateway:
|
if not any(subnet) and not is_gateway:
|
||||||
raise exceptions.KuryrException(
|
raise exceptions.KuryrException(
|
||||||
("Subnet with cidr({0}) and pool {1}, does not "
|
("Subnet with cidr({0}) and pool {1}, does not "
|
||||||
|
@ -18,6 +18,7 @@ from oslotest import base
|
|||||||
from kuryr.lib import constants as lib_const
|
from kuryr.lib import constants as lib_const
|
||||||
from kuryr.lib import utils as lib_utils
|
from kuryr.lib import utils as lib_utils
|
||||||
from kuryr_libnetwork import app
|
from kuryr_libnetwork import app
|
||||||
|
from kuryr_libnetwork import constants as const
|
||||||
from kuryr_libnetwork import controllers
|
from kuryr_libnetwork import controllers
|
||||||
from kuryr_libnetwork.port_driver import driver
|
from kuryr_libnetwork.port_driver import driver
|
||||||
from kuryr_libnetwork import utils
|
from kuryr_libnetwork import utils
|
||||||
@ -233,11 +234,14 @@ class TestKuryrBase(TestCase):
|
|||||||
"cidr": '192.168.1.0/24',
|
"cidr": '192.168.1.0/24',
|
||||||
"id": subnet_v4_id,
|
"id": subnet_v4_id,
|
||||||
"enable_dhcp": True,
|
"enable_dhcp": True,
|
||||||
"subnetpool_id": ''
|
"subnetpool_id": '',
|
||||||
|
"tags": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if subnetpool_id:
|
if subnetpool_id:
|
||||||
fake_v4_subnet['subnet'].update(subnetpool_id=subnetpool_id)
|
fake_v4_subnet['subnet'].update(subnetpool_id=subnetpool_id)
|
||||||
|
if not str(name).startswith(const.SUBNET_NAME_PREFIX):
|
||||||
|
fake_v4_subnet['subnet'].get('tags').append(subnetpool_id)
|
||||||
|
|
||||||
return fake_v4_subnet
|
return fake_v4_subnet
|
||||||
|
|
||||||
|
@ -14,12 +14,14 @@ import ddt
|
|||||||
import mock
|
import mock
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
|
from werkzeug import exceptions as w_exceptions
|
||||||
|
|
||||||
from kuryr.lib import constants as lib_const
|
from kuryr.lib import constants as lib_const
|
||||||
from kuryr.lib import utils as lib_utils
|
from kuryr.lib import utils as lib_utils
|
||||||
from kuryr_libnetwork import config
|
from kuryr_libnetwork import config
|
||||||
from kuryr_libnetwork import constants as const
|
from kuryr_libnetwork import constants as const
|
||||||
from kuryr_libnetwork.tests.unit import base
|
from kuryr_libnetwork.tests.unit import base
|
||||||
|
from kuryr_libnetwork import utils
|
||||||
|
|
||||||
|
|
||||||
FAKE_IP4_CIDR = '10.0.0.0/16'
|
FAKE_IP4_CIDR = '10.0.0.0/16'
|
||||||
@ -382,10 +384,9 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.create_port')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.create_port')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
||||||
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnetpools')
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnetpools')
|
||||||
def test_ipam_driver_request_address_overlapping_cidr(self,
|
def test_ipam_driver_request_address_overlapping_cidr_in_neutron(self,
|
||||||
mock_list_subnetpools, mock_list_subnets, mock_create_port):
|
mock_list_subnetpools, mock_list_subnets, mock_create_port):
|
||||||
# faking list_subnetpools
|
# faking list_subnetpools
|
||||||
|
|
||||||
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||||
fake_kuryr_subnetpool_id2 = uuidutils.generate_uuid()
|
fake_kuryr_subnetpool_id2 = uuidutils.generate_uuid()
|
||||||
|
|
||||||
@ -393,17 +394,16 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||||||
kuryr_subnetpools = self._get_fake_v4_subnetpools(
|
kuryr_subnetpools = self._get_fake_v4_subnetpools(
|
||||||
fake_kuryr_subnetpool_id, prefixes=[FAKE_IP4_CIDR],
|
fake_kuryr_subnetpool_id, prefixes=[FAKE_IP4_CIDR],
|
||||||
name=fake_name)
|
name=fake_name)
|
||||||
|
mock_list_subnetpools.return_value = kuryr_subnetpools
|
||||||
|
|
||||||
# faking list_subnets
|
# faking list_subnets
|
||||||
mock_list_subnetpools.return_value = kuryr_subnetpools
|
|
||||||
docker_endpoint_id = lib_utils.get_hash()
|
docker_endpoint_id = lib_utils.get_hash()
|
||||||
|
|
||||||
neutron_network_id = uuidutils.generate_uuid()
|
neutron_network_id = uuidutils.generate_uuid()
|
||||||
neutron_network_id2 = uuidutils.generate_uuid()
|
neutron_network_id2 = uuidutils.generate_uuid()
|
||||||
|
|
||||||
neutron_subnet_v4_id = uuidutils.generate_uuid()
|
neutron_subnet_v4_id = uuidutils.generate_uuid()
|
||||||
neutron_subnet_v4_id2 = uuidutils.generate_uuid()
|
neutron_subnet_v4_id2 = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
# Fake existing Neutron subnets
|
||||||
fake_v4_subnet = self._get_fake_v4_subnet(
|
fake_v4_subnet = self._get_fake_v4_subnet(
|
||||||
neutron_network_id, docker_endpoint_id, neutron_subnet_v4_id,
|
neutron_network_id, docker_endpoint_id, neutron_subnet_v4_id,
|
||||||
subnetpool_id=fake_kuryr_subnetpool_id,
|
subnetpool_id=fake_kuryr_subnetpool_id,
|
||||||
@ -423,7 +423,152 @@ class TestKuryrIpam(base.TestKuryrBase):
|
|||||||
mock_list_subnets.return_value = fake_subnet_response
|
mock_list_subnets.return_value = fake_subnet_response
|
||||||
# faking create_port
|
# faking create_port
|
||||||
fake_neutron_port_id = uuidutils.generate_uuid()
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
fake_port = base.TestKuryrBase._get_fake_port(
|
fake_port = self._get_fake_port(
|
||||||
|
docker_endpoint_id, neutron_network_id,
|
||||||
|
fake_neutron_port_id,
|
||||||
|
neutron_subnet_v4_id=neutron_subnet_v4_id,
|
||||||
|
neutron_subnet_v4_address="10.0.0.5")
|
||||||
|
mock_create_port.return_value = fake_port
|
||||||
|
port_request = {
|
||||||
|
'name': 'kuryr-unbound-port',
|
||||||
|
'admin_state_up': True,
|
||||||
|
'network_id': neutron_network_id,
|
||||||
|
'binding:host_id': lib_utils.get_hostname(),
|
||||||
|
}
|
||||||
|
port_request['fixed_ips'] = []
|
||||||
|
fixed_ip = {'subnet_id': neutron_subnet_v4_id}
|
||||||
|
port_request['fixed_ips'].append(fixed_ip)
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
mock_list_subnetpools.assert_called_with(
|
||||||
|
id=fake_kuryr_subnetpool_id)
|
||||||
|
mock_list_subnets.assert_called_with(
|
||||||
|
cidr=FAKE_IP4_CIDR)
|
||||||
|
mock_create_port.assert_called_with(
|
||||||
|
{'port': port_request})
|
||||||
|
decoded_json = jsonutils.loads(response.data)
|
||||||
|
self.assertEqual('10.0.0.5/16', decoded_json['Address'])
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.create_port')
|
||||||
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
||||||
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnetpools')
|
||||||
|
def test_ipam_driver_request_address_overlapping_cidr_no_subnet_tags(self,
|
||||||
|
mock_list_subnetpools, mock_list_subnets, mock_create_port):
|
||||||
|
# faking list_subnetpools
|
||||||
|
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||||
|
fake_kuryr_subnetpool_id2 = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
fake_name = lib_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)
|
||||||
|
mock_list_subnetpools.return_value = kuryr_subnetpools
|
||||||
|
|
||||||
|
# faking list_subnets
|
||||||
|
docker_endpoint_id = lib_utils.get_hash()
|
||||||
|
neutron_network_id = uuidutils.generate_uuid()
|
||||||
|
neutron_network_id2 = uuidutils.generate_uuid()
|
||||||
|
neutron_subnet_v4_id = uuidutils.generate_uuid()
|
||||||
|
neutron_subnet_v4_id2 = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
# Fake existing Neutron subnets
|
||||||
|
fake_v4_subnet = self._get_fake_v4_subnet(
|
||||||
|
neutron_network_id, docker_endpoint_id, neutron_subnet_v4_id,
|
||||||
|
subnetpool_id=fake_kuryr_subnetpool_id,
|
||||||
|
cidr=FAKE_IP4_CIDR)
|
||||||
|
# Making existing Neutron subnet has no tag attribute
|
||||||
|
del fake_v4_subnet['subnet']['tags']
|
||||||
|
|
||||||
|
fake_v4_subnet2 = self._get_fake_v4_subnet(
|
||||||
|
neutron_network_id2, docker_endpoint_id, neutron_subnet_v4_id2,
|
||||||
|
subnetpool_id=fake_kuryr_subnetpool_id2,
|
||||||
|
cidr=FAKE_IP4_CIDR)
|
||||||
|
# Making existing Neutron subnet has no tag attribute
|
||||||
|
del fake_v4_subnet2['subnet']['tags']
|
||||||
|
|
||||||
|
fake_subnet_response = {
|
||||||
|
'subnets': [
|
||||||
|
fake_v4_subnet2['subnet'],
|
||||||
|
fake_v4_subnet['subnet']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
mock_list_subnets.return_value = fake_subnet_response
|
||||||
|
|
||||||
|
# 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(w_exceptions.InternalServerError.code,
|
||||||
|
response.status_code)
|
||||||
|
mock_list_subnetpools.assert_called_with(
|
||||||
|
id=fake_kuryr_subnetpool_id)
|
||||||
|
mock_list_subnets.assert_called_with(
|
||||||
|
cidr=FAKE_IP4_CIDR)
|
||||||
|
decoded_json = jsonutils.loads(response.data)
|
||||||
|
self.assertIn('Err', decoded_json)
|
||||||
|
self.assertIn(fake_kuryr_subnetpool_id, decoded_json['Err'])
|
||||||
|
self.assertIn(FAKE_IP4_CIDR, decoded_json['Err'])
|
||||||
|
|
||||||
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.create_port')
|
||||||
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnets')
|
||||||
|
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_subnetpools')
|
||||||
|
def test_ipam_driver_request_address_overlapping_cidr_in_kuryr(self,
|
||||||
|
mock_list_subnetpools, mock_list_subnets, mock_create_port):
|
||||||
|
# faking list_subnetpools
|
||||||
|
fake_kuryr_subnetpool_id = uuidutils.generate_uuid()
|
||||||
|
fake_kuryr_subnetpool_id2 = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
fake_name = lib_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)
|
||||||
|
mock_list_subnetpools.return_value = kuryr_subnetpools
|
||||||
|
|
||||||
|
# faking list_subnets
|
||||||
|
docker_endpoint_id = lib_utils.get_hash()
|
||||||
|
neutron_network_id = uuidutils.generate_uuid()
|
||||||
|
neutron_network_id2 = uuidutils.generate_uuid()
|
||||||
|
neutron_subnet_v4_id = uuidutils.generate_uuid()
|
||||||
|
neutron_subnet_v4_id2 = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
fake_v4_subnet = self._get_fake_v4_subnet(
|
||||||
|
neutron_network_id, docker_endpoint_id, neutron_subnet_v4_id,
|
||||||
|
subnetpool_id=fake_kuryr_subnetpool_id,
|
||||||
|
cidr=FAKE_IP4_CIDR,
|
||||||
|
name=utils.make_subnet_name(FAKE_IP4_CIDR))
|
||||||
|
|
||||||
|
fake_v4_subnet2 = self._get_fake_v4_subnet(
|
||||||
|
neutron_network_id2, docker_endpoint_id, neutron_subnet_v4_id2,
|
||||||
|
subnetpool_id=fake_kuryr_subnetpool_id2,
|
||||||
|
cidr=FAKE_IP4_CIDR,
|
||||||
|
name=utils.make_subnet_name(FAKE_IP4_CIDR))
|
||||||
|
|
||||||
|
fake_subnet_response = {
|
||||||
|
'subnets': [
|
||||||
|
fake_v4_subnet2['subnet'],
|
||||||
|
fake_v4_subnet['subnet']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
mock_list_subnets.return_value = fake_subnet_response
|
||||||
|
# faking create_port
|
||||||
|
fake_neutron_port_id = uuidutils.generate_uuid()
|
||||||
|
fake_port = self._get_fake_port(
|
||||||
docker_endpoint_id, neutron_network_id,
|
docker_endpoint_id, neutron_network_id,
|
||||||
fake_neutron_port_id,
|
fake_neutron_port_id,
|
||||||
neutron_subnet_v4_id=neutron_subnet_v4_id,
|
neutron_subnet_v4_id=neutron_subnet_v4_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user