diff --git a/config.yaml b/config.yaml index f2819f9e..c9615b3d 100755 --- a/config.yaml +++ b/config.yaml @@ -140,7 +140,8 @@ options: gre vxlan . - Multiple types can be provided - field is space delimited. + Multiple types can be provided - field is space delimited. To disable + overlay networks set to the empty string '' flat-network-providers: type: string default: @@ -617,3 +618,8 @@ options: http://bugs.launchpad.net/charms providing an explanation of why the config was needed so that we may consider it for inclusion as a natively supported config in the the charm. + default-tenant-network-type: + type: string + default: + description: | + The default type for a tenant network e.g. vxlan, vlan, gre etc diff --git a/hooks/neutron_api_context.py b/hooks/neutron_api_context.py index 63e5702e..dcfedc3b 100644 --- a/hooks/neutron_api_context.py +++ b/hooks/neutron_api_context.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from collections import OrderedDict + from charmhelpers.core.hookenv import ( config, relation_ids, @@ -31,7 +33,11 @@ from charmhelpers.contrib.openstack.utils import ( VLAN = 'vlan' VXLAN = 'vxlan' GRE = 'gre' +FLAT = 'flat' +LOCAL = 'local' OVERLAY_NET_TYPES = [VXLAN, GRE] +NON_OVERLAY_NET_TYPES = [VLAN, FLAT, LOCAL] +TENANT_NET_TYPES = [VXLAN, GRE, VLAN, FLAT, LOCAL] def get_l2population(): @@ -39,13 +45,42 @@ def get_l2population(): return config('l2-population') if plugin == "ovs" else False -def get_overlay_network_type(): +def _get_overlay_network_type(): overlay_networks = config('overlay-network-type').split() for overlay_net in overlay_networks: if overlay_net not in OVERLAY_NET_TYPES: raise ValueError('Unsupported overlay-network-type %s' % overlay_net) - return ','.join(overlay_networks) + return overlay_networks + + +def get_overlay_network_type(): + return ','.join(_get_overlay_network_type()) + + +def _get_tenant_network_types(): + default_tenant_network_type = config('default-tenant-network-type') + tenant_network_types = _get_overlay_network_type() + tenant_network_types.extend(NON_OVERLAY_NET_TYPES) + if default_tenant_network_type: + if (default_tenant_network_type in TENANT_NET_TYPES and + default_tenant_network_type in tenant_network_types): + tenant_network_types[:0] = [default_tenant_network_type] + else: + raise ValueError('Unsupported or unconfigured ' + 'default-tenant-network-type' + ' {}'.format(default_tenant_network_type)) + # Dedupe list but preserve order + return list(OrderedDict.fromkeys(tenant_network_types)) + + +def get_tenant_network_types(): + '''Get the configured tenant network types + + @return: comma delimited string of configured tenant + network types. + ''' + return ','.join(_get_tenant_network_types()) def get_l3ha(): @@ -124,6 +159,10 @@ class NeutronCCContext(context.NeutronContext): def neutron_l2_population(self): return get_l2population() + @property + def neutron_tenant_network_types(self): + return get_tenant_network_types() + @property def neutron_overlay_network_type(self): return get_overlay_network_type() @@ -195,6 +234,7 @@ class NeutronCCContext(context.NeutronContext): ctxt['min_l3_agents_per_router'] = \ config('min-l3-agents-per-router') ctxt['dhcp_agents_per_network'] = config('dhcp-agents-per-network') + ctxt['tenant_network_types'] = self.neutron_tenant_network_types ctxt['overlay_network_type'] = self.neutron_overlay_network_type ctxt['external_network'] = config('neutron-external-network') release = os_release('neutron-server') diff --git a/templates/icehouse/ml2_conf.ini b/templates/icehouse/ml2_conf.ini index 1a6c3178..52cfa9df 100644 --- a/templates/icehouse/ml2_conf.ini +++ b/templates/icehouse/ml2_conf.ini @@ -8,8 +8,8 @@ type_drivers = local,flat mechanism_drivers = calico {% else -%} -type_drivers = {{ overlay_network_type }},vlan,flat,local -tenant_network_types = {{ overlay_network_type }},vlan,flat,local +type_drivers = {{ tenant_network_types }} +tenant_network_types = {{ tenant_network_types }} mechanism_drivers = openvswitch,hyperv,l2population [ml2_type_gre] diff --git a/templates/kilo/ml2_conf.ini b/templates/kilo/ml2_conf.ini index 5265b950..8b06d39f 100644 --- a/templates/kilo/ml2_conf.ini +++ b/templates/kilo/ml2_conf.ini @@ -12,8 +12,8 @@ extension_drivers=port_security type_drivers = local,flat mechanism_drivers = calico {% else -%} -type_drivers = {{ overlay_network_type }},vlan,flat,local -tenant_network_types = {{ overlay_network_type }},vlan,flat,local +type_drivers = {{ tenant_network_types }} +tenant_network_types = {{ tenant_network_types }} {% if enable_sriov %} mechanism_drivers = openvswitch,l2population,sriovnicswitch {% elif enable_hyperv %} diff --git a/tests/dfs-basic-trusty-icehouse b/tests/dfs-basic-trusty-icehouse index bacb2a16..19d7f839 100755 --- a/tests/dfs-basic-trusty-icehouse +++ b/tests/dfs-basic-trusty-icehouse @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/dfs-basic-trusty-kilo-git b/tests/dfs-basic-trusty-kilo-git index 92bc880d..ab886f22 100755 --- a/tests/dfs-basic-trusty-kilo-git +++ b/tests/dfs-basic-trusty-kilo-git @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-trusty-icehouse b/tests/gate-basic-trusty-icehouse index c5623990..86b91036 100755 --- a/tests/gate-basic-trusty-icehouse +++ b/tests/gate-basic-trusty-icehouse @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-trusty-kilo b/tests/gate-basic-trusty-kilo index f21386ec..1985851e 100755 --- a/tests/gate-basic-trusty-kilo +++ b/tests/gate-basic-trusty-kilo @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-trusty-liberty b/tests/gate-basic-trusty-liberty index 5b952418..87c4b296 100755 --- a/tests/gate-basic-trusty-liberty +++ b/tests/gate-basic-trusty-liberty @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-trusty-mitaka b/tests/gate-basic-trusty-mitaka index 609843d0..ecc7921a 100755 --- a/tests/gate-basic-trusty-mitaka +++ b/tests/gate-basic-trusty-mitaka @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-xenial-mitaka b/tests/gate-basic-xenial-mitaka index 1f6ee877..2bac07bc 100755 --- a/tests/gate-basic-xenial-mitaka +++ b/tests/gate-basic-xenial-mitaka @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-xenial-newton b/tests/gate-basic-xenial-newton index a6be42d2..6604c823 100755 --- a/tests/gate-basic-xenial-newton +++ b/tests/gate-basic-xenial-newton @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/tests/gate-basic-yakkety-newton b/tests/gate-basic-yakkety-newton index 4d21401e..d51960e1 100644 --- a/tests/gate-basic-yakkety-newton +++ b/tests/gate-basic-yakkety-newton @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # # Copyright 2016 Canonical Ltd # diff --git a/unit_tests/test_neutron_api_context.py b/unit_tests/test_neutron_api_context.py index 77cdec02..035a735d 100644 --- a/unit_tests/test_neutron_api_context.py +++ b/unit_tests/test_neutron_api_context.py @@ -49,21 +49,64 @@ class GeneralTests(CharmTestCase): self.test_config.set('neutron-plugin', 'nsx') self.assertEquals(context.get_l2population(), False) - def test_get_overlay_network_type(self): + def test_get_tenant_network_types(self): self.test_config.set('overlay-network-type', 'gre') - self.assertEquals(context.get_overlay_network_type(), 'gre') + self.assertEquals( + context._get_tenant_network_types(), + ['gre', 'vlan', 'flat', 'local']) - def test_get_overlay_network_type_multi(self): + def test_get_tenant_network_types_multi(self): self.test_config.set('overlay-network-type', 'gre vxlan') - self.assertEquals(context.get_overlay_network_type(), 'gre,vxlan') + self.assertEquals( + context._get_tenant_network_types(), + ['gre', 'vxlan', 'vlan', 'flat', 'local']) - def test_get_overlay_network_type_unsupported(self): + def test_get_tenant_network_types_unsupported(self): self.test_config.set('overlay-network-type', 'tokenring') with self.assertRaises(ValueError) as _exceptctxt: - context.get_overlay_network_type() + context._get_tenant_network_types() self.assertEqual(_exceptctxt.exception.message, 'Unsupported overlay-network-type tokenring') + def test_get_tenant_network_types_default(self): + self.test_config.set('overlay-network-type', 'gre vxlan') + self.test_config.set('default-tenant-network-type', 'vxlan') + self.assertEquals( + context._get_tenant_network_types(), + ['vxlan', 'gre', 'vlan', 'flat', 'local']) + + def test_get_tenant_network_types_default_dup(self): + self.test_config.set('overlay-network-type', 'gre') + self.test_config.set('default-tenant-network-type', 'vlan') + self.assertEquals( + context._get_tenant_network_types(), + ['vlan', 'gre', 'flat', 'local']) + + def test_get_tenant_network_types_empty(self): + self.test_config.set('overlay-network-type', '') + self.test_config.set('default-tenant-network-type', 'vlan') + self.assertEquals( + context._get_tenant_network_types(), + ['vlan', 'flat', 'local']) + + def test_get_tenant_network_types_unsupported_default(self): + self.test_config.set('overlay-network-type', '') + self.test_config.set('default-tenant-network-type', 'whizzy') + with self.assertRaises(ValueError) as _exceptctxt: + context._get_tenant_network_types() + self.assertEqual(_exceptctxt.exception.message, + 'Unsupported or unconfigured ' + 'default-tenant-network-type whizzy') + + def test_get_tenant_network_types_unconfigured_default(self): + self.test_config.set('overlay-network-type', 'gre') + self.test_config.set('default-tenant-network-type', 'vxlan') + with self.assertRaises(ValueError) as _exceptctxt: + context._get_tenant_network_types() + self.assertEqual(_exceptctxt.exception.message, + 'Unsupported or unconfigured ' + 'default-tenant-network-type vxlan') + def test_get_l3ha(self): self.test_config.set('enable-l3ha', True) self.test_config.set('overlay-network-type', 'gre') @@ -252,7 +295,6 @@ class HAProxyContextTest(CharmTestCase): _get_netmask_for_address.return_value = '255.255.255.0' _kv().get.return_value = 'abcdefghijklmnopqrstuvwxyz123456' service_ports = {'neutron-server': [9696, 9686]} - self.maxDiff = None ctxt_data = { 'local_host': '127.0.0.1', 'haproxy_host': '0.0.0.0', @@ -326,6 +368,7 @@ class NeutronCCContextTest(CharmTestCase): 'verbose': True, 'l2_population': True, 'overlay_network_type': 'gre', + 'tenant_network_types': 'gre,vlan,flat,local', 'quota_floatingip': 50, 'quota_health_monitors': -1, 'quota_member': -1, @@ -365,6 +408,7 @@ class NeutronCCContextTest(CharmTestCase): 'verbose': True, 'l2_population': True, 'overlay_network_type': 'vxlan', + 'tenant_network_types': 'vxlan,vlan,flat,local', 'quota_floatingip': 50, 'quota_health_monitors': -1, 'quota_member': -1, @@ -406,6 +450,7 @@ class NeutronCCContextTest(CharmTestCase): 'verbose': True, 'l2_population': False, 'overlay_network_type': 'gre', + 'tenant_network_types': 'gre,vlan,flat,local', 'max_l3_agents_per_router': 2, 'min_l3_agents_per_router': 2, 'dhcp_agents_per_network': 3, @@ -446,6 +491,7 @@ class NeutronCCContextTest(CharmTestCase): 'verbose': True, 'l2_population': True, 'overlay_network_type': 'gre', + 'tenant_network_types': 'gre,vlan,flat,local', 'quota_floatingip': 50, 'quota_health_monitors': -1, 'quota_member': -1,