promenade/promenade/config.py

107 lines
2.9 KiB
Python

from . import logging
from operator import itemgetter
import itertools
import yaml
__all__ = ['load_config_file']
LOG = logging.getLogger(__name__)
def load_config_file(*, config_path, hostname):
LOG.debug('Loading genesis configuration from "%s"', config_path)
cluster_data = yaml.load(open(config_path))
LOG.debug('Loaded genesis configruation from "%s"', config_path)
node_data = extract_node_data(hostname, cluster_data)
return {
'cluster_data': cluster_data,
'node_data': node_data,
}
def extract_node_data(hostname, cluster_data):
genesis = _extract_genesis_data(cluster_data['nodes'])
masters = _extract_master_data(cluster_data['nodes'])
return {
'cluster': cluster_data['nodes'],
'current_node': _extract_current_node_data(cluster_data['nodes'],
hostname),
'etcd': _extract_etcd_data(hostname, genesis, masters),
'genesis': genesis,
'masters': masters,
'network': cluster_data['network'],
}
def _extract_etcd_data(hostname, genesis, masters):
LOG.info('hostname=%r genesis=%r masters=%r',
hostname, genesis, masters)
non_genesis_masters = [d for d in masters if d['hostname'] != genesis['hostname']]
boot_order = [genesis] + sorted(non_genesis_masters, key=itemgetter('hostname'))
result = {
'boot_order': boot_order,
'env': {},
}
peers = []
for host in boot_order:
peers.append(host)
if host['hostname'] == hostname:
break
result['env']['ETCD_INITIAL_CLUSTER'] = ','.join(
'%s=https://%s:2380' % (p['hostname'], p['hostname'])
for p in peers)
if hostname == genesis['hostname']:
result['env']['ETCD_INITIAL_CLUSTER_STATE'] = 'new'
else:
result['env']['ETCD_INITIAL_CLUSTER_STATE'] = 'existing'
return result
def _extract_current_node_data(nodes, hostname):
base = nodes[hostname]
return {
'hostname': hostname,
'labels': _extract_node_labels(base),
**base,
}
ROLE_LABELS = {
'genesis': [
'promenade=genesis',
],
'master': [
'node-role.kubernetes.io/master=',
],
}
def _extract_node_labels(data):
labels = set(itertools.chain.from_iterable(
map(lambda k: ROLE_LABELS.get(k, []), ['common'] + data['roles'])))
labels.update(data.get('additional_labels', []))
return sorted(labels)
def _extract_genesis_data(nodes):
for hostname, node in nodes.items():
if 'genesis' in node['roles']:
return {
'hostname': hostname,
'ip': node['ip'],
}
def _extract_master_data(nodes):
return sorted(({'hostname': hostname, 'ip': node['ip']}
for hostname, node in nodes.items()
if 'master' in node['roles']),
key=itemgetter('hostname'))