Adds provisioning block to APIC_AIM mech driver
This is per design from: https://docs.openstack.org/neutron/pike/contributor/internals/provisioning_blocks.html Change-Id: Ie5e866cc65235f4775fd076fc4bfcf1f73fce928
This commit is contained in:
parent
70731da6f2
commit
3c6ecad766
|
@ -26,6 +26,7 @@ from aim.common import utils
|
|||
from aim import context as aim_context
|
||||
from aim import utils as aim_utils
|
||||
from neutron.agent import securitygroups_rpc
|
||||
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
|
||||
|
@ -35,6 +36,7 @@ from neutron.db.models import l3 as l3_db
|
|||
from neutron.db.models import securitygroup as sg_models
|
||||
from neutron.db.models import segment as segments_model
|
||||
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
|
||||
|
@ -83,6 +85,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,
|
||||
|
@ -1500,8 +1505,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
|
||||
|
@ -1593,6 +1597,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
|
||||
|
@ -1612,6 +1640,7 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
context.bottom_bound_segment[api.NETWORK_TYPE])):
|
||||
self._associate_domain(context, is_vmm=True)
|
||||
self._update_sg_rule_with_remote_group_set(context, port)
|
||||
self._insert_provisioning_block(context)
|
||||
|
||||
def update_port_postcommit(self, context):
|
||||
port = context.current
|
||||
|
|
|
@ -34,7 +34,9 @@ from aim import utils as aim_utils
|
|||
from keystoneclient.v3 import client as ksc_client
|
||||
from neutron.api import extensions
|
||||
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 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
|
||||
|
@ -2893,6 +2895,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
|
||||
|
|
Loading…
Reference in New Issue