Add configuration options and support for vlan and flat networking

This commit is contained in:
James Page 2014-11-10 17:11:14 +00:00
parent ed763bd834
commit 4c62002a99
6 changed files with 85 additions and 13 deletions

View File

@ -16,6 +16,12 @@ options:
traffic to the external public network. Valid values are either MAC
addresses (in which case only MAC addresses for interfaces without an IP
address already assigned will be used), or interfaces (eth0)
data-port:
type: string
default:
description: |
The data port will be added to br-data and will allow usage of flat or VLAN
network types with Neutron.
openstack-origin:
type: string
default: distro

View File

@ -169,10 +169,10 @@ class L3AgentContext(OSContextGenerator):
return ctxt
class ExternalPortContext(OSContextGenerator):
class NeutronPortContext(OSContextGenerator):
def __call__(self):
if not config('ext-port'):
def _resolve_port(self, config_key):
if not config(config_key):
return None
hwaddr_to_nic = {}
hwaddr_to_ip = {}
@ -183,7 +183,7 @@ class ExternalPortContext(OSContextGenerator):
get_ipv6_addr(iface=nic, fatal=False)
hwaddr_to_ip[hwaddr] = addresses
mac_regex = re.compile(r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})', re.I)
for entry in config('ext-port').split():
for entry in config(config_key).split():
entry = entry.strip()
if re.match(mac_regex, entry):
if entry in hwaddr_to_nic and len(hwaddr_to_ip[entry]) == 0:
@ -192,15 +192,35 @@ class ExternalPortContext(OSContextGenerator):
continue
# Entry is a MAC address for a valid interface that doesn't
# have an IP address assigned yet.
return {"ext_port": hwaddr_to_nic[entry]}
return hwaddr_to_nic[entry]
else:
# If the passed entry is not a MAC address, assume it's a valid
# interface, and that the user put it there on purpose (we can
# trust it to be the real external network).
return {"ext_port": entry}
return entry
return None
class ExternalPortContext(NeutronPortContext):
def __call__(self):
port = self._resolve_port('ext-port')
if port:
return {"ext_port": port}
else:
return None
class DataPortContext(NeutronPortContext):
def __call__(self):
port = self._resolve_port('data-port')
if port:
return {"data_port": port}
else:
return None
class QuantumGatewayContext(OSContextGenerator):
def __call__(self):

View File

@ -46,6 +46,7 @@ from quantum_contexts import (
NetworkServiceContext,
L3AgentContext,
ExternalPortContext,
DataPortContext,
remap_plugin
)
@ -404,6 +405,7 @@ def restart_map():
INT_BRIDGE = "br-int"
EXT_BRIDGE = "br-ex"
DATA_BRIDGE = 'br-data'
DHCP_AGENT = "DHCP Agent"
L3_AGENT = "L3 Agent"
@ -533,5 +535,11 @@ def configure_ovs():
add_bridge(INT_BRIDGE)
add_bridge(EXT_BRIDGE)
ext_port_ctx = ExternalPortContext()()
if ext_port_ctx is not None and ext_port_ctx['ext_port']:
if ext_port_ctx and ext_port_ctx['ext_port']:
add_bridge_port(EXT_BRIDGE, ext_port_ctx['ext_port'])
add_bridge(DATA_BRIDGE)
data_port_ctx = DataPortContext()()
if data_port_ctx and data_port_ctx['data_port']:
add_bridge_port(DATA_BRIDGE, data_port_ctx['data_port'],
promisc=True)

View File

@ -3,18 +3,30 @@
# Configuration file maintained by Juju. Local changes may be overwritten.
###############################################################################
[ml2]
type_drivers = gre,vxlan
tenant_network_types = gre,vxlan
type_drivers = gre,vxlan,vlan,flat
tenant_network_types = gre,vxlan,vlan,flat
mechanism_drivers = openvswitch,l2population
[ml2_type_gre]
tunnel_id_ranges = 1:1000
[ml2_type_vxlan]
vni_ranges = 1001:2000
[ml2_type_vlan]
network_vlan_ranges = physnet1:1000:2000
[ml2_type_flat]
flat_networks = physnet1
[ovs]
enable_tunneling = True
local_ip = {{ local_ip }}
bridge_mappings = physnet1:br-data
[agent]
tunnel_types = {{ overlay_network_type }}
l2_population = {{ l2_population }}
[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

View File

@ -117,11 +117,11 @@ class TestNetworkServiceContext(_TestQuantumContext):
}
class TestExternalPortContext(CharmTestCase):
class TestNeutronPortContext(CharmTestCase):
def setUp(self):
super(TestExternalPortContext, self).setUp(quantum_contexts,
TO_PATCH)
super(TestNeutronPortContext, self).setUp(quantum_contexts,
TO_PATCH)
self.machine_macs = {
'eth0': 'fe:c5:ce:8e:2b:00',
'eth1': 'fe:c5:ce:8e:2b:01',
@ -174,6 +174,11 @@ class TestExternalPortContext(CharmTestCase):
self.assertEquals(quantum_contexts.ExternalPortContext()(),
{'ext_port': 'eth2'})
def test_data_port_eth(self):
self.config.return_value = 'eth1010'
self.assertEquals(quantum_contexts.DataPortContext()(),
{'data_port': 'eth1010'})
class TestL3AgentContext(CharmTestCase):

View File

@ -36,6 +36,7 @@ TO_PATCH = [
'service_running',
'NetworkServiceContext',
'ExternalPortContext',
'DataPortContext',
'unit_private_ip',
'relations_of_type',
'service_stop',
@ -148,13 +149,33 @@ class TestQuantumUtils(CharmTestCase):
self.test_config.set('ext-port', 'eth0')
self.ExternalPortContext.return_value = \
DummyExternalPortContext(return_value={'ext_port': 'eth0'})
self.DataPortContext.return_value = \
DummyExternalPortContext(return_value=None)
quantum_utils.configure_ovs()
self.add_bridge.assert_has_calls([
call('br-int'),
call('br-ex')
call('br-ex'),
call('br-data')
])
self.add_bridge_port.assert_called_with('br-ex', 'eth0')
def test_configure_ovs_ovs_data_port(self):
self.config.side_effect = self.test_config.get
self.test_config.set('plugin', 'ovs')
self.test_config.set('data-port', 'eth0')
self.ExternalPortContext.return_value = \
DummyExternalPortContext(return_value=None)
self.DataPortContext.return_value = \
DummyExternalPortContext(return_value={'data_port': 'eth0'})
quantum_utils.configure_ovs()
self.add_bridge.assert_has_calls([
call('br-int'),
call('br-ex'),
call('br-data')
])
self.add_bridge_port.assert_called_with('br-data', 'eth0',
promisc=True)
def test_do_openstack_upgrade(self):
self.config.side_effect = self.test_config.get
self.is_relation_made.return_value = False