diff --git a/config.yaml b/config.yaml index acc64c46..aea9d3c6 100644 --- a/config.yaml +++ b/config.yaml @@ -8,6 +8,7 @@ options: . ovs - OpenVSwitch nvp|nsx - Nicira NVP/VMware NSX + n1kv - Cisco N1kv ext-port: type: string default: @@ -83,6 +84,12 @@ options: within the cloud. This is useful in deployments where its not possible to increase MTU on switches and physical servers to accomodate the packet overhead of using GRE tunnels. + enable-l3-agent: + type: boolean + default: True + description: | + Optional configuration to support use of linux router + Note that this is used only for Cisco n1kv plugin. database-user: default: nova type: string diff --git a/hooks/quantum_contexts.py b/hooks/quantum_contexts.py index f62a58d9..bf7312eb 100644 --- a/hooks/quantum_contexts.py +++ b/hooks/quantum_contexts.py @@ -50,6 +50,8 @@ NEUTRON_ML2_PLUGIN = \ "neutron.plugins.ml2.plugin.Ml2Plugin" NEUTRON_NVP_PLUGIN = \ "neutron.plugins.nicira.nicira_nvp_plugin.NeutronPlugin.NvpPluginV2" +NEUTRON_N1KV_PLUGIN = \ + "neutron.plugins.cisco.n1kv.n1kv_neutron_plugin.N1kvNeutronPluginV2" NEUTRON_NSX_PLUGIN = "vmware" NEUTRON = 'neutron' @@ -65,16 +67,18 @@ def networking_name(): OVS = 'ovs' NVP = 'nvp' +N1KV = 'n1kv' NSX = 'nsx' CORE_PLUGIN = { QUANTUM: { OVS: QUANTUM_OVS_PLUGIN, - NVP: QUANTUM_NVP_PLUGIN + NVP: QUANTUM_NVP_PLUGIN, }, NEUTRON: { OVS: NEUTRON_OVS_PLUGIN, NVP: NEUTRON_NVP_PLUGIN, + N1KV: NEUTRON_N1KV_PLUGIN, NSX: NEUTRON_NSX_PLUGIN }, } @@ -166,6 +170,9 @@ class L3AgentContext(OSContextGenerator): if config('external-network-id'): ctxt['ext_net_id'] = config('external-network-id') + + if config('plugin'): + ctxt['plugin'] = config('plugin') return ctxt diff --git a/hooks/quantum_hooks.py b/hooks/quantum_hooks.py index 62443d5b..eb7bfb50 100755 --- a/hooks/quantum_hooks.py +++ b/hooks/quantum_hooks.py @@ -16,6 +16,7 @@ from charmhelpers.fetch import ( apt_update, apt_install, filter_installed_packages, + apt_purge, ) from charmhelpers.core.host import ( restart_on_change, @@ -91,6 +92,11 @@ def config_changed(): else: log('Please provide a valid plugin config', level=ERROR) sys.exit(1) + if config('plugin') == 'n1kv': + if config('enable-l3-agent'): + apt_install(filter_installed_packages('neutron-l3-agent')) + else: + apt_purge('neutron-l3-agent') @hooks.hook('upgrade-charm') @@ -186,6 +192,10 @@ def cluster_departed(): ' failed nodes with nvp|nsx', level=WARNING) return + if config('plugin') == 'n1kv': + log('Unable to re-assign agent resources for failed nodes with n1kv', + level=WARNING) + return if eligible_leader(None): reassign_agent_resources() CONFIGS.write_all() diff --git a/hooks/quantum_utils.py b/hooks/quantum_utils.py index 7bc3a439..e07a7e00 100644 --- a/hooks/quantum_utils.py +++ b/hooks/quantum_utils.py @@ -39,7 +39,7 @@ from charmhelpers.contrib.openstack.context import ( import charmhelpers.contrib.openstack.templating as templating from charmhelpers.contrib.openstack.neutron import headers_package from quantum_contexts import ( - CORE_PLUGIN, OVS, NVP, NSX, + CORE_PLUGIN, OVS, NVP, NSX, N1KV, NEUTRON, QUANTUM, networking_name, QuantumGatewayContext, @@ -63,7 +63,7 @@ QUANTUM_NVP_PLUGIN_CONF = \ "/etc/quantum/plugins/nicira/nvp.ini" QUANTUM_PLUGIN_CONF = { OVS: QUANTUM_OVS_PLUGIN_CONF, - NVP: QUANTUM_NVP_PLUGIN_CONF + NVP: QUANTUM_NVP_PLUGIN_CONF, } NEUTRON_CONF_DIR = '/etc/neutron' @@ -120,6 +120,15 @@ NEUTRON_GATEWAY_PKGS = { 'python-psycopg2', 'python-oslo.config', # Force upgrade "nova-api-metadata" + ], + N1KV: [ + "neutron-plugin-cisco", + "neutron-dhcp-agent", + "python-mysqldb", + "python-psycopg2", + "nova-api-metadata", + "neutron-common", + "neutron-l3-agent" ] } NEUTRON_GATEWAY_PKGS[NSX] = NEUTRON_GATEWAY_PKGS[NVP] @@ -129,6 +138,12 @@ GATEWAY_PKGS = { NEUTRON: NEUTRON_GATEWAY_PKGS, } +EARLY_PACKAGES = { + OVS: ['openvswitch-datapath-dkms'], + NVP: [], + N1KV: [] +} + def get_early_packages(): '''Return a list of package for pre-install based on configured plugin''' @@ -326,6 +341,24 @@ NEUTRON_NVP_CONFIG_FILES = { } NEUTRON_NVP_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES) +NEUTRON_N1KV_CONFIG_FILES = { + NEUTRON_CONF: { + 'hook_contexts': [context.AMQPContext(ssl_dir=NEUTRON_CONF_DIR), + QuantumGatewayContext(), + SyslogContext()], + 'services': ['neutron-l3-agent', + 'neutron-dhcp-agent', + 'neutron-metadata-agent'] + }, + NEUTRON_L3_AGENT_CONF: { + 'hook_contexts': [NetworkServiceContext(), + L3AgentContext(), + QuantumGatewayContext()], + 'services': ['neutron-l3-agent'] + }, +} +NEUTRON_N1KV_CONFIG_FILES.update(NEUTRON_SHARED_CONFIG_FILES) + CONFIG_FILES = { QUANTUM: { NVP: QUANTUM_NVP_CONFIG_FILES, @@ -335,6 +368,7 @@ CONFIG_FILES = { NSX: NEUTRON_NVP_CONFIG_FILES, NVP: NEUTRON_NVP_CONFIG_FILES, OVS: NEUTRON_OVS_CONFIG_FILES, + N1KV: NEUTRON_N1KV_CONFIG_FILES, }, } diff --git a/templates/havana/dhcp_agent.ini b/templates/havana/dhcp_agent.ini index 059b26be..0ef4acf4 100644 --- a/templates/havana/dhcp_agent.ini +++ b/templates/havana/dhcp_agent.ini @@ -7,7 +7,7 @@ state_path = /var/lib/neutron interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf -ovs_use_veth = True + {% if instance_mtu -%} dnsmasq_config_file = /etc/neutron/dnsmasq.conf {% endif -%} @@ -15,3 +15,13 @@ dnsmasq_config_file = /etc/neutron/dnsmasq.conf enable_metadata_network = True enable_isolated_metadata = True {% endif -%} + +{% if plugin == 'n1kv' %} +enable_metadata_network = True +enable_isolated_metadata = True +resync_interval = 30 +use_namespaces = True +dhcp_lease_time=3600 +{% else %} +ovs_use_veth = True +{% endif %} diff --git a/templates/havana/l3_agent.ini b/templates/havana/l3_agent.ini index e8e2a0de..e64591a4 100644 --- a/templates/havana/l3_agent.ini +++ b/templates/havana/l3_agent.ini @@ -10,8 +10,15 @@ admin_tenant_name = {{ service_tenant }} admin_user = {{ service_username }} admin_password = {{ service_password }} root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf -ovs_use_veth = True handle_internal_only_routers = {{ handle_internal_only_router }} +{% if plugin == 'n1kv' %} +l3_agent_manager = neutron.agent.l3_agent.L3NATAgentWithStateReport +external_network_bridge = br-int +ovs_use_veth = False +use_namespaces = True +{% else %} +ovs_use_veth = True +{% endif %} {% if ext_net_id -%} gateway_external_network_id = {{ ext_net_id }} {% endif -%} diff --git a/unit_tests/test_quantum_contexts.py b/unit_tests/test_quantum_contexts.py index 298f6221..451aff08 100644 --- a/unit_tests/test_quantum_contexts.py +++ b/unit_tests/test_quantum_contexts.py @@ -187,7 +187,8 @@ class TestL3AgentContext(CharmTestCase): self.test_config.set('external-network-id', '') self.eligible_leader.return_value = False self.assertEquals(quantum_contexts.L3AgentContext()(), - {'handle_internal_only_router': False}) + {'handle_internal_only_router': False, + 'plugin': 'ovs'}) def test_hior_leader(self): self.test_config.set('run-internal-router', 'leader') @@ -195,7 +196,8 @@ class TestL3AgentContext(CharmTestCase): self.eligible_leader.return_value = True self.assertEquals(quantum_contexts.L3AgentContext()(), {'handle_internal_only_router': True, - 'ext_net_id': 'netid'}) + 'ext_net_id': 'netid', + 'plugin': 'ovs'}) def test_hior_all(self): self.test_config.set('run-internal-router', 'all') @@ -203,7 +205,8 @@ class TestL3AgentContext(CharmTestCase): self.eligible_leader.return_value = True self.assertEquals(quantum_contexts.L3AgentContext()(), {'handle_internal_only_router': True, - 'ext_net_id': 'netid'}) + 'ext_net_id': 'netid', + 'plugin': 'ovs'}) class TestQuantumGatewayContext(CharmTestCase): diff --git a/unit_tests/test_quantum_hooks.py b/unit_tests/test_quantum_hooks.py index 22ac6e17..c5f0520f 100644 --- a/unit_tests/test_quantum_hooks.py +++ b/unit_tests/test_quantum_hooks.py @@ -19,6 +19,7 @@ TO_PATCH = [ 'valid_plugin', 'apt_update', 'apt_install', + 'apt_purge', 'filter_installed_packages', 'get_early_packages', 'get_packages', @@ -119,6 +120,17 @@ class TestQuantumHooks(CharmTestCase): self.assertTrue(self.do_openstack_upgrade.called) self.assertTrue(self.configure_ovs.called) + def test_config_changed_n1kv(self): + self.openstack_upgrade_available.return_value = False + self.valid_plugin.return_value = True + self.filter_installed_packages.side_effect = lambda p: p + self.test_config.set('plugin', 'n1kv') + self._call_hook('config-changed') + self.apt_install.assert_called_with('neutron-l3-agent') + self.test_config.set('enable-l3-agent', False) + self._call_hook('config-changed') + self.apt_purge.assert_called_with('neutron-l3-agent') + @patch('sys.exit') def test_config_changed_invalid_plugin(self, _exit): self.valid_plugin.return_value = False