# Agent's polling interval in seconds
polling_interval = 2
+# (BoolOpt) Enable server RPC compatibility with old (pre-havana)
+# agents.
+#
+# Default: rpc_support_old_agents = True
+# Example: rpc_support_old_agents = False
+
[SECURITYGROUP]
# Firewall driver for realizing quantum security group function
firewall_driver = quantum.agent.linux.iptables_firewall.IptablesFirewallDriver
return bridge_name
def ensure_physical_in_bridge(self, network_id,
+ network_type,
physical_network,
- vlan_id):
+ segmentation_id):
physical_interface = self.interface_mappings.get(physical_network)
if not physical_interface:
LOG.error(_("No mapping for physical network %s"),
physical_network)
return
- if int(vlan_id) == lconst.FLAT_VLAN_ID:
+ if network_type == lconst.TYPE_FLAT:
return self.ensure_flat_bridge(network_id, physical_interface)
- else:
+ elif network_type == lconst.TYPE_VLAN:
return self.ensure_vlan_bridge(network_id, physical_interface,
- vlan_id)
+ segmentation_id)
+ else:
+ LOG.error(_("Unknown network_type %(network_type)s for network "
+ "%(network_id)s."), {network_type: network_type,
+ network_id: network_id})
- def add_tap_interface(self, network_id, physical_network, vlan_id,
- tap_device_name):
+ def add_tap_interface(self, network_id, network_type, physical_network,
+ segmentation_id, tap_device_name):
"""Add tap interface.
If a VIF has been plugged into a network, this function will
return False
bridge_name = self.get_bridge_name(network_id)
- if int(vlan_id) == lconst.LOCAL_VLAN_ID:
+ if network_type == lconst.TYPE_LOCAL:
self.ensure_local_bridge(network_id)
elif not self.ensure_physical_in_bridge(network_id,
+ network_type,
physical_network,
- vlan_id):
+ segmentation_id):
return False
# Check if device needs to be added to bridge
LOG.debug(msg)
return True
- def add_interface(self, network_id, physical_network, vlan_id,
- port_id):
+ def add_interface(self, network_id, network_type, physical_network,
+ segmentation_id, port_id):
tap_device_name = self.get_tap_device_name(port_id)
- return self.add_tap_interface(network_id,
- physical_network, vlan_id,
+ return self.add_tap_interface(network_id, network_type,
+ physical_network, segmentation_id,
tap_device_name)
def delete_vlan_bridge(self, bridge_name):
self.sg_agent.refresh_firewall()
if port['admin_state_up']:
- vlan_id = kwargs.get('vlan_id')
+ network_type = kwargs.get('network_type')
+ if network_type:
+ segmentation_id = kwargs.get('segmentation_id')
+ else:
+ # compatibility with pre-Havana RPC vlan_id encoding
+ vlan_id = kwargs.get('vlan_id')
+ (network_type,
+ segmentation_id) = lconst.interpret_vlan_id(vlan_id)
physical_network = kwargs.get('physical_network')
# create the networking for the port
self.agent.br_mgr.add_interface(port['network_id'],
+ network_type,
physical_network,
- vlan_id,
+ segmentation_id,
port['id'])
# update plugin about port status
self.agent.plugin_rpc.update_device_up(self.context,
{'device': device, 'details': details})
if details['admin_state_up']:
# create the networking for the port
+ network_type = details.get('network_type')
+ if network_type:
+ segmentation_id = details.get('segmentation_id')
+ else:
+ # compatibility with pre-Havana RPC vlan_id encoding
+ vlan_id = details.get('vlan_id')
+ (network_type,
+ segmentation_id) = lconst.interpret_vlan_id(vlan_id)
self.br_mgr.add_interface(details['network_id'],
+ network_type,
details['physical_network'],
- details['vlan_id'],
+ segmentation_id,
details['port_id'])
else:
self.remove_port_binding(details['network_id'],
cfg.IntOpt('polling_interval', default=2,
help=_("The number of seconds the agent will wait between "
"polling for local device changes.")),
+ #TODO(rkukura): Change default to False before havana rc1
+ cfg.BoolOpt('rpc_support_old_agents', default=True,
+ help=_("Enable server RPC compatibility with old agents")),
]
TYPE_VLAN = 'vlan'
TYPE_LOCAL = 'local'
TYPE_NONE = 'none'
+
+
+# TODO(rkukura): Eventually remove this function, which provides
+# temporary backward compatibility with pre-Havana RPC and DB vlan_id
+# encoding.
+def interpret_vlan_id(vlan_id):
+ """Return (network_type, segmentation_id) tuple for encoded vlan_id."""
+ if vlan_id == LOCAL_VLAN_ID:
+ return (TYPE_LOCAL, None)
+ elif vlan_id == FLAT_VLAN_ID:
+ return (TYPE_FLAT, None)
+ else:
+ return (TYPE_VLAN, vlan_id)
if port:
binding = db.get_network_binding(db_api.get_session(),
port['network_id'])
+ (network_type,
+ segmentation_id) = constants.interpret_vlan_id(binding.vlan_id)
entry = {'device': device,
+ 'network_type': network_type,
'physical_network': binding.physical_network,
- 'vlan_id': binding.vlan_id,
+ 'segmentation_id': segmentation_id,
'network_id': port['network_id'],
'port_id': port['id'],
'admin_state_up': port['admin_state_up']}
+ if cfg.CONF.AGENT.rpc_support_old_agents:
+ entry['vlan_id'] = binding.vlan_id
new_status = (q_const.PORT_STATUS_ACTIVE if port['admin_state_up']
else q_const.PORT_STATUS_DOWN)
if port['status'] != new_status:
topic=self.topic_network_delete)
def port_update(self, context, port, physical_network, vlan_id):
- self.fanout_cast(context,
- self.make_msg('port_update',
- port=port,
- physical_network=physical_network,
- vlan_id=vlan_id),
+ network_type, segmentation_id = constants.interpret_vlan_id(vlan_id)
+ kwargs = {'port': port,
+ 'network_type': network_type,
+ 'physical_network': physical_network,
+ 'segmentation_id': segmentation_id}
+ if cfg.CONF.AGENT.rpc_support_old_agents:
+ kwargs['vlan_id'] = vlan_id
+ msg = self.make_msg('port_update', **kwargs)
+ self.fanout_cast(context, msg,
topic=self.topic_port_update)
def test_defaults(self):
self.assertEqual(2,
cfg.CONF.AGENT.polling_interval)
+ self.assertEqual(True,
+ cfg.CONF.AGENT.rpc_support_old_agents)
self.assertEqual('sudo',
cfg.CONF.AGENT.root_helper)
self.assertEqual('local',
def test_ensure_physical_in_bridge_invalid(self):
result = self.linux_bridge.ensure_physical_in_bridge('network_id',
+ lconst.TYPE_VLAN,
'physnetx',
7)
self.assertFalse(result)
with mock.patch.object(self.linux_bridge,
'ensure_flat_bridge') as flat_bridge_func:
self.linux_bridge.ensure_physical_in_bridge(
- 'network_id', 'physnet1', lconst.FLAT_VLAN_ID)
+ 'network_id', lconst.TYPE_FLAT, 'physnet1', None)
self.assertTrue(flat_bridge_func.called)
def test_ensure_physical_in_bridge_vlan(self):
with mock.patch.object(self.linux_bridge,
'ensure_vlan_bridge') as vlan_bridge_func:
self.linux_bridge.ensure_physical_in_bridge(
- 'network_id', 'physnet1', 7)
+ 'network_id', lconst.TYPE_VLAN, 'physnet1', 7)
self.assertTrue(vlan_bridge_func.called)
def test_ensure_physical_in_bridge(self):
self.assertFalse(
- self.lbm.ensure_physical_in_bridge("123", "phys", "1")
+ self.lbm.ensure_physical_in_bridge("123", lconst.TYPE_VLAN,
+ "phys", "1")
)
with mock.patch.object(self.lbm, "ensure_flat_bridge") as flbr_fn:
self.assertTrue(
- self.lbm.ensure_physical_in_bridge("123", "physnet1", "-1")
+ self.lbm.ensure_physical_in_bridge("123", lconst.TYPE_FLAT,
+ "physnet1", None)
)
self.assertTrue(flbr_fn.called)
with mock.patch.object(self.lbm, "ensure_vlan_bridge") as vlbr_fn:
self.assertTrue(
- self.lbm.ensure_physical_in_bridge("123", "physnet1", "1")
+ self.lbm.ensure_physical_in_bridge("123", lconst.TYPE_VLAN,
+ "physnet1", "1")
)
self.assertTrue(vlbr_fn.called)
with mock.patch.object(self.lbm, "device_exists") as de_fn:
de_fn.return_value = False
self.assertFalse(
- self.lbm.add_tap_interface("123", "physnet1", "1", "tap1")
+ self.lbm.add_tap_interface("123", lconst.TYPE_VLAN,
+ "physnet1", "1", "tap1")
)
de_fn.return_value = True
) as (en_fn, exec_fn, get_br):
exec_fn.return_value = False
get_br.return_value = True
- self.assertTrue(self.lbm.add_tap_interface("123", "physnet1",
- "-2", "tap1"))
+ self.assertTrue(self.lbm.add_tap_interface("123",
+ lconst.TYPE_LOCAL,
+ "physnet1", None,
+ "tap1"))
en_fn.assert_called_with("123")
get_br.return_value = False
exec_fn.return_value = True
- self.assertFalse(self.lbm.add_tap_interface("123", "physnet1",
- "-2", "tap1"))
+ self.assertFalse(self.lbm.add_tap_interface("123",
+ lconst.TYPE_LOCAL,
+ "physnet1", None,
+ "tap1"))
with mock.patch.object(self.lbm,
"ensure_physical_in_bridge") as ens_fn:
ens_fn.return_value = False
- self.assertFalse(self.lbm.add_tap_interface("123", "physnet1",
- "1", "tap1"))
+ self.assertFalse(self.lbm.add_tap_interface("123",
+ lconst.TYPE_VLAN,
+ "physnet1", "1",
+ "tap1"))
def test_add_interface(self):
with mock.patch.object(self.lbm, "add_tap_interface") as add_tap:
- self.lbm.add_interface("123", "physnet-1", "1", "234")
- add_tap.assert_called_with("123", "physnet-1", "1", "tap234")
+ self.lbm.add_interface("123", lconst.TYPE_VLAN, "physnet-1",
+ "1", "234")
+ add_tap.assert_called_with("123", lconst.TYPE_VLAN, "physnet-1",
+ "1", "tap234")
def test_delete_vlan_bridge(self):
with contextlib.nested(
self.lb_rpc.port_update("unused_context", port=port,
vlan_id="1", physical_network="physnet1")
self.assertFalse(reffw_fn.called)
- addif_fn.assert_called_with(port["network_id"],
+ addif_fn.assert_called_with(port["network_id"], lconst.TYPE_VLAN,
"physnet1", "1", port["id"])
+ self.lb_rpc.port_update("unused_context", port=port,
+ network_type=lconst.TYPE_VLAN,
+ segmentation_id="2",
+ physical_network="physnet1")
+ self.assertFalse(reffw_fn.called)
+ addif_fn.assert_called_with(port["network_id"], lconst.TYPE_VLAN,
+ "physnet1", "2", port["id"])
+
+ self.lb_rpc.port_update("unused_context", port=port,
+ vlan_id=lconst.FLAT_VLAN_ID,
+ physical_network="physnet1")
+ self.assertFalse(reffw_fn.called)
+ addif_fn.assert_called_with(port["network_id"], lconst.TYPE_FLAT,
+ "physnet1", None, port["id"])
+
+ self.lb_rpc.port_update("unused_context", port=port,
+ network_type=lconst.TYPE_FLAT,
+ segmentation_id=None,
+ physical_network="physnet1")
+ self.assertFalse(reffw_fn.called)
+ addif_fn.assert_called_with(port["network_id"], lconst.TYPE_FLAT,
+ "physnet1", None, port["id"])
+
+ self.lb_rpc.port_update("unused_context", port=port,
+ vlan_id=lconst.LOCAL_VLAN_ID,
+ physical_network=None)
+ self.assertFalse(reffw_fn.called)
+ addif_fn.assert_called_with(port["network_id"], lconst.TYPE_LOCAL,
+ None, None, port["id"])
+
+ self.lb_rpc.port_update("unused_context", port=port,
+ network_type=lconst.TYPE_LOCAL,
+ segmentation_id=None,
+ physical_network=None)
+ self.assertFalse(reffw_fn.called)
+ addif_fn.assert_called_with(port["network_id"], lconst.TYPE_LOCAL,
+ None, None, port["id"])
+
port["admin_state_up"] = False
port["security_groups"] = True
getbr_fn.return_value = "br0"
Unit Tests for linuxbridge rpc
"""
+from oslo.config import cfg
import stubout
from quantum.agent import rpc as agent_rpc
class rpcApiTestCase(base.BaseTestCase):
-
- def _test_lb_api(self, rpcapi, topic, method, rpc_method, **kwargs):
+ def _test_lb_api(self, rpcapi, topic, method, rpc_method,
+ expected_msg=None, **kwargs):
ctxt = context.RequestContext('fake_user', 'fake_project')
expected_retval = 'foo' if method == 'call' else None
- expected_msg = rpcapi.make_msg(method, **kwargs)
+ if not expected_msg:
+ expected_msg = rpcapi.make_msg(method, **kwargs)
expected_msg['version'] = rpcapi.BASE_RPC_API_VERSION
if rpc_method == 'cast' and method == 'run_instance':
kwargs['call'] = False
retval = getattr(rpcapi, method)(ctxt, **kwargs)
- self.assertEqual(retval, expected_retval)
+ self.assertEqual(expected_retval, retval)
expected_args = [ctxt, topic, expected_msg]
for arg, expected_arg in zip(self.fake_args, expected_args):
- self.assertEqual(arg, expected_arg)
+ self.assertEqual(expected_arg, arg)
def test_delete_network(self):
rpcapi = plb.AgentNotifierApi(topics.AGENT)
network_id='fake_request_spec')
def test_port_update(self):
+ cfg.CONF.set_override('rpc_support_old_agents', False, 'AGENT')
+ rpcapi = plb.AgentNotifierApi(topics.AGENT)
+ expected_msg = rpcapi.make_msg('port_update',
+ port='fake_port',
+ network_type='vlan',
+ physical_network='fake_net',
+ segmentation_id='fake_vlan_id')
+ self._test_lb_api(rpcapi,
+ topics.get_topic_name(topics.AGENT,
+ topics.PORT,
+ topics.UPDATE),
+ 'port_update', rpc_method='fanout_cast',
+ expected_msg=expected_msg,
+ port='fake_port',
+ physical_network='fake_net',
+ vlan_id='fake_vlan_id')
+
+ def test_port_update_old_agent(self):
+ cfg.CONF.set_override('rpc_support_old_agents', True, 'AGENT')
rpcapi = plb.AgentNotifierApi(topics.AGENT)
+ expected_msg = rpcapi.make_msg('port_update',
+ port='fake_port',
+ network_type='vlan',
+ physical_network='fake_net',
+ segmentation_id='fake_vlan_id',
+ vlan_id='fake_vlan_id')
self._test_lb_api(rpcapi,
topics.get_topic_name(topics.AGENT,
topics.PORT,
topics.UPDATE),
'port_update', rpc_method='fanout_cast',
+ expected_msg=expected_msg,
port='fake_port',
physical_network='fake_net',
vlan_id='fake_vlan_id')