Merge "ovsfw: Raise exception if tag cannot be found in other_config" into stable/newton
This commit is contained in:
commit
a580459f8a
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2016, Red Hat, 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 neutron_lib import exceptions
|
||||
|
||||
from neutron._i18n import _
|
||||
|
||||
|
||||
class OVSFWPortNotFound(exceptions.NeutronException):
|
||||
message = _("Port %(port_id)s is not managed by this agent.")
|
||||
|
||||
|
||||
class OVSFWTagNotFound(exceptions.NeutronException):
|
||||
message = _(
|
||||
"Cannot get tag for port %(port_name)s from its other_config: "
|
||||
"%(other_config)s")
|
|
@ -15,13 +15,13 @@
|
|||
|
||||
import netaddr
|
||||
from neutron_lib import constants as lib_const
|
||||
from neutron_lib import exceptions
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import netutils
|
||||
|
||||
from neutron._i18n import _, _LE, _LW
|
||||
from neutron._i18n import _LE
|
||||
from neutron.agent import firewall
|
||||
from neutron.agent.linux.openvswitch_firewall import constants as ovsfw_consts
|
||||
from neutron.agent.linux.openvswitch_firewall import exceptions
|
||||
from neutron.agent.linux.openvswitch_firewall import rules
|
||||
from neutron.common import constants
|
||||
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants \
|
||||
|
@ -55,8 +55,21 @@ def create_reg_numbers(flow_params):
|
|||
_replace_register(flow_params, ovsfw_consts.REG_NET, 'reg_net')
|
||||
|
||||
|
||||
class OVSFWPortNotFound(exceptions.NeutronException):
|
||||
message = _("Port %(port_id)s is not managed by this agent. ")
|
||||
def get_tag_from_other_config(bridge, port_name):
|
||||
"""Return tag stored in OVSDB other_config metadata.
|
||||
|
||||
:param bridge: OVSBridge instance where port is.
|
||||
:param port_name: Name of the port.
|
||||
:raises OVSFWTagNotFound: In case tag cannot be found in OVSDB.
|
||||
"""
|
||||
other_config = None
|
||||
try:
|
||||
other_config = bridge.db_get_val(
|
||||
'Port', port_name, 'other_config')
|
||||
return int(other_config['tag'])
|
||||
except (KeyError, TypeError, ValueError):
|
||||
raise exceptions.OVSFWTagNotFound(
|
||||
port_name=port_name, other_config=other_config)
|
||||
|
||||
|
||||
class SecurityGroup(object):
|
||||
|
@ -243,18 +256,9 @@ class OVSFirewallDriver(firewall.FirewallDriver):
|
|||
except KeyError:
|
||||
ovs_port = self.int_br.br.get_vif_port_by_id(port_id)
|
||||
if not ovs_port:
|
||||
raise OVSFWPortNotFound(port_id=port_id)
|
||||
|
||||
try:
|
||||
other_config = self.int_br.br.db_get_val(
|
||||
'Port', ovs_port.port_name, 'other_config')
|
||||
port_vlan_id = int(other_config['tag'])
|
||||
except (KeyError, TypeError):
|
||||
LOG.warning(_LW("Can't get tag for port %(port_id)s from its "
|
||||
"other_config: %(other_config)s"),
|
||||
port_id=port_id,
|
||||
other_config=other_config)
|
||||
port_vlan_id = ovs_consts.DEAD_VLAN_TAG
|
||||
raise exceptions.OVSFWPortNotFound(port_id=port_id)
|
||||
port_vlan_id = get_tag_from_other_config(
|
||||
self.int_br.br, ovs_port.port_name)
|
||||
of_port = OFPort(port, ovs_port, port_vlan_id)
|
||||
self.sg_port_map.create_port(of_port, port)
|
||||
else:
|
||||
|
|
|
@ -823,17 +823,26 @@ class OVSNeutronAgent(sg_rpc.SecurityGroupAgentRpcCallbackMixin,
|
|||
port_info = self.int_br.get_ports_attributes(
|
||||
"Port", columns=["name", "tag", "other_config"],
|
||||
ports=port_names, if_exists=True)
|
||||
info_by_port = {x['name']: [x['tag'], x['other_config']]
|
||||
for x in port_info}
|
||||
info_by_port = {
|
||||
x['name']: {
|
||||
'tag': x['tag'],
|
||||
'other_config': x['other_config'] or {}
|
||||
}
|
||||
for x in port_info
|
||||
}
|
||||
for port_detail in need_binding_ports:
|
||||
try:
|
||||
lvm = self.vlan_manager.get(port_detail['network_id'])
|
||||
except vlanmanager.MappingNotFound:
|
||||
continue
|
||||
port = port_detail['vif_port']
|
||||
cur_info = info_by_port.get(port.port_name)
|
||||
if cur_info is not None and cur_info[0] != lvm.vlan:
|
||||
other_config = cur_info[1] or {}
|
||||
try:
|
||||
cur_info = info_by_port[port.port_name]
|
||||
except KeyError:
|
||||
continue
|
||||
other_config = cur_info['other_config']
|
||||
if (cur_info['tag'] != lvm.vlan or
|
||||
other_config.get('tag') != lvm.vlan):
|
||||
other_config['tag'] = str(lvm.vlan)
|
||||
self.int_br.set_db_attribute(
|
||||
"Port", port.port_name, "other_config", other_config)
|
||||
|
|
|
@ -374,7 +374,9 @@ class OVSBaseConnectionTester(ConnectionTester):
|
|||
bridge.set_db_attribute('Port', port_name, 'tag', tag)
|
||||
other_config = bridge.db_get_val(
|
||||
'Port', port_name, 'other_config')
|
||||
other_config['tag'] = tag
|
||||
if 'tag' in other_config:
|
||||
return
|
||||
other_config['tag'] = str(tag)
|
||||
bridge.set_db_attribute(
|
||||
'Port', port_name, 'other_config', other_config)
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2016, Red Hat, 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 testtools
|
||||
|
||||
from neutron.agent.linux.openvswitch_firewall import exceptions
|
||||
from neutron.agent.linux.openvswitch_firewall import firewall
|
||||
from neutron.tests.common import net_helpers
|
||||
from neutron.tests.functional import base
|
||||
|
||||
|
||||
class TestGetTagFromOtherConfig(base.BaseSudoTestCase):
|
||||
def setUp(self):
|
||||
super(TestGetTagFromOtherConfig, self).setUp()
|
||||
self.bridge = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
|
||||
|
||||
def set_port_tag(self, port_name, tag):
|
||||
self.bridge.set_db_attribute(
|
||||
'Port', port_name, 'other_config', {'tag': str(tag)})
|
||||
|
||||
def test_correct_tag_is_returned(self):
|
||||
port_number = 42
|
||||
port = self.useFixture(net_helpers.OVSPortFixture(self.bridge)).port
|
||||
self.set_port_tag(port.name, port_number)
|
||||
observed = firewall.get_tag_from_other_config(self.bridge, port.name)
|
||||
self.assertEqual(port_number, observed)
|
||||
|
||||
def test_not_existing_name_raises_exception(self):
|
||||
with testtools.ExpectedException(exceptions.OVSFWTagNotFound):
|
||||
firewall.get_tag_from_other_config(self.bridge, 'foo')
|
||||
|
||||
def test_bad_tag_value_raises_exception(self):
|
||||
port = self.useFixture(net_helpers.OVSPortFixture(self.bridge)).port
|
||||
self.set_port_tag(port.name, 'foo')
|
||||
with testtools.ExpectedException(exceptions.OVSFWTagNotFound):
|
||||
firewall.get_tag_from_other_config(self.bridge, port.name)
|
||||
|
||||
def test_no_value_set_for_other_config_raises_exception(self):
|
||||
port = self.useFixture(net_helpers.OVSPortFixture(self.bridge)).port
|
||||
with testtools.ExpectedException(exceptions.OVSFWTagNotFound):
|
||||
firewall.get_tag_from_other_config(self.bridge, port.name)
|
|
@ -19,6 +19,7 @@ import testtools
|
|||
from neutron.agent.common import ovs_lib
|
||||
from neutron.agent import firewall
|
||||
from neutron.agent.linux.openvswitch_firewall import constants as ovsfw_consts
|
||||
from neutron.agent.linux.openvswitch_firewall import exceptions
|
||||
from neutron.agent.linux.openvswitch_firewall import firewall as ovsfw
|
||||
from neutron.common import constants as n_const
|
||||
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants \
|
||||
|
@ -331,17 +332,9 @@ class TestOVSFirewallDriver(base.BaseTestCase):
|
|||
'device': 'port-id',
|
||||
'security_groups': [123, 456]}
|
||||
self.mock_bridge.br.get_vif_port_by_id.return_value = None
|
||||
with testtools.ExpectedException(ovsfw.OVSFWPortNotFound):
|
||||
with testtools.ExpectedException(exceptions.OVSFWPortNotFound):
|
||||
self.firewall.get_or_create_ofport(port_dict)
|
||||
|
||||
def test_get_or_create_ofport_not_tagged(self):
|
||||
port_dict = {
|
||||
'device': 'port-id',
|
||||
'security_groups': [123, 456]}
|
||||
self.mock_bridge.br.db_get_val.return_value = None
|
||||
port = self.firewall.get_or_create_ofport(port_dict)
|
||||
self.assertEqual(ovs_consts.DEAD_VLAN_TAG, port.vlan_tag)
|
||||
|
||||
def test_is_port_managed_managed_port(self):
|
||||
port_dict = {'device': 'port-id'}
|
||||
self.firewall.sg_port_map.ports[port_dict['device']] = object()
|
||||
|
|
Loading…
Reference in New Issue