diff --git a/README.md b/README.md index 294e48be..17bfe063 100644 --- a/README.md +++ b/README.md @@ -50,45 +50,65 @@ See upstream [Neutron multi extnet](http://docs.openstack.org/trunk/config-refer Configuration Options --------------------- -External Port Configuration -=========================== +Port Configuration +================== -If the port to be used for external traffic is consistent across all physical -servers then is can be specified by simply setting ext-port to the nic id: +All network types (internal, external) are configured with bridge-mappings and +data-port and the flat-network-providers configuration option of the +neutron-api charm. Once deployed, you can configure the network specifics +using neutron net-create. + +If the device name is not consistent between hosts, you can specify the same +bridge multiple times with MAC addresses instead of interface names. The charm +will loop through the list and configure the first matching interface. + +Basic configuration of a single external network, typically used as floating IP +addresses combined with a GRE private network: neutron-gateway: - ext-port: eth2 + bridge-mappings: physnet1:br-ex + data-port: br-ex:eth1 + neutron-api: + flat-network-providers: physnet1 -However, if it varies between hosts then the mac addresses of the external -nics for each host can be passed as a space separated list: + neutron net-create --provider:network_type flat \ + --provider:physical_network physnet1 --router:external=true \ + external + neutron router-gateway-set provider external + +Alternative configuration with two networks, where the internal private +network is directly connected to the gateway with public IP addresses but a +floating IP address range is also offered. neutron-gateway: - ext-port: + bridge-mappings: physnet1:br-data external:br-ex + data-port: br-data:eth1 br-ex:eth2 + neutron-api: + flat-network-providers: physnet1 external +Alternative configuration with two external networks, one for public instance +addresses and one for floating IP addresses. Both networks are on the same +physical network connection (but they might be on different VLANs, that is +configured later using neutron net-create). -Multiple Floating Pools -======================= + neutron-gateway: + bridge-mappings: physnet1:br-data + data-port: br-data:eth1 + neutron-api: + flat-network-providers: physnet1 -If multiple floating pools are needed then an L3 agent (which corresponds to -a neutron-gateway for the sake of this charm) is needed for each one. Each -gateway needs to be deployed as a separate service so that the external -network id can be set differently for each gateway e.g. + neutron net-create --provider:network_type vlan \ + --provider:segmentation_id 400 \ + --provider:physical_network physnet1 --shared external + neutron net-create --provider:network_type vlan \ + --provider:segmentation_id 401 \ + --provider:physical_network physnet1 --shared --router:external=true \ + floating + neutron router-gateway-set provider floating - juju deploy neutron-gateway neutron-gateway-extnet1 - juju add-relation neutron-gateway-extnet1 mysql - juju add-relation neutron-gateway-extnet1 rabbitmq-server - juju add-relation neutron-gateway-extnet1 nova-cloud-controller - juju deploy neutron-gateway neutron-gateway-extnet2 - juju add-relation neutron-gateway-extnet2 mysql - juju add-relation neutron-gateway-extnet2 rabbitmq-server - juju add-relation neutron-gateway-extnet2 nova-cloud-controller - - Create extnet1 and extnet2 via neutron client and take a note of their ids - - juju set neutron-gateway-extnet1 "run-internal-router=leader" - juju set neutron-gateway-extnet2 "run-internal-router=none" - juju set neutron-gateway-extnet1 "external-network-id=" - juju set neutron-gateway-extnet2 "external-network-id=" +This replaces the previous system of using ext-port, which always created a bridge +called br-ex for external networks which was used implicitly by external router +interfaces. Instance MTU ============ diff --git a/config.yaml b/config.yaml index d17ca25e..f83c1545 100644 --- a/config.yaml +++ b/config.yaml @@ -69,6 +69,10 @@ options: type: string default: description: | + Deprecated: Use bridge-mappings and data-port to create a network + which can be used for external connectivity. You can call the network + external and the bridge br-ex by convention, but neither is required. + Space-delimited list of external ports to use for routing of instance traffic to the external public network. Valid values are either MAC addresses (in which case only MAC addresses for interfaces without an IP diff --git a/hooks/neutron_contexts.py b/hooks/neutron_contexts.py index 9222c67f..ee567316 100644 --- a/hooks/neutron_contexts.py +++ b/hooks/neutron_contexts.py @@ -64,6 +64,10 @@ class L3AgentContext(OSContextGenerator): if config('external-network-id'): ctxt['ext_net_id'] = config('external-network-id') + + if not config('ext-port') and not config('external-network-id'): + ctxt['external_configuration_new'] = True + if config('plugin'): ctxt['plugin'] = config('plugin') if api_settings['enable_dvr']: diff --git a/templates/icehouse/l3_agent.ini b/templates/icehouse/l3_agent.ini index e64591a4..8a34af01 100644 --- a/templates/icehouse/l3_agent.ini +++ b/templates/icehouse/l3_agent.ini @@ -19,6 +19,9 @@ use_namespaces = True {% else %} ovs_use_veth = True {% endif %} -{% if ext_net_id -%} +{% if external_configuration_new -%} +gateway_external_network_id = +external_network_bridge = +{% elif ext_net_id %} gateway_external_network_id = {{ ext_net_id }} {% endif -%} diff --git a/templates/juno/l3_agent.ini b/templates/juno/l3_agent.ini index 6fd6cd4b..b0f5d696 100644 --- a/templates/juno/l3_agent.ini +++ b/templates/juno/l3_agent.ini @@ -19,7 +19,10 @@ use_namespaces = True {% else %} ovs_use_veth = True {% endif %} -{% if ext_net_id -%} +{% if external_configuration_new -%} +gateway_external_network_id = +external_network_bridge = +{% elif ext_net_id %} gateway_external_network_id = {{ ext_net_id }} {% endif -%} agent_mode = {{ agent_mode }} diff --git a/unit_tests/test_neutron_contexts.py b/unit_tests/test_neutron_contexts.py index 625b2f25..d95be7c1 100644 --- a/unit_tests/test_neutron_contexts.py +++ b/unit_tests/test_neutron_contexts.py @@ -56,12 +56,25 @@ class TestL3AgentContext(CharmTestCase): self.config.side_effect = self.test_config.get @patch('neutron_contexts.NeutronAPIContext') - def test_no_ext_netid(self, _NeutronAPIContext): + def test_new_ext_network(self, _NeutronAPIContext): _NeutronAPIContext.return_value = \ DummyNeutronAPIContext(return_value={'enable_dvr': False}) self.test_config.set('run-internal-router', 'none') self.test_config.set('external-network-id', '') self.eligible_leader.return_value = False + self.assertEquals(neutron_contexts.L3AgentContext()(), + {'agent_mode': 'legacy', + 'external_configuration_new': True, + 'handle_internal_only_router': False, + 'plugin': 'ovs'}) + + @patch('neutron_contexts.NeutronAPIContext') + def test_old_ext_network(self, _NeutronAPIContext): + _NeutronAPIContext.return_value = \ + DummyNeutronAPIContext(return_value={'enable_dvr': False}) + self.test_config.set('run-internal-router', 'none') + self.test_config.set('ext-port', 'eth1') + self.eligible_leader.return_value = False self.assertEquals(neutron_contexts.L3AgentContext()(), {'agent_mode': 'legacy', 'handle_internal_only_router': False,