Merge "Add subnetpool_id tag for existing Neutron subnet"

This commit is contained in:
Jenkins 2017-01-13 14:24:25 +00:00 committed by Gerrit Code Review
commit b895ee256d
3 changed files with 188 additions and 10 deletions

View File

@ -72,7 +72,7 @@ def check_for_neutron_ext_support():
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
try:
app.neutron.show_extension(TAG_NEUTRON_EXTENSION)
@ -287,6 +287,10 @@ def _neutron_net_remove_tags(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):
if tags:
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}"
"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:
new_subnets = [{
'name': utils.make_subnet_name(pool_cidr),
@ -1315,8 +1331,21 @@ def ipam_request_address():
if subnets_by_cidr:
if len(subnets_by_cidr) > 1:
for tmp_subnet in subnets_by_cidr:
if tmp_subnet.get('subnetpool_id', '') == pool_id:
subnet = tmp_subnet
subnet_name = tmp_subnet.get('name')
# 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:
raise exceptions.KuryrException(
("Subnet with cidr({0}) and pool {1}, does not "

View File

@ -18,6 +18,7 @@ from oslotest import base
from kuryr.lib import constants as lib_const
from kuryr.lib import utils as lib_utils
from kuryr_libnetwork import app
from kuryr_libnetwork import constants as const
from kuryr_libnetwork import controllers
from kuryr_libnetwork.port_driver import driver
from kuryr_libnetwork import utils
@ -233,11 +234,14 @@ class TestKuryrBase(TestCase):
"cidr": '192.168.1.0/24',
"id": subnet_v4_id,
"enable_dhcp": True,
"subnetpool_id": ''
"subnetpool_id": '',
"tags": []
}
}
if 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

View File

@ -14,12 +14,14 @@ import ddt
import mock
from oslo_serialization import jsonutils
from oslo_utils import uuidutils
from werkzeug import exceptions as w_exceptions
from kuryr.lib import constants as lib_const
from kuryr.lib import utils as lib_utils
from kuryr_libnetwork import config
from kuryr_libnetwork import constants as const
from kuryr_libnetwork.tests.unit import base
from kuryr_libnetwork import utils
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.list_subnets')
@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):
# faking list_subnetpools
fake_kuryr_subnetpool_id = 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(
fake_kuryr_subnetpool_id, prefixes=[FAKE_IP4_CIDR],
name=fake_name)
mock_list_subnetpools.return_value = kuryr_subnetpools
# faking list_subnets
mock_list_subnetpools.return_value = kuryr_subnetpools
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,
@ -423,7 +423,152 @@ class TestKuryrIpam(base.TestKuryrBase):
mock_list_subnets.return_value = fake_subnet_response
# faking create_port
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,
fake_neutron_port_id,
neutron_subnet_v4_id=neutron_subnet_v4_id,