Ensure CC contexts can functioon out of relation context.

When generating cloud compute context, the generator must query the relation
in a way that can function from other hook contexts.

Drops old tests that have been moved to charm-helpers proper.
This commit is contained in:
Adam Gandelman 2013-08-22 21:15:07 -07:00
parent 6c3f0a8c9b
commit 45cc506c03
2 changed files with 80 additions and 77 deletions

View File

@ -12,6 +12,7 @@ from charmhelpers.core.hookenv import (
log,
relation_get,
relation_ids,
related_units,
service_name,
unit_get,
ERROR,
@ -45,9 +46,21 @@ def _network_manager():
def _neutron_security_groups():
groups = [relation_get('neutron_security_groups'),
relation_get('quantum_security_groups')]
return ('yes' in groups or 'Yes' in groups)
'''
Inspects current cloud-compute relation and determine if nova-c-c has
instructed us to use neutron security groups.
'''
for rid in relation_ids('cloud-compute'):
for unit in related_units('cloud-compute'):
groups = [
relation_get('neutron_security_groups',
rid=rid, unit=unit),
relation_get('quantum_security_groups',
rid=rid, unit=unit)
]
if ('yes' in groups or 'Yes' in groups):
return True
return False
def _neutron_plugin():
@ -55,8 +68,10 @@ def _neutron_plugin():
return neutron_plugin()
def _neutron_url():
return relation_get('neutron_url') or relation_get('quantum_url')
def _neutron_url(rid, unit):
# supports legacy relation settings.
return (relation_get('neutron_url', rid=rid, unit=unit) or
relation_get('quantum_url', rid=rid, unit=unit))
class NovaComputeLibvirtContext(context.OSContextGenerator):
@ -131,10 +146,19 @@ class CloudComputeContext(context.OSContextGenerator):
@property
def volume_service(self):
return relation_get('volume_service')
volume_service = None
for rid in relation_ids('cloud-compute'):
for unit in related_units(rid):
volume_service = relation_get('volume_service',
rid=rid, unit=unit)
return volume_service
def flat_dhcp_context(self):
ec2_host = relation_get('ec2_host')
ec2_host = None
for rid in relation_ids('cloud-compute'):
for unit in related_units(rid):
ec2_host = relation_get('ec2_host', rid=rid, unit=unit)
if not ec2_host:
return {}
@ -150,23 +174,41 @@ class CloudComputeContext(context.OSContextGenerator):
# generate config context for neutron or quantum. these get converted
# directly into flags in nova.conf
# NOTE: Its up to release templates to set correct driver
def _legacy_quantum(ctxt):
# rename neutron flags to support legacy quantum.
renamed = {}
for k, v in ctxt.iteritems():
k = k.replace('neutron', 'quantum')
renamed[k] = v
return renamed
neutron_ctxt = {
'neutron_auth_strategy': 'keystone',
'keystone_host': relation_get('auth_host'),
'auth_port': relation_get('auth_port'),
'neutron_admin_tenant_name': relation_get('service_tenant_name'),
'neutron_admin_username': relation_get('service_username'),
'neutron_admin_password': relation_get('service_password'),
'neutron_plugin': _neutron_plugin(),
'neutron_url': _neutron_url(),
}
neutron_ctxt = {'neutron_url': None}
for rid in relation_ids('cloud-compute'):
for unit in related_units(rid):
rel = {'rid': rid, 'unit': unit}
url = _neutron_url(**rel)
if not url:
# only bother with units that have a neutron url set.
continue
neutron_ctxt = {
'neutron_auth_strategy': 'keystone',
'keystone_host': relation_get(
'auth_host', **rel),
'auth_port': relation_get(
'auth_port', **rel),
'neutron_admin_tenant_name': relation_get(
'service_tenant_name', **rel),
'neutron_admin_username': relation_get(
'service_username', **rel),
'neutron_admin_password': relation_get(
'service_password', **rel),
'neutron_plugin': _neutron_plugin(),
'neutron_url': url,
}
missing = [k for k, v in neutron_ctxt.iteritems() if v in ['', None]]
if missing:
log('Missing required relation settings for Quantum: ' +
@ -189,20 +231,20 @@ class CloudComputeContext(context.OSContextGenerator):
# given openstack release (nova-volume is only supported for E and F)
# it is up to release templates to set the correct volume driver.
os_rel = os_release('nova-common')
vol_service = relation_get('volume_service')
if not vol_service:
if not self.volume_service:
return {}
os_rel = os_release('nova-common')
# ensure volume service is supported on specific openstack release.
if vol_service == 'cinder':
if self.volume_service == 'cinder':
if os_rel == 'essex':
e = ('Attempting to configure cinder volume manager on '
'an unsupported OpenStack release (essex)')
log(e, level=ERROR)
raise context.OSContextError(e)
return 'cinder'
elif vol_service == 'nova-volume':
elif self.volume_service == 'nova-volume':
if os_release('nova-common') not in ['essex', 'folsom']:
e = ('Attempting to configure nova-volume manager on '
'an unsupported OpenStack release (%s).' % os_rel)
@ -211,7 +253,7 @@ class CloudComputeContext(context.OSContextGenerator):
return 'nova-volume'
else:
e = ('Invalid volume service received via cloud-compute: %s' %
vol_service)
self.volume_service)
log(e, level=ERROR)
raise context.OSContextError(e)
@ -300,6 +342,7 @@ class NeutronComputeContext(context.NeutronContext):
# In addition to generating config context, ensure the OVS service
# is running and the OVS bridge exists. Also need to ensure
# local_ip points to actual IP, not hostname.
from pprint import pprint; import ipdb; ipdb.set_trace() ############################## Breakpoint ##############################
ovs_ctxt = super(NeutronComputeContext, self).ovs_ctxt()
if not ovs_ctxt:
return {}

View File

@ -1,5 +1,4 @@
from mock import MagicMock, patch
from copy import deepcopy
from mock import patch
from unit_tests.test_utils import CharmTestCase
from charmhelpers.contrib.openstack.context import OSContextError
@ -11,6 +10,7 @@ TO_PATCH = [
'filter_installed_packages',
'relation_ids',
'relation_get',
'related_units',
'config',
'log',
'os_release',
@ -70,8 +70,8 @@ class NovaComputeContextTests(CharmTestCase):
def test_cloud_compute_volume_context_cinder(self, netman):
netman.return_value = None
self.relation_ids.return_value = 'cloud-compute:0'
self.related_units.return_value = 'nova-cloud-controller/0'
cloud_compute = context.CloudComputeContext()
self.test_relation.set({'volume_service': 'cinder'})
self.assertEquals({'volume_service': 'cinder'}, cloud_compute())
@ -79,6 +79,7 @@ class NovaComputeContextTests(CharmTestCase):
def test_cloud_compute_volume_context_nova_vol(self, netman):
netman.return_value = None
self.relation_ids.return_value = 'cloud-compute:0'
self.related_units.return_value = 'nova-cloud-controller/0'
cloud_compute = context.CloudComputeContext()
self.os_release.return_value = 'essex'
self.test_relation.set({'volume_service': 'nova-volume'})
@ -99,6 +100,7 @@ class NovaComputeContextTests(CharmTestCase):
def test_cloud_compute_flatdhcp_context(self, netman):
netman.return_value = 'flatdhcpmanager'
self.relation_ids.return_value = 'cloud-compute:0'
self.related_units.return_value = 'nova-cloud-controller/0'
self.test_relation.set({
'network_manager': 'FlatDHCPManager',
'ec2_host': 'novaapihost'})
@ -116,6 +118,8 @@ class NovaComputeContextTests(CharmTestCase):
@patch.object(context, '_neutron_url')
@patch.object(context, '_network_manager')
def test_cloud_compute_quantum_context(self, netman, url, plugin):
self.relation_ids.return_value = 'cloud-compute:0'
self.related_units.return_value = 'nova-cloud-controller/0'
netman.return_value = 'quantum'
plugin.return_value = 'ovs'
url.return_value = 'http://nova-c-c:9696'
@ -140,33 +144,13 @@ class NovaComputeContextTests(CharmTestCase):
self._save_flag_file.assert_called_with(
path='/etc/nova/nm.conf', data='quantum')
# def test_quantum_plugin_context_no_setting(self):
# qplugin = context.QuantumPluginContext()
# self.assertEquals({}, qplugin())
#
# def _test_qplugin_context(self, os_release):
# self.get_os_codename_package.return_value = os_release
# self.test_relation.set(
# {'quantum_plugin': 'ovs', 'quantum_security_groups': 'yes'})
# qplugin = context.QuantumPluginContext()
# qplugin._ensure_packages = MagicMock()
# return qplugin()
#
# def test_quantum_plugin_context_ovs_folsom(self):
# ex_ctxt = deepcopy(BASE_QUANTUM_OVS_PLUGIN_CONTEXT)
# ex_ctxt['libvirt_vif_driver'] = ('nova.virt.libvirt.vif.'
# 'LibvirtHybridOVSBridgeDriver')
# self.assertEquals(ex_ctxt, self._test_qplugin_context('folsom'))
# self._save_flag_file.assert_called_with(
# path='/etc/nova/quantum_plugin.conf', data='ovs')
#
# def test_quantum_plugin_context_ovs_grizzly_and_beyond(self):
# ex_ctxt = deepcopy(BASE_QUANTUM_OVS_PLUGIN_CONTEXT)
# ex_ctxt['libvirt_vif_driver'] = ('nova.virt.libvirt.vif.'
# 'LibvirtGenericVIFDriver')
# self.assertEquals(ex_ctxt, self._test_qplugin_context('grizzly'))
# self._save_flag_file.assert_called_with(
# path='/etc/nova/quantum_plugin.conf', data='ovs')
@patch.object(context.NeutronComputeContext, 'network_manager')
@patch.object(context.NeutronComputeContext, 'plugin')
def test_quantum_plugin_context_no_setting(self, plugin, nm):
plugin.return_value = None
qplugin = context.NeutronComputeContext()
with patch.object(qplugin, '_ensure_packages'):
self.assertEquals({}, qplugin())
def test_libvirt_bin_context_no_migration(self):
self.test_config.set('enable-live-migration', False)
@ -178,27 +162,3 @@ class NovaComputeContextTests(CharmTestCase):
libvirt = context.NovaComputeLibvirtContext()
self.assertEquals(
{'libvirtd_opts': '-d -l', 'listen_tls': 1}, libvirt())
# def test_config_flag_context_none_set_in_config(self):
# flags = context.OSConfigFlagContext()
# self.assertEquals({}, flags())
#
# def test_conflig_flag_context(self):
# self.test_config.set('config-flags', 'one=two,three=four,five=six')
# flags = context.OSConfigFlagContext()
# ex = {
# 'user_config_flags': {
# 'one': 'two', 'three': 'four', 'five': 'six'
# }
# }
# self.assertEquals(ex, flags())
#
# def test_conflig_flag_context_filters_bad_input(self):
# self.test_config.set('config-flags', 'one=two,threefour,five=six')
# flags = context.OSConfigFlagContext()
# ex = {
# 'user_config_flags': {
# 'one': 'two', 'five': 'six'
# }
# }
# self.assertEquals(ex, flags())