2
# Copyright 2012 Canonical Ltd.
4
# This file is sourced from lp:openstack-charm-helpers
7
# James Page <james.page@ubuntu.com>
8
# Adam Gandelman <adamg@ubuntu.com>
11
from lib.utils import (
22
from lib.cluster_utils import https
26
from base64 import b64decode
28
APACHE_SITE_DIR = "/etc/apache2/sites-available"
29
SITE_TEMPLATE = "apache2_site.tmpl"
30
RELOAD_CHECK = "To activate the new configuration"
34
cert = config_get('ssl_cert')
35
key = config_get('ssl_key')
36
if not (cert and key):
38
"Inspecting identity-service relations for SSL certificate.")
40
for r_id in relation_ids('identity-service'):
41
for unit in relation_list(r_id):
43
cert = relation_get('ssl_cert',
46
key = relation_get('ssl_key',
54
"Inspecting identity-service relations for CA SSL certificate.")
55
for r_id in relation_ids('identity-service'):
56
for unit in relation_list(r_id):
58
ca_cert = relation_get('ca_cert',
63
def install_ca_cert(ca_cert):
65
with open('/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt',
68
subprocess.check_call(['update-ca-certificates', '--fresh'])
71
def enable_https(port_maps, namespace, cert, key, ca_cert=None):
73
For a given number of port mappings, configures apache2
74
HTTPs local reverse proxying using certficates and keys provided in
75
either configuration data (preferred) or relation data. Assumes ports
76
are not in use (calling charm should ensure that).
78
port_maps: dict: external to internal port mappings
79
namespace: str: name of charm
81
def _write_if_changed(path, new_content):
83
if os.path.exists(path):
84
with open(path, 'r') as f:
85
content = f.read().strip()
86
if content != new_content:
87
with open(path, 'w') as f:
93
juju_log('INFO', "Enabling HTTPS for port mappings: {}".format(port_maps))
97
cert = b64decode(cert)
101
ca_cert = b64decode(ca_cert)
103
if not cert and not key:
105
"Expected but could not find SSL certificate data, not "
106
"configuring HTTPS!")
110
if RELOAD_CHECK in subprocess.check_output(['a2enmod', 'ssl',
111
'proxy', 'proxy_http']):
114
ssl_dir = os.path.join('/etc/apache2/ssl', namespace)
115
if not os.path.exists(ssl_dir):
118
if (_write_if_changed(os.path.join(ssl_dir, 'cert'), cert)):
120
if (_write_if_changed(os.path.join(ssl_dir, 'key'), key)):
122
os.chmod(os.path.join(ssl_dir, 'key'), 0600)
124
install_ca_cert(ca_cert)
126
sites_dir = '/etc/apache2/sites-available'
127
for ext_port, int_port in port_maps.items():
129
'Creating apache2 reverse proxy vhost'
130
' for {}:{}'.format(ext_port,
132
site = "{}_{}".format(namespace, ext_port)
133
site_path = os.path.join(sites_dir, site)
134
with open(site_path, 'w') as fsite:
138
"namespace": namespace,
139
"private_address": get_host_ip()
141
fsite.write(render_template(SITE_TEMPLATE,
144
if RELOAD_CHECK in subprocess.check_output(['a2ensite', site]):
153
def disable_https(port_maps, namespace):
155
Ensure HTTPS reverse proxying is disables for given port mappings
157
port_maps: dict: of ext -> int port mappings
158
namespace: str: name of chamr
160
juju_log('INFO', 'Ensuring HTTPS disabled for {}'.format(port_maps))
162
if (not os.path.exists('/etc/apache2') or
163
not os.path.exists(os.path.join('/etc/apache2/ssl', namespace))):
167
for ext_port in port_maps.keys():
168
if os.path.exists(os.path.join(APACHE_SITE_DIR,
169
"{}_{}".format(namespace,
172
"Disabling HTTPS reverse proxy"
173
" for {} {}.".format(namespace,
176
subprocess.check_output(['a2dissite',
177
'{}_{}'.format(namespace,
185
def setup_https(port_maps, namespace, cert, key, ca_cert=None):
187
Ensures HTTPS is either enabled or disabled for given port
190
port_maps: dict: of ext -> int port mappings
191
namespace: str: name of charm
194
disable_https(port_maps, namespace)
196
enable_https(port_maps, namespace, cert, key, ca_cert)