diff --git a/hooks/ceph_radosgw_context.py b/hooks/ceph_radosgw_context.py index d6fca54b..dfca00c6 100644 --- a/hooks/ceph_radosgw_context.py +++ b/hooks/ceph_radosgw_context.py @@ -9,8 +9,11 @@ from charmhelpers.core.hookenv import ( relation_ids, related_units, relation_get, + unit_get, ) import socket +import dns.resolver + class HAProxyContext(context.HAProxyContext): @@ -36,20 +39,21 @@ class HAProxyContext(context.HAProxyContext): return ctxt -class IdentityServiceContext(context.IdentityServiceContext): - interfaces = ['identity-service'] +class IdentityServiceContext(context.IdentityServiceContext): + interfaces = ['identity-service'] - def __call__(self): - ctxt = super(IdentityServiceContext, self).__call__() - if not ctxt: + def __call__(self): + ctxt = super(IdentityServiceContext, self).__call__() + if not ctxt: return + ctxt['admin_token'] = None for relid in relation_ids('identity-service'): for unit in related_units(relid): if not ctxt.get('admin_token'): ctxt['admin_token'] = \ relation_get('admin_token', unit, relid) - + ctxt['auth_type'] = 'keystone' ctxt['user_roles'] = config('operator-roles') ctxt['cache_size'] = config('cache-size') @@ -57,11 +61,11 @@ class IdentityServiceContext(context.IdentityServiceContext): if self.context_complete(ctxt): return ctxt - return {} + return {} -class MonContext(context.OSContextGenerator): - interfaces = ['mon'] +class MonContext(context.OSContextGenerator): + interfaces = ['ceph-radosgw'] def __call__(self): if not relation_ids('mon'): @@ -70,12 +74,14 @@ class MonContext(context.OSContextGenerator): auth = 'none' for relid in relation_ids('mon'): for unit in related_units(relid): - host_ip = self.get_host_ip(relation_get('ceph-public-address', - unit, relid)) - hosts.append('{}:6789'.format(host_ip)) - _auth = relation_get('auth', unit, relid) - if _auth: - auth = _auth + ceph_public_addr = relation_get('ceph-public-address', unit, + relid) + if ceph_public_addr: + host_ip = self.get_host_ip(ceph_public_addr) + hosts.append('{}:6789'.format(host_ip)) + _auth = relation_get('auth', unit, relid) + if _auth: + auth = _auth hosts.sort() ctxt = { 'auth_supported': auth, @@ -84,13 +90,12 @@ class MonContext(context.OSContextGenerator): 'old_auth': cmp_pkgrevno('radosgw', "0.51") < 0, 'use_syslog': str(config('use-syslog')).lower(), 'embedded_webserver': config('use-embedded-webserver'), - } + } if self.context_complete(ctxt): - print ctxt return ctxt - return {} + return {} def get_host_ip(self, hostname=None): try: diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index 49c04de0..faa4d79b 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -574,6 +574,7 @@ class HAProxyContext(OSContextGenerator): if not relation_ids('cluster') and not self.singlenode_mode: return {} + print "config('prefer-ipv6'): {}".format(config('prefer-ipv6')) if config('prefer-ipv6'): addr = get_ipv6_addr(exc_list=[config('vip')])[0] else: diff --git a/hooks/hooks.py b/hooks/hooks.py index 4912b5e1..8898706b 100755 --- a/hooks/hooks.py +++ b/hooks/hooks.py @@ -16,7 +16,6 @@ import ceph from charmhelpers.core.hookenv import ( relation_get, relation_ids, - related_units, config, unit_get, open_port, @@ -37,7 +36,6 @@ from charmhelpers.core.host import ( ) from utils import ( render_template, - get_host_ip, enable_pocket, is_apache_24, CEPHRG_HA_RES, @@ -48,7 +46,6 @@ from utils import ( from charmhelpers.payload.execd import execd_preinstall from charmhelpers.core.host import cmp_pkgrevno -from socket import gethostname as get_unit_hostname from charmhelpers.contrib.network.ip import ( get_iface_for_address, @@ -59,7 +56,7 @@ from charmhelpers.contrib.openstack.ip import ( PUBLIC, INTERNAL, ADMIN, ) from charmhelpers.contrib.openstack.utils import ( - os_workload_status, + set_os_workload_status, ) hooks = Hooks() CONFIGS = register_configs() @@ -116,42 +113,15 @@ def install_packages(): @hooks.hook('install.real') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) def install(): status_set('maintenance', 'Executing pre-install') execd_preinstall() enable_pocket('multiverse') install_packages() os.makedirs(NSS_DIR) - - -def emit_cephconf(): - # Ensure ceph directory actually exists if not os.path.exists('/etc/ceph'): os.makedirs('/etc/ceph') - cephcontext = { - 'auth_supported': get_auth() or 'none', - 'mon_hosts': ' '.join(get_mon_hosts()), - 'hostname': get_unit_hostname(), - 'old_auth': cmp_pkgrevno('radosgw', "0.51") < 0, - 'use_syslog': str(config('use-syslog')).lower(), - 'embedded_webserver': config('use-embedded-webserver'), - } - - # Check to ensure that correct version of ceph is - # in use - if cmp_pkgrevno('radosgw', '0.55') >= 0: - # Add keystone configuration if found - ks_conf = get_keystone_conf() - if ks_conf: - cephcontext.update(ks_conf) - - print cephcontext - with open('/etc/ceph/ceph.conf', 'w') as cephconf: - cephconf.write(render_template('ceph.conf', cephcontext)) - def emit_apacheconf(): apachecontext = { @@ -187,13 +157,10 @@ def apache_ports(): @hooks.hook('upgrade-charm', 'config-changed') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) @restart_on_change({'/etc/ceph/ceph.conf': ['radosgw'], '/etc/haproxy/haproxy.cfg': ['haproxy']}) def config_changed(): install_packages() - emit_cephconf() CONFIGS.write_all() if not config('use-embedded-webserver'): status_set('maintenance', 'configuring apache') @@ -207,60 +174,11 @@ def config_changed(): identity_joined(relid=r_id) -def get_mon_hosts(): - hosts = [] - for relid in relation_ids('mon'): - for unit in related_units(relid): - host_ip = get_host_ip(relation_get('ceph-public-address', - unit, relid)) - hosts.append('{}:6789'.format(host_ip)) - - hosts.sort() - return hosts - - -def get_auth(): - return get_conf('auth') - - -def get_conf(name): - for relid in relation_ids('mon'): - for unit in related_units(relid): - conf = relation_get(name, - unit, relid) - if conf: - return conf - return None - - -def get_keystone_conf(): - for relid in relation_ids('identity-service'): - for unit in related_units(relid): - ks_auth = { - 'auth_type': 'keystone', - 'auth_protocol': - relation_get('auth_protocol', unit, relid) or "http", - 'auth_host': relation_get('auth_host', unit, relid), - 'auth_port': relation_get('auth_port', unit, relid), - 'admin_token': relation_get('admin_token', unit, relid), - 'user_roles': config('operator-roles'), - 'cache_size': config('cache-size'), - 'revocation_check_interval': - config('revocation-check-interval') - } - if None not in ks_auth.itervalues(): - print ks_auth - return ks_auth - return None - - @hooks.hook('mon-relation-departed', 'mon-relation-changed') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) @restart_on_change({'/etc/ceph/ceph.conf': ['radosgw']}) def mon_relation(): - emit_cephconf() + CONFIGS.write_all() key = relation_get('radosgw_key') if key: ceph.import_radosgw_key(key) @@ -289,8 +207,6 @@ def restart(): @hooks.hook('identity-service-relation-joined') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) def identity_joined(relid=None): if cmp_pkgrevno('radosgw', '0.55') < 0: log('Integration with keystone requires ceph >= 0.55') @@ -311,18 +227,14 @@ def identity_joined(relid=None): @hooks.hook('identity-service-relation-changed') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) @restart_on_change({'/etc/ceph/ceph.conf': ['radosgw']}) def identity_changed(): - emit_cephconf() + CONFIGS.write_all() restart() @hooks.hook('cluster-relation-changed', 'cluster-relation-joined') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) @restart_on_change({'/etc/haproxy/haproxy.cfg': ['haproxy']}) def cluster_changed(): CONFIGS.write_all() @@ -331,8 +243,6 @@ def cluster_changed(): @hooks.hook('ha-relation-joined') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) def ha_relation_joined(): # Obtain the config values necessary for the cluster config. These # include multicast port and interface to bind to. @@ -385,8 +295,6 @@ def ha_relation_joined(): @hooks.hook('ha-relation-changed') -@os_workload_status(CONFIGS, REQUIRED_INTERFACES, - charm_func=check_optional_relations) def ha_relation_changed(): clustered = relation_get('clustered') if clustered: @@ -403,3 +311,5 @@ if __name__ == '__main__': hooks.execute(sys.argv) except UnregisteredHookError as e: log('Unknown hook {} - skipping.'.format(e)) + set_os_workload_status(CONFIGS, REQUIRED_INTERFACES, + charm_func=check_optional_relations) diff --git a/hooks/install b/hooks/install index 83a9d3ce..fa9f910f 100755 --- a/hooks/install +++ b/hooks/install @@ -2,7 +2,7 @@ # Wrapper to deal with newer Ubuntu versions that don't have py2 installed # by default. -declare -a DEPS=('apt' 'netaddr' 'netifaces' 'pip' 'yaml') +declare -a DEPS=('apt' 'netaddr' 'netifaces' 'pip' 'yaml' 'jinja2' 'dnspython') check_and_install() { pkg="${1}-${2}" diff --git a/hooks/utils.py b/hooks/utils.py index 95c80595..9681a3c7 100644 --- a/hooks/utils.py +++ b/hooks/utils.py @@ -9,10 +9,11 @@ import socket import re import os +import dns.resolver +import jinja2 from copy import deepcopy from collections import OrderedDict from charmhelpers.core.hookenv import unit_get, relation_ids, status_get -from charmhelpers.fetch import apt_install from charmhelpers.contrib.openstack import context, templating from charmhelpers.contrib.openstack.utils import set_os_workload_status from charmhelpers.contrib.hahelpers.cluster import get_hacluster_config @@ -44,18 +45,6 @@ BASE_RESOURCE_MAP = OrderedDict([ }), ]) -try: - import jinja2 -except ImportError: - apt_install('python-jinja2', fatal=True) - import jinja2 - -try: - import dns.resolver -except ImportError: - apt_install('python-dnspython', fatal=True) - import dns.resolver - def resource_map(): ''' diff --git a/unit_tests/test_hooks.py b/unit_tests/test_hooks.py index fe568690..77b15031 100644 --- a/unit_tests/test_hooks.py +++ b/unit_tests/test_hooks.py @@ -23,6 +23,7 @@ with patch('charmhelpers.fetch.apt_install'): import hooks as ceph_hooks TO_PATCH = [ + 'CONFIGS', 'add_source', 'apt_update', 'apt_install', @@ -31,22 +32,20 @@ TO_PATCH = [ 'cmp_pkgrevno', 'execd_preinstall', 'enable_pocket', - 'get_host_ip', 'get_iface_for_address', 'get_netmask_for_address', - 'get_unit_hostname', 'glob', 'is_apache_24', 'log', 'lsb_release', 'open_port', 'os', - 'related_units', 'relation_ids', 'relation_set', 'relation_get', 'render_template', 'shutil', + 'status_set', 'subprocess', 'sys', 'unit_get', @@ -123,30 +122,30 @@ class CephRadosGWTests(CharmTestCase): self.enable_pocket.assert_called_with('multiverse') self.os.makedirs.called_with('/var/lib/ceph/nss') - def test_emit_cephconf(self): - _get_keystone_conf = self.patch('get_keystone_conf') - _get_auth = self.patch('get_auth') - _get_mon_hosts = self.patch('get_mon_hosts') - _get_auth.return_value = 'cephx' - _get_keystone_conf.return_value = {'keystone_key': 'keystone_value'} - _get_mon_hosts.return_value = ['10.0.0.1:6789', '10.0.0.2:6789'] - self.get_unit_hostname.return_value = 'bob' - self.os.path.exists.return_value = False - cephcontext = { - 'auth_supported': 'cephx', - 'mon_hosts': '10.0.0.1:6789 10.0.0.2:6789', - 'hostname': 'bob', - 'old_auth': False, - 'use_syslog': 'false', - 'keystone_key': 'keystone_value', - 'embedded_webserver': False, - } - self.cmp_pkgrevno.return_value = 1 - with patch_open() as (_open, _file): - ceph_hooks.emit_cephconf() - self.os.makedirs.assert_called_with('/etc/ceph') - _open.assert_called_with('/etc/ceph/ceph.conf', 'w') - self.render_template.assert_called_with('ceph.conf', cephcontext) +# def test_emit_cephconf(self): +# _get_keystone_conf = self.patch('get_keystone_conf') +# _get_auth = self.patch('get_auth') +# _get_mon_hosts = self.patch('get_mon_hosts') +# _get_auth.return_value = 'cephx' +# _get_keystone_conf.return_value = {'keystone_key': 'keystone_value'} +# _get_mon_hosts.return_value = ['10.0.0.1:6789', '10.0.0.2:6789'] +# self.get_unit_hostname.return_value = 'bob' +# self.os.path.exists.return_value = False +# cephcontext = { +# 'auth_supported': 'cephx', +# 'mon_hosts': '10.0.0.1:6789 10.0.0.2:6789', +# 'hostname': 'bob', +# 'old_auth': False, +# 'use_syslog': 'false', +# 'keystone_key': 'keystone_value', +# 'embedded_webserver': False, +# } +# self.cmp_pkgrevno.return_value = 1 +# with patch_open() as (_open, _file): +# ceph_hooks.emit_cephconf() +# self.os.makedirs.assert_called_with('/etc/ceph') +# _open.assert_called_with('/etc/ceph/ceph.conf', 'w') +# self.render_template.assert_called_with('ceph.conf', cephcontext) def test_emit_apacheconf(self): self.is_apache_24.return_value = True @@ -195,7 +194,6 @@ class CephRadosGWTests(CharmTestCase): def test_config_changed(self): _install_packages = self.patch('install_packages') - _emit_cephconf = self.patch('emit_cephconf') _emit_apacheconf = self.patch('emit_apacheconf') _install_www_scripts = self.patch('install_www_scripts') _apache_sites = self.patch('apache_sites') @@ -203,105 +201,30 @@ class CephRadosGWTests(CharmTestCase): _apache_reload = self.patch('apache_reload') ceph_hooks.config_changed() _install_packages.assert_called() - _emit_cephconf.assert_called() + self.CONFIGS.write_all.assert_called_with() _emit_apacheconf.assert_called() _install_www_scripts.assert_called() _apache_sites.assert_called() _apache_modules.assert_called() _apache_reload.assert_called() - def test_get_mon_hosts(self): - self.relation_ids.return_value = ['monrelid'] - self.related_units.return_value = ['monunit'] - - def rel_get(k, *args): - return {'private-address': '127.0.0.1', - 'ceph-public-address': '10.0.0.1'}[k] - - self.relation_get.side_effect = rel_get - self.get_host_ip.side_effect = lambda x: x - self.assertEquals(ceph_hooks.get_mon_hosts(), ['10.0.0.1:6789']) - - def test_get_conf(self): - self.relation_ids.return_value = ['monrelid'] - self.related_units.return_value = ['monunit'] - self.relation_get.return_value = 'bob' - self.assertEquals(ceph_hooks.get_conf('key'), 'bob') - - def test_get_conf_nomatch(self): - self.relation_ids.return_value = ['monrelid'] - self.related_units.return_value = ['monunit'] - self.relation_get.return_value = '' - self.assertEquals(ceph_hooks.get_conf('key'), None) - - def test_get_auth(self): - self.relation_ids.return_value = ['monrelid'] - self.related_units.return_value = ['monunit'] - self.relation_get.return_value = 'bob' - self.assertEquals(ceph_hooks.get_auth(), 'bob') - - def test_get_keystone_conf(self): - self.test_config.set('operator-roles', 'admin') - self.test_config.set('cache-size', '42') - self.test_config.set('revocation-check-interval', '21') - self.relation_ids.return_value = ['idrelid'] - self.related_units.return_value = ['idunit'] - - def _relation_get(key, unit, relid): - ks_dict = { - 'auth_protocol': 'https', - 'auth_host': '10.0.0.2', - 'auth_port': '8090', - 'admin_token': 'sectocken', - } - return ks_dict[key] - self.relation_get.side_effect = _relation_get - self.assertEquals(ceph_hooks.get_keystone_conf(), { - 'auth_type': 'keystone', - 'auth_protocol': 'https', - 'admin_token': 'sectocken', - 'user_roles': 'admin', - 'auth_host': '10.0.0.2', - 'cache_size': '42', - 'auth_port': '8090', - 'revocation_check_interval': '21'}) - - def test_get_keystone_conf_missinginfo(self): - self.test_config.set('operator-roles', 'admin') - self.test_config.set('cache-size', '42') - self.test_config.set('revocation-check-interval', '21') - self.relation_ids.return_value = ['idrelid'] - self.related_units.return_value = ['idunit'] - - def _relation_get(key, unit, relid): - ks_dict = { - 'auth_protocol': 'https', - 'auth_host': '10.0.0.2', - 'auth_port': '8090', - } - return ks_dict[key] if key in ks_dict else None - self.relation_get.side_effect = _relation_get - self.assertEquals(ceph_hooks.get_keystone_conf(), None) - def test_mon_relation(self): - _emit_cephconf = self.patch('emit_cephconf') _ceph = self.patch('ceph') _restart = self.patch('restart') self.relation_get.return_value = 'seckey' ceph_hooks.mon_relation() _restart.assert_called() _ceph.import_radosgw_key.assert_called_with('seckey') - _emit_cephconf.assert_called() + self.CONFIGS.write_all.assert_called_with() def test_mon_relation_nokey(self): - _emit_cephconf = self.patch('emit_cephconf') _ceph = self.patch('ceph') _restart = self.patch('restart') self.relation_get.return_value = None ceph_hooks.mon_relation() self.assertFalse(_ceph.import_radosgw_key.called) self.assertFalse(_restart.called) - _emit_cephconf.assert_called() + self.CONFIGS.write_all.assert_called_with() def test_gateway_relation(self): self.unit_get.return_value = 'myserver' @@ -374,10 +297,9 @@ class CephRadosGWTests(CharmTestCase): admin_url='http://myserv:80/swift') def test_identity_changed(self): - _emit_cephconf = self.patch('emit_cephconf') _restart = self.patch('restart') ceph_hooks.identity_changed() - _emit_cephconf.assert_called() + self.CONFIGS.write_all.assert_called_with() _restart.assert_called() @patch('charmhelpers.contrib.openstack.ip.is_clustered') @@ -391,12 +313,11 @@ class CephRadosGWTests(CharmTestCase): self.assertEquals(ceph_hooks.canonical_url({}, PUBLIC), 'http://[%s]' % ipv6_addr) - @patch.object(ceph_hooks, 'CONFIGS') - def test_cluster_changed(self, configs): + def test_cluster_changed(self): _id_joined = self.patch('identity_joined') self.relation_ids.return_value = ['rid'] ceph_hooks.cluster_changed() - configs.write_all.assert_called() + self.CONFIGS.write_all.assert_called_with() _id_joined.assert_called_with(relid='rid') def test_ha_relation_joined_no_vip(self):