Add API mac learning extension for NVP
This commit adds an API extension for NVP where the NVP supported mac learning feature can be switched on/off for a specific port. The attribute can be True or False or omitted altogether. Implements blueprint nvp-mac-learning-extension Change-Id: I9173c7dfe0cf4a9ee7b0605722ce7fa01708f5ba
This commit is contained in:
parent
9105172d46
commit
82ccdf893e
@ -41,6 +41,7 @@
|
||||
"create_port:fixed_ips": "rule:admin_or_network_owner",
|
||||
"create_port:port_security_enabled": "rule:admin_or_network_owner",
|
||||
"create_port:binding:host_id": "rule:admin_only",
|
||||
"create_port:mac_learning_enabled": "rule:admin_or_network_owner",
|
||||
"get_port": "rule:admin_or_owner",
|
||||
"get_port:queue_id": "rule:admin_only",
|
||||
"get_port:binding:vif_type": "rule:admin_only",
|
||||
@ -51,6 +52,7 @@
|
||||
"update_port:fixed_ips": "rule:admin_or_network_owner",
|
||||
"update_port:port_security_enabled": "rule:admin_or_network_owner",
|
||||
"update_port:binding:host_id": "rule:admin_only",
|
||||
"update_port:mac_learning_enabled": "rule:admin_or_network_owner",
|
||||
"delete_port": "rule:admin_or_owner",
|
||||
|
||||
"create_service_type": "rule:admin_only",
|
||||
|
@ -0,0 +1,60 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""nvp_mac_learning
|
||||
|
||||
Revision ID: 3cbf70257c28
|
||||
Revises: 176a85fc7d79
|
||||
Create Date: 2013-05-15 10:15:50.875314
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '3cbf70257c28'
|
||||
down_revision = '176a85fc7d79'
|
||||
|
||||
# Change to ['*'] if this migration applies to all plugins
|
||||
|
||||
migration_for_plugins = [
|
||||
'quantum.plugins.nicira.QuantumPlugin.NvpPluginV2'
|
||||
]
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
from quantum.db import migration
|
||||
|
||||
|
||||
def upgrade(active_plugin=None, options=None):
|
||||
if not migration.should_run(active_plugin, migration_for_plugins):
|
||||
return
|
||||
|
||||
op.create_table(
|
||||
'maclearningstates',
|
||||
sa.Column('port_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('mac_learning_enabled', sa.Boolean(), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
['port_id'], ['ports.id'], ondelete='CASCADE'),
|
||||
sa.PrimaryKeyConstraint('port_id'))
|
||||
|
||||
|
||||
def downgrade(active_plugin=None, options=None):
|
||||
if not migration.should_run(active_plugin, migration_for_plugins):
|
||||
return
|
||||
|
||||
op.drop_table('maclearningstates')
|
@ -57,6 +57,8 @@ from quantum.plugins.nicira.common import config # noqa
|
||||
from quantum.plugins.nicira.common import exceptions as nvp_exc
|
||||
from quantum.plugins.nicira.common import metadata_access as nvp_meta
|
||||
from quantum.plugins.nicira.common import securitygroups as nvp_sec
|
||||
from quantum.plugins.nicira.dbexts import maclearning as mac_db
|
||||
from quantum.plugins.nicira.extensions import maclearning as mac_ext
|
||||
from quantum.plugins.nicira.extensions import nvp_networkgw as networkgw
|
||||
from quantum.plugins.nicira.extensions import nvp_qos as ext_qos
|
||||
from quantum.plugins.nicira import nicira_db
|
||||
@ -125,6 +127,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
l3_db.L3_NAT_db_mixin,
|
||||
portsecurity_db.PortSecurityDbMixin,
|
||||
securitygroups_db.SecurityGroupDbMixin,
|
||||
mac_db.MacLearningDbMixin,
|
||||
networkgw_db.NetworkGatewayMixin,
|
||||
qos_db.NVPQoSDbMixin,
|
||||
nvp_sec.NVPSecurityGroups,
|
||||
@ -136,7 +139,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
functionality using NVP.
|
||||
"""
|
||||
|
||||
supported_extension_aliases = ["network-gateway",
|
||||
supported_extension_aliases = ["mac-learning",
|
||||
"network-gateway",
|
||||
"nvp-qos",
|
||||
"port-security",
|
||||
"provider",
|
||||
@ -363,7 +367,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
port_data['fixed_ips'],
|
||||
port_data[psec.PORTSECURITY],
|
||||
port_data[ext_sg.SECURITYGROUPS],
|
||||
port_data[ext_qos.QUEUE])
|
||||
port_data[ext_qos.QUEUE],
|
||||
port_data.get(mac_ext.MAC_LEARNING))
|
||||
|
||||
def _nvp_create_port(self, context, port_data):
|
||||
"""Driver for creating a logical switch port on NVP platform."""
|
||||
@ -1056,6 +1061,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
context, filters)
|
||||
for quantum_lport in quantum_lports:
|
||||
self._extend_port_port_security_dict(context, quantum_lport)
|
||||
self._extend_port_mac_learning_state(context, quantum_lport)
|
||||
if (filters.get('network_id') and len(filters.get('network_id')) and
|
||||
self._network_is_external(context, filters['network_id'][0])):
|
||||
# Do not perform check on NVP platform
|
||||
@ -1192,6 +1198,10 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
port_data[ext_qos.QUEUE] = self._check_for_queue_and_create(
|
||||
context, port_data)
|
||||
self._process_port_queue_mapping(context, port_data)
|
||||
if (isinstance(port_data.get(mac_ext.MAC_LEARNING), bool)):
|
||||
self._create_mac_learning_state(context, port_data)
|
||||
elif mac_ext.MAC_LEARNING in port_data:
|
||||
port_data.pop(mac_ext.MAC_LEARNING)
|
||||
# provider networking extension checks
|
||||
# Fetch the network and network binding from Quantum db
|
||||
try:
|
||||
@ -1274,6 +1284,17 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
|
||||
ret_port[ext_qos.QUEUE] = self._check_for_queue_and_create(
|
||||
context, ret_port)
|
||||
# Populate the mac learning attribute
|
||||
new_mac_learning_state = port['port'].get(mac_ext.MAC_LEARNING)
|
||||
old_mac_learning_state = self._get_mac_learning_state(context, id)
|
||||
if (new_mac_learning_state is not None and
|
||||
old_mac_learning_state != new_mac_learning_state):
|
||||
self._update_mac_learning_state(context, id,
|
||||
new_mac_learning_state)
|
||||
ret_port[mac_ext.MAC_LEARNING] = new_mac_learning_state
|
||||
elif (new_mac_learning_state is None and
|
||||
old_mac_learning_state is not None):
|
||||
ret_port[mac_ext.MAC_LEARNING] = old_mac_learning_state
|
||||
self._delete_port_queue_mapping(context, ret_port['id'])
|
||||
self._process_port_queue_mapping(context, ret_port)
|
||||
self._extend_port_port_security_dict(context, ret_port)
|
||||
@ -1291,7 +1312,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
ret_port['fixed_ips'],
|
||||
ret_port[psec.PORTSECURITY],
|
||||
ret_port[ext_sg.SECURITYGROUPS],
|
||||
ret_port[ext_qos.QUEUE])
|
||||
ret_port[ext_qos.QUEUE],
|
||||
ret_port.get(mac_ext.MAC_LEARNING))
|
||||
|
||||
# Update the port status from nvp. If we fail here hide it
|
||||
# since the port was successfully updated but we were not
|
||||
@ -1365,6 +1387,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
id, fields)
|
||||
self._extend_port_port_security_dict(context, quantum_db_port)
|
||||
self._extend_port_qos_queue(context, quantum_db_port)
|
||||
self._extend_port_mac_learning_state(context, quantum_db_port)
|
||||
|
||||
if self._network_is_external(context,
|
||||
quantum_db_port['network_id']):
|
||||
|
0
quantum/plugins/nicira/dbexts/__init__.py
Normal file
0
quantum/plugins/nicira/dbexts/__init__.py
Normal file
73
quantum/plugins/nicira/dbexts/maclearning.py
Normal file
73
quantum/plugins/nicira/dbexts/maclearning.py
Normal file
@ -0,0 +1,73 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 VMware, Inc. 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.
|
||||
#
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
from quantum.db import model_base
|
||||
from quantum.openstack.common import log as logging
|
||||
from quantum.plugins.nicira.extensions import maclearning as mac
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MacLearningState(model_base.BASEV2):
|
||||
|
||||
port_id = sa.Column(sa.String(36),
|
||||
sa.ForeignKey('ports.id', ondelete="CASCADE"),
|
||||
primary_key=True)
|
||||
mac_learning_enabled = sa.Column(sa.Boolean(), nullable=False)
|
||||
|
||||
|
||||
class MacLearningDbMixin(object):
|
||||
"""Mixin class for mac learning."""
|
||||
|
||||
def _make_mac_learning_state_dict(self, port, fields=None):
|
||||
res = {'port_id': port['port_id'],
|
||||
mac.MAC_LEARNING: port[mac.MAC_LEARNING]}
|
||||
return self._fields(res, fields)
|
||||
|
||||
def _get_mac_learning_state(self, context, port_id):
|
||||
try:
|
||||
query = self._model_query(context, MacLearningState)
|
||||
state = query.filter(MacLearningState.port_id == port_id).one()
|
||||
except exc.NoResultFound:
|
||||
return None
|
||||
return state[mac.MAC_LEARNING]
|
||||
|
||||
def _extend_port_mac_learning_state(self, context, port):
|
||||
state = self._get_mac_learning_state(context, port['id'])
|
||||
if state:
|
||||
port[mac.MAC_LEARNING] = state
|
||||
|
||||
def _update_mac_learning_state(self, context, port_id, enabled):
|
||||
try:
|
||||
query = self._model_query(context, MacLearningState)
|
||||
state = query.filter(MacLearningState.port_id == port_id).one()
|
||||
state.update({mac.MAC_LEARNING: enabled})
|
||||
except exc.NoResultFound:
|
||||
self._create_mac_learning_state(context,
|
||||
{'id': port_id,
|
||||
mac.MAC_LEARNING: enabled})
|
||||
|
||||
def _create_mac_learning_state(self, context, port):
|
||||
with context.session.begin(subtransactions=True):
|
||||
enabled = port[mac.MAC_LEARNING]
|
||||
state = MacLearningState(port_id=port['id'],
|
||||
mac_learning_enabled=enabled)
|
||||
context.session.add(state)
|
||||
return self._make_mac_learning_state_dict(state)
|
65
quantum/plugins/nicira/extensions/maclearning.py
Normal file
65
quantum/plugins/nicira/extensions/maclearning.py
Normal file
@ -0,0 +1,65 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2013 Nicira Networks, Inc. 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 quantum.api.v2 import attributes
|
||||
|
||||
|
||||
MAC_LEARNING = 'mac_learning_enabled'
|
||||
EXTENDED_ATTRIBUTES_2_0 = {
|
||||
'ports': {
|
||||
MAC_LEARNING: {'allow_post': True, 'allow_put': True,
|
||||
'convert_to': attributes.convert_to_boolean,
|
||||
'default': attributes.ATTR_NOT_SPECIFIED,
|
||||
'is_visible': True},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Maclearning(object):
|
||||
"""Extension class supporting port security."""
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
return "MAC Learning"
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
return "mac-learning"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return "Provides mac learning capabilities"
|
||||
|
||||
@classmethod
|
||||
def get_namespace(cls):
|
||||
return "http://docs.openstack.org/ext/maclearning/api/v1.0"
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
return "2013-05-1T10:00:00-00:00"
|
||||
|
||||
@classmethod
|
||||
def get_resources(cls):
|
||||
"""Returns Ext Resources."""
|
||||
return []
|
||||
|
||||
def get_extended_resources(self, version):
|
||||
if version == "2.0":
|
||||
return EXTENDED_ATTRIBUTES_2_0
|
||||
else:
|
||||
return {}
|
@ -738,7 +738,8 @@ def get_port(cluster, network, port, relations=None):
|
||||
|
||||
|
||||
def _configure_extensions(lport_obj, mac_address, fixed_ips,
|
||||
port_security_enabled, security_profiles, queue_id):
|
||||
port_security_enabled, security_profiles,
|
||||
queue_id, mac_learning_enabled):
|
||||
lport_obj['allowed_address_pairs'] = []
|
||||
if port_security_enabled:
|
||||
for fixed_ip in fixed_ips:
|
||||
@ -753,12 +754,16 @@ def _configure_extensions(lport_obj, mac_address, fixed_ips,
|
||||
"ip_address": "0.0.0.0"})
|
||||
lport_obj['security_profiles'] = list(security_profiles or [])
|
||||
lport_obj['queue_uuid'] = queue_id
|
||||
if mac_learning_enabled is not None:
|
||||
lport_obj["mac_learning"] = mac_learning_enabled
|
||||
lport_obj["type"] = "LogicalSwitchPortConfig"
|
||||
|
||||
|
||||
def update_port(cluster, lswitch_uuid, lport_uuid, quantum_port_id, tenant_id,
|
||||
display_name, device_id, admin_status_enabled,
|
||||
mac_address=None, fixed_ips=None, port_security_enabled=None,
|
||||
security_profiles=None, queue_id=None):
|
||||
security_profiles=None, queue_id=None,
|
||||
mac_learning_enabled=None):
|
||||
# device_id can be longer than 40 so we rehash it
|
||||
hashed_device_id = hashlib.sha1(device_id).hexdigest()
|
||||
lport_obj = dict(
|
||||
@ -771,7 +776,7 @@ def update_port(cluster, lswitch_uuid, lport_uuid, quantum_port_id, tenant_id,
|
||||
|
||||
_configure_extensions(lport_obj, mac_address, fixed_ips,
|
||||
port_security_enabled, security_profiles,
|
||||
queue_id)
|
||||
queue_id, mac_learning_enabled)
|
||||
|
||||
path = "/ws.v1/lswitch/" + lswitch_uuid + "/lport/" + lport_uuid
|
||||
try:
|
||||
@ -791,7 +796,8 @@ def update_port(cluster, lswitch_uuid, lport_uuid, quantum_port_id, tenant_id,
|
||||
def create_lport(cluster, lswitch_uuid, tenant_id, quantum_port_id,
|
||||
display_name, device_id, admin_status_enabled,
|
||||
mac_address=None, fixed_ips=None, port_security_enabled=None,
|
||||
security_profiles=None, queue_id=None):
|
||||
security_profiles=None, queue_id=None,
|
||||
mac_learning_enabled=None):
|
||||
"""Creates a logical port on the assigned logical switch."""
|
||||
# device_id can be longer than 40 so we rehash it
|
||||
hashed_device_id = hashlib.sha1(device_id).hexdigest()
|
||||
@ -807,7 +813,7 @@ def create_lport(cluster, lswitch_uuid, tenant_id, quantum_port_id,
|
||||
|
||||
_configure_extensions(lport_obj, mac_address, fixed_ips,
|
||||
port_security_enabled, security_profiles,
|
||||
queue_id)
|
||||
queue_id, mac_learning_enabled)
|
||||
|
||||
path = _build_uri_path(LSWITCHPORT_RESOURCE,
|
||||
parent_resource_id=lswitch_uuid)
|
||||
|
141
quantum/tests/unit/nicira/test_maclearning.py
Normal file
141
quantum/tests/unit/nicira/test_maclearning.py
Normal file
@ -0,0 +1,141 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (c) 2013 OpenStack Foundation.
|
||||
# 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.
|
||||
|
||||
import contextlib
|
||||
import mock
|
||||
import os
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from quantum.api.v2 import attributes
|
||||
from quantum.common.test_lib import test_config
|
||||
from quantum import context
|
||||
from quantum.extensions import agent
|
||||
from quantum.openstack.common import log as logging
|
||||
import quantum.plugins.nicira as nvp_plugin
|
||||
from quantum.tests.unit.nicira import fake_nvpapiclient
|
||||
from quantum.tests.unit import test_db_plugin
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
NVP_MODULE_PATH = nvp_plugin.__name__
|
||||
NVP_FAKE_RESPS_PATH = os.path.join(os.path.dirname(__file__), 'etc')
|
||||
NVP_INI_CONFIG_PATH = os.path.join(os.path.dirname(__file__),
|
||||
'etc/nvp.ini.full.test')
|
||||
NVP_EXTENSIONS_PATH = os.path.join(os.path.dirname(__file__),
|
||||
'../../../plugins/nicira/extensions')
|
||||
|
||||
|
||||
class MacLearningExtensionManager(object):
|
||||
|
||||
def get_resources(self):
|
||||
# Add the resources to the global attribute map
|
||||
# This is done here as the setup process won't
|
||||
# initialize the main API router which extends
|
||||
# the global attribute map
|
||||
attributes.RESOURCE_ATTRIBUTE_MAP.update(
|
||||
agent.RESOURCE_ATTRIBUTE_MAP)
|
||||
return agent.Agent.get_resources()
|
||||
|
||||
def get_actions(self):
|
||||
return []
|
||||
|
||||
def get_request_extensions(self):
|
||||
return []
|
||||
|
||||
|
||||
class MacLearningDBTestCase(test_db_plugin.QuantumDbPluginV2TestCase):
|
||||
fmt = 'json'
|
||||
|
||||
def setUp(self):
|
||||
self.adminContext = context.get_admin_context()
|
||||
test_config['config_files'] = [NVP_INI_CONFIG_PATH]
|
||||
test_config['plugin_name_v2'] = (
|
||||
'quantum.plugins.nicira.QuantumPlugin.NvpPluginV2')
|
||||
cfg.CONF.set_override('api_extensions_path',
|
||||
NVP_EXTENSIONS_PATH)
|
||||
# Save the original RESOURCE_ATTRIBUTE_MAP
|
||||
self.saved_attr_map = {}
|
||||
for resource, attrs in attributes.RESOURCE_ATTRIBUTE_MAP.iteritems():
|
||||
self.saved_attr_map[resource] = attrs.copy()
|
||||
ext_mgr = MacLearningExtensionManager()
|
||||
test_config['extension_manager'] = ext_mgr
|
||||
# mock nvp api client
|
||||
self.fc = fake_nvpapiclient.FakeClient(NVP_FAKE_RESPS_PATH)
|
||||
self.mock_nvpapi = mock.patch('%s.NvpApiClient.NVPApiHelper'
|
||||
% NVP_MODULE_PATH, autospec=True)
|
||||
instance = self.mock_nvpapi.start()
|
||||
|
||||
def _fake_request(*args, **kwargs):
|
||||
return self.fc.fake_request(*args, **kwargs)
|
||||
|
||||
# Emulate tests against NVP 2.x
|
||||
instance.return_value.get_nvp_version.return_value = "2.999"
|
||||
instance.return_value.request.side_effect = _fake_request
|
||||
cfg.CONF.set_override('metadata_mode', None, 'NVP')
|
||||
self.addCleanup(self.fc.reset_all)
|
||||
self.addCleanup(self.mock_nvpapi.stop)
|
||||
self.addCleanup(self.restore_resource_attribute_map)
|
||||
self.addCleanup(cfg.CONF.reset)
|
||||
super(MacLearningDBTestCase, self).setUp()
|
||||
|
||||
def restore_resource_attribute_map(self):
|
||||
# Restore the original RESOURCE_ATTRIBUTE_MAP
|
||||
attributes.RESOURCE_ATTRIBUTE_MAP = self.saved_attr_map
|
||||
|
||||
def test_create_with_mac_learning(self):
|
||||
with self.port(arg_list=('mac_learning_enabled',),
|
||||
mac_learning_enabled=True) as port:
|
||||
req = self.new_show_request('ports', port['port']['id'], self.fmt)
|
||||
sport = self.deserialize(self.fmt, req.get_response(self.api))
|
||||
self.assertTrue(sport['port']['mac_learning_enabled'])
|
||||
|
||||
def test_create_port_without_mac_learning(self):
|
||||
with self.port() as port:
|
||||
req = self.new_show_request('ports', port['port']['id'], self.fmt)
|
||||
sport = self.deserialize(self.fmt, req.get_response(self.api))
|
||||
self.assertNotIn('mac_learning', sport['port'])
|
||||
|
||||
def test_update_port_with_mac_learning(self):
|
||||
with self.port(arg_list=('mac_learning_enabled',),
|
||||
mac_learning_enabled=False) as port:
|
||||
data = {'port': {'mac_learning_enabled': True}}
|
||||
req = self.new_update_request('ports', data, port['port']['id'])
|
||||
res = self.deserialize(self.fmt, req.get_response(self.api))
|
||||
self.assertTrue(res['port']['mac_learning_enabled'])
|
||||
|
||||
def test_update_preexisting_port_with_mac_learning(self):
|
||||
with self.port() as port:
|
||||
req = self.new_show_request('ports', port['port']['id'], self.fmt)
|
||||
sport = self.deserialize(self.fmt, req.get_response(self.api))
|
||||
self.assertNotIn('mac_learning_enabled', sport['port'])
|
||||
data = {'port': {'mac_learning_enabled': True}}
|
||||
req = self.new_update_request('ports', data, port['port']['id'])
|
||||
res = self.deserialize(self.fmt, req.get_response(self.api))
|
||||
self.assertTrue(res['port']['mac_learning_enabled'])
|
||||
|
||||
def test_list_ports(self):
|
||||
# for this test we need to enable overlapping ips
|
||||
cfg.CONF.set_default('allow_overlapping_ips', True)
|
||||
with contextlib.nested(self.port(arg_list=('mac_learning_enabled',),
|
||||
mac_learning_enabled=True),
|
||||
self.port(arg_list=('mac_learning_enabled',),
|
||||
mac_learning_enabled=True),
|
||||
self.port(arg_list=('mac_learning_enabled',),
|
||||
mac_learning_enabled=True)):
|
||||
for port in self._list('ports')['ports']:
|
||||
self.assertTrue(port['mac_learning_enabled'])
|
Loading…
x
Reference in New Issue
Block a user