diff --git a/octavia/network/drivers/neutron/allowed_address_pairs.py b/octavia/network/drivers/neutron/allowed_address_pairs.py index 71db462ca1..d00f941d9e 100644 --- a/octavia/network/drivers/neutron/allowed_address_pairs.py +++ b/octavia/network/drivers/neutron/allowed_address_pairs.py @@ -56,8 +56,7 @@ class AllowedAddressPairsDriver(neutron_base.BaseNeutronDriver): ) def _check_aap_loaded(self): - aliases = [ext.get('alias') for ext in self._extensions] - if AAP_EXT_ALIAS not in aliases: + if not self._check_extension_enabled(AAP_EXT_ALIAS): raise base.NetworkException( 'The {alias} extension is not enabled in neutron. This ' 'driver cannot be used with the {alias} extension ' @@ -433,9 +432,16 @@ class AllowedAddressPairsDriver(neutron_base.BaseNeutronDriver): for port in ports: try: - self.neutron_client.update_port(port.id, - {'port': {'device_id': '', - 'dns_name': ''}}) + + if self.dns_integration_enabled: + self.neutron_client.update_port(port.id, + {'port': {'device_id': '', + 'dns_name': ''}}) + else: + self.neutron_client.update_port(port.id, + {'port': + {'device_id': ''}}) + except (neutron_client_exceptions.NotFound, neutron_client_exceptions.PortNotFoundClient): raise base.PortNotFound() diff --git a/octavia/network/drivers/neutron/base.py b/octavia/network/drivers/neutron/base.py index 0a3553c669..f460fa973f 100644 --- a/octavia/network/drivers/neutron/base.py +++ b/octavia/network/drivers/neutron/base.py @@ -25,6 +25,7 @@ from octavia.network.drivers.neutron import utils LOG = logging.getLogger(__name__) +DNS_INT_EXT_ALIAS = 'dns-integration' SEC_GRP_EXT_ALIAS = 'security-group' CONF = cfg.CONF @@ -34,7 +35,6 @@ CONF.import_group('neutron', 'octavia.common.config') class BaseNeutronDriver(base.AbstractNetworkDriver): def __init__(self): - self.sec_grp_enabled = True self.neutron_client = clients.NeutronAuth.get_neutron_client( endpoint=CONF.neutron.endpoint, region=CONF.neutron.region_name, @@ -43,16 +43,20 @@ class BaseNeutronDriver(base.AbstractNetworkDriver): insecure=CONF.neutron.insecure, ca_cert=CONF.neutron.ca_certificates_file ) - extensions = self.neutron_client.list_extensions() - self._extensions = extensions.get('extensions') - self._check_sec_grps() + self.sec_grp_enabled = self._check_extension_enabled(SEC_GRP_EXT_ALIAS) + self.dns_integration_enabled = self._check_extension_enabled( + DNS_INT_EXT_ALIAS) - def _check_sec_grps(self): - aliases = [ext.get('alias') for ext in self._extensions] - if SEC_GRP_EXT_ALIAS not in aliases: - LOG.info(_LI('Neutron security groups are disabled. This driver ' - 'will not manage any security groups.')) - self.sec_grp_enabled = False + def _check_extension_enabled(self, extension_alias): + try: + self.neutron_client.show_extension(extension_alias) + LOG.info(_LI('Neutron extension {ext} found enabled').format( + ext=extension_alias)) + return True + except neutron_client_exceptions.NotFound: + LOG.info(_LI('Neutron extension {ext} is not enabled').format( + ext=extension_alias)) + return False def _port_to_vip(self, port, load_balancer): fixed_ip = None diff --git a/octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py b/octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py index a31438292b..2346be0e47 100644 --- a/octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py +++ b/octavia/tests/unit/network/drivers/neutron/test_allowed_address_pairs.py @@ -70,8 +70,9 @@ class TestAllowedAddressPairsDriver(base.TestCase): 'octavia.common.keystone.get_session').start() self.driver = allowed_address_pairs.AllowedAddressPairsDriver() - def test_check_aap_loaded(self): - self.driver._extensions = [{'alias': 'blah'}] + @mock.patch('octavia.network.drivers.neutron.base.BaseNeutronDriver.' + '_check_extension_enabled', return_value=False) + def test_check_aap_loaded(self, mock_check_ext): self.assertRaises(network_base.NetworkException, self.driver._check_aap_loaded) @@ -542,6 +543,8 @@ class TestAllowedAddressPairsDriver(base.TestCase): delete_rule.assert_called_once_with('ssh-rule') def test_failover_preparation(self): + original_dns_integration_state = self.driver.dns_integration_enabled + self.driver.dns_integration_enabled = False ports = {"ports": [ {"fixed_ips": [{"subnet_id": self.SUBNET_ID_1, "ip_address": self.IP_ADDRESS_1}], @@ -559,9 +562,34 @@ class TestAllowedAddressPairsDriver(base.TestCase): lb_network_ip=self.LB_NET_IP, ha_port_id=self.HA_PORT_ID, ha_ip=self.HA_IP) self.driver.failover_preparation(amphora) + port_update.assert_called_once_with(ports['ports'][1].get('id'), + {'port': {'device_id': ''}}) + self.driver.dns_integration_enabled = original_dns_integration_state + + def test_failover_preparation_dns_integration(self): + ports = {"ports": [ + {"fixed_ips": [{"subnet_id": self.SUBNET_ID_1, + "ip_address": self.IP_ADDRESS_1}], + "id": self.FIXED_IP_ID_1, "network_id": self.NETWORK_ID_1}, + {"fixed_ips": [{"subnet_id": self.SUBNET_ID_2, + "ip_address": self.IP_ADDRESS_2}], + "id": self.FIXED_IP_ID_2, "network_id": self.NETWORK_ID_2}]} + original_dns_integration_state = self.driver.dns_integration_enabled + self.driver.dns_integration_enabled = True + self.driver.neutron_client.list_ports.return_value = ports + self.driver.neutron_client.show_port = mock.Mock( + side_effect=self._failover_show_port_side_effect) + port_update = self.driver.neutron_client.update_port + amphora = data_models.Amphora( + id=self.AMPHORA_ID, load_balancer_id=self.LB_ID, + compute_id=self.COMPUTE_ID, status=self.ACTIVE, + lb_network_ip=self.LB_NET_IP, ha_port_id=self.HA_PORT_ID, + ha_ip=self.HA_IP) + self.driver.failover_preparation(amphora) port_update.assert_called_once_with(ports['ports'][1].get('id'), {'port': {'dns_name': '', - 'device_id': ''}}) + 'device_id': ''}}) + self.driver.dns_integration_enabled = original_dns_integration_state def _failover_show_port_side_effect(self, port_id): if port_id == self.LB_NET_PORT_ID: diff --git a/octavia/tests/unit/network/drivers/neutron/test_base.py b/octavia/tests/unit/network/drivers/neutron/test_base.py index 796237a356..ed224857ad 100644 --- a/octavia/tests/unit/network/drivers/neutron/test_base.py +++ b/octavia/tests/unit/network/drivers/neutron/test_base.py @@ -13,6 +13,7 @@ # under the License. import mock +from neutronclient.common import exceptions as neutron_client_exceptions from octavia.common import clients from octavia.common import data_models @@ -51,6 +52,13 @@ class TestBaseNeutronNetworkDriver(base.TestCase): self.driver = self._instantiate_partial_abc( neutron_base.BaseNeutronDriver) + def test__check_extension_enabled(self): + show_extension = self.driver.neutron_client.show_extension + show_extension.side_effect = [None, neutron_client_exceptions.NotFound] + + self.assertTrue(self.driver._check_extension_enabled('TEST')) + self.assertFalse(self.driver._check_extension_enabled('TEST')) + def test__port_to_vip(self): lb = dmh.generate_load_balancer_tree() lb.vip.subnet_id = n_constants.MOCK_SUBNET_ID @@ -99,13 +107,6 @@ class TestBaseNeutronNetworkDriver(base.TestCase): [port1['fixed_ips'][0]['ip_address'], port2['fixed_ips'][0]['ip_address']]) - def test_sec_grps_extension_check(self): - self.driver._check_sec_grps() - self.assertTrue(self.driver.sec_grp_enabled) - self.driver._extensions = [{'alias': 'blah'}] - self.driver._check_sec_grps() - self.assertFalse(self.driver.sec_grp_enabled) - def test_get_network(self): show_network = self.driver.neutron_client.show_network show_network.return_value = {'network': {