promenade/promenade/operator.py

78 lines
2.6 KiB
Python

from . import config, etcd, logging, kube, pki, renderer
import os
import subprocess
__all__ = ['Operator']
LOG = logging.getLogger(__name__)
class Operator:
@classmethod
def from_config(cls, *,
config_path,
hostname,
target_dir):
return cls(hostname=hostname, target_dir=target_dir,
**config.load_config_file(config_path=config_path,
hostname=hostname))
def __init__(self, *, cluster_data, hostname, node_data, target_dir):
self.cluster_data = cluster_data
self.hostname = hostname
self.node_data = node_data
self.target_dir = target_dir
def genesis(self, *, asset_dir=None):
self.setup(asset_dir=asset_dir)
self.expand_etcd_cluster()
def join(self, *, asset_dir=None):
self.setup(asset_dir=asset_dir)
def setup(self, *, asset_dir):
self.rsync_from(asset_dir)
self.render()
self.install_keys()
self.bootstrap()
def rsync_from(self, src):
if src:
LOG.debug('Syncing assets from "%s" to "%s".', src, self.target_dir)
subprocess.run(['/usr/bin/rsync', '-r',
os.path.join(src, ''), self.target_dir],
check=True)
else:
LOG.debug('No source directory given for rsync.')
def render(self):
r = renderer.Renderer(node_data=self.node_data,
target_dir=self.target_dir)
r.render()
def install_keys(self):
pki.generate_keys(initial_pki=self.cluster_data['pki'],
target_dir=self.target_dir)
def bootstrap(self):
LOG.debug('Running genesis script with chroot "%s"', self.target_dir)
subprocess.run([os.path.join(self.target_dir, 'usr/sbin/chroot'),
self.target_dir,
'/bin/bash', '/usr/local/bin/bootstrap'],
check=True)
def expand_etcd_cluster(self):
for node in self.node_data['etcd']['boot_order'][1:]:
LOG.info('Waiting for Node "%s" to be Ready', node['hostname'])
kube.wait_for_node(node['hostname'])
LOG.info('Node "%s" Ready. Adding to etcd cluster.', node['hostname'])
etcd.add_member(self.genesis_etcd_pod, node['hostname'], port=2380)
LOG.info('Finished expanding etcd cluster.')
@property
def genesis_etcd_pod(self):
return 'kube-etcd-%s' % self.node_data['genesis']['hostname']