diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py index 06779657b6a..093d7649c25 100644 --- a/neutron/db/l3_db.py +++ b/neutron/db/l3_db.py @@ -103,8 +103,11 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase, @property def _is_dns_integration_supported(self): if self._dns_integration is None: - self._dns_integration = utils.is_extension_supported( - self._core_plugin, 'dns-integration') + self._dns_integration = ( + utils.is_extension_supported(self._core_plugin, + 'dns-integration') or + utils.is_extension_supported(self._core_plugin, + 'dns-domain-ports')) return self._dns_integration @property diff --git a/neutron/extensions/dns_domain_ports.py b/neutron/extensions/dns_domain_ports.py new file mode 100644 index 00000000000..3abd147114e --- /dev/null +++ b/neutron/extensions/dns_domain_ports.py @@ -0,0 +1,60 @@ +# Copyright (c) 2017 IBM +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from neutron_lib.api import converters +from neutron_lib.api import extensions + +from neutron.extensions import dns + + +EXTENDED_ATTRIBUTES_2_0 = { + 'ports': { + dns.DNSDOMAIN: {'allow_post': True, 'allow_put': True, + 'default': '', + 'convert_to': + converters.convert_string_to_case_insensitive, + 'validate': {'type:dns_domain': dns.FQDN_MAX_LEN}, + 'is_visible': True}, + }, +} + + +class Dns_domain_ports(extensions.ExtensionDescriptor): + """Extension class supporting dns_domain attribute for ports.""" + + @classmethod + def get_name(cls): + return "dns_domain for ports" + + @classmethod + def get_alias(cls): + return "dns-domain-ports" + + @classmethod + def get_description(cls): + return "Allows the DNS domain to be specified for a network port." + + @classmethod + def get_updated(cls): + return "2017-06-25T18:00:00-00:00" + + def get_required_extensions(self): + return ["dns-integration"] + + def get_extended_resources(self, version): + if version == "2.0": + return EXTENDED_ATTRIBUTES_2_0 + else: + return {} diff --git a/neutron/plugins/ml2/extensions/dns_integration.py b/neutron/plugins/ml2/extensions/dns_integration.py index a7293ce1ca1..cab66b558e1 100644 --- a/neutron/plugins/ml2/extensions/dns_integration.py +++ b/neutron/plugins/ml2/extensions/dns_integration.py @@ -320,6 +320,17 @@ class DNSExtensionDriverML2(DNSExtensionDriver): return True +class DNSDomainPortsExtensionDriver(DNSExtensionDriverML2): + _supported_extension_alias = 'dns-domain-ports' + + @property + def extension_alias(self): + return self._supported_extension_alias + + def initialize(self): + LOG.info(_LI("DNSDomainPortsExtensionDriver initialization complete")) + + DNS_DRIVER = None diff --git a/neutron/tests/unit/plugins/ml2/extensions/test_dns_integration.py b/neutron/tests/unit/plugins/ml2/extensions/test_dns_integration.py index fa7a5db3559..e87853abe29 100644 --- a/neutron/tests/unit/plugins/ml2/extensions/test_dns_integration.py +++ b/neutron/tests/unit/plugins/ml2/extensions/test_dns_integration.py @@ -62,7 +62,8 @@ class DNSIntegrationTestCase(test_plugin.Ml2PluginV2TestCase): config.cfg.CONF.set_override('dns_domain', self._domain) def _create_port_for_test(self, provider_net=True, dns_domain=True, - dns_name=True, ipv4=True, ipv6=True): + dns_name=True, ipv4=True, ipv6=True, + dns_domain_port=False): net_kwargs = {} if provider_net: net_kwargs = { @@ -91,6 +92,10 @@ class DNSIntegrationTestCase(test_plugin.Ml2PluginV2TestCase): 'arg_list': (dns.DNSNAME,), dns.DNSNAME: DNSNAME } + if dns_domain_port: + port_kwargs[dns.DNSDOMAIN] = self._port_domain + port_kwargs['arg_list'] = (port_kwargs.get('arg_list', ()) + + (dns.DNSDOMAIN,)) res = self._create_port('json', network['network']['id'], **port_kwargs) self.assertEqual(201, res.status_int) @@ -528,6 +533,19 @@ class DNSIntegrationTestCaseDefaultDomain(DNSIntegrationTestCase): self._verify_port_dns(net, port, dns_data_db) +@mock.patch( + 'neutron.services.externaldns.drivers.designate.driver.get_clients', + **mock_config) +class DNSDomainPortsTestCase(DNSIntegrationTestCase): + _extension_drivers = ['dns_domain_ports'] + _domain = 'domain.com.' + _port_domain = 'portdomain.com.' + + def test_create_port(self, *mocks): + net, port, dns_data_db = self._create_port_for_test( + dns_domain_port=True) + + class TestDesignateClientKeystoneV2(testtools.TestCase): """Test case for designate clients """ diff --git a/setup.cfg b/setup.cfg index f6aaed9c053..f8985f4bda3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -106,6 +106,7 @@ neutron.ml2.extension_drivers = qos = neutron.plugins.ml2.extensions.qos:QosExtensionDriver dns = neutron.plugins.ml2.extensions.dns_integration:DNSExtensionDriverML2 data_plane_status = neutron.plugins.ml2.extensions.data_plane_status:DataPlaneStatusExtensionDriver + dns_domain_ports = neutron.plugins.ml2.extensions.dns_integration:DNSDomainPortsExtensionDriver neutron.ipam_drivers = fake = neutron.tests.unit.ipam.fake_driver:FakeDriver internal = neutron.ipam.drivers.neutrondb_ipam.driver:NeutronDbPool