2014-02-25 12:34:13 +01:00
|
|
|
from charmhelpers.core.hookenv import (
|
|
|
|
config, unit_private_ip)
|
|
|
|
|
|
|
|
from charmhelpers.contrib.openstack import context
|
|
|
|
|
|
|
|
from charmhelpers.contrib.hahelpers.cluster import (
|
|
|
|
determine_apache_port,
|
|
|
|
determine_api_port,
|
|
|
|
is_clustered,
|
|
|
|
)
|
|
|
|
|
|
|
|
from subprocess import (
|
|
|
|
check_call
|
|
|
|
)
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
|
|
|
CA_CERT_PATH = '/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt'
|
|
|
|
|
2014-02-26 17:28:37 +00:00
|
|
|
|
2014-02-25 12:34:13 +01:00
|
|
|
class ApacheSSLContext(context.ApacheSSLContext):
|
|
|
|
|
|
|
|
interfaces = ['https']
|
|
|
|
external_ports = []
|
|
|
|
service_namespace = 'keystone'
|
|
|
|
|
|
|
|
def __call__(self):
|
|
|
|
# late import to work around circular dependency
|
|
|
|
from keystone_utils import determine_ports
|
|
|
|
self.external_ports = determine_ports()
|
|
|
|
return super(ApacheSSLContext, self).__call__()
|
|
|
|
|
|
|
|
def configure_cert(self):
|
2014-05-21 11:02:01 +01:00
|
|
|
# import keystone_ssl as ssl
|
2014-02-25 12:34:13 +01:00
|
|
|
from keystone_utils import SSH_USER, get_ca
|
|
|
|
if not os.path.isdir('/etc/apache2/ssl'):
|
|
|
|
os.mkdir('/etc/apache2/ssl')
|
|
|
|
ssl_dir = os.path.join('/etc/apache2/ssl/', self.service_namespace)
|
|
|
|
if not os.path.isdir(ssl_dir):
|
|
|
|
os.mkdir(ssl_dir)
|
|
|
|
if is_clustered():
|
|
|
|
https_cn = config('vip')
|
|
|
|
else:
|
|
|
|
https_cn = unit_private_ip()
|
|
|
|
ca = get_ca(user=SSH_USER)
|
|
|
|
cert, key = ca.get_cert_and_key(common_name=https_cn)
|
|
|
|
with open(os.path.join(ssl_dir, 'cert'), 'w') as cert_out:
|
|
|
|
cert_out.write(cert)
|
|
|
|
with open(os.path.join(ssl_dir, 'key'), 'w') as key_out:
|
|
|
|
key_out.write(key)
|
|
|
|
if ca:
|
|
|
|
with open(CA_CERT_PATH, 'w') as ca_out:
|
|
|
|
ca_out.write(ca.get_ca_bundle())
|
|
|
|
check_call(['update-ca-certificates'])
|
|
|
|
|
|
|
|
|
|
|
|
class HAProxyContext(context.HAProxyContext):
|
|
|
|
interfaces = []
|
|
|
|
|
|
|
|
def __call__(self):
|
|
|
|
'''
|
|
|
|
Extends the main charmhelpers HAProxyContext with a port mapping
|
|
|
|
specific to this charm.
|
|
|
|
Also used to extend nova.conf context with correct api_listening_ports
|
|
|
|
'''
|
|
|
|
from keystone_utils import api_port
|
|
|
|
ctxt = super(HAProxyContext, self).__call__()
|
|
|
|
|
|
|
|
# determine which port api processes should bind to, depending
|
|
|
|
# on existence of haproxy + apache frontends
|
|
|
|
listen_ports = {}
|
|
|
|
listen_ports['admin_port'] = api_port('keystone-admin')
|
|
|
|
listen_ports['public_port'] = api_port('keystone-public')
|
|
|
|
|
|
|
|
# Apache ports
|
|
|
|
a_admin_port = determine_apache_port(api_port('keystone-admin'))
|
|
|
|
a_public_port = determine_apache_port(api_port('keystone-public'))
|
|
|
|
|
|
|
|
port_mapping = {
|
|
|
|
'admin-port': [
|
|
|
|
api_port('keystone-admin'), a_admin_port],
|
|
|
|
'public-port': [
|
|
|
|
api_port('keystone-public'), a_public_port],
|
|
|
|
}
|
|
|
|
|
|
|
|
# for haproxy.conf
|
|
|
|
ctxt['service_ports'] = port_mapping
|
|
|
|
# for keystone.conf
|
|
|
|
ctxt['listen_ports'] = listen_ports
|
|
|
|
return ctxt
|
|
|
|
|
|
|
|
|
|
|
|
class KeystoneContext(context.OSContextGenerator):
|
|
|
|
interfaces = []
|
|
|
|
|
|
|
|
def __call__(self):
|
2014-09-21 18:57:48 +01:00
|
|
|
from keystone_utils import (
|
|
|
|
api_port, set_admin_token,
|
|
|
|
endpoint_url, resolve_address,
|
|
|
|
PUBLIC, ADMIN
|
|
|
|
)
|
2014-02-25 12:34:13 +01:00
|
|
|
ctxt = {}
|
2014-03-28 11:34:38 +00:00
|
|
|
ctxt['token'] = set_admin_token(config('admin-token'))
|
2014-02-25 12:34:13 +01:00
|
|
|
ctxt['admin_port'] = determine_api_port(api_port('keystone-admin'))
|
|
|
|
ctxt['public_port'] = determine_api_port(api_port('keystone-public'))
|
2014-02-26 17:28:37 +00:00
|
|
|
ctxt['debug'] = config('debug') in ['yes', 'true', 'True']
|
|
|
|
ctxt['verbose'] = config('verbose') in ['yes', 'true', 'True']
|
2014-08-11 17:23:45 +08:00
|
|
|
ctxt['identity_backend'] = config('identity-backend')
|
|
|
|
ctxt['assignment_backend'] = config('assignment-backend')
|
|
|
|
if config('identity-backend') == 'ldap':
|
|
|
|
ctxt['ldap_server'] = config('ldap-server')
|
|
|
|
ctxt['ldap_user'] = config('ldap-user')
|
|
|
|
ctxt['ldap_password'] = config('ldap-password')
|
|
|
|
ctxt['ldap_suffix'] = config('ldap-suffix')
|
2014-08-12 13:39:51 +08:00
|
|
|
ctxt['ldap_readonly'] = config('ldap-readonly')
|
2014-08-11 17:23:45 +08:00
|
|
|
ldap_flags = config('ldap-config-flags')
|
|
|
|
if ldap_flags:
|
|
|
|
flags = context.config_flags_parser(ldap_flags)
|
|
|
|
ctxt['ldap_config_flags'] = flags
|
|
|
|
|
2014-02-25 12:34:13 +01:00
|
|
|
if config('enable-pki') not in ['false', 'False', 'no', 'No']:
|
|
|
|
ctxt['signing'] = True
|
2014-09-21 18:57:48 +01:00
|
|
|
|
2014-09-22 09:32:02 +01:00
|
|
|
# Base endpoint URL's which are used in keystone responses
|
|
|
|
# to unauthenticated requests to redirect clients to the
|
|
|
|
# correct auth URL.
|
|
|
|
ctxt['public_endpoint'] = endpoint_url(
|
|
|
|
resolve_address(PUBLIC),
|
2014-09-22 09:39:54 +01:00
|
|
|
api_port('keystone-public')).rstrip('v2.0')
|
2014-09-22 09:32:02 +01:00
|
|
|
ctxt['admin_endpoint'] = endpoint_url(
|
|
|
|
resolve_address(ADMIN),
|
2014-09-22 09:39:54 +01:00
|
|
|
api_port('keystone-admin')).rstrip('v2.0')
|
2014-02-25 12:34:13 +01:00
|
|
|
return ctxt
|