diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index 1d695117..65f7973d 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -6,6 +6,12 @@ from subprocess import ( check_call ) + +from charmhelpers.core.host import ( + apt_install, + filter_installed_packages, +) + from charmhelpers.core.hookenv import ( config, local_unit, @@ -14,6 +20,7 @@ from charmhelpers.core.hookenv import ( relation_ids, related_units, unit_get, + unit_private_ip, ) from charmhelpers.contrib.hahelpers.cluster import ( @@ -29,6 +36,11 @@ from charmhelpers.contrib.hahelpers.apache import ( get_ca_cert, ) +from charmhelpers.contrib.openstack.neutron import ( + network_manager, + neutron_plugin_attribute, +) + CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt' @@ -305,3 +317,84 @@ class ApacheSSLContext(OSContextGenerator): portmap = (int(ext_port), int(int_port)) ctxt['endpoints'].append(portmap) return ctxt + + +class NeutronContext(object): + interfaces = [] + + @property + def plugin(self): + return None + + @property + def network_manager(self): + return None + + @property + def packages(self): + return neutron_plugin_attribute(self.plugin, 'packages') + + @property + def neutron_security_groups(self): + return None + + def _ensure_packages(self): + '''Install but do not upgrade required plugin packages''' + required = filter_installed_packages(self.packages) + if required: + apt_install(required, fatal=True) + + def _save_flag_file(self): + if self.network_manager == 'quantum': + _file = '/etc/nova/quantum_plugin.conf' + else: + _file = '/etc/nova/neutron_plugin.conf' + with open(_file, 'wb') as out: + out.write(self.plugin + '\n') + + def ovs_ctxt(self): + ovs_ctxt = { + 'neutron_plugin': 'ovs', + # quantum.conf + 'core_plugin': neutron_plugin_attribute(self.plugin, 'driver'), + # NOTE: network api class in template for each release. + # nova.conf + #'libvirt_vif_driver': n_driver, + #'libvirt_use_virtio_for_bridges': True, + # ovs config + 'local_ip': unit_private_ip(), + } + + if self.neutron_security_groups: + ovs_ctxt['neutron_security_groups'] = True + + fw_driver = ('%s.agent.linux.iptables_firewall.' + 'OVSHybridIptablesFirewallDriver' % + self.network_manager) + + ovs_ctxt.update({ + # IN TEMPLATE: + # - security_group_api=quantum in nova.conf for >= g + # nova_firewall_driver=nova.virt.firewall.NoopFirewallDriver' + 'neutron_firewall_driver': fw_driver, + }) + + return ovs_ctxt + + def __call__(self): + + if self.network_manager not in ['quantum', 'neutron']: + return {} + + if not self.plugin: + return {} + + self._ensure_packages() + + ctxt = {'network_manager': self.network_manager} + + if self.plugin == 'ovs': + ctxt.update(self.ovs_ctxt()) + + self._save_flagfile() + return ctxt diff --git a/hooks/nova_cc_hooks.py b/hooks/nova_cc_hooks.py index 6e48021b..623171e3 100755 --- a/hooks/nova_cc_hooks.py +++ b/hooks/nova_cc_hooks.py @@ -26,6 +26,12 @@ from charmhelpers.contrib.openstack.utils import ( openstack_upgrade_available, ) +from charmhelpers.contrib.openstack.utils import ( + network_manager, + neutron_plugin, + neutron_plugin_attribute, +) + from nova_cc_utils import ( auth_token_config, determine_endpoints, @@ -45,12 +51,6 @@ from nova_cc_utils import ( CLUSTER_RES, ) -from misc_utils import ( - network_manager, - network_plugin, - network_plugin_attribute, -) - from charmhelpers.contrib.hahelpers.cluster import ( canonical_url, eligible_leader, @@ -120,9 +120,9 @@ def db_changed(): CONFIGS.write('/etc/nova/nova.conf') if network_manager() in ['neutron', 'quantum']: - plugin = network_plugin() + plugin = neutron_plugin() # DB config might have been moved to main neutron.conf in H? - CONFIGS.write(network_plugin_attribute(plugin, 'config')) + CONFIGS.write(neutron_plugin_attribute(plugin, 'config')) if eligible_leader(CLUSTER_RES): migrate_database() @@ -207,7 +207,7 @@ def compute_joined(rid=None): rel_settings.update(ks_auth_config) rel_settings.update({ # XXX: Rename these relations settings? - 'quantum_plugin': network_plugin(), + 'quantum_plugin': neutron_plugin(), 'region': config('region'), 'quantum_security_groups': config('quantum_security_groups'), }) @@ -256,7 +256,7 @@ def quantum_joined(rid=None): 'quantum_host': urlparse(url).hostname, 'quantum_url': url, 'quantum_port': 9696, - 'quantum_plugin': network_plugin(), + 'quantum_plugin': neutron_plugin(), 'region': config('region') } diff --git a/unit_tests/test_misc_utils.py b/unit_tests/test_misc_utils.py deleted file mode 100644 index e9c63ce3..00000000 --- a/unit_tests/test_misc_utils.py +++ /dev/null @@ -1,134 +0,0 @@ -from mock import patch, MagicMock -from unit_tests.test_utils import CharmTestCase - - -from charmhelpers.core import hookenv -_conf = hookenv.config -hookenv.config = MagicMock() - -import hooks.misc_utils as utils - -hookenv.config = _conf - -TO_PATCH = [ - 'apt_install', - 'filter_installed_packages', - 'config', - 'log', - 'get_os_codename_package', - 'get_os_codename_install_source', - 'relation_get', - 'unit_private_ip' -] - - -class NovaCCMiscUtilsTests(CharmTestCase): - def setUp(self): - super(NovaCCMiscUtilsTests, self).setUp(utils, TO_PATCH) - self.config.side_effect = self.test_config.get - self.relation_get.side_effect = self.test_relation.get - - def _set_os_codename(self, codename): - self.get_os_codename_package.return_value = codename - - def test_network_manager_non_sdn(self): - self.test_config.set('network-manager', 'FlatDHCPManager') - self._set_os_codename('essex') - self.assertEquals('flatdhcpmanager', utils.network_manager()) - - def test_network_manager_q_n_unsupported(self): - self.test_config.set('network-manager', 'quantum') - self._set_os_codename('essex') - self.assertRaises(Exception, utils.network_manager) - - def test_network_manager_quantum_folsom(self): - self.test_config.set('network-manager', 'quantum') - self._set_os_codename('folsom') - self.assertEquals('quantum', utils.network_manager()) - - def test_network_manager_quantum_grizzly(self): - self.test_config.set('network-manager', 'neutron') - self._set_os_codename('grizzly') - self.assertEquals('quantum', utils.network_manager()) - - def test_network_manager_neutron_havana(self): - self.test_config.set('network-manager', 'neutron') - self._set_os_codename('havana') - self.assertEquals('neutron', utils.network_manager()) - - def test_network_manager_quantum_havana(self): - self.test_config.set('network-manager', 'quantum') - self._set_os_codename('havana') - self.assertEquals('neutron', utils.network_manager()) - - @patch.object(utils, 'network_manager') - def test_network_plugin_attribute_quantum(self, nm): - nm.return_value = 'quantum' - self.assertEquals( - utils.network_plugin_attribute('ovs', 'config'), - '/etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini') - - @patch.object(utils, 'network_manager') - def test_network_plugin_attribute_neutron(self, nm): - nm.return_value = 'neutron' - self.assertEquals( - utils.network_plugin_attribute('ovs', 'config'), - '/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini') - - -class NovaNeutronContextTests(CharmTestCase): - def setUp(self): - super(NovaNeutronContextTests, self).setUp(utils, TO_PATCH) - self.config.side_effect = self.test_config.get - self.relation_get.side_effect = self.test_relation.get - self.unit_private_ip.return_value = '10.0.0.1' - - def test_neutron_nova_context_nova_network(self): - ctxts = [utils.NeutronContext(), utils.NeutronCCContext(), - utils.NeutronComputeContext()] - for ctxt in ctxts: - self.assertEquals({}, ctxt()) - - @patch.object(utils, '_save_flag_file') - def test_neutron_cc_context_neutron_quantum(self, ff): - self.test_config.set('network-manager', 'Quantum') - - ex_keys = ['core_plugin', 'local_ip', - 'network_manager', 'neutron_plugin'] - - self.get_os_codename_package.return_value = 'grizzly' - ctxt = utils.NeutronCCContext() - self.assertEquals(sorted(ex_keys), sorted(ctxt().iterkeys())) - self.assertTrue(ctxt()['core_plugin'].startswith('quantum')) - - self.test_config.set('network-manager', 'Neutron') - self.get_os_codename_package.return_value = 'havana' - ctxt = utils.NeutronCCContext() - self.assertEquals(sorted(ex_keys), sorted(ctxt().iterkeys())) - self.assertTrue(ctxt()['core_plugin'].startswith('')) - - @patch.object(utils, '_save_flag_file') - def test_neutron_compute_context_quantum(self, ff): - self.test_relation.set({ - 'network_manager': 'quantum', - 'quantum_plugin': 'ovs', - 'quantum_security_groups': 'yes', - }) - - ex_keys = ['network_manager', 'neutron_security_groups', - 'neutron_firewall_driver', 'local_ip', 'core_plugin', - 'neutron_plugin', 'libvirt_vif_driver'] - - self.test_config.set('network-manager', 'Quantum') - self.get_os_codename_package.return_value = 'folsom' - ctxt = utils.NeutronComputeContext() - result = ctxt() - self.assertTrue(ctxt()['core_plugin'].startswith('quantum')) - self.assertEquals(sorted(ex_keys), sorted(result)) - - self.test_config.set('network-manager', 'Neutron') - self.get_os_codename_package.return_value = 'havana' - ctxt = utils.NeutronComputeContext() - result = ctxt() - self.assertTrue(ctxt()['core_plugin'].startswith('neutron')) - self.assertEquals(sorted(ex_keys), sorted(result))