From 9e7a8b8ba7492a548fc90a9eda0b58962ad4fd91 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Mon, 19 Jun 2017 14:36:48 -0500 Subject: [PATCH] update operator code for new config/pki --- promenade/cli.py | 8 +-- promenade/config.py | 4 +- promenade/operator.py | 22 ++----- promenade/pki.py | 134 ------------------------------------------ promenade/renderer.py | 13 ++-- 5 files changed, 15 insertions(+), 166 deletions(-) diff --git a/promenade/cli.py b/promenade/cli.py index 6aad49ac..76f254af 100644 --- a/promenade/cli.py +++ b/promenade/cli.py @@ -18,9 +18,7 @@ def promenade(*, verbose): type=click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True), help='Source path for binaries to deploy.') -@click.option('-c', '--config-path', - type=click.Path(exists=True, file_okay=True, - dir_okay=False, resolve_path=True), +@click.option('-c', '--config-path', type=click.File(), help='Location of cluster configuration data.') @click.option('--hostname', help='Current hostname.') @click.option('-t', '--target-dir', default='/target', @@ -41,9 +39,7 @@ def genesis(*, asset_dir, config_path, hostname, target_dir): type=click.Path(exists=True, file_okay=False, dir_okay=True, resolve_path=True), help='Source path for binaries to deploy.') -@click.option('-c', '--config-path', - type=click.Path(exists=True, file_okay=True, - dir_okay=False, resolve_path=True), +@click.option('-c', '--config-path', type=click.File(), help='Location of cluster configuration data.') @click.option('--hostname', help='Current hostname.') @click.option('-t', '--target-dir', default='/target', diff --git a/promenade/config.py b/promenade/config.py index 8a782f33..63777e86 100644 --- a/promenade/config.py +++ b/promenade/config.py @@ -36,7 +36,9 @@ class Document: } def __init__(self, data): - assert set(data.keys()) == self.KEYS + if set(data.keys()) != self.KEYS: + LOG.error('data.keys()=%s expected %s', data.keys(), self.KEYS) + raise AssertionError('Did not get expected keys') assert data['apiVersion'] == 'promenade/v1' assert data['kind'] in self.SUPPORTED_KINDS diff --git a/promenade/operator.py b/promenade/operator.py index b20b1c97..b0f58e8a 100644 --- a/promenade/operator.py +++ b/promenade/operator.py @@ -1,4 +1,4 @@ -from . import config, logging, pki, renderer +from . import config, logging, renderer import os import subprocess @@ -10,18 +10,13 @@ LOG = logging.getLogger(__name__) class Operator: @classmethod - def from_config(cls, *, - config_path, - hostname, - target_dir): + 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)) + config_=config.load(config_path)) - def __init__(self, *, cluster_data, hostname, node_data, target_dir): - self.cluster_data = cluster_data + def __init__(self, *, config_, hostname, target_dir): + self.config = config_ self.hostname = hostname - self.node_data = node_data self.target_dir = target_dir def genesis(self, *, asset_dir=None): @@ -33,7 +28,6 @@ class Operator: def setup(self, *, asset_dir): self.rsync_from(asset_dir) self.render() - self.install_keys() self.bootstrap() @@ -48,14 +42,10 @@ class Operator: def render(self): - r = renderer.Renderer(node_data=self.node_data, + r = renderer.Renderer(config=self.config, 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'), diff --git a/promenade/pki.py b/promenade/pki.py index 7863efb6..41adc0d6 100644 --- a/promenade/pki.py +++ b/promenade/pki.py @@ -1,7 +1,6 @@ from . import config, logging import json import os -import shutil import subprocess import tempfile import yaml @@ -153,136 +152,3 @@ def block_literal_representer(dumper, data): yaml.add_representer(block_literal, block_literal_representer) - - -CA_ONLY_MAP = { - 'cluster-ca': [ - 'kubelet', - ], -} - - -FULL_DISTRIBUTION_MAP = { - 'apiserver': [ - 'apiserver', - ], - 'apiserver-key': [ - 'apiserver', - ], - 'controller-manager': [ - 'controller-manager', - ], - 'controller-manager-key': [ - 'controller-manager', - ], - 'kubelet': [ - 'kubelet', - ], - 'kubelet-key': [ - 'kubelet', - ], - 'proxy': [ - 'proxy', - ], - 'proxy-key': [ - 'proxy', - ], - 'scheduler': [ - 'scheduler', - ], - 'scheduler-key': [ - 'scheduler', - ], - - 'cluster-ca': [ - 'admin', - 'apiserver', - 'asset-loader', - 'controller-manager', - 'etcd', - 'genesis', - 'kubelet', - 'proxy', - 'scheduler', - ], - 'cluster-ca-key': [ - 'controller-manager', - ], - - 'sa': [ - 'apiserver', - ], - 'sa-key': [ - 'controller-manager', - ], - - 'etcd': [ - 'etcd', - ], - 'etcd-key': [ - 'etcd', - ], - - 'admin': [ - 'admin', - ], - 'admin-key': [ - 'admin', - ], - 'asset-loader': [ - 'asset-loader', - ], - 'asset-loader-key': [ - 'asset-loader', - ], - 'genesis': [ - 'genesis', - ], - 'genesis-key': [ - 'genesis', - ], -} - - -def generate_keys(*, initial_pki, target_dir): - if os.path.exists(os.path.join(target_dir, 'etc/kubernetes/cfssl')): - with tempfile.TemporaryDirectory() as tmp: - _write_initial_pki(tmp, initial_pki) - - _generate_certs(tmp, target_dir) - - _distribute_files(tmp, target_dir, FULL_DISTRIBUTION_MAP) - - -def _write_initial_pki(tmp, initial_pki): - for filename, data in initial_pki.items(): - path = os.path.join(tmp, filename + '.pem') - with open(path, 'w') as f: - LOG.debug('Writing data for "%s" to path "%s"', filename, path) - f.write(data) - - -def _generate_certs(dest, target): - ca_config_path = os.path.join(target, 'etc/kubernetes/cfssl/ca-config.json') - ca_path = os.path.join(dest, 'cluster-ca.pem') - ca_key_path = os.path.join(dest, 'cluster-ca-key.pem') - search_dir = os.path.join(target, 'etc/kubernetes/cfssl/csr-configs') - for filename in os.listdir(search_dir): - name, _ext = os.path.splitext(filename) - LOG.info('Generating cert for %s', name) - path = os.path.join(search_dir, filename) - cfssl_result = subprocess.check_output([ - 'cfssl', 'gencert', '-ca', ca_path, '-ca-key', ca_key_path, - '-config', ca_config_path, '-profile', 'kubernetes', path]) - subprocess.run(['cfssljson', '-bare', name], cwd=dest, - input=cfssl_result, check=True) - - -def _distribute_files(src, dest, distribution_map): - for filename, destinations in distribution_map.items(): - src_path = os.path.join(src, filename + '.pem') - if os.path.exists(src_path): - for destination in destinations: - dest_dir = os.path.join(dest, 'etc/kubernetes/%s/pki' % destination) - os.makedirs(dest_dir, exist_ok=True) - shutil.copy(src_path, dest_dir) diff --git a/promenade/renderer.py b/promenade/renderer.py index 385125b8..e605f3d0 100644 --- a/promenade/renderer.py +++ b/promenade/renderer.py @@ -10,19 +10,14 @@ LOG = logging.getLogger(__name__) class Renderer: - def __init__(self, *, node_data, target_dir): - self.data = node_data + def __init__(self, *, config, target_dir): + self.config = config self.target_dir = target_dir - @property - def template_paths(self): - return ['common'] + self.data['current_node']['roles'] - def render(self): - for template_dir in self.template_paths: + for template_dir in self.config['Node']['templates']: self.render_template_dir(template_dir) - def render_template_dir(self, template_dir): source_root = pkg_resources.resource_filename( 'promenade', os.path.join('templates', template_dir)) @@ -46,7 +41,7 @@ class Renderer: with open(path) as f: template = env.from_string(f.read()) - rendered_data = template.render(**self.data) + rendered_data = template.render(config=self.config) with open(target_path, 'w') as f: f.write(rendered_data)