diff --git a/kuryr_libnetwork/controllers.py b/kuryr_libnetwork/controllers.py index 1e2a2673..3c292826 100644 --- a/kuryr_libnetwork/controllers.py +++ b/kuryr_libnetwork/controllers.py @@ -42,6 +42,7 @@ LOG = log.getLogger(__name__) MANDATORY_NEUTRON_EXTENSION = "subnet_allocation" TAG_NEUTRON_EXTENSION = "tag" +TAG_EXT_NEUTRON_EXTENSION = "tag-ext" SUBNET_POOLS_V4 = [] SUBNET_POOLS_V6 = [] @@ -71,16 +72,20 @@ def check_for_neutron_ext_support(): .format(MANDATORY_NEUTRON_EXTENSION)) -def check_for_neutron_ext_tag(): - """Validates for tags extension support availability in neutron.""" - app.tag = True +def check_for_neutron_tag_support(ext_name): + """Validates tag and tag-ext extension support availability in Neutron.""" + if ext_name == TAG_EXT_NEUTRON_EXTENSION: + ext_rename = "tag_ext" + else: + ext_rename = ext_name + setattr(app, ext_rename, True) try: - app.neutron.show_extension(TAG_NEUTRON_EXTENSION) + app.neutron.show_extension(ext_name) except n_exceptions.NeutronClientException as e: - app.tag = False + setattr(app, ext_rename, False) if e.status_code == n_exceptions.NotFound.status_code: - app.logger.warning(_LW("Neutron tags not supported. " - "Continue without using them.")) + app.logger.warning(_LW("Neutron extension %s not supported. " + "Continue without using them."), ext_name) def load_default_subnet_pools(): @@ -1458,34 +1463,27 @@ def ipam_release_pool(): pool_id = json_data['PoolID'] # Remove subnetpool_id tag from Neutron existing subnet. - if app.tag: - 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']: - pools = _get_subnetpools_by_attrs(id=pool_id) - if pools: - pool = pools[0] - prefixes = pool['prefixes'] - if len(prefixes) > 1: - app.logger.warning(_LW("More than one prefixes present. " - "Picking first one.")) - for prefix in prefixes: - subnet_cidr = ipaddress.ip_network(six.text_type(prefix)) - break - else: - raise exceptions.NoResourceException( - "No subnetpools with id {0} is found." - .format(pool_id)) - subnets_by_cidr = _get_subnets_by_attrs( - cidr=six.text_type(subnet_cidr)) - for tmp_subnet in subnets_by_cidr: - if pool_id in tmp_subnet.get('tags', []): - _neutron_subnet_remove_tag(tmp_subnet['id'], pool_id) - break + if app.tag_ext: + pools = _get_subnetpools_by_attrs(id=pool_id) + if pools: + pool = pools[0] + prefixes = pool['prefixes'] + if len(prefixes) > 1: + app.logger.warning(_LW("More than one prefixes present. " + "Picking first one.")) + for prefix in prefixes: + subnet_cidr = ipaddress.ip_network(six.text_type(prefix)) + break + else: + raise exceptions.NoResourceException( + "No subnetpools with id {0} is found." + .format(pool_id)) + subnets_by_cidr = _get_subnets_by_attrs( + cidr=six.text_type(subnet_cidr)) + for tmp_subnet in subnets_by_cidr: + if pool_id in tmp_subnet.get('tags', []): + _neutron_subnet_remove_tag(tmp_subnet['id'], pool_id) + break try: app.neutron.delete_subnetpool(pool_id) except n_exceptions.Conflict as ex: diff --git a/kuryr_libnetwork/server.py b/kuryr_libnetwork/server.py index daa02dc2..26786b1a 100644 --- a/kuryr_libnetwork/server.py +++ b/kuryr_libnetwork/server.py @@ -26,7 +26,10 @@ def configure_app(): log.setup(config.CONF, 'kuryr') controllers.neutron_client() controllers.check_for_neutron_ext_support() - controllers.check_for_neutron_ext_tag() + controllers.check_for_neutron_tag_support( + controllers.TAG_NEUTRON_EXTENSION) + controllers.check_for_neutron_tag_support( + controllers.TAG_EXT_NEUTRON_EXTENSION) controllers.load_default_subnet_pools() controllers.load_port_driver() diff --git a/kuryr_libnetwork/tests/unit/base.py b/kuryr_libnetwork/tests/unit/base.py index 55aa91df..05ea655b 100644 --- a/kuryr_libnetwork/tests/unit/base.py +++ b/kuryr_libnetwork/tests/unit/base.py @@ -39,6 +39,7 @@ class TestCase(base.BaseTestCase): self.app.neutron = client.Client(token=TOKEN, endpoint_url=ENDURL) app.driver = mock.Mock(spec=driver.Driver) app.tag = True + app.tag_ext = True class TestKuryrBase(TestCase): diff --git a/kuryr_libnetwork/tests/unit/test_config.py b/kuryr_libnetwork/tests/unit/test_config.py index b5037eb1..8aa3117d 100644 --- a/kuryr_libnetwork/tests/unit/test_config.py +++ b/kuryr_libnetwork/tests/unit/test_config.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +import ddt import mock import os from six.moves.urllib import parse @@ -24,6 +25,7 @@ from kuryr_libnetwork.server import start from kuryr_libnetwork.tests.unit import base +@ddt.ddt class ConfigurationTest(base.TestKuryrBase): def test_defaults(self): @@ -46,18 +48,22 @@ class ConfigurationTest(base.TestKuryrBase): config.CONF.port_driver) @mock.patch.object(sys, 'argv', return_value='[]') - @mock.patch('kuryr_libnetwork.controllers.check_for_neutron_ext_tag') + @mock.patch('kuryr_libnetwork.controllers.check_for_neutron_tag_support') @mock.patch('kuryr_libnetwork.controllers.check_for_neutron_ext_support') @mock.patch('kuryr_libnetwork.controllers.neutron_client') @mock.patch('kuryr_libnetwork.app.run') def test_start(self, mock_run, mock_neutron_client, - mock_check_neutron_ext_support, mock_check_neutron_ext_tag, + mock_check_neutron_ext_support, + mock_check_for_neutron_tag_support, mock_sys_argv): start() kuryr_uri = parse.urlparse(config.CONF.kuryr_uri) mock_neutron_client.assert_called_once() mock_check_neutron_ext_support.assert_called_once() - mock_check_neutron_ext_tag.assert_called_once() + mock_check_for_neutron_tag_support.assert_any_call( + controllers.TAG_NEUTRON_EXTENSION) + mock_check_for_neutron_tag_support.assert_any_call( + controllers.TAG_EXT_NEUTRON_EXTENSION) mock_run.assert_called_once_with(kuryr_uri.hostname, 23750, ssl_context=None) @@ -73,3 +79,30 @@ class ConfigurationTest(base.TestKuryrBase): ex = exceptions.MandatoryApiMissing self.assertRaises(ex, controllers.check_for_neutron_ext_support) mock_extension.assert_called_once_with(ext_alias) + + @mock.patch('kuryr_libnetwork.controllers.app.neutron.show_extension') + @ddt.data('tag', 'tag-ext') + def test_check_for_neutron_tag_support_with_ex(self, + ext_name, + mock_extension): + err = n_exceptions.NotFound.status_code + ext_not_found_ex = n_exceptions.NeutronClientException( + status_code=err, + message="") + mock_extension.side_effect = ext_not_found_ex + controllers.check_for_neutron_tag_support(ext_name) + mock_extension.assert_called_once_with(ext_name) + + @mock.patch('kuryr_libnetwork.controllers.app.neutron.show_extension') + @ddt.data('fake_ext') + def test_check_for_neutron_tag_support_wrong_ext_name_with_ex( + self, + ext_name, + mock_extension): + err = n_exceptions.NotFound.status_code + ext_not_found_ex = n_exceptions.NeutronClientException( + status_code=err, + message="") + mock_extension.side_effect = ext_not_found_ex + controllers.check_for_neutron_tag_support(ext_name) + mock_extension.assert_called_once_with(ext_name) diff --git a/kuryr_libnetwork/tests/unit/test_kuryr_ipam.py b/kuryr_libnetwork/tests/unit/test_kuryr_ipam.py index 20e94c28..da6ad417 100644 --- a/kuryr_libnetwork/tests/unit/test_kuryr_ipam.py +++ b/kuryr_libnetwork/tests/unit/test_kuryr_ipam.py @@ -172,24 +172,16 @@ class TestKuryrIpam(base.TestKuryrBase): @mock.patch('kuryr_libnetwork.controllers.app.neutron.remove_tag') @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.show_extension') @mock.patch('kuryr_libnetwork.controllers.app') @ddt.data((True), (False)) def test_ipam_driver_release_pool(self, - use_tags, - mock_tag, - mock_show_extension, + use_tag_ext, + mock_app, mock_list_subnetpools, mock_list_subnets, mock_remove_tag, mock_delete_subnetpool): - mock_tag.tag = use_tags - fake_tag_extension = { - "extension": - {"alias": "tag", "updated": "mock_time", - "name": "Tag support", "links": [], - "description": "mock tag on resources ['subnet', 'network']."}} - mock_show_extension.return_value = fake_tag_extension + mock_app.tag_ext = use_tag_ext fake_kuryr_subnetpool_id = uuidutils.generate_uuid() fake_subnetpool_name = lib_utils.get_neutron_subnetpool_name( @@ -223,8 +215,7 @@ class TestKuryrIpam(base.TestKuryrBase): data=jsonutils.dumps(fake_request)) self.assertEqual(200, response.status_code) - if mock_tag.tag: - mock_show_extension.assert_called_with("tag") + if mock_app.tag_ext: mock_list_subnetpools.assert_called_with( id=fake_kuryr_subnetpool_id) mock_list_subnets.assert_called_with(