Merge "ovsfw: Raise exception if tag cannot be found in other_config" into stable/newton

This commit is contained in:
Jenkins 2017-04-02 03:13:51 +00:00 committed by Gerrit Code Review
commit a580459f8a
7 changed files with 120 additions and 31 deletions

View File

@ -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")

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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()