Resync latest ssl-everywhere helpers, add ssl_ca config option

This commit is contained in:
James Page 2014-02-27 09:19:33 +00:00
parent 3b3b7f3d1e
commit 5b42343053
10 changed files with 88 additions and 47 deletions

View File

@ -1,4 +1,4 @@
branch: lp:~hazmat/charm-helpers/ssl-everywhere branch: lp:~openstack-charmers/charm-helpers/ssl-everywhere
destination: hooks/charmhelpers destination: hooks/charmhelpers
include: include:
- core - core

View File

@ -121,6 +121,11 @@ options:
ssl_key: ssl_key:
type: string type: string
description: SSL key to use with certificate specified as ssl_cert. description: SSL key to use with certificate specified as ssl_cert.
ssl_ca:
type: string
description: |
SSL CA to use with the certificate and key provided - this is only
required if you are providing a privately signed ssl_cert and ssl_key.
config-flags: config-flags:
type: string type: string
description: Comma separated list of key=value config flags to be set in cinder.conf. description: Comma separated list of key=value config flags to be set in cinder.conf.

View File

@ -39,14 +39,15 @@ def get_cert():
def get_ca_cert(): def get_ca_cert():
ca_cert = None ca_cert = config_get('ssl_ca')
log("Inspecting identity-service relations for CA SSL certificate.", if ca_cert is None:
level=INFO) log("Inspecting identity-service relations for CA SSL certificate.",
for r_id in relation_ids('identity-service'): level=INFO)
for unit in relation_list(r_id): for r_id in relation_ids('identity-service'):
if not ca_cert: for unit in relation_list(r_id):
ca_cert = relation_get('ca_cert', if ca_cert is None:
rid=r_id, unit=unit) ca_cert = relation_get('ca_cert',
rid=r_id, unit=unit)
return ca_cert return ca_cert

View File

@ -126,17 +126,17 @@ def determine_api_port(public_port):
return public_port - (i * 10) return public_port - (i * 10)
def determine_haproxy_port(public_port): def determine_apache_port(public_port):
''' '''
Description: Determine correct proxy listening port based on public IP + Description: Determine correct apache listening port based on public IP +
existence of HTTPS reverse proxy. state of the cluster.
public_port: int: standard public port for given service public_port: int: standard public port for given service
returns: int: the correct listening port for the HAProxy service returns: int: the correct listening port for the HAProxy service
''' '''
i = 0 i = 0
if https(): if len(peer_units()) > 0 or is_clustered():
i += 1 i += 1
return public_port - (i * 10) return public_port - (i * 10)

View File

@ -27,11 +27,10 @@ from charmhelpers.core.hookenv import (
) )
from charmhelpers.contrib.hahelpers.cluster import ( from charmhelpers.contrib.hahelpers.cluster import (
determine_apache_port,
determine_api_port, determine_api_port,
determine_haproxy_port,
https, https,
is_clustered, is_clustered
peer_units,
) )
from charmhelpers.contrib.hahelpers.apache import ( from charmhelpers.contrib.hahelpers.apache import (
@ -190,22 +189,19 @@ class IdentityServiceContext(OSContextGenerator):
for rid in relation_ids('identity-service'): for rid in relation_ids('identity-service'):
for unit in related_units(rid): for unit in related_units(rid):
rdata = relation_get(rid=rid, unit=unit)
ctxt = { ctxt = {
'service_port': relation_get('service_port', rid=rid, 'service_port': rdata.get('service_port'),
unit=unit), 'service_host': rdata.get('service_host'),
'service_host': relation_get('service_host', rid=rid, 'auth_host': rdata.get('auth_host'),
unit=unit), 'auth_port': rdata.get('auth_port'),
'auth_host': relation_get('auth_host', rid=rid, unit=unit), 'admin_tenant_name': rdata.get('service_tenant'),
'auth_port': relation_get('auth_port', rid=rid, unit=unit), 'admin_user': rdata.get('service_username'),
'admin_tenant_name': relation_get('service_tenant', 'admin_password': rdata.get('service_password'),
rid=rid, unit=unit), 'service_protocol':
'admin_user': relation_get('service_username', rid=rid, rdata.get('service_protocol') or 'http',
unit=unit), 'auth_protocol':
'admin_password': relation_get('service_password', rid=rid, rdata.get('auth_protocol') or 'http',
unit=unit),
# XXX: Hard-coded http.
'service_protocol': 'http',
'auth_protocol': 'http',
} }
if context_complete(ctxt): if context_complete(ctxt):
return ctxt return ctxt
@ -265,7 +261,12 @@ class AMQPContext(OSContextGenerator):
# Sufficient information found = break out! # Sufficient information found = break out!
break break
# Used for active/active rabbitmq >= grizzly # Used for active/active rabbitmq >= grizzly
if 'clustered' not in ctxt and len(related_units(rid)) > 1: if ('clustered' not in ctxt or relation_get('ha-vip-only') == 'True') and \
len(related_units(rid)) > 1:
if relation_get('ha_queues'):
ctxt['rabbitmq_ha_queues'] = relation_get('ha_queues')
else:
ctxt['rabbitmq_ha_queues'] = False
rabbitmq_hosts = [] rabbitmq_hosts = []
for unit in related_units(rid): for unit in related_units(rid):
rabbitmq_hosts.append(relation_get('private-address', rabbitmq_hosts.append(relation_get('private-address',
@ -284,10 +285,13 @@ class CephContext(OSContextGenerator):
'''This generates context for /etc/ceph/ceph.conf templates''' '''This generates context for /etc/ceph/ceph.conf templates'''
if not relation_ids('ceph'): if not relation_ids('ceph'):
return {} return {}
log('Generating template context for ceph') log('Generating template context for ceph')
mon_hosts = [] mon_hosts = []
auth = None auth = None
key = None key = None
use_syslog = str(config('use-syslog')).lower()
for rid in relation_ids('ceph'): for rid in relation_ids('ceph'):
for unit in related_units(rid): for unit in related_units(rid):
mon_hosts.append(relation_get('private-address', rid=rid, mon_hosts.append(relation_get('private-address', rid=rid,
@ -299,6 +303,7 @@ class CephContext(OSContextGenerator):
'mon_hosts': ' '.join(mon_hosts), 'mon_hosts': ' '.join(mon_hosts),
'auth': auth, 'auth': auth,
'key': key, 'key': key,
'use_syslog': use_syslog
} }
if not os.path.isdir('/etc/ceph'): if not os.path.isdir('/etc/ceph'):
@ -427,17 +432,15 @@ class ApacheSSLContext(OSContextGenerator):
'private_address': unit_get('private-address'), 'private_address': unit_get('private-address'),
'endpoints': [] 'endpoints': []
} }
for ext_port in self.external_ports: for api_port in self.external_ports:
if peer_units() or is_clustered(): ext_port = determine_apache_port(api_port)
int_port = determine_haproxy_port(ext_port) int_port = determine_api_port(api_port)
else:
int_port = determine_api_port(ext_port)
portmap = (int(ext_port), int(int_port)) portmap = (int(ext_port), int(int_port))
ctxt['endpoints'].append(portmap) ctxt['endpoints'].append(portmap)
return ctxt return ctxt
class NeutronContext(object): class NeutronContext(OSContextGenerator):
interfaces = [] interfaces = []
@property @property
@ -498,6 +501,22 @@ class NeutronContext(object):
return nvp_ctxt return nvp_ctxt
def neutron_ctxt(self):
if https():
proto = 'https'
else:
proto = 'http'
if is_clustered():
host = config('vip')
else:
host = unit_get('private-address')
url = '%s://%s:%s' % (proto, host, '9292')
ctxt = {
'network_manager': self.network_manager,
'neutron_url': url,
}
return ctxt
def __call__(self): def __call__(self):
self._ensure_packages() self._ensure_packages()
@ -507,7 +526,7 @@ class NeutronContext(object):
if not self.plugin: if not self.plugin:
return {} return {}
ctxt = {'network_manager': self.network_manager} ctxt = self.neutron_ctxt()
if self.plugin == 'ovs': if self.plugin == 'ovs':
ctxt.update(self.ovs_ctxt()) ctxt.update(self.ovs_ctxt())
@ -633,6 +652,7 @@ class SubordinateConfigContext(OSContextGenerator):
class SyslogContext(OSContextGenerator): class SyslogContext(OSContextGenerator):
def __call__(self): def __call__(self):
ctxt = { ctxt = {
'use_syslog': config('use-syslog') 'use_syslog': config('use-syslog')

View File

@ -9,3 +9,6 @@
keyring = /etc/ceph/$cluster.$name.keyring keyring = /etc/ceph/$cluster.$name.keyring
mon host = {{ mon_hosts }} mon host = {{ mon_hosts }}
{% endif -%} {% endif -%}
log to syslog = {{ use_syslog }}
err to syslog = {{ use_syslog }}
clog to syslog = {{ use_syslog }}

View File

@ -8,8 +8,8 @@ global
defaults defaults
log global log global
mode http mode tcp
option httplog option tcplog
option dontlognull option dontlognull
retries 3 retries 3
timeout queue 1000 timeout queue 1000
@ -29,7 +29,6 @@ listen stats :8888
{% for service, ports in service_ports.iteritems() -%} {% for service, ports in service_ports.iteritems() -%}
listen {{ service }} 0.0.0.0:{{ ports[0] }} listen {{ service }} 0.0.0.0:{{ ports[0] }}
balance roundrobin balance roundrobin
option tcplog
{% for unit, address in units.iteritems() -%} {% for unit, address in units.iteritems() -%}
server {{ unit }} {{ address }}:{{ ports[1] }} check server {{ unit }} {{ address }}:{{ ports[1] }} check
{% endfor %} {% endfor %}

View File

@ -49,6 +49,9 @@ CEPH_CONF = """[global]
auth supported = {auth} auth supported = {auth}
keyring = {keyring} keyring = {keyring}
mon host = {mon_hosts} mon host = {mon_hosts}
log to syslog = {use_syslog}
err to syslog = {use_syslog}
clog to syslog = {use_syslog}
""" """
@ -194,7 +197,7 @@ def get_ceph_nodes():
return hosts return hosts
def configure(service, key, auth): def configure(service, key, auth, use_syslog):
''' Perform basic configuration of Ceph ''' ''' Perform basic configuration of Ceph '''
create_keyring(service, key) create_keyring(service, key)
create_key_file(service, key) create_key_file(service, key)
@ -202,7 +205,8 @@ def configure(service, key, auth):
with open('/etc/ceph/ceph.conf', 'w') as ceph_conf: with open('/etc/ceph/ceph.conf', 'w') as ceph_conf:
ceph_conf.write(CEPH_CONF.format(auth=auth, ceph_conf.write(CEPH_CONF.format(auth=auth,
keyring=_keyring_path(service), keyring=_keyring_path(service),
mon_hosts=",".join(map(str, hosts)))) mon_hosts=",".join(map(str, hosts)),
use_syslog=use_syslog))
modprobe('rbd') modprobe('rbd')

View File

@ -194,7 +194,7 @@ def file_hash(path):
return None return None
def restart_on_change(restart_map): def restart_on_change(restart_map, stopstart=False):
"""Restart services based on configuration files changing """Restart services based on configuration files changing
This function is used a decorator, for example This function is used a decorator, for example
@ -219,8 +219,14 @@ def restart_on_change(restart_map):
for path in restart_map: for path in restart_map:
if checksums[path] != file_hash(path): if checksums[path] != file_hash(path):
restarts += restart_map[path] restarts += restart_map[path]
for service_name in list(OrderedDict.fromkeys(restarts)): services_list = list(OrderedDict.fromkeys(restarts))
service('restart', service_name) if not stopstart:
for service_name in services_list:
service('restart', service_name)
else:
for action in ['stop', 'start']:
for service_name in services_list:
service(action, service_name)
return wrapped_f return wrapped_f
return wrap return wrap

View File

@ -58,6 +58,9 @@ paste.filter_factory = cinder.api.middleware.auth:CinderKeystoneContext.factory
[filter:authtoken] [filter:authtoken]
paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
{% if service_host -%} {% if service_host -%}
service_protocol = {{ service_protocol }}
service_host = {{ service_host }}
service_port = {{ service_port }}
auth_host = {{ auth_host }} auth_host = {{ auth_host }}
auth_port = {{ auth_port }} auth_port = {{ auth_port }}
auth_protocol = {{ auth_protocol }} auth_protocol = {{ auth_protocol }}