This change adds the missing region setting in service_credentials. In a shared keystone multi region setup, this setting is mandatory in order for ceilometer to properly find the services it relies upon from the same region it resides in. Without this setting, the ceilometer-upgrade action will fail (along with any other calls made to ceilometer) if the first endpoint returned by keystone is from a different region. Change-Id: Ie14df0f5fc7ee18072091dbdb3ada817615a6670 Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
238 lines
7.7 KiB
Python
238 lines
7.7 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.
|
|
|
|
from charmhelpers.core.hookenv import (
|
|
relation_ids,
|
|
relation_get,
|
|
related_units,
|
|
config,
|
|
log,
|
|
INFO,
|
|
WARNING,
|
|
)
|
|
|
|
from charmhelpers.contrib.openstack.utils import (
|
|
get_os_codename_package,
|
|
os_release,
|
|
CompareOpenStackReleases,
|
|
)
|
|
|
|
from charmhelpers.contrib.openstack.context import (
|
|
OSContextGenerator,
|
|
context_complete,
|
|
ApacheSSLContext as SSLContext,
|
|
AMQPContext,
|
|
)
|
|
|
|
from charmhelpers.contrib.hahelpers.cluster import (
|
|
determine_apache_port,
|
|
determine_api_port
|
|
)
|
|
|
|
CEILOMETER_DB = 'ceilometer'
|
|
|
|
|
|
class LoggingConfigContext(OSContextGenerator):
|
|
def __call__(self):
|
|
return {'debug': config('debug'), 'verbose': config('verbose')}
|
|
|
|
|
|
class MongoDBContext(OSContextGenerator):
|
|
interfaces = ['mongodb']
|
|
|
|
def __call__(self):
|
|
mongo_servers = []
|
|
replset = None
|
|
_release = os_release('ceilometer-common')
|
|
use_replset = CompareOpenStackReleases(_release) >= 'icehouse'
|
|
|
|
for relid in relation_ids('shared-db'):
|
|
rel_units = related_units(relid)
|
|
use_replset = use_replset and (len(rel_units) > 1)
|
|
|
|
for unit in rel_units:
|
|
host = relation_get('hostname', unit, relid)
|
|
port = relation_get('port', unit, relid)
|
|
|
|
conf = {
|
|
"db_host": host,
|
|
"db_port": port,
|
|
"db_name": CEILOMETER_DB
|
|
}
|
|
|
|
if not context_complete(conf):
|
|
continue
|
|
|
|
if not use_replset:
|
|
return conf
|
|
|
|
if replset is None:
|
|
replset = relation_get('replset', unit, relid)
|
|
|
|
mongo_servers.append('{}:{}'.format(host, port))
|
|
|
|
if mongo_servers and replset:
|
|
return {
|
|
'db_mongo_servers': ','.join(mongo_servers),
|
|
'db_name': CEILOMETER_DB,
|
|
'db_replset': replset
|
|
}
|
|
|
|
return {}
|
|
|
|
|
|
CEILOMETER_PORT = 8777
|
|
|
|
|
|
class CeilometerContext(OSContextGenerator):
|
|
def __call__(self):
|
|
# Lazy-import to avoid a circular dependency in the imports
|
|
from ceilometer_utils import get_shared_secret
|
|
|
|
# Make sure to cast the time-to-live events to integer values.
|
|
# For large enough numbers, Juju returns the value in scientific
|
|
# notation which causes python to treat the number as a float
|
|
# value, which in turn causes ceilometer to fail to start.
|
|
# See LP#1651645 for more details.
|
|
ctxt = {
|
|
'port': CEILOMETER_PORT,
|
|
'metering_secret': get_shared_secret(),
|
|
'metering_time_to_live': int(config('metering-time-to-live')),
|
|
'event_time_to_live': int(config('event-time-to-live')),
|
|
'polling_interval': int(config('polling-interval')),
|
|
'enable_all_pollsters': config('enable-all-pollsters'),
|
|
'polling_batch_size': config('polling-batch-size'),
|
|
'region': config('region'),
|
|
}
|
|
return ctxt
|
|
|
|
|
|
class CeilometerServiceContext(OSContextGenerator):
|
|
interfaces = ['ceilometer-service']
|
|
|
|
def __call__(self):
|
|
for relid in relation_ids('ceilometer-service'):
|
|
for unit in related_units(relid):
|
|
conf = relation_get(unit=unit, rid=relid)
|
|
if context_complete(conf):
|
|
return conf
|
|
return {}
|
|
|
|
|
|
class CeilometerPipelineContext(OSContextGenerator):
|
|
def __call__(self):
|
|
ctxt = {
|
|
'pipeline_yaml': config('pipeline-yaml')
|
|
}
|
|
return ctxt
|
|
|
|
|
|
class HAProxyContext(OSContextGenerator):
|
|
interfaces = ['ceilometer-haproxy']
|
|
|
|
def __call__(self):
|
|
'''Extends the main charmhelpers HAProxyContext with a port mapping
|
|
specific to this charm.
|
|
'''
|
|
haproxy_port = CEILOMETER_PORT
|
|
api_port = determine_api_port(CEILOMETER_PORT, singlenode_mode=True)
|
|
apache_port = determine_apache_port(CEILOMETER_PORT,
|
|
singlenode_mode=True)
|
|
|
|
ctxt = {
|
|
'service_ports': {'ceilometer_api': [haproxy_port, apache_port]},
|
|
'port': api_port
|
|
}
|
|
return ctxt
|
|
|
|
|
|
class RemoteSinksContext(OSContextGenerator):
|
|
interfaces = ['event-service']
|
|
|
|
def __call__(self):
|
|
'''Generates context for remote sinks for Panko and other compatible
|
|
remote consumers of Ceilometer event data.
|
|
'''
|
|
ctxt = {}
|
|
if config('remote-sink'):
|
|
ctxt['remote_sinks'] = config('remote-sink').split(' ')
|
|
for relid in relation_ids('event-service'):
|
|
for unit in related_units(relid):
|
|
publisher = relation_get('publisher', unit=unit, rid=relid)
|
|
if publisher:
|
|
if not ctxt.get('internal_sinks'):
|
|
ctxt['internal_sinks'] = {}
|
|
ctxt['internal_sinks'][unit.split('/')[0]] = publisher
|
|
|
|
release = get_os_codename_package('ceilometer-common', fatal=False)
|
|
ctxt['event_sink_publisher'] = None
|
|
if CompareOpenStackReleases(release) >= 'queens':
|
|
# NOTE: see bug LP 1676586
|
|
if config('events-publisher') == "aodh":
|
|
ctxt['event_sink_publisher'] = 'notifier://?topic=alarm.all'
|
|
elif config('events-publisher') == "gnocchi":
|
|
if relation_ids('metric-service'):
|
|
ctxt['event_sink_publisher'] = 'gnocchi://'
|
|
else:
|
|
log("Unable to configure event publisher '{}' since "
|
|
"no gnocchi relation found".
|
|
format(config('events-publisher')), level=INFO)
|
|
elif config('events-publisher') == "":
|
|
log("Not configuring any event publishers", level=INFO)
|
|
else:
|
|
log("Invalid event publisher config provided '{}'. Not "
|
|
"configuring any event publishers".
|
|
format(config('events-publisher')), level=WARNING)
|
|
|
|
return ctxt
|
|
|
|
|
|
class ApacheSSLContext(SSLContext):
|
|
|
|
external_ports = [CEILOMETER_PORT]
|
|
service_namespace = "ceilometer"
|
|
|
|
|
|
class MetricServiceContext(OSContextGenerator):
|
|
interfaces = ['metric-service']
|
|
|
|
def __call__(self):
|
|
|
|
for relid in relation_ids('metric-service'):
|
|
for unit in related_units(relid):
|
|
gnocchi_url = relation_get('gnocchi_url', unit=unit, rid=relid)
|
|
if gnocchi_url:
|
|
return {'gnocchi_url': gnocchi_url,
|
|
'archive_policy': config('gnocchi-archive-policy')}
|
|
return {}
|
|
|
|
|
|
class AMQPListenersContext(OSContextGenerator):
|
|
interfaces = ['amqp-listener']
|
|
|
|
def __init__(self, ssl_dir=None):
|
|
self.ssl_dir = ssl_dir
|
|
|
|
def __call__(self):
|
|
ctxt = {}
|
|
messaging_urls = []
|
|
relids = relation_ids('amqp-listener') + relation_ids('amqp')
|
|
for relid in relids:
|
|
amqp_ctxt = AMQPContext(ssl_dir=self.ssl_dir, relation_id=relid)()
|
|
if amqp_ctxt.get('transport_url'):
|
|
messaging_urls.append(amqp_ctxt['transport_url'])
|
|
if messaging_urls:
|
|
ctxt['messaging_urls'] = messaging_urls
|
|
return ctxt
|