[AIM] Move code from policy driver to mechanism driver

Move the nova_client module from the aim_mapping policy driver to the
apic_aim mechanism driver. The HAIP model class and code are not moved
in this back-port because they are shared with the legacy drivers in
stable/newton. Moving (actually copying) the HAIP code (but not model
class) to the mechanism driver may be addressed in a later patch.

(cherry picked from commit 389740089c)
Conflicts:
	gbpservice/neutron/db/all_models.py
	gbpservice/neutron/plugins/ml2plus/drivers/apic_aim/rpc.py
	gbpservice/neutron/services/grouppolicy/drivers/cisco/apic/aim_mapping_rpc.py
	gbpservice/neutron/tests/unit/plugins/ml2plus/test_db_apic_aim.py

Change-Id: Ie1798dbe07d9da8206a202ab15c4982342855823
This commit is contained in:
Robert Kukura 2019-02-21 11:03:03 -05:00
parent c627aaf2f0
commit 847ee64aa7
11 changed files with 99 additions and 34 deletions

View File

@ -26,10 +26,10 @@ from oslo_log import log
from oslo_utils import importutils
from gbpservice._i18n import _LW
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import (
nova_client as nclient)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
apic_mapping as amap)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
nova_client as nclient)
LOG = log.getLogger(__name__)

View File

@ -87,6 +87,9 @@ class VMNameUpdate(model_base.BASEV2):
class DbMixin(object):
# AddressScopeMapping functions.
def _add_address_scope_mapping(self, session, scope_id, vrf,
vrf_owned=True, update_scope=True):
mapping = AddressScopeMapping(
@ -151,6 +154,8 @@ class DbMixin(object):
tenant_name=mapping.vrf_tenant_name,
name=mapping.vrf_name)
# NetworkMapping functions.
def _add_network_mapping(self, session, network_id, bd, epg, vrf,
ext_net=None, update_network=True):
if not ext_net:
@ -302,6 +307,8 @@ class DbMixin(object):
mapping.vrf_tenant_name = vrf.tenant_name
mapping.vrf_name = vrf.name
# VMName functions.
def _get_vm_name(self, session, device_id, is_detailed=False):
if is_detailed:
query = BAKERY(lambda s: s.query(VMName))
@ -334,6 +341,8 @@ class DbMixin(object):
if db_obj:
session.delete(db_obj)
# VMNameUpdate functions.
def _get_vm_name_update(self, session):
query = BAKERY(lambda s: s.query(VMNameUpdate))
return query(session).one_or_none()

View File

@ -86,10 +86,9 @@ from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import config # noqa
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import db
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import exceptions
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import extension_db
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import nova_client
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import rpc
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import trunk_driver
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
nova_client as nclient)
LOG = log.getLogger(__name__)
@ -284,7 +283,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
self.apic_nova_vm_name_cache_update_interval * 10):
is_full_update = False
nova_vms = nclient.NovaClient().get_servers(
nova_vms = nova_client.NovaClient().get_servers(
is_full_update, self.apic_nova_vm_name_cache_update_interval * 10)
# This means Nova API has thrown an exception
if nova_vms is None:

View File

@ -45,7 +45,8 @@ from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import constants
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import db
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import extension_db
# REVISIT: This should be moved to the mechanism driver.
# REVISIT: This has been moved to the mechanism driver in stable/ocata
# and newer, but not yet in stable/newton.
from apic_ml2.neutron.db import port_ha_ipaddress_binding as ha_ip_db
LOG = log.getLogger(__name__)
@ -204,14 +205,6 @@ class ApicRpcHandlerMixin(object):
return conn.consume_in_threads()
# The following five methods handle RPCs from the Opflex agent.
#
# REVISIT: These handler methods are currently called by
# corresponding handler methods in the aim_mapping_rpc
# module. Once these RPC handlers are all fully implemented and
# tested, move the instantiation of the
# opflexagent.rpc.GBPServerRpcCallback class from aim_mapping_rpc
# to this module and eliminate the other RPC handler
# implementations.
def get_gbp_details(self, context, **kwargs):
LOG.debug("APIC AIM MD handling get_gbp_details for: %s", kwargs)
@ -285,9 +278,15 @@ class ApicRpcHandlerMixin(object):
def ip_address_owner_update(self, context, **kwargs):
LOG.debug("APIC AIM MD handling ip_address_owner_update for: %s",
kwargs)
# REVISIT: Move actual handler implementation to this class.
if self.gbp_driver:
self.gbp_driver.ip_address_owner_update(context, **kwargs)
if not kwargs.get('ip_owner_info'):
return
if not self.gbp_driver:
return
ports_to_update = self.gbp_driver.update_ip_owner(
kwargs['ip_owner_info'])
for p in ports_to_update:
LOG.debug("APIC ownership update for port %s", p)
self._notify_port_update(context, p)
@db_api.retry_if_session_inactive()
def _get_vrf_details(self, context, vrf_id):

View File

@ -48,6 +48,7 @@ from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import (
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import (
mechanism_driver as md)
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import apic_mapper
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import nova_client
from gbpservice.neutron.services.grouppolicy.common import (
constants as gp_const)
from gbpservice.neutron.services.grouppolicy.common import constants as g_const
@ -61,8 +62,6 @@ from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
aim_validation)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
apic_mapping_lib as alib)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
nova_client as nclient)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import config # noqa
from gbpservice.neutron.services.grouppolicy import plugin as gbp_plugin
@ -1153,7 +1152,7 @@ class AIMMappingDriver(nrd.CommonNeutronBase, aim_rpc.AIMMappingRPCMixin):
context._plugin_context, l2p['l3_policy_id'])
if l3p.get('allowed_vm_names'):
ok_to_bind = False
vm = nclient.NovaClient().get_server(port['device_id'])
vm = nova_client.NovaClient().get_server(port['device_id'])
for allowed_vm_name in l3p['allowed_vm_names']:
match = re.search(allowed_vm_name, vm.name)
if match:

View File

@ -53,6 +53,8 @@ from gbpservice.network.neutronv2 import local_api
from gbpservice.neutron.db.grouppolicy.extensions import apic_reuse_bd_db
from gbpservice.neutron.db.grouppolicy import group_policy_mapping_db as gpdb
from gbpservice.neutron.extensions import group_policy as gpolicy
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import (
nova_client as nclient)
from gbpservice.neutron.plugins.ml2plus.drivers.apic_aim import cache
from gbpservice.neutron.services.grouppolicy.common import constants as g_const
from gbpservice.neutron.services.grouppolicy.common import exceptions as gpexc
@ -63,8 +65,6 @@ from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
apic_mapping_lib as alib)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
name_manager as name_manager)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
nova_client as nclient)
from gbpservice.neutron.services.grouppolicy import group_policy_context
from gbpservice.neutron.services.grouppolicy import plugin as gbp_plugin

View File

@ -246,8 +246,8 @@ class ApicAimTestCase(test_address_scope.AddressScopeTestCase,
def setUp(self, mechanism_drivers=None, tenant_network_types=None,
plugin=None, ext_mgr=None):
self.nova_client = mock.patch(
'gbpservice.neutron.services.grouppolicy.drivers.cisco.'
'apic.nova_client.NovaClient.get_servers').start()
'gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.'
'nova_client.NovaClient.get_servers').start()
self.nova_client.return_value = []
# Enable the test mechanism driver to ensure that
# we can successfully call through to all mechanism
@ -8522,3 +8522,48 @@ class TestOpflexRpc(ApicAimTestCase):
# REVISIT: Test with missing request, missing device, invalid
# device prefix, unbindable port, port bound to wrong host.
# REVISIT: This test cannot be enabled in stable/newton until the
# HAIP code is moved to the MD, as the PD is not configured in
# these tests.
#
# def test_ip_address_owner_update(self):
# self._register_agent('h1', AGENT_CONF_OPFLEX)
# self._register_agent('h2', AGENT_CONF_OPFLEX)
#
# net = self._make_network(self.fmt, 'net1', True)
# net_id = net['network']['id']
#
# self._make_subnet(self.fmt, net, '10.0.1.1', '10.0.1.0/24')
#
# port1_id = self._make_port(self.fmt, net_id)['port']['id']
# port2_id = self._make_port(self.fmt, net_id)['port']['id']
#
# self._bind_port_to_host(port1_id, 'h1')
# self._bind_port_to_host(port2_id, 'h2')
#
# ip_owner_info = {'port': port1_id, 'ip_address_v4': '1.2.3.4'}
# self.driver._notify_port_update = mock.Mock()
#
# # Set new owner and check.
# self.driver.ip_address_owner_update(
# n_context.get_admin_context(), ip_owner_info=ip_owner_info,
# host='h1')
# obj = self.driver.get_port_for_ha_ipaddress('1.2.3.4', net_id)
# self.assertEqual(port1_id, obj['port_id'])
# self.driver._notify_port_update.assert_called_with(
# mock.ANY, port1_id)
#
# # Update existing owner and check.
# self.driver._notify_port_update.reset_mock()
# ip_owner_info['port'] = port2_id
# self.driver.ip_address_owner_update(
# n_context.get_admin_context(), ip_owner_info=ip_owner_info,
# host='h2')
# obj = self.driver.get_port_for_ha_ipaddress('1.2.3.4', net_id)
# self.assertEqual(port2_id, obj['port_id'])
# exp_calls = [
# mock.call(mock.ANY, port1_id),
# mock.call(mock.ANY, port2_id)]
# self._check_call_list(exp_calls,
# self.driver._notify_port_update.call_args_list)

View File

@ -0,0 +1,14 @@
# 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.
# REVISIT: Copy the PortToHAIPAddressBindingTestCase class here from
# stable/ocata when moving/copying the HAIP code to the MD.

View File

@ -124,8 +124,8 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
def setUp(self, policy_drivers=None, core_plugin=None, ml2_options=None,
l3_plugin=None, sc_plugin=None, trunk_plugin=None, **kwargs):
self.nova_client1 = mock.patch(
'gbpservice.neutron.services.grouppolicy.drivers.cisco.'
'apic.nova_client.NovaClient.get_servers').start()
'gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.'
'nova_client.NovaClient.get_servers').start()
self.nova_client1.return_value = []
core_plugin = core_plugin or ML2PLUS_PLUGIN
if not l3_plugin:
@ -186,8 +186,8 @@ class AIMBaseTestCase(test_nr_base.CommonNeutronBaseTestCase,
self._name_mapper = None
self._driver = None
nova_client = mock.patch(
'gbpservice.neutron.services.grouppolicy.drivers.cisco.'
'apic.nova_client.NovaClient.get_server').start()
'gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.'
'nova_client.NovaClient.get_server').start()
vm = mock.Mock()
vm.name = 'someid'
nova_client.return_value = vm
@ -3844,8 +3844,8 @@ class TestPolicyTarget(AIMBaseTestCase,
policy_target_group_id=ptg['id'])['policy_target']
nova_client = mock.patch(
'gbpservice.neutron.services.grouppolicy.drivers.cisco.'
'apic.nova_client.NovaClient.get_server').start()
'gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.'
'nova_client.NovaClient.get_server').start()
vm = mock.Mock()
vm.name = 'secure_vm1'
nova_client.return_value = vm

View File

@ -134,8 +134,8 @@ class ApicMappingTestCase(
'apic.apic_mapping.ApicMappingDriver.'
'_setup_keystone_notification_listeners').start()
nova_client = mock.patch(
'gbpservice.neutron.services.grouppolicy.drivers.cisco.'
'apic.nova_client.NovaClient.get_server').start()
'gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.'
'nova_client.NovaClient.get_server').start()
vm = mock.Mock()
vm.name = 'someid'
nova_client.return_value = vm
@ -1880,8 +1880,8 @@ class TestPolicyTargetDvs(ApicMappingTestCase):
policy_target_group_id=ptg['id'])['policy_target']
nova_client = mock.patch(
'gbpservice.neutron.services.grouppolicy.drivers.cisco.'
'apic.nova_client.NovaClient.get_server').start()
'gbpservice.neutron.plugins.ml2plus.drivers.apic_aim.'
'nova_client.NovaClient.get_server').start()
vm = mock.Mock()
vm.name = 'secure_vm1'
nova_client.return_value = vm