2
# Copyright 2012 Canonical Ltd.
5
# James Page <james.page@ubuntu.com>
8
from lib.utils import (
19
from lib.cluster_utils import https
23
from base64 import b64decode
25
APACHE_SITE_DIR = "/etc/apache2/sites-available"
26
SITE_TEMPLATE = "apache2_site.tmpl"
27
RELOAD_CHECK = "To activate the new configuration"
31
cert = config_get('ssl_cert')
32
key = config_get('ssl_key')
33
if not (cert and key):
35
"Inspecting identity-service relations for SSL certificate.")
37
for r_id in relation_ids('identity-service'):
38
for unit in relation_list(r_id):
40
cert = relation_get('ssl_cert',
43
key = relation_get('ssl_key',
51
"Inspecting identity-service relations for CA SSL certificate.")
52
for r_id in relation_ids('identity-service'):
53
for unit in relation_list(r_id):
55
ca_cert = relation_get('ca_cert',
60
def install_ca_cert(ca_cert):
62
with open('/usr/local/share/ca-certificates/keystone_juju_ca_cert.crt',
65
subprocess.check_call(['update-ca-certificates', '--fresh'])
68
def enable_https(port_maps, namespace, cert, key, ca_cert=None):
70
For a given number of port mappings, configures apache2
71
HTTPs local reverse proxying using certficates and keys provided in
72
either configuration data (preferred) or relation data. Assumes ports
73
are not in use (calling charm should ensure that).
75
port_maps: dict: external to internal port mappings
76
namespace: str: name of charm
78
def _write_if_changed(path, new_content):
80
if os.path.exists(path):
81
with open(path, 'r') as f:
82
content = f.read().strip()
83
if content != new_content:
84
with open(path, 'w') as f:
90
juju_log('INFO', "Enabling HTTPS for port mappings: {}".format(port_maps))
94
cert = b64decode(cert)
98
ca_cert = b64decode(ca_cert)
100
if not cert and not key:
102
"Expected but could not find SSL certificate data, not "
103
"configuring HTTPS!")
107
if RELOAD_CHECK in subprocess.check_output(['a2enmod', 'ssl',
108
'proxy', 'proxy_http']):
111
ssl_dir = os.path.join('/etc/apache2/ssl', namespace)
112
if not os.path.exists(ssl_dir):
115
if (_write_if_changed(os.path.join(ssl_dir, 'cert'), cert)):
117
if (_write_if_changed(os.path.join(ssl_dir, 'key'), key)):
119
os.chmod(os.path.join(ssl_dir, 'key'), 0600)
121
install_ca_cert(ca_cert)
123
sites_dir = '/etc/apache2/sites-available'
124
for ext_port, int_port in port_maps.items():
126
'Creating apache2 reverse proxy vhost'
127
' for {}:{}'.format(ext_port,
129
site = "{}_{}".format(namespace, ext_port)
130
site_path = os.path.join(sites_dir, site)
131
with open(site_path, 'w') as fsite:
135
"namespace": namespace,
136
"private_address": get_host_ip()
138
fsite.write(render_template(SITE_TEMPLATE,
141
if RELOAD_CHECK in subprocess.check_output(['a2ensite', site]):
150
def disable_https(port_maps, namespace):
152
Ensure HTTPS reverse proxying is disables for given port mappings
154
port_maps: dict: of ext -> int port mappings
155
namespace: str: name of chamr
157
juju_log('INFO', 'Ensuring HTTPS disabled for {}'.format(port_maps))
159
if (not os.path.exists('/etc/apache2') or
160
not os.path.exists(os.path.join('/etc/apache2/ssl', namespace))):
164
for ext_port in port_maps.keys():
165
if os.path.exists(os.path.join(APACHE_SITE_DIR,
166
"{}_{}".format(namespace,
169
"Disabling HTTPS reverse proxy"
170
" for {} {}.".format(namespace,
173
subprocess.check_output(['a2dissite',
174
'{}_{}'.format(namespace,
182
def setup_https(port_maps, namespace, cert, key, ca_cert=None):
184
Ensures HTTPS is either enabled or disabled for given port
187
port_maps: dict: of ext -> int port mappings
188
namespace: str: name of charm
191
disable_https(port_maps, namespace)
193
enable_https(port_maps, namespace, cert, key, ca_cert)