5d2dfd94dd
The ceph project has focussed on running the RADOS Gateway using the embedded civetweb engine for many cycles now; mod-fastcgi is buggy and no longer provided in Ubuntu as of 17.04, so switch to always running in embedded mode. Existing installs will be upgraded to run in this mode, purging apache related packaging and configuration. Change-Id: I90e6c047d78de2b0ebf8c24bd2f2d6d1bfbd5c5d Closes-Bug: 1657370
194 lines
6.1 KiB
Python
194 lines
6.1 KiB
Python
# Copyright 2016 Canonical Ltd
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import os
|
|
import re
|
|
import socket
|
|
import tempfile
|
|
import shutil
|
|
|
|
from charmhelpers.contrib.openstack import context
|
|
from charmhelpers.contrib.hahelpers.cluster import (
|
|
determine_api_port,
|
|
determine_apache_port,
|
|
)
|
|
from charmhelpers.core.host import cmp_pkgrevno
|
|
from charmhelpers.core.hookenv import (
|
|
DEBUG,
|
|
WARNING,
|
|
config,
|
|
log,
|
|
relation_ids,
|
|
related_units,
|
|
relation_get,
|
|
)
|
|
from charmhelpers.contrib.network.ip import (
|
|
format_ipv6_addr,
|
|
get_host_ip,
|
|
get_ipv6_addr,
|
|
)
|
|
from charmhelpers.contrib.storage.linux.ceph import CephConfContext
|
|
|
|
|
|
class HAProxyContext(context.HAProxyContext):
|
|
|
|
def __call__(self):
|
|
ctxt = super(HAProxyContext, self).__call__()
|
|
port = config('port')
|
|
|
|
# Apache ports
|
|
a_cephradosgw_api = determine_apache_port(port, singlenode_mode=True)
|
|
|
|
port_mapping = {
|
|
'cephradosgw-server': [port, a_cephradosgw_api]
|
|
}
|
|
|
|
ctxt['cephradosgw_bind_port'] = determine_api_port(
|
|
port,
|
|
singlenode_mode=True,
|
|
)
|
|
|
|
# for haproxy.conf
|
|
ctxt['service_ports'] = port_mapping
|
|
return ctxt
|
|
|
|
|
|
class IdentityServiceContext(context.IdentityServiceContext):
|
|
interfaces = ['identity-service']
|
|
|
|
def __call__(self):
|
|
ctxt = super(IdentityServiceContext, self).__call__()
|
|
if not ctxt:
|
|
return
|
|
|
|
ctxt['admin_token'] = None
|
|
for relid in relation_ids('identity-service'):
|
|
for unit in related_units(relid):
|
|
if not ctxt.get('admin_token'):
|
|
ctxt['admin_token'] = \
|
|
relation_get('admin_token', unit, relid)
|
|
|
|
ctxt['auth_type'] = 'keystone'
|
|
ctxt['user_roles'] = config('operator-roles')
|
|
ctxt['cache_size'] = config('cache-size')
|
|
ctxt['revocation_check_interval'] = config('revocation-check-interval')
|
|
if self.context_complete(ctxt):
|
|
return ctxt
|
|
|
|
return {}
|
|
|
|
|
|
def ensure_host_resolvable_v6(hostname):
|
|
"""Ensure that we can resolve our hostname to an IPv6 address by adding it
|
|
to /etc/hosts if it is not already resolvable.
|
|
"""
|
|
try:
|
|
socket.getaddrinfo(hostname, None, socket.AF_INET6)
|
|
except socket.gaierror:
|
|
log("Host '%s' is not ipv6 resolvable - adding to /etc/hosts" %
|
|
hostname, level=DEBUG)
|
|
else:
|
|
log("Host '%s' appears to be ipv6 resolvable" % (hostname),
|
|
level=DEBUG)
|
|
return
|
|
|
|
# This must be the backend address used by haproxy
|
|
host_addr = get_ipv6_addr(exc_list=[config('vip')])[0]
|
|
dtmp = tempfile.mkdtemp()
|
|
try:
|
|
tmp_hosts = os.path.join(dtmp, 'hosts')
|
|
shutil.copy('/etc/hosts', tmp_hosts)
|
|
with open(tmp_hosts, 'a+') as fd:
|
|
lines = fd.readlines()
|
|
for line in lines:
|
|
key = "^%s\s+" % (host_addr)
|
|
if re.search(key, line):
|
|
break
|
|
else:
|
|
fd.write("%s\t%s\n" % (host_addr, hostname))
|
|
|
|
os.rename(tmp_hosts, '/etc/hosts')
|
|
finally:
|
|
shutil.rmtree(dtmp)
|
|
|
|
|
|
class MonContext(context.OSContextGenerator):
|
|
interfaces = ['ceph-radosgw']
|
|
|
|
def __call__(self):
|
|
if not relation_ids('mon'):
|
|
return {}
|
|
mon_hosts = []
|
|
auths = []
|
|
for relid in relation_ids('mon'):
|
|
for unit in related_units(relid):
|
|
ceph_public_addr = relation_get('ceph-public-address', unit,
|
|
relid)
|
|
if ceph_public_addr:
|
|
host_ip = format_ipv6_addr(ceph_public_addr) or \
|
|
get_host_ip(ceph_public_addr)
|
|
mon_hosts.append('{}:6789'.format(host_ip))
|
|
_auth = relation_get('auth', unit, relid)
|
|
if _auth:
|
|
auths.append(_auth)
|
|
|
|
if len(set(auths)) != 1:
|
|
e = ("Inconsistent or absent auth returned by mon units. Setting "
|
|
"auth_supported to 'none'")
|
|
log(e, level=WARNING)
|
|
auth = 'none'
|
|
else:
|
|
auth = auths[0]
|
|
|
|
# /etc/init.d/radosgw mandates that a dns name is used for this
|
|
# parameter so ensure that address is resolvable
|
|
host = socket.gethostname()
|
|
if config('prefer-ipv6'):
|
|
ensure_host_resolvable_v6(host)
|
|
|
|
port = determine_apache_port(config('port'), singlenode_mode=True)
|
|
if config('prefer-ipv6'):
|
|
port = "[::]:%s" % (port)
|
|
|
|
mon_hosts.sort()
|
|
ctxt = {
|
|
'auth_supported': auth,
|
|
'mon_hosts': ' '.join(mon_hosts),
|
|
'hostname': host,
|
|
'old_auth': cmp_pkgrevno('radosgw', "0.51") < 0,
|
|
'use_syslog': str(config('use-syslog')).lower(),
|
|
'loglevel': config('loglevel'),
|
|
'port': port,
|
|
'ipv6': config('prefer-ipv6')
|
|
}
|
|
|
|
certs_path = '/var/lib/ceph/nss'
|
|
paths = [os.path.join(certs_path, 'ca.pem'),
|
|
os.path.join(certs_path, 'signing_certificate.pem')]
|
|
if all([os.path.isfile(p) for p in paths]):
|
|
ctxt['cms'] = True
|
|
|
|
# NOTE(dosaboy): these sections must correspond to what is supported in
|
|
# the config template.
|
|
sections = ['global', 'client.radosgw.gateway']
|
|
user_provided = CephConfContext(permitted_sections=sections)()
|
|
user_provided = {k.replace('.', '_'): user_provided[k]
|
|
for k in user_provided}
|
|
ctxt.update(user_provided)
|
|
|
|
if self.context_complete(ctxt):
|
|
return ctxt
|
|
|
|
return {}
|