168
178
for rid in relation_ids('shared-db'):
169
179
for unit in related_units(rid):
170
180
rdata = relation_get(rid=rid, unit=unit)
181
host = rdata.get('db_host')
182
host = format_ipv6_addr(host) or host
172
'database_host': rdata.get('db_host'),
184
'database_host': host,
173
185
'database': self.database,
174
186
'database_user': self.user,
175
187
'database_password': rdata.get(password_setting),
245
257
for rid in relation_ids('identity-service'):
246
258
for unit in related_units(rid):
247
259
rdata = relation_get(rid=rid, unit=unit)
260
serv_host = rdata.get('service_host')
261
serv_host = format_ipv6_addr(serv_host) or serv_host
262
auth_host = rdata.get('auth_host')
263
auth_host = format_ipv6_addr(auth_host) or auth_host
249
266
'service_port': rdata.get('service_port'),
250
'service_host': rdata.get('service_host'),
251
'auth_host': rdata.get('auth_host'),
267
'service_host': serv_host,
268
'auth_host': auth_host,
252
269
'auth_port': rdata.get('auth_port'),
253
270
'admin_tenant_name': rdata.get('service_tenant'),
254
271
'admin_user': rdata.get('service_username'),
297
314
for unit in related_units(rid):
298
315
if relation_get('clustered', rid=rid, unit=unit):
299
316
ctxt['clustered'] = True
300
ctxt['rabbitmq_host'] = relation_get('vip', rid=rid,
317
vip = relation_get('vip', rid=rid, unit=unit)
318
vip = format_ipv6_addr(vip) or vip
319
ctxt['rabbitmq_host'] = vip
303
ctxt['rabbitmq_host'] = relation_get('private-address',
321
host = relation_get('private-address', rid=rid, unit=unit)
322
host = format_ipv6_addr(host) or host
323
ctxt['rabbitmq_host'] = host
306
325
'rabbitmq_user': username,
307
326
'rabbitmq_password': relation_get('password', rid=rid,
340
359
and len(related_units(rid)) > 1:
341
360
rabbitmq_hosts = []
342
361
for unit in related_units(rid):
343
rabbitmq_hosts.append(relation_get('private-address',
362
host = relation_get('private-address', rid=rid, unit=unit)
363
host = format_ipv6_addr(host) or host
364
rabbitmq_hosts.append(host)
345
365
ctxt['rabbitmq_hosts'] = ','.join(rabbitmq_hosts)
346
366
if not context_complete(ctxt):
402
426
if not relation_ids('cluster'):
429
l_unit = local_unit().replace('/', '-')
431
if config('prefer-ipv6'):
432
addr = get_ipv6_addr(exc_list=[config('vip')])[0]
434
addr = get_host_ip(unit_get('private-address'))
405
436
cluster_hosts = {}
406
l_unit = local_unit().replace('/', '-')
407
if config('prefer-ipv6'):
408
addr = get_ipv6_addr()
410
addr = unit_get('private-address')
411
cluster_hosts[l_unit] = get_address_in_network(config('os-internal-network'),
414
for rid in relation_ids('cluster'):
415
for unit in related_units(rid):
416
_unit = unit.replace('/', '-')
417
addr = relation_get('private-address', rid=rid, unit=unit)
418
cluster_hosts[_unit] = addr
438
# NOTE(jamespage): build out map of configured network endpoints
439
# and associated backends
440
for addr_type in ADDRESS_TYPES:
441
laddr = get_address_in_network(
442
config('os-{}-network'.format(addr_type)))
444
cluster_hosts[laddr] = {}
445
cluster_hosts[laddr]['network'] = "{}/{}".format(
447
get_netmask_for_address(laddr)
449
cluster_hosts[laddr]['backends'] = {}
450
cluster_hosts[laddr]['backends'][l_unit] = laddr
451
for rid in relation_ids('cluster'):
452
for unit in related_units(rid):
453
_unit = unit.replace('/', '-')
454
_laddr = relation_get('{}-address'.format(addr_type),
457
cluster_hosts[laddr]['backends'][_unit] = _laddr
459
# NOTE(jamespage) no split configurations found, just use
461
if not cluster_hosts:
462
cluster_hosts[addr] = {}
463
cluster_hosts[addr]['network'] = "{}/{}".format(
465
get_netmask_for_address(addr)
467
cluster_hosts[addr]['backends'] = {}
468
cluster_hosts[addr]['backends'][l_unit] = addr
469
for rid in relation_ids('cluster'):
470
for unit in related_units(rid):
471
_unit = unit.replace('/', '-')
472
_laddr = relation_get('private-address',
475
cluster_hosts[addr]['backends'][_unit] = _laddr
421
'units': cluster_hosts,
478
'frontends': cluster_hosts,
424
481
if config('haproxy-server-timeout'):
425
ctxt['haproxy-server-timeout'] = config('haproxy-server-timeout')
482
ctxt['haproxy_server_timeout'] = config('haproxy-server-timeout')
426
483
if config('haproxy-client-timeout'):
427
ctxt['haproxy-client-timeout'] = config('haproxy-client-timeout')
484
ctxt['haproxy_client_timeout'] = config('haproxy-client-timeout')
429
486
if config('prefer-ipv6'):
430
487
ctxt['local_host'] = 'ip6-localhost'
435
492
ctxt['haproxy_host'] = '0.0.0.0'
436
493
ctxt['stat_port'] = ':8888'
438
if len(cluster_hosts.keys()) > 1:
439
# Enable haproxy when we have enough peers.
440
log('Ensuring haproxy enabled in /etc/default/haproxy.')
441
with open('/etc/default/haproxy', 'w') as out:
442
out.write('ENABLED=1\n')
495
for frontend in cluster_hosts:
496
if len(cluster_hosts[frontend]['backends']) > 1:
497
# Enable haproxy when we have enough peers.
498
log('Ensuring haproxy enabled in /etc/default/haproxy.')
499
with open('/etc/default/haproxy', 'w') as out:
500
out.write('ENABLED=1\n')
444
502
log('HAProxy context is incomplete, this unit has no peers.')
495
553
cmd = ['a2enmod', 'ssl', 'proxy', 'proxy_http']
498
def configure_cert(self):
499
if not os.path.isdir('/etc/apache2/ssl'):
500
os.mkdir('/etc/apache2/ssl')
556
def configure_cert(self, cn=None):
501
557
ssl_dir = os.path.join('/etc/apache2/ssl/', self.service_namespace)
502
if not os.path.isdir(ssl_dir):
504
cert, key = get_cert()
505
with open(os.path.join(ssl_dir, 'cert'), 'w') as cert_out:
506
cert_out.write(b64decode(cert))
507
with open(os.path.join(ssl_dir, 'key'), 'w') as key_out:
508
key_out.write(b64decode(key))
559
cert, key = get_cert(cn)
561
cert_filename = 'cert_{}'.format(cn)
562
key_filename = 'key_{}'.format(cn)
564
cert_filename = 'cert'
566
write_file(path=os.path.join(ssl_dir, cert_filename),
567
content=b64decode(cert))
568
write_file(path=os.path.join(ssl_dir, key_filename),
569
content=b64decode(key))
571
def configure_ca(self):
509
572
ca_cert = get_ca_cert()
511
with open(CA_CERT_PATH, 'w') as ca_out:
512
ca_out.write(b64decode(ca_cert))
513
check_call(['update-ca-certificates'])
574
install_ca_cert(b64decode(ca_cert))
576
def canonical_names(self):
577
'''Figure out which canonical names clients will access this service'''
579
for r_id in relation_ids('identity-service'):
580
for unit in related_units(r_id):
581
rdata = relation_get(rid=r_id, unit=unit)
583
if k.startswith('ssl_key_'):
584
cns.append(k.lstrip('ssl_key_'))
585
return list(set(cns))
515
587
def __call__(self):
516
588
if isinstance(self.external_ports, basestring):
518
590
if (not self.external_ports or not https()):
521
self.configure_cert()
522
594
self.enable_modules()
525
597
'namespace': self.service_namespace,
526
'private_address': unit_get('private-address'),
530
ctxt['private_address'] = config('vip')
531
for api_port in self.external_ports:
532
ext_port = determine_apache_port(api_port)
533
int_port = determine_api_port(api_port)
534
portmap = (int(ext_port), int(int_port))
535
ctxt['endpoints'].append(portmap)
602
for cn in self.canonical_names():
603
self.configure_cert(cn)
608
vips = config('vip').split()
610
for network_type in ['os-internal-network',
612
'os-public-network']:
613
address = get_address_in_network(config(network_type),
614
unit_get('private-address'))
615
if len(vips) > 0 and is_clustered():
617
if is_address_in_network(config(network_type),
619
addresses.append((address, vip))
622
addresses.append((address, config('vip')))
624
addresses.append((address, address))
626
for address, endpoint in set(addresses):
627
for api_port in self.external_ports:
628
ext_port = determine_apache_port(api_port)
629
int_port = determine_api_port(api_port)
630
portmap = (address, endpoint, int(ext_port), int(int_port))
631
ctxt['endpoints'].append(portmap)
632
ctxt['ext_ports'].append(int(ext_port))
633
ctxt['ext_ports'] = list(set(ctxt['ext_ports']))
663
761
class OSConfigFlagContext(OSContextGenerator):
666
Responsible for adding user-defined config-flags in charm config to a
669
NOTE: the value of config-flags may be a comma-separated list of
670
key=value pairs and some Openstack config files support
671
comma-separated lists as values.
675
config_flags = config('config-flags')
679
flags = config_flags_parser(config_flags)
680
return {'user_config_flags': flags}
764
Responsible for adding user-defined config-flags in charm config to a
767
NOTE: the value of config-flags may be a comma-separated list of
768
key=value pairs and some Openstack config files support
769
comma-separated lists as values.
773
config_flags = config('config-flags')
777
flags = config_flags_parser(config_flags)
778
return {'user_config_flags': flags}
683
781
class SubordinateConfigContext(OSContextGenerator):
792
890
'use_syslog': config('use-syslog')
895
class BindHostContext(OSContextGenerator):
898
if config('prefer-ipv6'):
904
'bind_host': '0.0.0.0'
908
class WorkerConfigContext(OSContextGenerator):
913
from psutil import NUM_CPUS
915
apt_install('python-psutil', fatal=True)
916
from psutil import NUM_CPUS
920
multiplier = config('worker-multiplier') or 1
922
"workers": self.num_cpus * multiplier