2
# Copyright 2012 Canonical Ltd.
5
# James Page <james.page@ubuntu.com>
6
# Adam Gandelman <adamg@ubuntu.com>
12
from socket import gethostname as get_unit_hostname
14
from charmhelpers.core.hookenv import (
17
related_units as relation_list,
26
class HAIncompleteConfig(Exception):
31
for r_id in (relation_ids('ha') or []):
32
for unit in (relation_list(r_id) or []):
33
clustered = relation_get('clustered',
41
def is_leader(resource):
47
status = subprocess.check_output(cmd)
48
except subprocess.CalledProcessError:
51
if get_unit_hostname() in status:
59
for r_id in (relation_ids('cluster') or []):
60
for unit in (relation_list(r_id) or []):
65
def oldest_peer(peers):
66
local_unit_no = int(os.getenv('JUJU_UNIT_NAME').split('/')[1])
68
remote_unit_no = int(peer.split('/')[1])
69
if remote_unit_no < local_unit_no:
74
def eligible_leader(resource):
76
if not is_leader(resource):
77
log('Deferring action to CRM leader.', level=INFO)
81
if peers and not oldest_peer(peers):
82
log('Deferring action to oldest service unit.', level=INFO)
89
Determines whether enough data has been provided in configuration
90
or relation data to configure HTTPS
94
if config_get('use-https') == "yes":
96
if config_get('ssl_cert') and config_get('ssl_key'):
98
for r_id in relation_ids('identity-service'):
99
for unit in relation_list(r_id):
101
relation_get('https_keystone', rid=r_id, unit=unit),
102
relation_get('ssl_cert', rid=r_id, unit=unit),
103
relation_get('ssl_key', rid=r_id, unit=unit),
104
relation_get('ca_cert', rid=r_id, unit=unit),
106
# NOTE: works around (LP: #1203241)
107
if (None not in rel_state) and ('' not in rel_state):
112
def determine_api_port(public_port):
114
Determine correct API server listening port based on
115
existence of HTTPS reverse proxy and/or haproxy.
117
public_port: int: standard public port for given service
119
returns: int: the correct listening port for the API service
122
if len(peer_units()) > 0 or is_clustered():
126
return public_port - (i * 10)
129
def determine_haproxy_port(public_port):
131
Description: Determine correct proxy listening port based on public IP +
132
existence of HTTPS reverse proxy.
134
public_port: int: standard public port for given service
136
returns: int: the correct listening port for the HAProxy service
141
return public_port - (i * 10)
144
def get_hacluster_config():
146
Obtains all relevant configuration from charm configuration required
147
for initiating a relation to hacluster:
149
ha-bindiface, ha-mcastport, vip, vip_iface, vip_cidr
151
returns: dict: A dict containing settings keyed by setting name.
152
raises: HAIncompleteConfig if settings are missing.
154
settings = ['ha-bindiface', 'ha-mcastport', 'vip', 'vip_iface', 'vip_cidr']
156
for setting in settings:
157
conf[setting] = config_get(setting)
159
[missing.append(s) for s, v in conf.iteritems() if v is None]
161
log('Insufficient config data to configure hacluster.', level=ERROR)
162
raise HAIncompleteConfig
166
def canonical_url(configs, vip_setting='vip'):
168
Returns the correct HTTP URL to this host given the state of HTTPS
169
configuration and hacluster.
171
:configs : OSTemplateRenderer: A config tempating object to inspect for
172
a complete https context.
173
:vip_setting: str: Setting in charm config that specifies
177
if 'https' in configs.complete_contexts():
180
addr = config_get(vip_setting)
182
addr = unit_get('private-address')
183
return '%s://%s' % (scheme, addr)