Few changes:
- Add support for shared secret for ceilometer's signed messages - Refactor MongoDBContext to be a bit more clean - Specify replicaSet and readPreference parameters in the mongodb url
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import os
|
||||
import uuid
|
||||
from charmhelpers.core.hookenv import (
|
||||
relation_ids,
|
||||
relation_get,
|
||||
@@ -32,66 +31,52 @@ class MongoDBContext(OSContextGenerator):
|
||||
interfaces = ['mongodb']
|
||||
|
||||
def __call__(self):
|
||||
hostnames = []
|
||||
port = None
|
||||
mongo_servers = []
|
||||
replset = None
|
||||
# TODO(wolsen) add a check in which will only execute this on a
|
||||
# supported level of ceilometer code, which would be a specific version
|
||||
# of the code, not just icehouse.
|
||||
support = os_release('ceilometer-api') >= 'icehouse'
|
||||
use_replset = os_release('ceilometer-api') >= 'icehouse'
|
||||
|
||||
for relid in relation_ids('shared-db'):
|
||||
for unit in related_units(relid):
|
||||
replset = relation_get('replset', unit, relid)
|
||||
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)
|
||||
if port is None:
|
||||
port = relation_get('port', unit, relid)
|
||||
port = relation_get('port', unit, relid)
|
||||
|
||||
# If replica sets aren't used or aren't supported by ceilometer
|
||||
# then stop looping if there is enough data
|
||||
if not support or not replset:
|
||||
if context_complete({'db_host': host, 'db_port': port}):
|
||||
hostnames.append(host)
|
||||
break
|
||||
if not use_replset:
|
||||
conf = {
|
||||
"db_host": host,
|
||||
"db_port": port,
|
||||
"db_name": CEILOMETER_DB
|
||||
}
|
||||
|
||||
if context_complete(conf):
|
||||
return conf
|
||||
else:
|
||||
hostnames.append('{}:{}'.format(host, port))
|
||||
|
||||
# If there aren't any hosts, then there's no real configuration
|
||||
# to fill in here, so bail early
|
||||
if port is None or port == '':
|
||||
return {}
|
||||
if replset is None:
|
||||
replset = relation_get('replset', unit, relid)
|
||||
|
||||
mongo_servers.append('{}:{}'.format(host, port))
|
||||
|
||||
conf = {
|
||||
'db_host': ','.join(hostnames),
|
||||
'db_port': port,
|
||||
'db_name': CEILOMETER_DB
|
||||
}
|
||||
if mongo_servers:
|
||||
conf = {
|
||||
'db_mongo_servers': ','.join(mongo_servers),
|
||||
'db_name': CEILOMETER_DB,
|
||||
'db_replset': replset
|
||||
}
|
||||
return conf
|
||||
|
||||
if replset:
|
||||
conf['db_replset'] = replset
|
||||
return {}
|
||||
|
||||
return conf
|
||||
|
||||
|
||||
SHARED_SECRET = "/etc/ceilometer/secret.txt"
|
||||
|
||||
|
||||
def get_shared_secret():
|
||||
secret = None
|
||||
if not os.path.exists(SHARED_SECRET):
|
||||
secret = str(uuid.uuid4())
|
||||
with open(SHARED_SECRET, 'w') as secret_file:
|
||||
secret_file.write(secret)
|
||||
else:
|
||||
with open(SHARED_SECRET, 'r') as secret_file:
|
||||
secret = secret_file.read().strip()
|
||||
return secret
|
||||
|
||||
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
|
||||
|
||||
ctxt = {
|
||||
'port': CEILOMETER_PORT,
|
||||
'metering_secret': get_shared_secret()
|
||||
|
||||
@@ -31,7 +31,9 @@ from ceilometer_utils import (
|
||||
register_configs,
|
||||
restart_map,
|
||||
get_ceilometer_context,
|
||||
do_openstack_upgrade
|
||||
get_shared_secret,
|
||||
do_openstack_upgrade,
|
||||
set_shared_secret
|
||||
)
|
||||
from ceilometer_contexts import CEILOMETER_PORT
|
||||
from charmhelpers.contrib.openstack.ip import (
|
||||
@@ -43,7 +45,8 @@ from charmhelpers.contrib.network.ip import (
|
||||
get_netmask_for_address
|
||||
)
|
||||
from charmhelpers.contrib.hahelpers.cluster import (
|
||||
get_hacluster_config
|
||||
get_hacluster_config,
|
||||
is_elected_leader
|
||||
)
|
||||
|
||||
hooks = Hooks()
|
||||
@@ -109,11 +112,29 @@ def upgrade_charm():
|
||||
any_changed()
|
||||
|
||||
|
||||
@hooks.hook('cluster-relation-joined',
|
||||
'cluster-relation-changed',
|
||||
@hooks.hook('cluster-relation-joined')
|
||||
@restart_on_change(restart_map(), stopstart=True)
|
||||
def cluster_joined():
|
||||
vip = get_hacluster_config()['vip'].split()[0]
|
||||
resource = 'res_ceilometer_{}_vip'.format(get_iface_for_address(vip))
|
||||
|
||||
# If this node is the elected leader then share our secret with other nodes
|
||||
if is_elected_leader(resource):
|
||||
relation_set(shared_secret=get_shared_secret())
|
||||
|
||||
CONFIGS.write_all()
|
||||
|
||||
|
||||
@hooks.hook('cluster-relation-changed',
|
||||
'cluster-relation-departed')
|
||||
@restart_on_change(restart_map(), stopstart=True)
|
||||
def cluster_changed():
|
||||
shared_secret = relation_get('shared_secret')
|
||||
if shared_secret is None or shared_secret.strip() == '':
|
||||
log('waiting for shared secret to be provided by leader')
|
||||
elif not shared_secret == get_shared_secret():
|
||||
set_shared_secret(shared_secret)
|
||||
|
||||
CONFIGS.write_all()
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
@@ -84,6 +85,8 @@ CONFIG_FILES = OrderedDict([
|
||||
|
||||
TEMPLATES = 'templates'
|
||||
|
||||
SHARED_SECRET = "/etc/ceilometer/secret.txt"
|
||||
|
||||
|
||||
def register_configs():
|
||||
"""
|
||||
@@ -171,3 +174,28 @@ def get_packages():
|
||||
>= 'icehouse'):
|
||||
packages = packages + ICEHOUSE_PACKAGES
|
||||
return packages
|
||||
|
||||
|
||||
def get_shared_secret():
|
||||
"""
|
||||
Returns the current shared secret for the ceilometer node. If the shared
|
||||
secret does not exist, this method will generate one.
|
||||
"""
|
||||
secret = None
|
||||
if not os.path.exists(SHARED_SECRET):
|
||||
secret = str(uuid.uuid4())
|
||||
set_shared_secret(secret)
|
||||
else:
|
||||
with open(SHARED_SECRET, 'r') as secret_file:
|
||||
secret = secret_file.read().strip()
|
||||
return secret
|
||||
|
||||
|
||||
def set_shared_secret(secret):
|
||||
"""
|
||||
Sets the shared secret which is used to sign ceilometer messages.
|
||||
|
||||
:param secret: the secret to set
|
||||
"""
|
||||
with open(SHARED_SECRET, 'w') as secret_file:
|
||||
secret_file.write(secret)
|
||||
@@ -18,7 +18,7 @@ os_username = {{ admin_user }}
|
||||
os_password = {{ admin_password }}
|
||||
[database]
|
||||
{% if db_replset: -%}
|
||||
connection = mongodb://{{ db_host }}/{{ db_name }}?readPreference=primaryPreferred
|
||||
connection = mongodb://{{ db_mongo_servers }}/{{ db_name }}?readPreference=primaryPreferred&replicaSet={{ db_replset }}
|
||||
mongodb_replica_set = {{ db_replset }}
|
||||
{% else -%}
|
||||
connection = mongodb://{{ db_host }}:{{ db_port }}/{{ db_name }}
|
||||
|
||||
Reference in New Issue
Block a user