Merge "Adds provisioning block to APIC_AIM mech driver" into stable/ocata

This commit is contained in:
Zuul 2018-03-01 17:54:56 +00:00 committed by Gerrit Code Review
commit 2a6c279404
2 changed files with 65 additions and 2 deletions

View File

@ -28,6 +28,7 @@ from aim import utils as aim_utils
from neutron.agent import securitygroups_rpc
from neutron.callbacks import events
from neutron.callbacks import registry
from neutron.callbacks import resources
from neutron.common import rpc as n_rpc
from neutron.common import topics as n_topics
from neutron.db import api as db_api
@ -36,6 +37,7 @@ from neutron.db.models import allowed_address_pair as n_addr_pair_db
from neutron.db.models import l3 as l3_db
from neutron.db.models import securitygroup as sg_models
from neutron.db import models_v2
from neutron.db import provisioning_blocks
from neutron.db import rbac_db_models
from neutron.db import segments_db
from neutron.extensions import external_net
@ -90,6 +92,9 @@ L3OUT_NODE_PROFILE_NAME = 'NodeProfile'
L3OUT_IF_PROFILE_NAME = 'IfProfile'
L3OUT_EXT_EPG = 'ExtEpg'
SUPPORTED_VNIC_TYPES = [portbindings.VNIC_NORMAL,
portbindings.VNIC_DIRECT]
AGENT_TYPE_DVS = 'DVS agent'
VIF_TYPE_DVS = 'dvs'
PROMISCUOUS_TYPES = [n_constants.DEVICE_OWNER_DHCP,
@ -1686,8 +1691,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
# Check the VNIC type.
vnic_type = port.get(portbindings.VNIC_TYPE,
portbindings.VNIC_NORMAL)
if vnic_type not in [portbindings.VNIC_NORMAL,
portbindings.VNIC_DIRECT]:
if vnic_type not in SUPPORTED_VNIC_TYPES:
LOG.debug("Refusing to bind due to unsupported vnic_type: %s",
vnic_type)
return
@ -1779,6 +1783,30 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
port = context.current
self._really_update_sg_rule_with_remote_group_set(
context, port, port['security_groups'], is_delete=False)
self._insert_provisioning_block(context)
def _insert_provisioning_block(self, context):
# we insert a status barrier to prevent the port from transitioning
# to active until the agent reports back that the wiring is done
port = context.current
if (not context.host or
port['status'] == n_constants.PORT_STATUS_ACTIVE):
# no point in putting in a block if the status is already ACTIVE
return
# Check the VNIC type.
vnic_type = port.get(portbindings.VNIC_TYPE,
portbindings.VNIC_NORMAL)
if vnic_type not in SUPPORTED_VNIC_TYPES:
LOG.debug("No provisioning_block due to unsupported vnic_type: %s",
vnic_type)
return
if (context.host_agents(ofcst.AGENT_TYPE_OPFLEX_OVS) or
context.host_agents(AGENT_TYPE_DVS)):
provisioning_blocks.add_provisioning_component(
context._plugin_context, port['id'], resources.PORT,
provisioning_blocks.L2_AGENT_ENTITY)
def update_port_precommit(self, context):
port = context.current
@ -1800,6 +1828,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
self._update_sg_rule_with_remote_group_set(context, port)
registry.notify(sfc_cts.GBP_PORT, events.PRECOMMIT_UPDATE,
self, driver_context=context)
self._insert_provisioning_block(context)
def update_port_postcommit(self, context):
port = context.current

View File

@ -35,8 +35,10 @@ from keystoneclient.v3 import client as ksc_client
from neutron.api import extensions
from neutron.callbacks import registry
from neutron.db import api as db_api
from neutron.db import provisioning_blocks
from neutron.db import segments_db
from neutron.plugins.ml2 import config
from neutron.plugins.ml2 import driver_context
from neutron.tests.unit.api import test_extensions
from neutron.tests.unit.db import test_db_base_plugin_v2 as test_plugin
from neutron.tests.unit.extensions import test_address_scope
@ -2928,6 +2930,38 @@ class TestAimMapping(ApicAimTestCase):
is_implicit=True)['subnetpool']
self.assertTrue(sp3['is_implicit'])
def test_dhcp_provisioning_blocks_inserted_on_update(self):
ctx = n_context.get_admin_context()
plugin = directory.get_plugin()
def _fake_dhcp_agent():
agent = mock.Mock()
plugin = directory.get_plugin()
return mock.patch.object(
plugin, 'get_dhcp_agents_hosting_networks',
return_value=[agent]).start()
dhcp_agt_mock = _fake_dhcp_agent()
update_dict = {'binding:host_id': 'newhost'}
def _host_agents(self, agent_type):
if agent_type == ofcst.AGENT_TYPE_OPFLEX_OVS:
fake_agent = {"alive": False}
return [fake_agent]
orig_host_agents = getattr(driver_context.PortContext, "host_agents")
setattr(driver_context.PortContext, "host_agents", _host_agents)
with self.port() as port:
with mock.patch.object(provisioning_blocks,
'add_provisioning_component') as ap:
port['port'].update(update_dict)
plugin.update_port(ctx, port['port']['id'], port)
ap.assert_called()
setattr(driver_context.PortContext, "host_agents", orig_host_agents)
dhcp_agt_mock.stop()
class TestSyncState(ApicAimTestCase):
@staticmethod