diff --git a/config.yaml b/config.yaml index 140e8da..07a6db4 100644 --- a/config.yaml +++ b/config.yaml @@ -30,3 +30,7 @@ options: default: heat type: string description: Database name + region: + default: RegionOne + type: string + description: OpenStack Region diff --git a/hooks/heat_context.py b/hooks/heat_context.py index 3ce118a..3b2e64a 100644 --- a/hooks/heat_context.py +++ b/hooks/heat_context.py @@ -6,17 +6,3 @@ from charmhelpers.contrib.openstack import context, neutron, utils from charmhelpers.contrib.hahelpers.cluster import ( determine_api_port, determine_haproxy_port) - - -class IdentityServiceContext(context.IdentityServiceContext): - def __call__(self): - ctxt = super(IdentityServiceContext, self).__call__() - if not ctxt: - return - - # the ec2 api needs to know the location of the keystone ec2 - # tokens endpoint, set in heat.conf - ec2_tokens = 'http://%s:%s/v2.0/ec2tokens' % (ctxt['service_host'], - ctxt['service_port']) - ctxt['keystone_ec2_url'] = ec2_tokens - return ctxt diff --git a/hooks/hooks.py b/hooks/hooks.py index 74c2f3f..06d4cf9 100755 --- a/hooks/hooks.py +++ b/hooks/hooks.py @@ -42,17 +42,20 @@ from charmhelpers.contrib.openstack.utils import ( configure_installation_source, ) + +from charmhelpers.contrib.hahelpers.cluster import ( + canonical_url +) + from utils import ( api_port, auth_token_config, - determine_endpoints, determine_packages, - determine_ports, - keystone_ca_cert_b64, save_script_rc, register_configs, - restart_map, - HEAT_CONF + HEAT_CONF, + HEAT_API_PASTE, + API_PORTS ) from charmhelpers.payload.execd import execd_preinstall @@ -74,11 +77,14 @@ def install(): f = os.path.join(_files, f) log('Installing %s to /usr/bin' % f) shutil.copy2(f, '/usr/bin') - [open_port(port) for port in determine_ports()] + + for key, port in API_PORTS.iteritems(): + open_port(port) @hooks.hook('config-changed') -@restart_on_change(restart_map()) def config_changed(): + if not os.path.isdir('/etc/heat'): + os.mkdir('/etc/heat') save_script_rc() CONFIGS.write_all() @@ -90,7 +96,6 @@ def amqp_joined(relation_id=None): @hooks.hook('amqp-relation-changed') -@restart_on_change(restart_map()) def amqp_changed(): if 'amqp' not in CONFIGS.complete_contexts(): log('amqp relation incomplete. Peer not ready?') @@ -106,7 +111,6 @@ def db_joined(): @hooks.hook('shared-db-relation-changed') -@restart_on_change(restart_map()) def db_changed(): if 'shared-db' not in CONFIGS.complete_contexts(): log('shared-db relation incomplete. Peer not ready?') @@ -118,48 +122,32 @@ def db_changed(): @hooks.hook('identity-service-relation-joined') def identity_joined(rid=None): base_url = canonical_url(CONFIGS) - relation_set(relation_id=rid, **determine_endpoints(base_url)) + api_url = '%s:8004/v1/$(tenant_id)s' % base_url + cfn_url = '%s:8000/v1' % base_url + relation_data = { + 'heat_service': 'heat', + 'heat_region': config('region'), + 'heat_public_url': api_url, + 'heat_admin_url': api_url, + 'heat_internal_url': api_url, + 'heat-cfn_service': 'heat-cfn', + 'heat-cfn_region': config('region'), + 'heat-cfn_public_url': cfn_url, + 'heat-cfn_admin_url': cfn_url, + 'heat-cfn_internal_url': cfn_url, + } + relation_set(relation_id=rid, **relation_data) @hooks.hook('identity-service-relation-changed') -@restart_on_change(restart_map()) def identity_changed(): if 'identity-service' not in CONFIGS.complete_contexts(): log('identity-service relation incomplete. Peer not ready?') return - CONFIGS.write('/etc/heat/api-paste.ini') + CONFIGS.write(HEAT_API_PASTE) CONFIGS.write(HEAT_CONF) -def _auth_config(): - '''Grab all KS auth token config from api-paste.ini, or return empty {}''' - ks_auth_host = auth_token_config('auth_host') - if not ks_auth_host: - # if there is no auth_host set, identity-service changed hooks - # have not fired, yet. - return {} - cfg = { - 'auth_host': ks_auth_host, - 'auth_port': auth_token_config('auth_port'), - 'service_port': auth_token_config('service_port'), - 'service_username': auth_token_config('admin_user'), - 'service_password': auth_token_config('admin_password'), - 'service_tenant_name': auth_token_config('admin_tenant_name'), - 'auth_uri': auth_token_config('auth_uri') - } - return cfg - - -def keystone_compute_settings(): - ks_auth_config = _auth_config() - rel_settings = {} - - ks_ca = keystone_ca_cert_b64() - if ks_auth_config and ks_ca: - rel_settings['ca_cert'] = ks_ca - - return rel_settings - @hooks.hook('amqp-relation-broken', 'identity-service-relation-broken', diff --git a/hooks/utils.py b/hooks/utils.py index 7583591..6452492 100644 --- a/hooks/utils.py +++ b/hooks/utils.py @@ -62,68 +62,42 @@ API_PORTS = { HEAT_CONF = '/etc/heat/heat.conf' HEAT_API_PASTE = '/etc/heat/api-paste.ini' -BASE_RESOURCE_MAP = OrderedDict([ +CONFIG_FILES = OrderedDict([ (HEAT_CONF, { 'services': BASE_SERVICES, 'contexts': [context.AMQPContext(), context.SharedDBContext(relation_prefix='heat'), context.OSConfigFlagContext(), - heat_context.IdentityServiceContext()] + context.IdentityServiceContext()] }), (HEAT_API_PASTE, { 'services': [s for s in BASE_SERVICES if 'api' in s], - 'contexts': [heat_context.IdentityServiceContext()], + 'contexts': [context.IdentityServiceContext()], }) ]) CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt' -def resource_map(): - ''' - Dynamically generate a map of resources that will be managed for a single - hook execution. - ''' - resource_map = deepcopy(BASE_RESOURCE_MAP) - - return resource_map - def register_configs(): release = os_release('heat-engine') configs = templating.OSConfigRenderer(templates_dir=TEMPLATES, openstack_release=release) - for cfg, rscs in resource_map().iteritems(): - configs.register(cfg, rscs['contexts']) + + confs = [HEAT_CONF, HEAT_API_PASTE] + for conf in confs: + configs.register(conf, CONFIG_FILES[conf]['contexts']) + return configs -def restart_map(): - return OrderedDict([(cfg, v['services']) - for cfg, v in resource_map().iteritems() - if v['services']]) - - -def determine_ports(): - '''Assemble a list of API ports for services we are managing''' - ports = [] - for cfg, services in restart_map().iteritems(): - for service in services: - try: - ports.append(API_PORTS[service]) - except KeyError: - pass - return list(set(ports)) - - def api_port(service): return API_PORTS[service] def determine_packages(): # currently all packages match service names - packages = [] + BASE_PACKAGES - for k, v in resource_map().iteritems(): - packages.extend(v['services']) + packages = BASE_PACKAGES + BASE_SERVICES return list(set(packages)) @@ -150,27 +124,3 @@ def auth_token_config(setting): if value.startswith('%'): return None return value - - -def keystone_ca_cert_b64(): - '''Returns the local Keystone-provided CA cert if it exists, or None.''' - if not os.path.isfile(CA_CERT_PATH): - return None - with open(CA_CERT_PATH) as _in: - return b64encode(_in.read()) - - -def determine_endpoints(url): - '''Generates a dictionary containing all relevant endpoints to be - passed to keystone as relation settings.''' - region = config('region') - - heat_url = ('%s:%s/$(tenant_id)s' % - (url, api_port('heat-api-cfn'))) - - # the base endpoints - endpoints = { - 'heat_service': 'heat', - } - - return endpoints diff --git a/revision b/revision index d00491f..0cfbf08 100644 --- a/revision +++ b/revision @@ -1 +1 @@ -1 +2 diff --git a/templates/etc_heat_api-paste.ini b/templates/etc_heat_api-paste.ini index 92526a0..f33c40b 100644 --- a/templates/etc_heat_api-paste.ini +++ b/templates/etc_heat_api-paste.ini @@ -76,6 +76,13 @@ paste.filter_factory = heat.api.aws.ec2token:EC2Token_filter_factory # Auth middleware that validates token against keystone [filter:authtoken] paste.filter_factory = heat.common.auth_token:filter_factory +auth_host = {{ auth_host }} +auth_port = {{ auth_port }} +auth_protocol = {{ auth_protocol }} +auth_uri = http://{{ service_host }}:{{ service_port }}/v2.0 +admin_tenant_name = {{ admin_tenant_name }} +admin_user = {{ admin_user }} +admin_password = {{ admin_password }} # Auth middleware that validates username/password against keystone [filter:authpassword] diff --git a/templates/heat.conf b/templates/heat.conf index 68c80f4..6a612dc 100644 --- a/templates/heat.conf +++ b/templates/heat.conf @@ -40,6 +40,21 @@ rabbit_use_ssl = false sql_connection = mysql://{{ database_user }}:{{ database_password }}@{{ database_host }}/{{ database }} {% endif -%} +verbose = True +log_dir = /var/log/heat + +[keystone_authtoken] +auth_host = 127.0.0.1 +auth_port = 35357 +auth_protocol = http +admin_tenant_name = %SERVICE_TENANT_NAME% +admin_user = %SERVICE_USER% +admin_password = %SERVICE_PASSWORD% + +[ec2_authtoken] +auth_uri = {{service_protocol }}://{{ service_host }}:{{ service_port }}/v2.0 +keystone_ec2_uri = {{service_protocol }}://{{ service_host }}:{{ service_port }}/v2.0/ec2tokens + [database] # sql @@ -62,3 +77,4 @@ bind_port=8004 # The port on which the server will listen. (integer value) bind_port=8000 +