From d1334e4a5928fb1982db7317664e246b87fd4ee7 Mon Sep 17 00:00:00 2001 From: Mark Burnett Date: Fri, 28 Jul 2017 08:14:09 -0500 Subject: [PATCH] Allow additional Armada data to be provided --- docs/configuration.md | 3 ++ example/vagrant-input-config.yaml | 38 ++++++++++++++++++- promenade/config.py | 22 ++++++++++- promenade/generator.py | 2 + promenade/renderer.py | 9 +++++ .../armada-loader/assets/external-armada.yaml | 1 + .../kubelet/manifests/armada-loader.yaml | 15 ++++++-- 7 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 promenade/templates/genesis/etc/kubernetes/armada-loader/assets/external-armada.yaml diff --git a/docs/configuration.md b/docs/configuration.md index 606dc478..c3088ac0 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,6 +43,9 @@ needed for a particular node. `spec` contains specific data for each kind of configuration document. +Additionally, documents for [Armada](https://github.com/att-comdev/armada) are +allowed and will be applied after CNI and DNS are deployed. + ## Generating Configuration from Minimal Input To construct a complete set of cluster configuration, the minimal input are diff --git a/example/vagrant-input-config.yaml b/example/vagrant-input-config.yaml index 8c0c1c5f..df57712d 100644 --- a/example/vagrant-input-config.yaml +++ b/example/vagrant-input-config.yaml @@ -60,7 +60,7 @@ metadata: target: all spec: images: - armada: quay.io/attcomdev/armada:latest + armada: quay.io/attcomdev/armada:master calico: cni: quay.io/calico/cni:v1.9.1 etcd: quay.io/coreos/etcd:v3.2.1 @@ -85,3 +85,39 @@ spec: socat: socat=1.7.3.1-1 additional_packages: - ceph-common=10.2.7-0ubuntu0.16.04.1 +--- +schema: armada/Manifest/v1 +metadata: + schema: metadata/Document/v1 + name: example-application +data: + release_prefix: example + chart_groups: + - example-application +--- +schema: armada/ChartGroup/v1 +metadata: + schema: metadata/Document/v1 + name: example-application +data: + description: Just an example + chart_group: + - redis +--- +schema: armada/Chart/v1 +metadata: + schema: metadata/Document/v1 + name: redis +data: + chart_name: redis + release: example-redis + namespace: default + timeout: 600 + values: + persistence: + enabled: false + source: + type: git + location: https://github.com/kubernetes/charts.git + subpath: stable/redis + dependencies: [] diff --git a/promenade/config.py b/promenade/config.py index 8b01478f..e7e927ac 100644 --- a/promenade/config.py +++ b/promenade/config.py @@ -10,7 +10,22 @@ LOG = logging.getLogger(__name__) def load(f): - return Configuration(list(map(Document, yaml.load_all(f)))) + return Configuration(list(map(instantiate_document, yaml.safe_load_all(f)))) + + +def instantiate_document(data): + if data.get('schema', '').startswith('armada'): + return Document({ + 'apiVersion': 'promenade/v1', + 'kind': 'ArmadaDocument', + 'metadata': { + 'name': data['schema'] + '/' + data['metadata']['name'], + 'target': 'none', + }, + 'spec': data, + }) + else: + return Document(data) class Document: @@ -22,6 +37,8 @@ class Document: } SUPPORTED_KINDS = { + 'ArmadaDocument', + 'Certificate', 'CertificateAuthority', 'CertificateAuthorityKey', @@ -116,6 +133,9 @@ class Configuration: if not kind or document.kind == kind: yield document + def get_armada_documents(self): + return [d.data['spec'] for d in self.iterate(kind='ArmadaDocument')] + def _iterate_with_target(self, target): for document in self.documents: if document.target == target or document.target == 'all': diff --git a/promenade/generator.py b/promenade/generator.py index 5ce3b19c..d4b4033e 100644 --- a/promenade/generator.py +++ b/promenade/generator.py @@ -41,6 +41,7 @@ class Generator: cluster = self.input_config['Cluster'] network = self.input_config['Network'] versions = self.input_config['Versions'] + armada_documents = list(self.input_config.iterate(kind='ArmadaDocument')) cluster_name = cluster.metadata['name'] LOG.info('Generating configuration for cluster "%s"', cluster_name) @@ -198,6 +199,7 @@ class Generator: role_specific_documents.extend(master_documents) if 'genesis' in data.get('roles', []): + role_specific_documents.extend(armada_documents) role_specific_documents.extend(_genesis_config(hostname, data, masters, network, keys)) role_specific_documents.append(_genesis_etcd_config(cluster_name, hostname)) diff --git a/promenade/renderer.py b/promenade/renderer.py index 93c26d39..785dd019 100644 --- a/promenade/renderer.py +++ b/promenade/renderer.py @@ -1,8 +1,10 @@ from . import logging import base64 +import io import jinja2 import os import pkg_resources +import yaml __all__ = ['Renderer'] @@ -45,6 +47,7 @@ class Renderer: loader=jinja2.PackageLoader('promenade', 'templates/include'), undefined=jinja2.StrictUndefined) env.filters['b64enc'] = _base64_encode + env.filters['yaml_safe_dump_all'] = _yaml_safe_dump_all with open(path) as f: template = env.from_string(f.read()) @@ -63,3 +66,9 @@ def _ensure_path(path): def _base64_encode(s): return base64.b64encode(s.encode()).decode() + + +def _yaml_safe_dump_all(documents): + f = io.StringIO() + yaml.safe_dump_all(documents, f) + return f.getvalue() diff --git a/promenade/templates/genesis/etc/kubernetes/armada-loader/assets/external-armada.yaml b/promenade/templates/genesis/etc/kubernetes/armada-loader/assets/external-armada.yaml new file mode 100644 index 00000000..83a6132e --- /dev/null +++ b/promenade/templates/genesis/etc/kubernetes/armada-loader/assets/external-armada.yaml @@ -0,0 +1 @@ +{{ config.get_armada_documents() | yaml_safe_dump_all }} diff --git a/promenade/templates/genesis/etc/kubernetes/kubelet/manifests/armada-loader.yaml b/promenade/templates/genesis/etc/kubernetes/kubelet/manifests/armada-loader.yaml index cc78975d..c6e45385 100644 --- a/promenade/templates/genesis/etc/kubernetes/kubelet/manifests/armada-loader.yaml +++ b/promenade/templates/genesis/etc/kubernetes/kubelet/manifests/armada-loader.yaml @@ -19,11 +19,11 @@ spec: - |- set -x + mkdir -p /root/.kube + cp /etc/kubernetes/armada-loader/kubeconfig.yaml /root/.kube/config + cd /etc/kubernetes/armada-loader/assets if [ -s promenade-armada.yaml ]; then - mkdir -p /root/.kube - cp /etc/kubernetes/armada-loader/kubeconfig.yaml /root/.kube/config - while true; do sleep 10 if armada --debug apply --tiller-host 127.0.0.1 promenade-armada.yaml ; then @@ -32,6 +32,15 @@ spec: done fi + if [ -s external-armada.yaml ]; then + while true; do + sleep 10 + if armada --debug apply --tiller-host 127.0.0.1 external-armada.yaml ; then + break + fi + done + fi + rm -rf /etc/kubernetes/kubelet/manifests/armada-loader.yaml # Sleep so that kubelet doesn't restart this pod before it kills it sleep 10000