charm-swift-proxy/lib/swift_context.py
Alex Kavanagh 4336b8d644 Convert charm to Python 3 only
* Needed to add a swift_manager/manager.py file which uses the payload
  software python modules to perform certain functions on behalf of the
  charm.  These were part of the main charm, which couldn't be retained
  in the charm due to the charm changing to Py3.
* Changed to absolute imports using the charm root as the root for all
  charm modules.
* The py2 target in tox.ini is used to test the swift_manager/manager.py
  file only.
* The .testr.conf file has been migrated to .stestr.conf

Change-Id: If37a393aa6ed27651b04810aa0bbf69eda37d7b4
2017-12-06 14:20:25 +00:00

242 lines
8.4 KiB
Python

import os
import uuid
from charmhelpers.core.hookenv import (
config,
log,
relation_ids,
related_units,
relation_get,
unit_get,
service_name,
leader_get,
)
from charmhelpers.contrib.openstack.context import (
OSContextGenerator,
ApacheSSLContext as SSLContext,
IdentityServiceContext,
)
from charmhelpers.contrib.hahelpers.cluster import (
determine_api_port,
determine_apache_port,
)
from charmhelpers.contrib.network.ip import (
format_ipv6_addr,
get_ipv6_addr,
)
from charmhelpers.contrib.openstack.utils import get_host_ip
SWIFT_HASH_FILE = '/var/lib/juju/swift-hash-path.conf'
WWW_DIR = '/var/www/swift-rings'
class HAProxyContext(OSContextGenerator):
interfaces = ['cluster']
def __call__(self):
"""Extends the main charmhelpers HAProxyContext with a port mapping
specific to this charm.
Also used to extend cinder.conf context with correct api_listening_port
"""
haproxy_port = config('bind-port')
api_port = determine_apache_port(config('bind-port'),
singlenode_mode=True)
ctxt = {
'service_ports': {'swift_api': [haproxy_port, api_port]},
}
return ctxt
class ApacheSSLContext(SSLContext):
interfaces = ['https']
service_namespace = 'swift'
# We make this a property so that we avoid import-time
# dependencies on config()
@property
def external_ports(self):
return [config('bind-port')]
class SwiftRingContext(OSContextGenerator):
def __call__(self):
allowed_hosts = []
for relid in relation_ids('swift-storage'):
for unit in related_units(relid):
host = relation_get('private-address', unit, relid)
if config('prefer-ipv6'):
host_ip = get_ipv6_addr(exc_list=[config('vip')])[0]
else:
host_ip = get_host_ip(host)
allowed_hosts.append(host_ip)
ctxt = {
'www_dir': WWW_DIR,
'allowed_hosts': allowed_hosts
}
return ctxt
class SwiftIdentityContext(OSContextGenerator):
interfaces = ['identity-service']
def __call__(self):
bind_port = config('bind-port')
workers = config('workers')
if workers == 0:
import multiprocessing
workers = multiprocessing.cpu_count()
if config('prefer-ipv6'):
proxy_ip = ('[{}]'
.format(get_ipv6_addr(exc_list=[config('vip')])[0]))
memcached_ip = 'ip6-localhost'
else:
proxy_ip = get_host_ip(unit_get('private-address'))
memcached_ip = get_host_ip(unit_get('private-address'))
ctxt = {
'proxy_ip': proxy_ip,
'memcached_ip': memcached_ip,
'bind_port': determine_api_port(bind_port, singlenode_mode=True),
'workers': workers,
'operator_roles': config('operator-roles'),
'delay_auth_decision': config('delay-auth-decision'),
'node_timeout': config('node-timeout'),
'recoverable_node_timeout': config('recoverable-node-timeout'),
'log_headers': config('log-headers'),
'statsd_host': config('statsd-host'),
'statsd_port': config('statsd-port'),
'statsd_sample_rate': config('statsd-sample-rate')
}
admin_key = leader_get('swauth-admin-key')
if admin_key is not None:
ctxt['swauth_admin_key'] = admin_key
if config('debug'):
ctxt['log_level'] = 'DEBUG'
else:
ctxt['log_level'] = 'INFO'
# Instead of duplicating code lets use charm-helpers to set signing_dir
# TODO(hopem): refactor this context handler to use charm-helpers
# code.
_ctxt = IdentityServiceContext(service='swift', service_user='swift')()
signing_dir = _ctxt.get('signing_dir')
if signing_dir:
ctxt['signing_dir'] = signing_dir
ctxt['ssl'] = False
auth_type = config('auth-type')
ctxt['auth_type'] = auth_type
auth_host = config('keystone-auth-host')
admin_user = config('keystone-admin-user')
admin_password = config('keystone-admin-user')
if (auth_type == 'keystone' and auth_host and
admin_user and admin_password):
log('Using user-specified Keystone configuration.')
ks_auth = {
'auth_type': 'keystone',
'auth_protocol': config('keystone-auth-protocol'),
'keystone_host': auth_host,
'auth_port': config('keystone-auth-port'),
'service_user': admin_user,
'service_password': admin_password,
'service_tenant': config('keystone-admin-tenant-name'),
}
ctxt.update(ks_auth)
for relid in relation_ids('identity-service'):
log('Using Keystone configuration from identity-service.')
for unit in related_units(relid):
ks_auth = {
'auth_type': 'keystone',
'auth_protocol': relation_get('auth_protocol',
unit, relid) or 'http',
'service_protocol': relation_get('service_protocol',
unit, relid) or 'http',
'keystone_host': relation_get('auth_host',
unit, relid),
'service_host': relation_get('service_host',
unit, relid),
'auth_port': relation_get('auth_port',
unit, relid),
'service_user': relation_get('service_username',
unit, relid),
'service_password': relation_get('service_password',
unit, relid),
'service_tenant': relation_get('service_tenant',
unit, relid),
'service_port': relation_get('service_port',
unit, relid),
'admin_token': relation_get('admin_token',
unit, relid),
'api_version': relation_get('api_version',
unit, relid) or '2',
}
if ks_auth['api_version'] == '3':
ks_auth['admin_domain_id'] = relation_get(
'admin_domain_id', unit, relid)
ks_auth['service_tenant_id'] = relation_get(
'service_tenant_id', unit, relid)
ks_auth['admin_domain_name'] = relation_get(
'service_domain', unit, relid)
ks_auth['admin_tenant_name'] = relation_get(
'service_tenant', unit, relid)
ctxt.update(ks_auth)
if config('prefer-ipv6'):
for key in ['keystone_host', 'service_host']:
host = ctxt.get(key)
if host:
ctxt[key] = format_ipv6_addr(host)
return ctxt
class MemcachedContext(OSContextGenerator):
def __call__(self):
ctxt = {}
if config('prefer-ipv6'):
ctxt['memcached_ip'] = 'ip6-localhost'
else:
ctxt['memcached_ip'] = get_host_ip(unit_get('private-address'))
return ctxt
def get_swift_hash():
if os.path.isfile(SWIFT_HASH_FILE):
with open(SWIFT_HASH_FILE, 'r') as hashfile:
swift_hash = hashfile.read().strip()
elif config('swift-hash'):
swift_hash = config('swift-hash')
with open(SWIFT_HASH_FILE, 'w') as hashfile:
hashfile.write(swift_hash)
else:
model_uuid = os.environ.get("JUJU_ENV_UUID",
os.environ.get("JUJU_MODEL_UUID"))
swift_hash = str(uuid.uuid3(uuid.UUID(model_uuid),
service_name()))
with open(SWIFT_HASH_FILE, 'w') as hashfile:
hashfile.write(swift_hash)
return swift_hash
class SwiftHashContext(OSContextGenerator):
def __call__(self):
ctxt = {
'swift_hash': get_swift_hash()
}
return ctxt