338 lines
14 KiB
Python
Raw Normal View History

import io
from contextlib import contextmanager
from mock import (
MagicMock,
patch
)
import neutron_contexts
2013-07-22 16:39:07 +01:00
from test_utils import (
CharmTestCase
)
TO_PATCH = [
'config',
'eligible_leader',
2013-07-22 16:39:07 +01:00
'unit_get',
'network_get_primary_address',
2013-07-22 16:39:07 +01:00
]
@contextmanager
def patch_open():
'''Patch open() to allow mocking both open() itself and the file that is
yielded.
Yields the mock for "open" and "file", respectively.'''
mock_open = MagicMock(spec=open)
mock_file = MagicMock(spec=io.FileIO)
2013-07-22 16:39:07 +01:00
@contextmanager
def stub_open(*args, **kwargs):
mock_open(*args, **kwargs)
yield mock_file
with patch('builtins.open', stub_open):
2013-07-22 16:39:07 +01:00
yield mock_open, mock_file
2015-03-31 08:48:28 +01:00
class DummyNeutronAPIContext():
def __init__(self, return_value):
self.return_value = return_value
def __call__(self):
return self.return_value
2013-11-06 13:37:11 +00:00
class TestL3AgentContext(CharmTestCase):
2014-02-24 17:47:55 +00:00
2013-11-06 13:37:11 +00:00
def setUp(self):
super(TestL3AgentContext, self).setUp(neutron_contexts,
2013-11-06 13:37:11 +00:00
TO_PATCH)
self.network_get_primary_address.side_effect = NotImplementedError
2013-11-06 13:37:11 +00:00
self.config.side_effect = self.test_config.get
@patch('neutron_contexts.NeutronAPIContext')
Support new style (and multiple) external networks Switch the generated configuration to use "new" style external networks when ext-port is not set. In this case we configure external_network_bridge = (intentionally blank), gateway_external_network_id = (blank) and update the README with information on using this new style of configuration. The current template configures external networks by using the default external_network_bridge=br-ex (implied when not set). This activates legacy code which assumes that a single external network exists on that bridge and the L3 Agent directly plugs itself in. provider:network_type, provider:physical_network and provider:segmentation_id are ignored. You cannot create multiple networks and you cannot use segmented networks (e.g. VLAN) By setting external_network_bridge = (intentionally blank) the L2 Agent handles the configuration instead, this allows us to create multiple networks and also to use more complex network configurations such as VLAN. It is also possible to use the same physical connection with different segmentation IDs for both internal and external networks, as well as multiple external networks. Legacy/existing configurations where ext-port is set generate the same configuration as previous and should continue to work as before. I do not believe it to be easy to migrate existing setups to the "new" style configuration automatically as changes to the neutron network configuration may be required (specifically: provider:physical_network will now be used when it was not before, and may not be correct) and the physical port needs to be moved from br-ex to br-data which the charm does not currently handle and is likely to error as it does not attempt removal first. Further work may be possible in this area. For information about this new style of configuration being preferred, see discussions in LP#1491668, LP#1525059 and http://docs.openstack.org/liberty/networking-guide/scenario-classic-ovs.html Change-Id: I8d2bb8098e080969e0445293b1ed79714b2c964f Related-Bug: #1491668 Related-Bug: #1525059 Closes-Bug: #1536768
2016-03-23 00:33:06 +08:00
def test_new_ext_network(self, _NeutronAPIContext):
2015-03-31 08:48:28 +01:00
_NeutronAPIContext.return_value = \
DummyNeutronAPIContext(return_value={'enable_dvr': False,
'report_interval': 30,
'rpc_response_timeout': 60,
})
self.test_config.set('run-internal-router', 'none')
self.test_config.set('external-network-id', '')
2013-11-06 13:37:11 +00:00
self.eligible_leader.return_value = False
self.assertEqual(neutron_contexts.L3AgentContext()(),
{'agent_mode': 'legacy',
'report_interval': 30,
'rpc_response_timeout': 60,
'external_configuration_new': True,
'handle_internal_only_router': False,
'plugin': 'ovs'})
Support new style (and multiple) external networks Switch the generated configuration to use "new" style external networks when ext-port is not set. In this case we configure external_network_bridge = (intentionally blank), gateway_external_network_id = (blank) and update the README with information on using this new style of configuration. The current template configures external networks by using the default external_network_bridge=br-ex (implied when not set). This activates legacy code which assumes that a single external network exists on that bridge and the L3 Agent directly plugs itself in. provider:network_type, provider:physical_network and provider:segmentation_id are ignored. You cannot create multiple networks and you cannot use segmented networks (e.g. VLAN) By setting external_network_bridge = (intentionally blank) the L2 Agent handles the configuration instead, this allows us to create multiple networks and also to use more complex network configurations such as VLAN. It is also possible to use the same physical connection with different segmentation IDs for both internal and external networks, as well as multiple external networks. Legacy/existing configurations where ext-port is set generate the same configuration as previous and should continue to work as before. I do not believe it to be easy to migrate existing setups to the "new" style configuration automatically as changes to the neutron network configuration may be required (specifically: provider:physical_network will now be used when it was not before, and may not be correct) and the physical port needs to be moved from br-ex to br-data which the charm does not currently handle and is likely to error as it does not attempt removal first. Further work may be possible in this area. For information about this new style of configuration being preferred, see discussions in LP#1491668, LP#1525059 and http://docs.openstack.org/liberty/networking-guide/scenario-classic-ovs.html Change-Id: I8d2bb8098e080969e0445293b1ed79714b2c964f Related-Bug: #1491668 Related-Bug: #1525059 Closes-Bug: #1536768
2016-03-23 00:33:06 +08:00
@patch('neutron_contexts.NeutronAPIContext')
def test_old_ext_network(self, _NeutronAPIContext):
_NeutronAPIContext.return_value = \
DummyNeutronAPIContext(return_value={'enable_dvr': False,
'report_interval': 30,
'rpc_response_timeout': 60,
})
Support new style (and multiple) external networks Switch the generated configuration to use "new" style external networks when ext-port is not set. In this case we configure external_network_bridge = (intentionally blank), gateway_external_network_id = (blank) and update the README with information on using this new style of configuration. The current template configures external networks by using the default external_network_bridge=br-ex (implied when not set). This activates legacy code which assumes that a single external network exists on that bridge and the L3 Agent directly plugs itself in. provider:network_type, provider:physical_network and provider:segmentation_id are ignored. You cannot create multiple networks and you cannot use segmented networks (e.g. VLAN) By setting external_network_bridge = (intentionally blank) the L2 Agent handles the configuration instead, this allows us to create multiple networks and also to use more complex network configurations such as VLAN. It is also possible to use the same physical connection with different segmentation IDs for both internal and external networks, as well as multiple external networks. Legacy/existing configurations where ext-port is set generate the same configuration as previous and should continue to work as before. I do not believe it to be easy to migrate existing setups to the "new" style configuration automatically as changes to the neutron network configuration may be required (specifically: provider:physical_network will now be used when it was not before, and may not be correct) and the physical port needs to be moved from br-ex to br-data which the charm does not currently handle and is likely to error as it does not attempt removal first. Further work may be possible in this area. For information about this new style of configuration being preferred, see discussions in LP#1491668, LP#1525059 and http://docs.openstack.org/liberty/networking-guide/scenario-classic-ovs.html Change-Id: I8d2bb8098e080969e0445293b1ed79714b2c964f Related-Bug: #1491668 Related-Bug: #1525059 Closes-Bug: #1536768
2016-03-23 00:33:06 +08:00
self.test_config.set('run-internal-router', 'none')
self.test_config.set('ext-port', 'eth1')
self.eligible_leader.return_value = False
self.assertEqual(neutron_contexts.L3AgentContext()(),
{'agent_mode': 'legacy',
'report_interval': 30,
'rpc_response_timeout': 60,
'handle_internal_only_router': False,
'plugin': 'ovs'})
2013-11-06 13:37:11 +00:00
@patch('neutron_contexts.NeutronAPIContext')
2015-03-31 08:48:28 +01:00
def test_hior_leader(self, _NeutronAPIContext):
_NeutronAPIContext.return_value = \
DummyNeutronAPIContext(return_value={'enable_dvr': False,
'report_interval': 30,
'rpc_response_timeout': 60,
})
self.test_config.set('run-internal-router', 'leader')
self.test_config.set('external-network-id', 'netid')
2013-11-06 13:37:11 +00:00
self.eligible_leader.return_value = True
self.assertEqual(neutron_contexts.L3AgentContext()(),
{'agent_mode': 'legacy',
'report_interval': 30,
'rpc_response_timeout': 60,
'handle_internal_only_router': True,
'ext_net_id': 'netid',
'plugin': 'ovs'})
2013-11-06 13:37:11 +00:00
@patch('neutron_contexts.NeutronAPIContext')
2015-03-31 08:48:28 +01:00
def test_hior_all(self, _NeutronAPIContext):
_NeutronAPIContext.return_value = \
DummyNeutronAPIContext(return_value={'enable_dvr': False,
'report_interval': 30,
'rpc_response_timeout': 60,
})
self.test_config.set('run-internal-router', 'all')
self.test_config.set('external-network-id', 'netid')
2013-11-06 13:37:11 +00:00
self.eligible_leader.return_value = True
self.assertEqual(neutron_contexts.L3AgentContext()(),
{'agent_mode': 'legacy',
'report_interval': 30,
'rpc_response_timeout': 60,
'handle_internal_only_router': True,
'ext_net_id': 'netid',
'plugin': 'ovs'})
2013-11-06 13:37:11 +00:00
@patch('neutron_contexts.NeutronAPIContext')
2015-03-31 08:48:28 +01:00
def test_dvr(self, _NeutronAPIContext):
_NeutronAPIContext.return_value = \
DummyNeutronAPIContext(return_value={'enable_dvr': True,
'report_interval': 30,
'rpc_response_timeout': 60,
})
self.assertEqual(neutron_contexts.L3AgentContext()()['agent_mode'],
'dvr_snat')
2015-02-26 09:09:27 +00:00
2013-11-06 13:37:11 +00:00
2015-05-07 10:33:38 +01:00
class TestNeutronGatewayContext(CharmTestCase):
2014-02-24 17:47:55 +00:00
2013-07-22 16:39:07 +01:00
def setUp(self):
2015-05-07 10:33:38 +01:00
super(TestNeutronGatewayContext, self).setUp(neutron_contexts,
2013-07-22 16:39:07 +01:00
TO_PATCH)
2013-12-18 09:50:58 +00:00
self.config.side_effect = self.test_config.get
2015-03-25 07:58:50 +00:00
self.maxDiff = None
2013-07-22 16:39:07 +01:00
2015-03-24 12:07:21 +00:00
@patch('charmhelpers.contrib.openstack.context.relation_get')
@patch('charmhelpers.contrib.openstack.context.related_units')
@patch('charmhelpers.contrib.openstack.context.relation_ids')
@patch.object(neutron_contexts, 'get_shared_secret')
def test_all(self, _secret, _rids, _runits, _rget):
2015-03-23 18:25:01 +00:00
rdata = {'l2-population': 'True',
'enable-dvr': 'True',
'overlay-network-type': 'gre',
'enable-l3ha': 'True',
'enable-qos': 'True',
'network-device-mtu': 9000,
'dns-domain': 'openstack.example.'}
2013-12-18 09:50:58 +00:00
self.test_config.set('plugin', 'ovs')
self.test_config.set('debug', False)
self.test_config.set('verbose', True)
2014-03-14 14:41:45 +00:00
self.test_config.set('instance-mtu', 1420)
self.test_config.set('dnsmasq-flags', 'dhcp-userclass=set:ipxe,iPXE,'
'dhcp-match=set:ipxe,175')
self.test_config.set('dns-servers', '8.8.8.8,4.4.4.4')
2015-03-16 18:44:02 +00:00
self.test_config.set('vlan-ranges',
'physnet1:1000:2000 physnet2:2001:3000')
self.test_config.set('flat-network-providers', 'physnet3 physnet4')
self.network_get_primary_address.side_effect = NotImplementedError
self.unit_get.return_value = '10.5.0.1'
2015-03-16 18:44:02 +00:00
# Provided by neutron-api relation
2015-03-24 12:07:21 +00:00
_rids.return_value = ['neutron-plugin-api:0']
_runits.return_value = ['neutron-api/0']
_rget.side_effect = lambda *args, **kwargs: rdata
2013-07-22 16:39:07 +01:00
_secret.return_value = 'testsecret'
2015-05-07 10:33:38 +01:00
ctxt = neutron_contexts.NeutronGatewayContext()()
self.assertEqual(ctxt, {
'shared_secret': 'testsecret',
2015-02-26 09:09:27 +00:00
'enable_dvr': True,
'enable_l3ha': True,
'dns_servers': '8.8.8.8,4.4.4.4',
'extension_drivers': 'qos',
'dns_domain': 'openstack.example.',
'local_ip': '10.5.0.1',
'instance_mtu': 1420,
'core_plugin': "ml2",
2013-12-18 09:50:58 +00:00
'plugin': 'ovs',
'debug': False,
2014-09-04 15:24:27 +00:00
'verbose': True,
2015-02-26 09:09:27 +00:00
'l2_population': True,
2014-10-02 14:02:31 +00:00
'overlay_network_type': 'gre',
'report_interval': 30,
'rpc_response_timeout': 60,
2015-02-12 11:18:46 +00:00
'bridge_mappings': 'physnet1:br-data',
'network_providers': 'physnet3,physnet4',
2015-04-10 16:45:07 +01:00
'vlan_ranges': 'physnet1:1000:2000,physnet2:2001:3000',
2015-03-16 18:44:02 +00:00
'network_device_mtu': 9000,
'veth_mtu': 9000,
'enable_isolated_metadata': False,
'enable_metadata_network': False,
'dnsmasq_flags': {
'dhcp-userclass': 'set:ipxe,iPXE',
'dhcp-match': 'set:ipxe,175'
}
})
2013-07-22 16:39:07 +01:00
@patch('charmhelpers.contrib.openstack.context.relation_get')
@patch('charmhelpers.contrib.openstack.context.related_units')
@patch('charmhelpers.contrib.openstack.context.relation_ids')
@patch.object(neutron_contexts, 'get_shared_secret')
def test_all_network_spaces(self, _secret, _rids, _runits, _rget):
rdata = {'l2-population': 'True',
'enable-dvr': 'True',
'overlay-network-type': 'gre',
'enable-l3ha': 'True',
'enable-qos': 'True',
'network-device-mtu': 9000,
'dns-domain': 'openstack.example.'}
self.test_config.set('plugin', 'ovs')
self.test_config.set('debug', False)
self.test_config.set('verbose', True)
self.test_config.set('instance-mtu', 1420)
self.test_config.set('dnsmasq-flags', 'dhcp-userclass=set:ipxe,iPXE,'
'dhcp-match=set:ipxe,175')
self.test_config.set('vlan-ranges',
'physnet1:1000:2000 physnet2:2001:3000')
self.test_config.set('flat-network-providers', 'physnet3 physnet4')
self.network_get_primary_address.return_value = '192.168.20.2'
self.unit_get.return_value = '10.5.0.1'
# Provided by neutron-api relation
_rids.return_value = ['neutron-plugin-api:0']
_runits.return_value = ['neutron-api/0']
_rget.side_effect = lambda *args, **kwargs: rdata
_secret.return_value = 'testsecret'
ctxt = neutron_contexts.NeutronGatewayContext()()
self.assertEqual(ctxt, {
'shared_secret': 'testsecret',
'enable_dvr': True,
'enable_l3ha': True,
'dns_servers': None,
'extension_drivers': 'qos',
'dns_domain': 'openstack.example.',
'local_ip': '192.168.20.2',
'instance_mtu': 1420,
'core_plugin': "ml2",
'plugin': 'ovs',
'debug': False,
'verbose': True,
'l2_population': True,
'overlay_network_type': 'gre',
'report_interval': 30,
'rpc_response_timeout': 60,
'bridge_mappings': 'physnet1:br-data',
'network_providers': 'physnet3,physnet4',
'vlan_ranges': 'physnet1:1000:2000,physnet2:2001:3000',
'network_device_mtu': 9000,
'veth_mtu': 9000,
'enable_isolated_metadata': False,
'enable_metadata_network': False,
'dnsmasq_flags': {
'dhcp-userclass': 'set:ipxe,iPXE',
'dhcp-match': 'set:ipxe,175'
}
})
@patch('charmhelpers.contrib.openstack.context.relation_get')
@patch('charmhelpers.contrib.openstack.context.related_units')
@patch('charmhelpers.contrib.openstack.context.relation_ids')
@patch.object(neutron_contexts, 'get_shared_secret')
def test_dhcp_settings(self, _secret, _rids, _runits, _rget):
self.test_config.set('enable-isolated-metadata', True)
self.test_config.set('enable-metadata-network', True)
self.network_get_primary_address.return_value = '192.168.20.2'
self.unit_get.return_value = '10.5.0.1'
ctxt = neutron_contexts.NeutronGatewayContext()()
self.assertTrue(ctxt['enable_isolated_metadata'])
self.assertTrue(ctxt['enable_metadata_network'])
@patch('charmhelpers.contrib.openstack.context.relation_get')
@patch('charmhelpers.contrib.openstack.context.related_units')
@patch('charmhelpers.contrib.openstack.context.relation_ids')
@patch.object(neutron_contexts, 'get_shared_secret')
def test_dhcp_setting_plug_override(self, _secret, _rids, _runits, _rget):
self.test_config.set('plugin', 'nsx')
self.test_config.set('enable-isolated-metadata', False)
self.test_config.set('enable-metadata-network', False)
self.network_get_primary_address.return_value = '192.168.20.2'
self.unit_get.return_value = '10.5.0.1'
ctxt = neutron_contexts.NeutronGatewayContext()()
self.assertTrue(ctxt['enable_isolated_metadata'])
self.assertTrue(ctxt['enable_metadata_network'])
2013-07-22 16:39:07 +01:00
class TestSharedSecret(CharmTestCase):
2014-02-24 17:47:55 +00:00
2013-07-22 16:39:07 +01:00
def setUp(self):
super(TestSharedSecret, self).setUp(neutron_contexts,
2013-07-22 16:39:07 +01:00
TO_PATCH)
2013-09-04 11:38:36 +01:00
self.config.side_effect = self.test_config.get
self.network_get_primary_address.side_effect = NotImplementedError
2013-07-22 16:39:07 +01:00
@patch('os.path')
@patch('uuid.uuid4')
def test_secret_created_stored(self, _uuid4, _path):
_path.exists.return_value = False
_uuid4.return_value = 'secret_thing'
with patch_open() as (_open, _file):
self.assertEqual(neutron_contexts.get_shared_secret(),
'secret_thing')
2013-09-04 12:00:08 +01:00
_open.assert_called_with(
neutron_contexts.SHARED_SECRET.format('neutron'), 'w')
2013-07-22 16:39:07 +01:00
_file.write.assert_called_with('secret_thing')
@patch('os.path')
def test_secret_retrieved(self, _path):
_path.exists.return_value = True
with patch_open() as (_open, _file):
_file.read.return_value = 'secret_thing\n'
self.assertEqual(neutron_contexts.get_shared_secret(),
'secret_thing')
2013-09-04 12:00:08 +01:00
_open.assert_called_with(
neutron_contexts.SHARED_SECRET.format('neutron'), 'r')
2013-07-22 16:39:07 +01:00
class TestMisc(CharmTestCase):
2014-02-24 17:47:55 +00:00
2013-09-04 11:38:36 +01:00
def setUp(self):
super(TestMisc,
self).setUp(neutron_contexts,
2013-09-04 11:38:36 +01:00
TO_PATCH)
def test_core_plugin_ml2(self):
self.config.return_value = 'ovs'
self.assertEqual(neutron_contexts.core_plugin(),
neutron_contexts.NEUTRON_ML2_PLUGIN)