├── tests ├── __init__.py └── unit │ ├── __init__.py │ ├── api │ ├── __init__.py │ ├── test_health_api.py │ └── test_versions.py │ └── test_generator.py ├── promenade ├── __init__.py ├── control │ ├── __init__.py │ └── health_api.py ├── templates │ ├── roles │ │ ├── join │ │ │ ├── etc │ │ │ │ └── kubernetes │ │ │ │ │ └── manifests │ │ │ │ │ └── .placeholder │ │ │ └── usr │ │ │ │ └── local │ │ │ │ └── bin │ │ │ │ └── helm │ │ ├── common │ │ │ ├── etc │ │ │ │ ├── docker │ │ │ │ │ └── daemon.json │ │ │ │ ├── kubernetes │ │ │ │ │ ├── admin │ │ │ │ │ │ ├── pki │ │ │ │ │ │ │ ├── admin.pem │ │ │ │ │ │ │ ├── admin-key.pem │ │ │ │ │ │ │ └── cluster-ca.pem │ │ │ │ │ │ └── kubeconfig.yaml │ │ │ │ │ ├── pki │ │ │ │ │ │ ├── cluster-ca.pem │ │ │ │ │ │ ├── kubelet.pem │ │ │ │ │ │ └── kubelet-key.pem │ │ │ │ │ ├── kubeconfig │ │ │ │ │ └── manifests │ │ │ │ │ │ └── haproxy.yaml │ │ │ │ ├── apt │ │ │ │ │ └── sources.list.d │ │ │ │ │ │ └── promenade-sources.list │ │ │ │ ├── resolv.conf │ │ │ │ ├── systemd │ │ │ │ │ └── system │ │ │ │ │ │ ├── docker.service.d │ │ │ │ │ │ └── http-proxy.conf │ │ │ │ │ │ └── kubelet.service │ │ │ │ ├── hosts │ │ │ │ └── promenade │ │ │ │ │ └── haproxy │ │ │ │ │ └── haproxy.cfg │ │ │ └── usr │ │ │ │ └── local │ │ │ │ └── bin │ │ │ │ ├── kubectl │ │ │ │ └── promenade-teardown │ │ └── genesis │ │ │ ├── etc │ │ │ ├── genesis │ │ │ │ ├── armada │ │ │ │ │ ├── assets │ │ │ │ │ │ └── manifest.yaml │ │ │ │ │ └── auth │ │ │ │ │ │ ├── pki │ │ │ │ │ │ ├── armada.pem │ │ │ │ │ │ ├── armada-key.pem │ │ │ │ │ │ └── cluster-ca.pem │ │ │ │ │ │ └── config │ │ │ │ ├── apiserver │ │ │ │ │ └── pki │ │ │ │ │ │ ├── apiserver.pem │ │ │ │ │ │ ├── apiserver-key.pem │ │ │ │ │ │ ├── cluster-ca.pem │ │ │ │ │ │ ├── etcd-client.pem │ │ │ │ │ │ ├── service-account.pub │ │ │ │ │ │ ├── etcd-client-key.pem │ │ │ │ │ │ └── etcd-client-ca.pem │ │ │ │ ├── armada-cli │ │ │ │ │ └── auth │ │ │ │ │ │ ├── pki │ │ │ │ │ │ ├── armada.pem │ │ │ │ │ │ ├── armada-key.pem │ │ │ │ │ │ └── cluster-ca.pem │ │ │ │ │ │ └── config │ │ │ │ ├── scheduler │ │ │ │ │ ├── pki │ │ │ │ │ │ ├── scheduler.pem │ │ │ │ │ │ ├── scheduler-key.pem │ │ │ │ │ │ └── cluster-ca.pem │ │ │ │ │ └── kubeconfig.yaml │ │ │ │ ├── etcd │ │ │ │ │ └── pki │ │ │ │ │ │ ├── client-ca.pem │ │ │ │ │ │ ├── etcd-client.pem │ │ │ │ │ │ ├── etcd-peer.pem │ │ │ │ │ │ ├── peer-ca.pem │ │ │ │ │ │ ├── etcd-client-key.pem │ │ │ │ │ │ └── etcd-peer-key.pem │ │ │ │ └── controller-manager │ │ │ │ │ ├── pki │ │ │ │ │ ├── cluster-ca.pem │ │ │ │ │ ├── service-account.key │ │ │ │ │ ├── controller-manager.pem │ │ │ │ │ └── controller-manager-key.pem │ │ │ │ │ └── kubeconfig.yaml │ │ │ └── kubernetes │ │ │ │ └── manifests │ │ │ │ ├── kubernetes-etcd.yaml │ │ │ │ ├── kubernetes-scheduler.yaml │ │ │ │ ├── kubernetes-controller-manager.yaml │ │ │ │ └── kubernetes-apiserver.yaml │ │ │ └── usr │ │ │ └── local │ │ │ └── bin │ │ │ ├── armada │ │ │ └── helm │ ├── include │ │ ├── cleanup.sh │ │ ├── genesis-etcd │ │ │ └── common-volumes.yaml │ │ ├── basic-host-validation.sh │ │ └── header.sh │ └── scripts │ │ ├── validate-genesis.sh │ │ ├── validate-join.sh │ │ ├── validate-cluster.sh │ │ ├── join.sh │ │ └── genesis.sh ├── schemas │ ├── Docker.yaml │ ├── ArmadaPlaceholders.yaml │ ├── Kubelet.yaml │ ├── PKICatalog.yaml │ ├── KubernetesNode.yaml │ └── DeckhandPlaceholders.yaml ├── options.py ├── promenade.py ├── tar_bundler.py ├── design_ref.py └── logging.py ├── tools ├── gate │ ├── config │ │ └── .gitkeep │ ├── promenade-bundle │ │ └── .gitkeep │ ├── final-validation.sh │ ├── .gitignore │ ├── required-config-env │ ├── config-templates │ │ ├── LayeringPolicy.yaml │ │ └── genesis-config.yaml │ ├── util │ │ └── validate-test-env.sh │ ├── default-config-env │ └── build.sh ├── g2 │ ├── .gitignore │ ├── templates │ │ ├── meta-data.sub │ │ ├── user-data.sub │ │ ├── network-config.sub │ │ └── ssh-config.sub │ ├── stages │ │ ├── create-vms.sh │ │ ├── hard-reboot-cluster.sh │ │ ├── gate-setup.sh │ │ ├── report-disk-io.sh │ │ ├── build-scripts.sh │ │ ├── genesis.sh │ │ ├── reprovision-genesis.sh │ │ ├── move-master.sh │ │ ├── load-site-config.sh │ │ ├── build-image.sh │ │ ├── conformance.sh │ │ ├── fail-join-node.sh │ │ └── teardown-nodes.sh │ ├── bin │ │ ├── etcdctl.sh │ │ ├── ssh.sh │ │ └── rsync.sh │ ├── lib │ │ ├── const.sh │ │ ├── etcd.sh │ │ ├── docker.sh │ │ ├── all.sh │ │ ├── validate.sh │ │ ├── openstack.sh │ │ ├── config.sh │ │ ├── nginx.sh │ │ ├── ssh.sh │ │ ├── kube.sh │ │ ├── log.sh │ │ └── promenade.sh │ ├── xml │ │ └── network.xml │ ├── manifests │ │ ├── smoke.json │ │ ├── genesis.json │ │ ├── integration.json │ │ └── conformance.json │ └── on_error │ │ └── collect_genesis_info.sh ├── registry │ ├── stop.sh │ ├── revert_example.sh │ ├── update_example.sh │ ├── start.sh │ ├── update_cache.sh │ └── IMAGES ├── stop_gate.sh ├── dev-build.sh ├── dev │ ├── get-token.sh │ └── server.sh ├── lint_gate.sh ├── gate.sh ├── setup_gate.sh ├── simple-deployment.sh └── helm_tk.sh ├── test-requirements.txt ├── charts ├── .gitignore ├── coredns │ ├── Chart.yaml │ ├── requirements.yaml │ ├── templates │ │ ├── configmap-etc.yaml │ │ ├── service.yaml │ │ ├── rbac.yaml │ │ └── pod-test.yaml │ └── values.yaml ├── calico │ ├── Chart.yaml │ ├── .helmignore │ ├── templates │ │ ├── secret.yaml │ │ ├── rbac.yaml │ │ └── configmap.yaml │ ├── requirements.yaml │ └── values.yaml ├── promenade │ ├── Chart.yaml │ ├── requirements.yaml │ └── templates │ │ ├── job-ks-user.yaml │ │ ├── job-ks-service.yaml │ │ ├── job-ks-endpoints.yaml │ │ ├── secret-keystone-env.yaml │ │ ├── service-api.yaml │ │ ├── rbac.yaml │ │ ├── configmap-bin.yaml │ │ └── tests │ │ └── test-promenade-api.yaml ├── scheduler │ ├── Chart.yaml │ ├── requirements.yaml │ ├── templates │ │ ├── secret.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── bin │ │ │ ├── _pre_stop.tpl │ │ │ └── _anchor.tpl │ │ └── etc │ │ │ └── _kubeconfig.yaml.tpl │ └── values.yaml ├── proxy │ ├── requirements.yaml │ ├── Chart.yaml │ ├── templates │ │ └── rbac.yaml │ └── values.yaml ├── haproxy │ ├── requirements.yaml │ ├── Chart.yaml │ └── templates │ │ ├── bin │ │ └── _pre_stop.tpl │ │ ├── configmap-bin.yaml │ │ ├── configmap-etc.yaml │ │ ├── rbac.yaml │ │ └── tests │ │ └── test-haproxy-health.yaml ├── apiserver │ ├── templates │ │ ├── bin │ │ │ ├── _pre_stop.tpl │ │ │ └── _anchor.tpl │ │ ├── configmap-etc.yaml │ │ ├── secret-apiserver.yaml │ │ ├── configmap-bin.yaml │ │ ├── configmap-certs.yaml │ │ └── service.yaml │ ├── Chart.yaml │ └── requirements.yaml ├── controller_manager │ ├── templates │ │ ├── bin │ │ │ ├── _pre_stop.tpl │ │ │ └── _anchor.tpl │ │ ├── secret.yaml │ │ ├── configmap-bin.yaml │ │ ├── etc │ │ │ └── _kubeconfig.yaml.tpl │ │ └── configmap-etc.yaml │ ├── Chart.yaml │ └── requirements.yaml └── etcd │ ├── Chart.yaml │ ├── requirements.yaml │ └── templates │ ├── bin │ ├── _readiness.tpl │ └── _pre_stop.tpl │ ├── configmap-etc.yaml │ ├── secret-keys.yaml │ ├── configmap-bin.yaml │ ├── configmap-certs.yaml │ └── service.yaml ├── .gitreview ├── requirements.txt ├── docs └── source │ ├── troubleshooting │ └── index.rst │ ├── configuration │ ├── docker.rst │ ├── index.rst │ ├── kubelet.rst │ └── kubernetes-node.rst │ ├── index.rst │ ├── api.rst │ └── exceptions.rst ├── examples ├── basic │ ├── LayeringPolicy.yaml │ ├── Docker.yaml │ ├── Kubelet.yaml │ ├── PKICatalog-addition.yaml │ ├── KubernetesNetwork.yaml │ └── Genesis.yaml └── complete │ ├── LayeringPolicy.yaml │ ├── Docker.yaml │ ├── Kubelet.yaml │ ├── KubernetesNetwork.yaml │ └── Genesis.yaml ├── requirements-direct.txt ├── .dockerignore ├── .gitignore ├── entrypoint.sh ├── etc └── promenade │ ├── api-paste.ini │ └── noauth-api-paste.ini ├── setup.py ├── tox.ini ├── README.md ├── Dockerfile ├── Makefile └── requirements-frozen.txt /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /promenade/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/unit/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/unit/api/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/gate/config/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /promenade/control/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /tools/g2/.gitignore: -------------------------------------------------------------------------------- 1 | config-ssh 2 | -------------------------------------------------------------------------------- /tools/gate/promenade-bundle/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /charts/.gitignore: -------------------------------------------------------------------------------- 1 | /*.tgz 2 | /*/charts 3 | /*/requirements.lock 4 | -------------------------------------------------------------------------------- /tools/gate/final-validation.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | -------------------------------------------------------------------------------- /promenade/templates/roles/join/etc/kubernetes/manifests/.placeholder: -------------------------------------------------------------------------------- 1 | # placeholder 2 | -------------------------------------------------------------------------------- /tools/gate/.gitignore: -------------------------------------------------------------------------------- 1 | /config 2 | /config-env 3 | /promenade-bundle 4 | /promenade-bundle.tgz 5 | -------------------------------------------------------------------------------- /tools/registry/stop.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | docker rm -fv registry 6 | -------------------------------------------------------------------------------- /.gitreview: -------------------------------------------------------------------------------- 1 | [gerrit] 2 | host=review.gerrithub.io 3 | port=29418 4 | project=att-comdev/promenade 5 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/docker/daemon.json: -------------------------------------------------------------------------------- 1 | {{ config['Docker:config'] | tojson(indent=2) }} 2 | -------------------------------------------------------------------------------- /tools/g2/templates/meta-data.sub: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | instance-id: promenade-${NAME} 3 | local-hostname: ${NAME} 4 | -------------------------------------------------------------------------------- /charts/coredns/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A chart for coredns 3 | name: coredns 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /charts/calico/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for Calico 3 | name: calico 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /charts/promenade/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: The Promenade API 3 | name: promenade 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Warning: This file should be empty. 2 | # Specify direct dependencies in requirements-direct.txt instead. 3 | -------------------------------------------------------------------------------- /promenade/templates/include/cleanup.sh: -------------------------------------------------------------------------------- 1 | set +x 2 | log 3 | log === Restarting kubelet === 4 | set -x 5 | systemctl restart kubelet 6 | -------------------------------------------------------------------------------- /charts/scheduler/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A chart for Kubernetes scheduler. 3 | name: scheduler 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/admin/pki/admin.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='admin') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/admin/pki/admin-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='admin') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada/assets/manifest.yaml: -------------------------------------------------------------------------------- 1 | {{ config.iterate(schema='armada') | yaml_safe_dump_all | safe }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada/auth/pki/armada.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='armada') }} 2 | -------------------------------------------------------------------------------- /tools/g2/stages/create-vms.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | vm_clean_all 8 | vm_create_all 9 | -------------------------------------------------------------------------------- /charts/proxy/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: helm-toolkit 3 | repository: http://localhost:8879/charts 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/apiserver/pki/apiserver.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='apiserver') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada-cli/auth/pki/armada.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='armada') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/scheduler/pki/scheduler.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='scheduler') }} 2 | -------------------------------------------------------------------------------- /charts/coredns/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: helm-toolkit 3 | repository: http://localhost:8879/charts 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /charts/haproxy/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: helm-toolkit 3 | repository: http://localhost:8879/charts 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /charts/promenade/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: helm-toolkit 3 | repository: http://localhost:8879/charts 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /charts/scheduler/requirements.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: helm-toolkit 3 | repository: http://localhost:8879/charts 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/pki/cluster-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/apiserver/pki/apiserver-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='apiserver') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada-cli/auth/pki/armada-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='armada') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada/auth/pki/armada-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='armada') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/scheduler/pki/scheduler-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='scheduler') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/admin/pki/cluster-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/pki/kubelet.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='kubelet-' + config.kubelet_name) }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/apiserver/pki/cluster-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/apiserver/pki/etcd-client.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='apiserver-etcd') }} 2 | 3 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/apiserver/pki/service-account.pub: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/PublicKey/v1', name='service-account') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/etcd/pki/client-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes-etcd') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/etcd/pki/etcd-client.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='kubernetes-etcd-genesis') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/scheduler/pki/cluster-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes') }} 2 | -------------------------------------------------------------------------------- /charts/haproxy/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A chart for using HAProxy for Kubernetes API server discovery 3 | name: haproxy 4 | version: 0.1.0 5 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/apiserver/pki/etcd-client-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='apiserver-etcd') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada-cli/auth/pki/cluster-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada/auth/pki/cluster-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/etcd/pki/etcd-peer.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='kubernetes-etcd-genesis-peer') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/etcd/pki/peer-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes-etcd-peer') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/pki/kubelet-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='kubelet-' + config.kubelet_name) }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/apiserver/pki/etcd-client-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes-etcd') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/controller-manager/pki/cluster-ca.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateAuthority/v1', name='kubernetes') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/controller-manager/pki/service-account.key: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/PrivateKey/v1', name='service-account') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/etcd/pki/etcd-client-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='kubernetes-etcd-genesis') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/etcd/pki/etcd-peer-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='kubernetes-etcd-genesis-peer') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/controller-manager/pki/controller-manager.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/Certificate/v1', name='controller-manager') }} 2 | -------------------------------------------------------------------------------- /tools/g2/stages/hard-reboot-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | vm_restart_all 8 | validate_cluster "${GENESIS_NAME}" 9 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/controller-manager/pki/controller-manager-key.pem: -------------------------------------------------------------------------------- 1 | {{ config.get(schema='deckhand/CertificateKey/v1', name='controller-manager') }} 2 | -------------------------------------------------------------------------------- /promenade/templates/scripts/validate-genesis.sh: -------------------------------------------------------------------------------- 1 | {% include "header.sh" with context %} 2 | 3 | wait_for_kubernetes_api 4 | 5 | validate_kubectl_logs {{ config['Genesis:hostname'] }} 6 | -------------------------------------------------------------------------------- /docs/source/troubleshooting/index.rst: -------------------------------------------------------------------------------- 1 | Troubleshooting 2 | =============== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Troubleshooting 7 | 8 | genesis 9 | 10 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/apt/sources.list.d/promenade-sources.list: -------------------------------------------------------------------------------- 1 | {%- for repo in config.get_path('HostSystem:packages.repositories', []) %} 2 | {{ repo }} 3 | {%- endfor %} 4 | -------------------------------------------------------------------------------- /promenade/templates/scripts/validate-join.sh: -------------------------------------------------------------------------------- 1 | {% include "header.sh" with context %} 2 | 3 | wait_for_kubernetes_api 4 | 5 | validate_kubectl_logs {{ config['KubernetesNode:hostname'] }} 6 | -------------------------------------------------------------------------------- /charts/coredns/templates/configmap-etc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ .Values.service.name }}-etc 6 | data: 7 | Corefile: {{ .Values.conf.coredns.corefile | quote }} 8 | -------------------------------------------------------------------------------- /tools/gate/required-config-env: -------------------------------------------------------------------------------- 1 | CALICO_IP_AUTODETECTION_METHOD 2 | GENESIS_HOSTNAME 3 | GENESIS_IP 4 | MASTER1_HOSTNAME 5 | MASTER1_IP 6 | MASTER2_HOSTNAME 7 | MASTER2_IP 8 | WORKER_HOSTNAME 9 | WORKER_IP 10 | -------------------------------------------------------------------------------- /charts/scheduler/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: kubernetes-scheduler 6 | type: Opaque 7 | data: 8 | scheduler-key.pem: {{ .Values.secrets.tls.key | b64enc }} 9 | -------------------------------------------------------------------------------- /examples/basic/LayeringPolicy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/LayeringPolicy/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: layering-policy 6 | data: 7 | layerOrder: 8 | - global 9 | - type 10 | - site 11 | ... 12 | -------------------------------------------------------------------------------- /examples/complete/LayeringPolicy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/LayeringPolicy/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: layering-policy 6 | data: 7 | layerOrder: 8 | - global 9 | - type 10 | - site 11 | ... 12 | -------------------------------------------------------------------------------- /promenade/templates/include/genesis-etcd/common-volumes.yaml: -------------------------------------------------------------------------------- 1 | - name: data-{{ etcd_name }} 2 | hostPath: 3 | path: /var/lib/etcd/{{ volume_name }} 4 | - name: pki-{{ etcd_name }} 5 | hostPath: 6 | path: /etc/genesis/etcd/pki 7 | -------------------------------------------------------------------------------- /tools/gate/config-templates/LayeringPolicy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/LayeringPolicy/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: layering-policy 6 | data: 7 | layerOrder: 8 | - global 9 | - type 10 | - site 11 | ... 12 | -------------------------------------------------------------------------------- /promenade/templates/scripts/validate-cluster.sh: -------------------------------------------------------------------------------- 1 | {% include "header.sh" with context %} 2 | 3 | wait_for_kubernetes_api 4 | 5 | for node in $(kubectl get nodes -o name | cut -d / -f 2); do 6 | wait_for_node_ready $node 180 7 | validate_kubectl_logs $node 8 | done 9 | -------------------------------------------------------------------------------- /tools/g2/bin/etcdctl.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(realpath $(dirname $0)) 6 | WORKSPACE=$(realpath ${SCRIPT_DIR}/../../..) 7 | GATE_UTILS=${WORKSPACE}/tools/g2/lib/all.sh 8 | 9 | source ${GATE_UTILS} 10 | 11 | etcdctl_cmd ${@} 12 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/resolv.conf: -------------------------------------------------------------------------------- 1 | options timeout:1 attempts:1 2 | 3 | nameserver {{ config['KubernetesNetwork:dns.service_ip'] }} 4 | {% for server in config['KubernetesNetwork:dns.upstream_servers'] | default([]) %} 5 | nameserver {{ server }} 6 | {%- endfor %} 7 | -------------------------------------------------------------------------------- /tools/g2/templates/user-data.sub: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | 3 | disable_root: false 4 | 5 | hostname: ${NAME} 6 | manage_etc_hosts: false 7 | 8 | ssh_authorized_keys: 9 | - ${SSH_PUBLIC_KEY} 10 | 11 | chpasswd: 12 | list: | 13 | root:password 14 | expire: false 15 | -------------------------------------------------------------------------------- /tools/registry/revert_example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | IMAGES_FILE=$(dirname $0)/IMAGES 6 | 7 | IFS=, 8 | grep -v '^#.*' $IMAGES_FILE | while read src tag dst; do 9 | sed -i "s;registry:5000/$dst:$tag;$src:$tag;g" examples/basic/*.yaml 10 | done 11 | -------------------------------------------------------------------------------- /tools/registry/update_example.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | IMAGES_FILE=$(dirname $0)/IMAGES 6 | 7 | IFS=, 8 | grep -v '^#.*' $IMAGES_FILE | while read src tag dst; do 9 | sed -i "s;$src:$tag;registry:5000/$dst:$tag;g" examples/basic/*.yaml 10 | done 11 | -------------------------------------------------------------------------------- /tools/g2/bin/ssh.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(realpath $(dirname $0)) 6 | WORKSPACE=$(realpath ${SCRIPT_DIR}/../../..) 7 | GATE_UTILS=${WORKSPACE}/tools/g2/lib/all.sh 8 | 9 | source ${GATE_UTILS} 10 | 11 | exec ssh -F ${SSH_CONFIG_DIR}/config $@ 12 | -------------------------------------------------------------------------------- /tools/g2/lib/const.sh: -------------------------------------------------------------------------------- 1 | export GENESIS_NAME=n0 2 | export SSH_CONFIG_DIR=${WORKSPACE}/tools/g2/config-ssh 3 | export TEMPLATE_DIR=${WORKSPACE}/tools/g2/templates 4 | export XML_DIR=${WORKSPACE}/tools/g2/xml 5 | export ALL_VM_NAMES=( 6 | n0 7 | n1 8 | n2 9 | n3 10 | ) 11 | -------------------------------------------------------------------------------- /promenade/templates/include/basic-host-validation.sh: -------------------------------------------------------------------------------- 1 | # Validate the hostname is as expected 2 | # 3 | if [ "$(hostname)" != "{{ config.get_first('KubernetesNode:hostname', 'Genesis:hostname') }}" ]; then 4 | echo "The node hostname must match the Kubernetes node name" 1>&2 5 | exit 1 6 | fi 7 | -------------------------------------------------------------------------------- /tools/g2/bin/rsync.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(realpath $(dirname $0)) 6 | WORKSPACE=$(realpath ${SCRIPT_DIR}/../../..) 7 | GATE_UTILS=${WORKSPACE}/tools/g2/lib/all.sh 8 | 9 | source ${GATE_UTILS} 10 | 11 | exec rsync -e "ssh -F ${SSH_CONFIG_DIR}/config" $@ 12 | -------------------------------------------------------------------------------- /tools/g2/templates/network-config.sub: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | version: 1 3 | config: 4 | - type: physical 5 | name: ens3 6 | subnets: 7 | - type: static 8 | address: ${BR_IP_NODE}/24 9 | gateway: 192.168.77.1 10 | - type: nameserver 11 | address: 12 | - 8.8.8.8 13 | - 8.8.4.4 14 | -------------------------------------------------------------------------------- /promenade/templates/include/header.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | {% include "utils.sh" with context %} 6 | 7 | # Ensure the script is running as root. 8 | # 9 | if [ "$(id -u)" != "0" ]; then 10 | echo "This script must be run as root." 1>&2 11 | exit 1 12 | fi 13 | 14 | function log { 15 | echo $(date) $* 1>&2 16 | } 17 | -------------------------------------------------------------------------------- /tools/registry/start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | REGISTRY_DATA_DIR=${REGISTRY_DATA_DIR:-/mnt/registry} 6 | 7 | docker run -d \ 8 | -p 5000:5000 \ 9 | -e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \ 10 | --restart=always \ 11 | --name registry \ 12 | -v $REGISTRY_DATA_DIR:/var/lib/registry \ 13 | registry:2 14 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/systemd/system/docker.service.d/http-proxy.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | Environment="HTTP_PROXY={{ config['KubernetesNetwork:proxy.url'] | default('', true) }}" 3 | Environment="HTTPS_PROXY={{ config['KubernetesNetwork:proxy.url'] | default('', true) }}" 4 | Environment="NO_PROXY={{ config.get(kind='KubernetesNetwork') | fill_no_proxy }}" 5 | -------------------------------------------------------------------------------- /tools/stop_gate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(realpath "$(dirname "${0}")") 6 | WORKSPACE=$(realpath "${SCRIPT_DIR}/..") 7 | GATE_UTILS=${WORKSPACE}/tools/g2/lib/all.sh 8 | 9 | export GATE_UTILS 10 | export WORKSPACE 11 | 12 | source "${GATE_UTILS}" 13 | 14 | vm_clean_all 15 | net_clean 16 | registry_down 17 | nginx_down 18 | -------------------------------------------------------------------------------- /charts/scheduler/templates/configmap-bin.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: kubernetes-scheduler-bin 6 | data: 7 | anchor: |+ 8 | {{ tuple "bin/_anchor.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 9 | pre_stop: |+ 10 | {{ tuple "bin/_pre_stop.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 11 | -------------------------------------------------------------------------------- /tools/dev-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eux 4 | 5 | SCRIPT_DIR=$(realpath $(dirname $0)) 6 | SOURCE_DIR=$(realpath $SCRIPT_DIR/..) 7 | 8 | echo === Building image === 9 | docker build -t quay.io/attcomdev/promenade:latest ${SOURCE_DIR} 10 | 11 | export PROMENADE_DEBUG=${PROMENADE_DEBUG:-1} 12 | 13 | exec $SCRIPT_DIR/simple-deployment.sh ${@} 14 | -------------------------------------------------------------------------------- /tools/g2/xml/network.xml: -------------------------------------------------------------------------------- 1 | 2 | promenade 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/hosts: -------------------------------------------------------------------------------- 1 | # This file is controlled by Promenade. Do not modify. 2 | # 3 | 127.0.0.1 {{ config.get_first('Genesis:hostname', 'KubernetesNode:hostname') }} 4 | 127.0.0.1 localhost 5 | {%- for entry in config.get_path('KubernetesNetwork:hosts_entries', []) %} 6 | {{ entry['ip'] }} {{ entry['names'] | join(' ') }} 7 | {%- endfor %} 8 | -------------------------------------------------------------------------------- /tools/g2/templates/ssh-config.sub: -------------------------------------------------------------------------------- 1 | IdentityFile ${SSH_CONFIG_DIR}/id_rsa 2 | LogLevel QUIET 3 | StrictHostKeyChecking no 4 | User root 5 | UserKnownHostsFile /dev/null 6 | 7 | Host n0 8 | HostName 192.168.77.10 9 | 10 | Host n1 11 | HostName 192.168.77.11 12 | 13 | Host n2 14 | HostName 192.168.77.12 15 | 16 | Host n3 17 | HostName 192.168.77.13 18 | -------------------------------------------------------------------------------- /tools/g2/lib/etcd.sh: -------------------------------------------------------------------------------- 1 | etcdctl_cmd() { 2 | CLUSTER=${1} 3 | VM=${2} 4 | 5 | shift 2 6 | 7 | kubectl_cmd "${VM}" -n kube-system exec -t "${CLUSTER}-etcd-${VM}" -- etcdctl "${@}" 8 | } 9 | 10 | etcdctl_member_list() { 11 | CLUSTER=${1} 12 | VM=${2} 13 | shift 2 14 | 15 | etcdctl_cmd "${CLUSTER}" "${VM}" member list -w json | jq -r '.members[].name' | sort 16 | } 17 | -------------------------------------------------------------------------------- /tools/gate/util/validate-test-env.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | SCRIPT_DIR=$(dirname $0) 6 | REQUIRED_VARIABLES_PATH=$(realpath $SCRIPT_DIR/../required-config-env) 7 | 8 | env | sort 9 | 10 | for varname in $(cat $REQUIRED_VARIABLES_PATH); do 11 | if [ "x${!varname}" = "x" ]; then 12 | echo Missing required variable: $varname 13 | exit 1 14 | fi 15 | done 16 | -------------------------------------------------------------------------------- /promenade/schemas/Docker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/DataSchema/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: promenade/Docker/v1 6 | labels: 7 | application: promenade 8 | data: 9 | $schema: http://json-schema.org/schema# 10 | type: object 11 | properties: 12 | config: 13 | type: object 14 | required: 15 | - config 16 | additionalProperties: false 17 | ... 18 | -------------------------------------------------------------------------------- /tools/g2/stages/gate-setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | # Docker registry (cache) setup 8 | registry_up 9 | registry_populate 10 | 11 | # NginX for serving config files in the absence of Deckhand 12 | nginx_down 13 | nginx_up 14 | 15 | # SSH setup 16 | ssh_setup_declare 17 | 18 | # Virsh setup 19 | pool_declare 20 | img_base_declare 21 | net_declare 22 | -------------------------------------------------------------------------------- /tools/registry/update_cache.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | IMAGES_FILE=$(dirname $0)/IMAGES 6 | 7 | IFS=, 8 | grep -v '^#.*' $IMAGES_FILE | while read src tag dst; do 9 | echo src=$src tag=$tag dst=$dst 10 | sudo docker pull $src:$tag 11 | 12 | full_dst=localhost:5000/$dst:$tag 13 | sudo docker tag $src:$tag $full_dst 14 | 15 | sudo docker push $full_dst 16 | done 17 | -------------------------------------------------------------------------------- /tools/g2/stages/report-disk-io.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | source "${GATE_UTILS}" 6 | 7 | log Testing disk IO 8 | 9 | fio \ 10 | --randrepeat=1 \ 11 | --ioengine=libaio \ 12 | --direct=1 \ 13 | --gtod_reduce=1 \ 14 | --name=test \ 15 | --filename=.fiotest \ 16 | --bs=4k \ 17 | --iodepth=64 \ 18 | --size=1G \ 19 | --readwrite=randrw \ 20 | --rwmixread=50 21 | -------------------------------------------------------------------------------- /examples/complete/Docker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/Docker/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: docker 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | data: 10 | config: 11 | insecure-registries: 12 | - registry:5000 13 | live-restore: true 14 | max-concurrent-downloads: 10 15 | oom-score-adjust: -999 16 | storage-driver: overlay2 17 | ... 18 | -------------------------------------------------------------------------------- /promenade/options.py: -------------------------------------------------------------------------------- 1 | from oslo_config import cfg 2 | import keystoneauth1.loading 3 | 4 | OPTIONS = [] 5 | 6 | 7 | def setup(disable_keystone=False): 8 | cfg.CONF([], project='promenade') 9 | cfg.CONF.register_opts(OPTIONS) 10 | if disable_keystone is False: 11 | cfg.CONF.register_opts( 12 | keystoneauth1.loading.get_auth_plugin_conf_options('password'), 13 | group='keystone_authtoken') 14 | -------------------------------------------------------------------------------- /requirements-direct.txt: -------------------------------------------------------------------------------- 1 | click==6.7 2 | falcon==1.2.0 3 | jinja2==2.9.6 4 | jsonpath-ng==1.4.3 5 | jsonschema==2.6.0 6 | keystoneauth1==3.2.0 7 | keystonemiddleware==4.17.0 8 | kubernetes==3.0.0 9 | oslo.context==2.19.2 10 | oslo.policy==1.22.1 11 | pastedeploy==1.5.2 12 | pbr==3.0.1 13 | pyyaml==3.12 14 | requests==2.18.4 15 | uwsgi==2.0.15 16 | git+https://github.com/att-comdev/deckhand.git@c962eeb975af5ecf9793f794d536538d210b7735#egg=deckhand 17 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Pyenv version file 2 | .python-version 3 | 4 | # Chart artifacts 5 | charts/*.tgz 6 | charts/*/charts 7 | charts/*/requirements.lock 8 | 9 | # Build & test artifacts 10 | .eggs 11 | .fiotest 12 | .git 13 | .helm-pid 14 | .tox 15 | AUTHORS 16 | ChangeLog 17 | build 18 | conformance 19 | promenade.egg-info 20 | tmp 21 | 22 | # Python artifacts 23 | __pycache__ 24 | 25 | # Non-image related files 26 | docs 27 | examples 28 | tools 29 | -------------------------------------------------------------------------------- /charts/calico/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /examples/basic/Docker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/Docker/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: docker 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | storagePolicy: cleartext 10 | data: 11 | config: 12 | insecure-registries: 13 | - registry:5000 14 | live-restore: true 15 | max-concurrent-downloads: 10 16 | oom-score-adjust: -999 17 | storage-driver: overlay2 18 | ... 19 | -------------------------------------------------------------------------------- /tools/g2/manifests/smoke.json: -------------------------------------------------------------------------------- 1 | { 2 | "configuration": [ 3 | "examples/complete", 4 | "promenade/schemas" 5 | ], 6 | "stages": [ 7 | { 8 | "name": "Build Image", 9 | "script": "build-image.sh" 10 | }, 11 | { 12 | "name": "Generate Certificates", 13 | "script": "generate-certificates.sh" 14 | }, 15 | { 16 | "name": "Build Scripts", 17 | "script": "build-scripts.sh" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Pyenv version file 2 | /.python-version 3 | 4 | # Chart artifacts 5 | /charts/*.tgz 6 | /charts/*/charts 7 | /charts/*/requirements.lock 8 | 9 | # Build & test artifacts 10 | /.cache 11 | /.eggs 12 | /.helm-pid 13 | /.tox 14 | /build 15 | /conformance 16 | /promenade.egg-info 17 | 18 | # Python artifacts 19 | __pycache__ 20 | 21 | # Sphinx artifacts 22 | /docs/build/ 23 | /docs/*/_static/ 24 | /AUTHORS 25 | /ChangeLog 26 | 27 | # Additional gate artifacts 28 | /.fiotest 29 | -------------------------------------------------------------------------------- /tools/g2/stages/build-scripts.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | cd "${TEMP_DIR}" 8 | mkdir scripts 9 | chmod 777 scripts 10 | 11 | log Building scripts 12 | docker run --rm -t \ 13 | -w /target \ 14 | -v "${TEMP_DIR}:/target" \ 15 | -e "PROMENADE_DEBUG=${PROMENADE_DEBUG}" \ 16 | "${IMAGE_PROMENADE}" \ 17 | promenade \ 18 | build-all \ 19 | --validators \ 20 | -o scripts \ 21 | config/*.yaml 22 | -------------------------------------------------------------------------------- /tools/dev/get-token.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | curl -is \ 5 | -H "Content-Type: application/json" \ 6 | -d ' 7 | { "auth": { 8 | "identity": { 9 | "methods": ["password"], 10 | "password": { 11 | "user": { 12 | "name": "admin", 13 | "domain": { "id": "default" }, 14 | "password": "password" 15 | } 16 | } 17 | } 18 | } 19 | }' \ 20 | http://keystone-api.ucp.svc.cluster.local/v3/auth/tokens | grep 'X-Subject-Token' | awk '{print $2}' 21 | -------------------------------------------------------------------------------- /charts/scheduler/templates/configmap-etc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: kubernetes-scheduler-etc 6 | data: 7 | cluster-ca.pem: {{ .Values.secrets.tls.ca | quote }} 8 | kubeconfig.yaml: |+ 9 | {{ tuple "etc/_kubeconfig.yaml.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 10 | kubernetes-scheduler.yaml: |+ 11 | {{ tuple "etc/_kubernetes-scheduler.yaml.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 12 | scheduler.pem: {{ .Values.secrets.tls.cert | quote }} 13 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/usr/local/bin/armada: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | EXTRA_ARGS= 6 | 7 | if [ "x$ARMADA_CHART_PATH_OVERRIDE" != "x" ]; then 8 | EXTRA_ARGS=" -v $ARMADA_CHART_PATH_OVERRIDE:/etc/genesis/armada/assets/charts" 9 | fi 10 | 11 | exec docker run --rm -i \ 12 | --net host \ 13 | -v /etc/genesis/armada-cli/auth:/armada/.kube \ 14 | -v /etc/genesis/armada/assets:/etc/genesis/armada/assets \ 15 | $EXTRA_ARGS \ 16 | {{ config['Genesis:images.armada'] }} \ 17 | $* 18 | -------------------------------------------------------------------------------- /promenade/templates/roles/join/usr/local/bin/helm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ "x$(pwd)" = "x/" ]; then 6 | UPDIR=/ 7 | WORKDIR=/ 8 | else 9 | UPDIR=$(pwd)/.. 10 | WORKDIR=/up/$(basename $(pwd)) 11 | fi 12 | 13 | exec docker run --rm -it \ 14 | --net host \ 15 | -v $UPDIR:/up \ 16 | -v /etc/kubernetes/admin:/etc/kubernetes/admin \ 17 | -w $WORKDIR \ 18 | -e KUBECONFIG=/etc/kubernetes/admin/kubeconfig.yaml \ 19 | {{ config['HostSystem:images.helm.helm'] }} \ 20 | $* 21 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/usr/local/bin/helm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [ "x$(pwd)" = "x/" ]; then 6 | UPDIR=/ 7 | WORKDIR=/up 8 | else 9 | UPDIR=$(pwd)/.. 10 | WORKDIR=/up/$(basename $(pwd)) 11 | fi 12 | 13 | exec docker run --rm \ 14 | --net host \ 15 | -v $UPDIR:/up \ 16 | -v /etc/kubernetes/admin:/etc/kubernetes/admin \ 17 | -w $WORKDIR \ 18 | -e KUBECONFIG=/etc/kubernetes/admin/kubeconfig.yaml \ 19 | {{ config['HostSystem:images.helm.helm'] }} \ 20 | $* 21 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/admin/kubeconfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | clusters: 4 | - cluster: 5 | server: https://127.0.0.1:6553 6 | certificate-authority: pki/cluster-ca.pem 7 | name: kubernetes 8 | contexts: 9 | - context: 10 | cluster: kubernetes 11 | user: admin 12 | name: admin@kubernetes 13 | current-context: admin@kubernetes 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: admin 18 | user: 19 | client-certificate: pki/admin.pem 20 | client-key: pki/admin-key.pem 21 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/kubeconfig: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | clusters: 4 | - cluster: 5 | server: https://127.0.0.1:6553 6 | certificate-authority: pki/cluster-ca.pem 7 | name: kubernetes 8 | contexts: 9 | - context: 10 | cluster: kubernetes 11 | user: kubelet 12 | name: kubelet@kubernetes 13 | current-context: kubelet@kubernetes 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: kubelet 18 | user: 19 | client-certificate: pki/kubelet.pem 20 | client-key: pki/kubelet-key.pem 21 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada/auth/config: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | clusters: 4 | - cluster: 5 | server: https://localhost:6444 6 | certificate-authority: pki/cluster-ca.pem 7 | name: kubernetes 8 | contexts: 9 | - context: 10 | cluster: kubernetes 11 | user: armada 12 | name: armada@kubernetes 13 | current-context: armada@kubernetes 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: armada 18 | user: 19 | client-certificate: pki/armada.pem 20 | client-key: pki/armada-key.pem 21 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/armada-cli/auth/config: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | clusters: 4 | - cluster: 5 | server: https://localhost:6443 6 | certificate-authority: pki/cluster-ca.pem 7 | name: kubernetes 8 | contexts: 9 | - context: 10 | cluster: kubernetes 11 | user: armada 12 | name: armada@kubernetes 13 | current-context: armada@kubernetes 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: armada 18 | user: 19 | client-certificate: pki/armada.pem 20 | client-key: pki/armada-key.pem 21 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/scheduler/kubeconfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | clusters: 4 | - cluster: 5 | server: https://127.0.0.1:6553 6 | certificate-authority: pki/cluster-ca.pem 7 | name: kubernetes 8 | contexts: 9 | - context: 10 | cluster: kubernetes 11 | user: scheduler 12 | name: scheduler@kubernetes 13 | current-context: scheduler@kubernetes 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: scheduler 18 | user: 19 | client-certificate: pki/scheduler.pem 20 | client-key: pki/scheduler-key.pem 21 | -------------------------------------------------------------------------------- /examples/complete/Kubelet.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/Kubelet/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: kubelet 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | data: 10 | arguments: 11 | - --cni-bin-dir=/opt/cni/bin 12 | - --cni-conf-dir=/etc/cni/net.d 13 | - --eviction-max-pod-grace-period=-1 14 | - --network-plugin=cni 15 | - --node-status-update-frequency=5s 16 | - --serialize-image-pulls=false 17 | - --v=5 18 | images: 19 | pause: gcr.io/google_containers/pause-amd64:3.0 20 | ... 21 | -------------------------------------------------------------------------------- /examples/basic/Kubelet.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/Kubelet/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: kubelet 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | storagePolicy: cleartext 10 | data: 11 | arguments: 12 | - --cni-bin-dir=/opt/cni/bin 13 | - --cni-conf-dir=/etc/cni/net.d 14 | - --eviction-max-pod-grace-period=-1 15 | - --network-plugin=cni 16 | - --node-status-update-frequency=5s 17 | - --serialize-image-pulls=false 18 | - --v=5 19 | images: 20 | pause: gcr.io/google_containers/pause-amd64:3.0 21 | ... 22 | -------------------------------------------------------------------------------- /examples/basic/PKICatalog-addition.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/PKICatalog/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: cluster-certificates-addition 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | data: 10 | certificate_authorities: 11 | kubernetes: 12 | description: CA for Kubernetes components 13 | certificates: 14 | - document_name: kubelet-n3 15 | common_name: system:node:n3 16 | hosts: 17 | - n3 18 | - 192.168.77.13 19 | groups: 20 | - system:nodes 21 | ... 22 | -------------------------------------------------------------------------------- /tools/g2/lib/docker.sh: -------------------------------------------------------------------------------- 1 | docker_ps() { 2 | VIA="${1}" 3 | ssh_cmd "${VIA}" docker ps -a 4 | } 5 | 6 | docker_info() { 7 | VIA="${1}" 8 | ssh_cmd "${VIA}" docker info 2>&1 9 | } 10 | 11 | docker_exited_containers() { 12 | VIA="${1}" 13 | ssh_cmd "${VIA}" docker ps -q --filter "status=exited" 14 | } 15 | 16 | docker_inspect() { 17 | VIA="${1}" 18 | CONTAINER_ID="${2}" 19 | ssh_cmd "${VIA}" docker inspect "${CONTAINER_ID}" 20 | } 21 | 22 | docker_logs() { 23 | VIA="${1}" 24 | CONTAINER_ID="${2}" 25 | ssh_cmd "${VIA}" docker logs "${CONTAINER_ID}" 26 | } 27 | -------------------------------------------------------------------------------- /tools/dev/server.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eux 4 | 5 | SCRIPT_DIR=$(realpath $(dirname $0)) 6 | SOURCE_DIR=$(realpath $SCRIPT_DIR/../..) 7 | 8 | echo === Building image === 9 | docker build -t quay.io/attcomdev/promenade:latest ${SOURCE_DIR} 10 | 11 | export PROMENADE_DEBUG=${PROMENADE_DEBUG:-1} 12 | 13 | exec docker run \ 14 | --rm -it \ 15 | --publish 9000:9000 \ 16 | --env PROMENADE_DEBUG=${PROMENADE_DEBUG} \ 17 | --volume "${SOURCE_DIR}/etc/promenade/noauth-api-paste.ini":/etc/promenade/api-paste.ini:ro \ 18 | quay.io/attcomdev/promenade:latest \ 19 | server 20 | -------------------------------------------------------------------------------- /tools/g2/lib/all.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -o nounset 3 | 4 | LIB_DIR=$(realpath "$(dirname "${BASH_SOURCE}")") 5 | 6 | source "$LIB_DIR"/config.sh 7 | source "$LIB_DIR"/const.sh 8 | source "$LIB_DIR"/docker.sh 9 | source "$LIB_DIR"/etcd.sh 10 | source "$LIB_DIR"/kube.sh 11 | source "$LIB_DIR"/log.sh 12 | source "$LIB_DIR"/nginx.sh 13 | source "$LIB_DIR"/openstack.sh 14 | source "$LIB_DIR"/promenade.sh 15 | source "$LIB_DIR"/registry.sh 16 | source "$LIB_DIR"/ssh.sh 17 | source "$LIB_DIR"/validate.sh 18 | source "$LIB_DIR"/virsh.sh 19 | 20 | if [[ -v GATE_DEBUG && ${GATE_DEBUG} = "1" ]]; then 21 | set -x 22 | fi 23 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/genesis/controller-manager/kubeconfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | clusters: 4 | - cluster: 5 | server: https://127.0.0.1:6553 6 | certificate-authority: pki/cluster-ca.pem 7 | name: kubernetes 8 | contexts: 9 | - context: 10 | cluster: kubernetes 11 | user: controller-manager 12 | name: controller-manager@kubernetes 13 | current-context: controller-manager@kubernetes 14 | kind: Config 15 | preferences: {} 16 | users: 17 | - name: controller-manager 18 | user: 19 | client-certificate: pki/controller-manager.pem 20 | client-key: pki/controller-manager-key.pem 21 | -------------------------------------------------------------------------------- /tools/g2/stages/genesis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | rsync_cmd "${TEMP_DIR}/scripts"/*genesis* "${GENESIS_NAME}:/root/promenade/" 8 | 9 | set -o pipefail 10 | ssh_cmd "${GENESIS_NAME}" /root/promenade/genesis.sh 2>&1 | tee -a "${LOG_FILE}" 11 | ssh_cmd "${GENESIS_NAME}" /root/promenade/validate-genesis.sh 2>&1 | tee -a "${LOG_FILE}" 12 | set +o pipefail 13 | 14 | if ! ssh_cmd n0 docker images | tail -n +2 | grep -v registry:5000 ; then 15 | log_warn "Using some non-cached docker images. This will slow testing." 16 | ssh_cmd n0 docker images | tail -n +2 | grep -v registry:5000 | tee -a "${LOG_FILE}" 17 | fi 18 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/kubernetes/manifests/kubernetes-etcd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: kubernetes-etcd 6 | namespace: kube-system 7 | labels: 8 | # NOTE: This label needs coordination with the etcd deployed via chart. 9 | kubernetes-etcd-service: enabled 10 | spec: 11 | hostNetwork: true 12 | {%- with etcd_name = config['Genesis:hostname'], client_port = 2379, peer_port = 2380, volume_name = 'kubernetes' %} 13 | containers: 14 | {% include "genesis-etcd/server-container.yaml" with context %} 15 | volumes: 16 | {% include "genesis-etcd/common-volumes.yaml" with context %} 17 | {%- endwith %} 18 | ... 19 | -------------------------------------------------------------------------------- /charts/coredns/templates/service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ .Values.service.name }} 6 | labels: 7 | kubernetes.io/cluster-service: "true" 8 | kubernetes.io/name: "CoreDNS" 9 | annotations: 10 | {{- if .Values.monitoring.prometheus.enabled }} 11 | {{ tuple .Values.monitoring.prometheus.coredns | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 -}} 12 | {{- end }} 13 | spec: 14 | selector: 15 | {{ .Values.service.name }}: enabled 16 | clusterIP: {{ .Values.service.ip }} 17 | ports: 18 | - name: dns 19 | port: 53 20 | protocol: UDP 21 | - name: dns-tcp 22 | port: 53 23 | protocol: TCP 24 | -------------------------------------------------------------------------------- /promenade/schemas/ArmadaPlaceholders.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/DataSchema/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: armada/Manifest/v1 6 | labels: 7 | application: armada 8 | data: 9 | $schema: http://json-schema.org/schema# 10 | --- 11 | schema: deckhand/DataSchema/v1 12 | metadata: 13 | schema: metadata/Control/v1 14 | name: armada/ChartGroup/v1 15 | labels: 16 | application: armada 17 | data: 18 | $schema: http://json-schema.org/schema# 19 | --- 20 | schema: deckhand/DataSchema/v1 21 | metadata: 22 | schema: metadata/Control/v1 23 | name: armada/Chart/v1 24 | labels: 25 | application: armada 26 | data: 27 | $schema: http://json-schema.org/schema# 28 | ... 29 | -------------------------------------------------------------------------------- /tools/gate/default-config-env: -------------------------------------------------------------------------------- 1 | IMAGE_ARMADA=quay.io/attcomdev/armada:latest 2 | IMAGE_CALICO_CNI=quay.io/calico/cni:v1.11.2 3 | IMAGE_CALICO_CTL=quay.io/calico/ctl:v1.6.3 4 | IMAGE_CALICO_KUBE_CONTROLLERS=quay.io/calico/kube-controllers:v1.0.2 5 | IMAGE_CALICO_NODE=quay.io/calico/node:v2.6.5 6 | IMAGE_COREDNS=coredns/coredns:1.1.2 7 | IMAGE_DEP_CHECK=quay.io/stackanetes/kubernetes-entrypoint:v0.2.1 8 | IMAGE_ETCD=quay.io/coreos/etcd:v3.2.14 9 | IMAGE_HAPROXY=haproxy:1.8.3 10 | IMAGE_HELM=lachlanevenson/k8s-helm:v2.7.2 11 | IMAGE_HYPERKUBE=gcr.io/google_containers/hyperkube-amd64:v1.10.2 12 | IMAGE_TILLER=gcr.io/kubernetes-helm/tiller:v2.7.2 13 | KUBELET_URL=https://dl.k8s.io/v1.10.2/kubernetes-node-linux-amd64.tar.gz 14 | -------------------------------------------------------------------------------- /tools/lint_gate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(realpath "$(dirname "${0}")") 6 | WORKSPACE=$(realpath "${SCRIPT_DIR}/..") 7 | 8 | for manifest in $(find "${WORKSPACE}/tools/g2/manifests" -type f | sort); do 9 | echo Checking "${manifest}" 10 | python -m jsonschema "${WORKSPACE}/tools/g2/manifest-schema.json" -i "${manifest}" 11 | done 12 | 13 | if [[ -x $(which shellcheck) ]]; then 14 | echo Checking shell scripts.. 15 | shellcheck -s bash -e SC2029 "${WORKSPACE}"/tools/cleanup.sh "${WORKSPACE}"/tools/*gate*.sh "${WORKSPACE}"/tools/g2/stages/* "${WORKSPACE}"/tools/g2/lib/* 16 | else 17 | echo No shellcheck executable found. Please, install it. 18 | exit 1 19 | fi 20 | -------------------------------------------------------------------------------- /promenade/schemas/Kubelet.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/DataSchema/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: promenade/Kubelet/v1 6 | labels: 7 | application: promenade 8 | data: 9 | $schema: http://json-schema.org/schema# 10 | type: object 11 | definitions: 12 | image: 13 | type: string 14 | # XXX add regex 15 | 16 | properties: 17 | images: 18 | type: object 19 | properties: 20 | pause: 21 | $ref: '#/definitions/image' 22 | required: 23 | - pause 24 | additionalProperties: false 25 | arguments: 26 | type: array 27 | items: 28 | type: string 29 | required: 30 | - images 31 | additionalProperties: false 32 | ... 33 | -------------------------------------------------------------------------------- /tools/registry/IMAGES: -------------------------------------------------------------------------------- 1 | # source_name, tag, cache_name 2 | coredns/coredns,0.9.9,coredns 3 | gcr.io/google_containers/hyperkube-amd64,v1.10.2,hyperkube 4 | gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64,1.14.4,k8s-dns-dnsmasq-nanny-amd64 5 | gcr.io/google_containers/k8s-dns-kube-dns-amd64,1.14.4,k8s-dns-kube-dns-amd64 6 | gcr.io/google_containers/k8s-dns-sidecar-amd64,1.14.4,k8s-dns-sidecar-amd64 7 | gcr.io/kubernetes-helm/tiller,v2.7.2,tiller 8 | lachlanevenson/k8s-helm,v2.7.2,helm 9 | quay.io/attcomdev/armada,latest,armada 10 | quay.io/calico/cni,v1.11.0,calico-cni 11 | quay.io/calico/ctl,v1.6.1,calico-ctl 12 | quay.io/calico/kube-controllers,v1.0.0,calico-kube-controllers 13 | quay.io/calico/node,v2.6.1,calico-node 14 | quay.io/coreos/etcd,v3.0.17,etcd 15 | -------------------------------------------------------------------------------- /tools/g2/stages/reprovision-genesis.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | EXPECTED_MEMBERS="${*}" 8 | 9 | promenade_teardown_node "${GENESIS_NAME}" n1 10 | 11 | vm_clean "${GENESIS_NAME}" 12 | vm_create "${GENESIS_NAME}" 13 | 14 | rsync_cmd "${TEMP_DIR}/scripts/"*"${GENESIS_NAME}"* "${GENESIS_NAME}:/root/promenade/" 15 | 16 | ssh_cmd "${GENESIS_NAME}" "/root/promenade/join-${GENESIS_NAME}.sh" 17 | ssh_cmd "${GENESIS_NAME}" "/root/promenade/validate-${GENESIS_NAME}.sh" 18 | 19 | validate_cluster n1 20 | 21 | validate_etcd_membership kubernetes n1 "${EXPECTED_MEMBERS}" 22 | validate_etcd_membership calico n1 "${EXPECTED_MEMBERS}" 23 | 24 | # NOTE(mark-burnett): Ensure disk cache is flushed after join. 25 | ssh_cmd "${GENESIS_NAME}" sync 26 | -------------------------------------------------------------------------------- /charts/proxy/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | description: A chart for the Kubernetes proxy. 17 | name: proxy 18 | version: 0.1.0 -------------------------------------------------------------------------------- /docs/source/configuration/docker.rst: -------------------------------------------------------------------------------- 1 | Docker 2 | ====== 3 | 4 | Configuration for the docker daemon. This document contains a single `config` 5 | key that directly translates into the contents of the `daemon.json` file 6 | described in `Docker's configuration`_. 7 | 8 | 9 | Sample Document 10 | --------------- 11 | 12 | Here is a sample document: 13 | 14 | .. code-block:: yaml 15 | 16 | schema: promenade/Docker/v1 17 | metadata: 18 | schema: metadata/Document/v1 19 | name: docker 20 | layeringDefinition: 21 | abstract: false 22 | layer: site 23 | data: 24 | config: 25 | live-restore: true 26 | storage-driver: overlay2 27 | 28 | 29 | .. _Docker's configuration: https://docs.docker.com/engine/reference/commandline/dockerd/ 30 | -------------------------------------------------------------------------------- /charts/apiserver/templates/bin/_pre_stop.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -x 17 | 18 | touch /tmp/stop 19 | sleep {{ .Values.anchor.period }} 20 | -------------------------------------------------------------------------------- /charts/haproxy/templates/bin/_pre_stop.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | {{/* 3 | Copyright 2018 AT&T Intellectual Property. All other rights reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | */}} 17 | 18 | set -x 19 | 20 | touch /tmp/stop 21 | sleep {{ .Values.conf.anchor.period }} 22 | -------------------------------------------------------------------------------- /docs/source/configuration/index.rst: -------------------------------------------------------------------------------- 1 | Configuration 2 | ============= 3 | 4 | Promenade is configured using a set of Deckhand_ compatible configuration 5 | documents and a bootstrapping Armada_ manifest that is responsible for 6 | deploying core components into the cluster. 7 | 8 | Details about Promenade-specific documents can be found here: 9 | 10 | .. toctree:: 11 | :maxdepth: 2 12 | :caption: Documents 13 | 14 | docker 15 | genesis 16 | host-system 17 | kubelet 18 | kubernetes-network 19 | kubernetes-node 20 | pki-catalog 21 | 22 | 23 | The provided Armada_ manifest and will be applied on the genesis node as soon 24 | as it is healthy. 25 | 26 | 27 | .. _Armada: https://github.com/att-comdev/armada 28 | .. _Deckhand: https://github.com/att-comdev/deckhand 29 | -------------------------------------------------------------------------------- /charts/apiserver/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | description: A chart for Kubernetes API server 17 | name: apiserver 18 | version: 0.1.0 19 | -------------------------------------------------------------------------------- /charts/calico/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # The following contains k8s Secrets for use with a TLS enabled etcd cluster. 3 | # For information on populating Secrets, see http://kubernetes.io/docs/user-guide/secrets/ 4 | apiVersion: v1 5 | kind: Secret 6 | type: Opaque 7 | metadata: 8 | name: calico-etcd-secrets 9 | namespace: kube-system 10 | data: 11 | # Populate the following files with etcd TLS configuration if desired, but leave blank if 12 | # not using TLS for etcd. 13 | # This self-hosted install expects three files with the following names. The values 14 | # should be base64 encoded strings of the entire contents of each file. 15 | etcd-key: {{ .Values.etcd.tls.key | b64enc }} 16 | etcd-cert: {{ .Values.etcd.tls.cert | b64enc }} 17 | etcd-ca: {{ .Values.etcd.tls.ca | b64enc }} 18 | -------------------------------------------------------------------------------- /charts/controller_manager/templates/bin/_pre_stop.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -x 17 | 18 | touch /tmp/stop 19 | sleep {{ .Values.anchor.period }} 20 | -------------------------------------------------------------------------------- /charts/etcd/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | description: A chart for a DaemonSet-based etcd deployment. 17 | name: etcd 18 | version: 0.1.0 19 | -------------------------------------------------------------------------------- /charts/calico/requirements.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | dependencies: 16 | - name: helm-toolkit 17 | repository: http://localhost:8879/charts 18 | version: 0.1.0 19 | -------------------------------------------------------------------------------- /charts/etcd/requirements.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | dependencies: 16 | - name: helm-toolkit 17 | repository: http://localhost:8879/charts 18 | version: 0.1.0 19 | -------------------------------------------------------------------------------- /charts/apiserver/requirements.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | dependencies: 16 | - name: helm-toolkit 17 | repository: http://localhost:8879/charts 18 | version: 0.1.0 19 | -------------------------------------------------------------------------------- /charts/scheduler/templates/bin/_pre_stop.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | {{/* 3 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | */}} 17 | 18 | set -x 19 | 20 | touch /tmp/stop 21 | sleep {{ .Values.anchor.period }} 22 | -------------------------------------------------------------------------------- /charts/controller_manager/Chart.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | description: A chart for Kubernetes controller-manager 17 | name: controller_manager 18 | version: 0.1.0 19 | -------------------------------------------------------------------------------- /charts/controller_manager/requirements.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | dependencies: 16 | - name: helm-toolkit 17 | repository: http://localhost:8879/charts 18 | version: 0.1.0 19 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -ex 3 | 4 | PORT=${PORT:-9000} 5 | UWSGI_TIMEOUT=${UWSGI_TIMEOUT:-300} 6 | 7 | PROMENADE_THREADS=${PROMENADE_THREADS:-1} 8 | PROMENADE_WORKERS=${PROMENADE_WORKERS:-4} 9 | 10 | if [ "$1" = 'server' ]; then 11 | exec uwsgi \ 12 | --http ":${PORT}" \ 13 | --http-timeout "${UWSGI_TIMEOUT}" \ 14 | --harakiri "${UWSGI_TIMEOUT}" \ 15 | --socket-timeout "${UWSGI_TIMEOUT}" \ 16 | --harakiri-verbose \ 17 | -b 32768 \ 18 | --lazy-apps \ 19 | --master \ 20 | --thunder-lock \ 21 | --die-on-term \ 22 | -z "${UWSGI_TIMEOUT}" \ 23 | --paste config:/etc/promenade/api-paste.ini \ 24 | --enable-threads \ 25 | --threads "${PROMENADE_THREADS}" \ 26 | --workers "${PROMENADE_WORKERS}" 27 | fi 28 | 29 | exec ${@} 30 | -------------------------------------------------------------------------------- /charts/etcd/templates/bin/_readiness.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -ex 17 | 18 | export ETCDCTL_ENDPOINTS=https://$POD_IP:{{ .Values.network.service_client.target_port }} 19 | 20 | etcdctl endpoint health 21 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/kubernetes/manifests/kubernetes-scheduler.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: kubernetes-scheduler 6 | namespace: kube-system 7 | labels: 8 | tier: control-plane 9 | component: kube-scheduler 10 | annotations: 11 | scheduler.alpha.kubernetes.io/critical-pod: '' 12 | spec: 13 | hostNetwork: true 14 | containers: 15 | - name: kube-scheduler 16 | image: {{ config['Genesis:images.kubernetes.scheduler'] }} 17 | command: 18 | - ./hyperkube 19 | - scheduler 20 | - --leader-elect=true 21 | - --kubeconfig=/etc/kubernetes/scheduler/kubeconfig.yaml 22 | - --v=5 23 | volumeMounts: 24 | - name: config 25 | mountPath: /etc/kubernetes/scheduler 26 | volumes: 27 | - name: config 28 | hostPath: 29 | path: /etc/genesis/scheduler 30 | -------------------------------------------------------------------------------- /tools/g2/manifests/genesis.json: -------------------------------------------------------------------------------- 1 | { 2 | "configuration": [ 3 | "examples/complete", 4 | "promenade/schemas" 5 | ], 6 | "stages": [ 7 | { 8 | "name": "Gate Setup", 9 | "script": "gate-setup.sh" 10 | }, 11 | { 12 | "name": "Build Image", 13 | "script": "build-image.sh" 14 | }, 15 | { 16 | "name": "Generate Certificates", 17 | "script": "generate-certificates.sh" 18 | }, 19 | { 20 | "name": "Build Scripts", 21 | "script": "build-scripts.sh" 22 | }, 23 | { 24 | "name": "Create VMs", 25 | "script": "create-vms.sh" 26 | }, 27 | { 28 | "name": "Genesis", 29 | "script": "genesis.sh", 30 | "on_error": "collect_genesis_info.sh" 31 | } 32 | ], 33 | "vm": { 34 | "memory": 12288, 35 | "names": [ 36 | "n0" 37 | ], 38 | "vcpus": 4 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /charts/promenade/templates/job-ks-user.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.job_ks_user }} 18 | {{- $ksUserJob := dict "envAll" . "serviceName" "promenade" -}} 19 | {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /tools/g2/lib/validate.sh: -------------------------------------------------------------------------------- 1 | validate_cluster() { 2 | NAME=${1} 3 | 4 | log Validating cluster via VM "${NAME}" 5 | rsync_cmd "${TEMP_DIR}/scripts/validate-cluster.sh" "${NAME}:/root/promenade/" 6 | ssh_cmd "${NAME}" /root/promenade/validate-cluster.sh 7 | } 8 | 9 | validate_etcd_membership() { 10 | CLUSTER=${1} 11 | VM=${2} 12 | shift 2 13 | EXPECTED_MEMBERS="${*}" 14 | 15 | # NOTE(mark-burnett): Wait a moment for disks in test environment to settle. 16 | sleep 10 17 | log Validating "${CLUSTER}" etcd membership via "${VM}" 18 | FOUND_MEMBERS=$(etcdctl_member_list "${CLUSTER}" "${VM}" | tr '\n' ' ' | sed 's/ $//') 19 | 20 | if [[ "x${EXPECTED_MEMBERS}" != "x${FOUND_MEMBERS}" ]]; then 21 | log Etcd membership check failed for cluster "${CLUSTER}" 22 | log "Found \"${FOUND_MEMBERS}\", expected \"${EXPECTED_MEMBERS}\"" 23 | exit 1 24 | fi 25 | } 26 | -------------------------------------------------------------------------------- /tools/g2/stages/move-master.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | log Adding labels to node n0 8 | kubectl_cmd n1 label node n0 \ 9 | calico-etcd=enabled \ 10 | kubernetes-apiserver=enabled \ 11 | kubernetes-controller-manager=enabled \ 12 | kubernetes-etcd=enabled \ 13 | kubernetes-scheduler=enabled 14 | 15 | # XXX Need to wait 16 | sleep 60 17 | 18 | validate_etcd_membership kubernetes n1 n0 n1 n2 n3 19 | validate_etcd_membership calico n1 n0 n1 n2 n3 20 | 21 | log Removing labels from node n2 22 | kubectl_cmd n1 label node n2 \ 23 | calico-etcd- \ 24 | kubernetes-apiserver- \ 25 | kubernetes-controller-manager- \ 26 | kubernetes-etcd- \ 27 | kubernetes-scheduler- 28 | 29 | # XXX Need to wait 30 | sleep 60 31 | 32 | validate_cluster n1 33 | 34 | validate_etcd_membership kubernetes n1 n0 n1 n3 35 | validate_etcd_membership calico n1 n0 n1 n3 36 | -------------------------------------------------------------------------------- /charts/calico/values.yaml: -------------------------------------------------------------------------------- 1 | calico: 2 | ip_autodetection_method: null 3 | pod_ip_cidr: 10.97.0.0/16 4 | mtu: 1500 5 | ipip: always 6 | ctl: 7 | install_on_host: false 8 | 9 | etcd: 10 | service: 11 | ip: 10.96.232.136 12 | port: 6666 13 | tls: 14 | ca: |- 15 | invalid ca 16 | cert: |- 17 | invalid cert 18 | key: |- 19 | invalid key 20 | 21 | images: 22 | cni: quay.io/calico/cni:v1.11.2 23 | ctl: quay.io/calico/ctl:v1.6.3 24 | node: quay.io/calico/node:v2.6.5 25 | policy_controller: quay.io/calico/kube-controllers:v1.0.2 26 | 27 | pod: 28 | resources: 29 | enabled: false 30 | calico_node: 31 | requests: 32 | memory: "128Mi" 33 | cpu: "100m" 34 | limits: 35 | memory: "1024Mi" 36 | cpu: "2000m" 37 | calico_policy_controller: 38 | requests: 39 | memory: "128Mi" 40 | cpu: "100m" 41 | limits: 42 | memory: "1024Mi" 43 | cpu: "2000m" 44 | -------------------------------------------------------------------------------- /charts/promenade/templates/job-ks-service.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.job_ks_service -}} 18 | {{- $ksServiceJob := dict "envAll" . "serviceName" "promenade" "serviceTypes" ( tuple "kubernetesprovisioner" ) -}} 19 | {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /charts/promenade/templates/job-ks-endpoints.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.job_ks_endpoints }} 18 | {{- $ksServiceJob := dict "envAll" . "serviceName" "promenade" "serviceTypes" ( tuple "kubernetesprovisioner" ) -}} 19 | {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /tools/g2/stages/load-site-config.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | source "${GATE_UTILS}" 6 | 7 | while getopts "v:" opt; do 8 | case "${opt}" in 9 | v) 10 | VIA=${OPTARG} 11 | ;; 12 | *) 13 | echo "Unknown option" 14 | exit 1 15 | ;; 16 | esac 17 | done 18 | shift $((OPTIND-1)) 19 | 20 | if [ $# -gt 0 ]; then 21 | echo "Unknown arguments specified: ${*}" 22 | exit 1 23 | fi 24 | 25 | TOKEN=$(os_ks_get_token "${VIA}") 26 | 27 | DECKHAND_URL=http://deckhand-int.ucp.svc.cluster.local:9000/api/v1.0/buckets/prom/documents 28 | 29 | rsync_cmd "${TEMP_DIR}/nginx/promenade.yaml" "${VIA}:/root/promenade/promenade.yaml" 30 | ssh_cmd "${VIA}" curl -v \ 31 | --fail \ 32 | --max-time 300 \ 33 | --retry 10 \ 34 | --retry-delay 15 \ 35 | -H "X-Auth-Token: ${TOKEN}" \ 36 | -H "Content-Type: application/x-yaml" \ 37 | -T "/root/promenade/promenade.yaml" \ 38 | "${DECKHAND_URL}" 39 | -------------------------------------------------------------------------------- /charts/haproxy/templates/configmap-bin.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2018 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | --- 17 | apiVersion: v1 18 | kind: ConfigMap 19 | metadata: 20 | name: haproxy-bin 21 | data: 22 | anchor.sh: | 23 | {{ tuple "bin/_anchor.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 24 | pre_stop.sh: | 25 | {{ tuple "bin/_pre_stop.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 26 | -------------------------------------------------------------------------------- /charts/coredns/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: coredns 6 | namespace: {{ .Release.Namespace }} 7 | --- 8 | kind: ClusterRoleBinding 9 | apiVersion: rbac.authorization.k8s.io/v1 10 | metadata: 11 | name: coredns 12 | annotations: 13 | rbac.authorization.kubernetes.io/autoupdate: "true" 14 | subjects: 15 | - kind: User 16 | name: coredns 17 | apiGroup: rbac.authorization.k8s.io 18 | - kind: ServiceAccount 19 | name: coredns 20 | namespace: {{ .Release.Namespace }} 21 | roleRef: 22 | kind: ClusterRole 23 | name: system:coredns 24 | apiGroup: rbac.authorization.k8s.io 25 | --- 26 | apiVersion: rbac.authorization.k8s.io/v1beta1 27 | kind: ClusterRole 28 | metadata: 29 | labels: 30 | kubernetes.io/bootstrapping: rbac-defaults 31 | name: system:coredns 32 | rules: 33 | - apiGroups: 34 | - "" 35 | resources: 36 | - endpoints 37 | - services 38 | - pods 39 | - namespaces 40 | verbs: 41 | - get 42 | - list 43 | - watch 44 | -------------------------------------------------------------------------------- /etc/promenade/api-paste.ini: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | #PasteDeploy Configuration File 16 | #Used to configure uWSGI middleware pipeline 17 | 18 | [filter:authtoken] 19 | paste.filter_factory = keystonemiddleware.auth_token:filter_factory 20 | 21 | [app:promenade-api] 22 | paste.app_factory = promenade.promenade:paste_start_promenade 23 | 24 | [pipeline:main] 25 | pipeline = promenade-api 26 | -------------------------------------------------------------------------------- /tools/g2/stages/build-image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | CONFIG_PROXY=${HTTP_PROXY:-} 8 | 9 | log Building docker image "${IMAGE_PROMENADE}" 10 | 11 | if [[ -z "$CONFIG_PROXY" ]] 12 | then 13 | docker build -q \ 14 | --network host \ 15 | -t "${IMAGE_PROMENADE}" \ 16 | "${WORKSPACE}" 17 | else 18 | docker build -q \ 19 | --network host \ 20 | -t "${IMAGE_PROMENADE}" \ 21 | --build-arg "HTTP_PROXY=${HTTP_PROXY:-}" \ 22 | --build-arg "HTTPS_PROXY=${HTTPS_PROXY:-}" \ 23 | --build-arg "NO_PROXY=${NO_PROXY:-}" \ 24 | --build-arg "http_proxy=${http_proxy:-}" \ 25 | --build-arg "https_proxy=${https_proxy:-}" \ 26 | --build-arg "no_proxy=${no_proxy:-}" \ 27 | "${WORKSPACE}" 28 | fi 29 | 30 | log Loading Promenade image "${IMAGE_PROMENADE}" into local registry 31 | docker tag "${IMAGE_PROMENADE}" "localhost:5000/${IMAGE_PROMENADE}" &>> "${LOG_FILE}" 32 | docker push "localhost:5000/${IMAGE_PROMENADE}" &>> "${LOG_FILE}" 33 | -------------------------------------------------------------------------------- /charts/etcd/templates/configmap-etc.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_etc }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: ConfigMap 22 | metadata: 23 | name: {{ $envAll.Values.service.name }}-etc 24 | data: 25 | {{ .Values.service.name }}.yaml: |+ 26 | {{ tuple "etc/_kubernetes-etcd.yaml.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 27 | {{- end }} 28 | -------------------------------------------------------------------------------- /charts/apiserver/templates/configmap-etc.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_etc }} 18 | {{- $envAll := . }} 19 | 20 | --- 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: {{ .Values.service.name }}-etc 25 | data: 26 | kubernetes-apiserver.yaml: |+ 27 | {{ tuple "etc/_kubernetes-apiserver.yaml.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /charts/apiserver/templates/secret-apiserver.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.secret }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: Secret 22 | metadata: 23 | name: {{ .Values.service.name }}-keys 24 | type: Opaque 25 | data: 26 | apiserver-key.pem: {{ .Values.secrets.tls.key | b64enc }} 27 | etcd-client-key.pem: {{ .Values.secrets.etcd.tls.key | b64enc }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /promenade/templates/scripts/join.sh: -------------------------------------------------------------------------------- 1 | {% include "header.sh" with context %} 2 | 3 | {%- if not config.leave_kubectl %} 4 | function delete_kubectl() { 5 | set +x 6 | log 7 | log === Removing kubectl and credentials === 8 | set -x 9 | rm -rf /etc/kubernetes/admin 10 | rm -f /usr/local/bin/kubectl 11 | } 12 | 13 | trap delete_kubectl EXIT 14 | {%- endif %} 15 | 16 | {% include "basic-host-validation.sh" with context %} 17 | 18 | {% include "up.sh" with context %} 19 | 20 | set +x 21 | log 22 | log === Waiting for Node to be Ready === 23 | set -x 24 | wait_for_node_ready {{ config['KubernetesNode:hostname'] }} 3600 25 | 26 | {%- if config['KubernetesNode:labels.dynamic'] is defined %} 27 | set +x 28 | log 29 | log === Registering dynamic labels for node === 30 | set -x 31 | register_labels {{ config['KubernetesNode:hostname'] }} 3600 {{ config['KubernetesNode:labels.dynamic'] | join(' ') }} 32 | {%- endif %} 33 | 34 | sleep 60 35 | 36 | {% include "cleanup.sh" with context %} 37 | 38 | set +x 39 | log 40 | log === Finished join process === 41 | -------------------------------------------------------------------------------- /charts/controller_manager/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.secret }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: Secret 22 | metadata: 23 | name: {{ .Values.service.name }} 24 | type: Opaque 25 | data: 26 | controller-manager-key.pem: {{ .Values.secrets.tls.key | b64enc }} 27 | service-account.priv: {{ .Values.secrets.service_account.private_key | b64enc }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2017 The Promenade Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | from setuptools import setup 18 | 19 | setup( 20 | setup_requires=['setuptools>=17.1'], 21 | name='promenade', 22 | version='0.8.0', 23 | packages=['promenade'], 24 | package_data={ 25 | 'schemas': 'schemas/*', 26 | 'templates': 'templates/*', 27 | }, 28 | entry_points={ 29 | 'console_scripts': 'promenade=promenade.cli:promenade', 30 | }, 31 | ) 32 | -------------------------------------------------------------------------------- /examples/complete/KubernetesNetwork.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/KubernetesNetwork/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: kubernetes-network 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | data: 10 | dns: 11 | cluster_domain: cluster.local 12 | service_ip: 10.96.0.10 13 | bootstrap_validation_checks: 14 | - calico-etcd.kube-system.svc.cluster.local 15 | - google.com 16 | - kubernetes-etcd.kube-system.svc.cluster.local 17 | - kubernetes.default.svc.cluster.local 18 | upstream_servers: 19 | - 8.8.8.8 20 | - 8.8.4.4 21 | 22 | kubernetes: 23 | apiserver_port: 6443 24 | haproxy_port: 6553 25 | pod_cidr: 10.97.0.0/16 26 | service_cidr: 10.96.0.0/16 27 | service_ip: 10.96.0.1 28 | 29 | etcd: 30 | container_port: 2379 31 | haproxy_port: 2378 32 | 33 | hosts_entries: 34 | - ip: 192.168.77.1 35 | names: 36 | - registry 37 | 38 | # proxy: 39 | # url: http://proxy.example.com:8080 40 | # additional_no_proxy: 41 | # - 10.0.1.1 42 | ... 43 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/kubernetes/manifests/haproxy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: haproxy 6 | namespace: kube-system 7 | annotations: 8 | scheduler.alpha.kubernetes.io/critical-pod: '' 9 | spec: 10 | hostNetwork: true 11 | containers: 12 | - name: haproxy 13 | image: {{ config['HostSystem:images.haproxy'] }} 14 | imagePullPolicy: IfNotPresent 15 | hostNetwork: true 16 | env: 17 | - name: HAPROXY_CONF 18 | value: /usr/local/etc/haproxy/haproxy.cfg 19 | command: 20 | - /bin/sh 21 | - -c 22 | - | 23 | set -eux 24 | 25 | while [ ! -s "$HAPROXY_CONF" ]; do 26 | echo Waiting for "HAPROXY_CONF" 27 | sleep 1 28 | done 29 | 30 | haproxy -f "$HAPROXY_CONF" 31 | 32 | volumeMounts: 33 | - name: etc 34 | mountPath: /usr/local/etc/haproxy 35 | readOnly: true 36 | volumes: 37 | - name: etc 38 | hostPath: 39 | path: /etc/promenade/haproxy 40 | -------------------------------------------------------------------------------- /etc/promenade/noauth-api-paste.ini: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | #PasteDeploy Configuration File 16 | #Used to configure uWSGI middleware pipeline 17 | 18 | [filter:noauth] 19 | forged_roles = admin 20 | paste.filter_factory = promenade.control.middleware:noauth_filter_factory 21 | 22 | [app:promenade-api] 23 | disable = keystone 24 | paste.app_factory = promenade.promenade:paste_start_promenade 25 | 26 | [pipeline:main] 27 | pipeline = noauth promenade-api 28 | -------------------------------------------------------------------------------- /promenade/control/health_api.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import falcon 15 | 16 | from promenade.control import base 17 | 18 | 19 | class HealthResource(base.BaseResource): 20 | """ 21 | Return empty response/body to show 22 | that promenade is healthy 23 | """ 24 | 25 | def on_get(self, req, resp): 26 | """ 27 | It really does nothing right now. It may do more later 28 | """ 29 | resp.status = falcon.HTTP_204 30 | -------------------------------------------------------------------------------- /docs/source/configuration/kubelet.rst: -------------------------------------------------------------------------------- 1 | Kubelet 2 | ======= 3 | 4 | Configuration for the Kubernetes worker daemon (the Kubelet). This document 5 | contains two keys: ``arguments`` and ``images``. The ``arguments`` are 6 | appended directly to the ``kubelet`` command line, along with arguments that 7 | are controlled by Promenade more directly. 8 | 9 | The only image that is configurable is for the ``pause`` container. 10 | 11 | 12 | Sample Document 13 | --------------- 14 | 15 | Here is a sample document: 16 | 17 | .. code-block:: yaml 18 | 19 | schema: promenade/Kubelet/v1 20 | metadata: 21 | schema: metadata/Document/v1 22 | name: kubelet 23 | layeringDefinition: 24 | abstract: false 25 | layer: site 26 | data: 27 | arguments: 28 | - --cni-bin-dir=/opt/cni/bin 29 | - --cni-conf-dir=/etc/cni/net.d 30 | - --eviction-max-pod-grace-period=-1 31 | - --network-plugin=cni 32 | - --node-status-update-frequency=5s 33 | - --v=5 34 | images: 35 | pause: gcr.io/google_containers/pause-amd64:3.0 36 | -------------------------------------------------------------------------------- /tools/g2/lib/openstack.sh: -------------------------------------------------------------------------------- 1 | os_ks_get_token() { 2 | VIA=${1} 3 | KEYSTONE_URL=${2:-http://keystone-api.ucp.svc.cluster.local} 4 | DOMAIN=${3:-default} 5 | USERNAME=${4:-promenade} 6 | PASSWORD=${5:-password} 7 | 8 | REQUEST_BODY_PATH="ks-token-request.json" 9 | cat < "${TEMP_DIR}/${REQUEST_BODY_PATH}" 10 | { 11 | "auth": { 12 | "identity": { 13 | "methods": ["password"], 14 | "password": { 15 | "user": { 16 | "name": "${USERNAME}", 17 | "domain": { "id": "${DOMAIN}" }, 18 | "password": "${PASSWORD}" 19 | } 20 | } 21 | } 22 | } 23 | } 24 | EOBODY 25 | 26 | rsync_cmd "${TEMP_DIR}/${REQUEST_BODY_PATH}" "${VIA}:/root/${REQUEST_BODY_PATH}" 27 | 28 | ssh_cmd "${VIA}" curl -isS \ 29 | --fail \ 30 | --max-time 60 \ 31 | --retry 10 \ 32 | --retry-delay 15 \ 33 | -H 'Content-Type: application/json' \ 34 | -d "@/root/${REQUEST_BODY_PATH}" \ 35 | "${KEYSTONE_URL}/v3/auth/tokens" | grep 'X-Subject-Token' | awk '{print $2}' | sed "s;';;g" | sed "s;\r;;g" 36 | } 37 | -------------------------------------------------------------------------------- /examples/basic/KubernetesNetwork.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/KubernetesNetwork/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: kubernetes-network 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | storagePolicy: cleartext 10 | data: 11 | dns: 12 | cluster_domain: cluster.local 13 | service_ip: 10.96.0.10 14 | bootstrap_validation_checks: 15 | - calico-etcd.kube-system.svc.cluster.local 16 | - google.com 17 | - kubernetes-etcd.kube-system.svc.cluster.local 18 | - kubernetes.default.svc.cluster.local 19 | upstream_servers: 20 | - 8.8.8.8 21 | - 8.8.4.4 22 | 23 | kubernetes: 24 | apiserver_port: 6443 25 | haproxy_port: 6553 26 | pod_cidr: 10.97.0.0/16 27 | service_cidr: 10.96.0.0/16 28 | service_ip: 10.96.0.1 29 | 30 | etcd: 31 | container_port: 2379 32 | haproxy_port: 2378 33 | 34 | hosts_entries: 35 | - ip: 192.168.77.1 36 | names: 37 | - registry 38 | 39 | # proxy: 40 | # url: http://proxy.example.com:8080 41 | # additional_no_proxy: 42 | # - 10.0.1.1 43 | ... 44 | -------------------------------------------------------------------------------- /charts/apiserver/templates/configmap-bin.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_bin }} 18 | {{- $envAll := . }} 19 | 20 | --- 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: {{ .Values.service.name }}-bin 25 | data: 26 | anchor: |+ 27 | {{ tuple "bin/_anchor.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 28 | pre_stop: |+ 29 | {{ tuple "bin/_pre_stop.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 30 | {{- end }} 31 | -------------------------------------------------------------------------------- /charts/promenade/templates/secret-keystone-env.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | */}} 14 | {{- if .Values.manifests.secret_keystone }} 15 | {{- $envAll := . }} 16 | {{- range $key1, $userClass := tuple "admin" "promenade" }} 17 | {{- $secretName := index $envAll.Values.secrets.identity $userClass }} 18 | --- 19 | apiVersion: v1 20 | kind: Secret 21 | metadata: 22 | name: {{ $secretName }} 23 | type: Opaque 24 | data: 25 | {{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 }} 26 | ... 27 | {{- end }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /charts/controller_manager/templates/configmap-bin.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_bin }} 18 | {{- $envAll := . }} 19 | 20 | --- 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: {{ .Values.service.name }}-bin 25 | data: 26 | anchor: |+ 27 | {{ tuple "bin/_anchor.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 28 | pre_stop: |+ 29 | {{ tuple "bin/_pre_stop.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 30 | {{- end }} 31 | -------------------------------------------------------------------------------- /promenade/schemas/PKICatalog.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/DataSchema/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: promenade/PKICatalog/v1 6 | labels: 7 | application: promenade 8 | data: 9 | $schema: http://json-schema.org/schema# 10 | certificate_authorities: 11 | type: array 12 | items: 13 | type: object 14 | properties: 15 | description: 16 | type: string 17 | certificates: 18 | type: array 19 | items: 20 | type: object 21 | properties: 22 | document_name: 23 | type: string 24 | description: 25 | type: string 26 | common_name: 27 | type: string 28 | hosts: 29 | type: array 30 | items: string 31 | groups: 32 | type: array 33 | items: string 34 | keypairs: 35 | type: array 36 | items: 37 | type: object 38 | properties: 39 | name: 40 | type: string 41 | description: 42 | type: string 43 | ... 44 | -------------------------------------------------------------------------------- /tests/unit/api/test_health_api.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import falcon 16 | from falcon import testing 17 | import pytest 18 | 19 | from promenade.control import health_api 20 | from promenade import promenade 21 | 22 | 23 | @pytest.fixture() 24 | def client(): 25 | return testing.TestClient(promenade.start_promenade(disable='keystone')) 26 | 27 | 28 | def test_get_health(client): 29 | response = client.simulate_get('/api/v1.0/health') 30 | assert response.status == falcon.HTTP_204 31 | -------------------------------------------------------------------------------- /tools/g2/on_error/collect_genesis_info.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # NOTE(mark-burnett): Keep trying to collect info even if there's an error 4 | set +e 5 | set -x 6 | 7 | source "${GATE_UTILS}" 8 | 9 | ERROR_DIR="${TEMP_DIR}/errors" 10 | VIA=n0 11 | mkdir -p "${ERROR_DIR}" 12 | 13 | log "Gathering info from failed genesis server (n0) in ${ERROR_DIR}" 14 | 15 | log "Gathering docker info for exitted containers" 16 | mkdir -p "${ERROR_DIR}/docker" 17 | docker_ps "${VIA}" | tee "${ERROR_DIR}/docker/ps" 18 | docker_info "${VIA}" | tee "${ERROR_DIR}/docker/info" 19 | 20 | for container_id in $(docker_exited_containers "${VIA}"); do 21 | docker_inspect "${VIA}" "${container_id}" | tee "${ERROR_DIR}/docker/${container_id}" 22 | echo "=== Begin logs ===" | tee -a "${ERROR_DIR}/docker/${container_id}" 23 | docker_logs "${VIA}" "${container_id}" | tee -a "${ERROR_DIR}/docker/${container_id}" 24 | done 25 | 26 | log "Gathering kubectl output" 27 | mkdir -p "${ERROR_DIR}/kube" 28 | kubectl_cmd "${VIA}" describe nodes n0 | tee "${ERROR_DIR}/kube/n0" 29 | kubectl_cmd "${VIA}" get --all-namespaces -o wide pod | tee "${ERROR_DIR}/kube/pods" 30 | -------------------------------------------------------------------------------- /charts/promenade/templates/service-api.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.service_api }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: promenade-api 24 | spec: 25 | ports: 26 | - name: http 27 | port: {{ .Values.network.api.port }} 28 | targetPort: {{ .Values.network.api.target_port }} 29 | selector: 30 | {{ tuple $envAll "promenade" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} 31 | {{- end }} 32 | -------------------------------------------------------------------------------- /tools/g2/stages/conformance.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | rm -rf "${WORKSPACE}/conformance" 8 | mkdir -p "${WORKSPACE}/conformance" 9 | 10 | rsync_cmd "${WORKSPACE}/tools/g2/sonobuoy.yaml" "${GENESIS_NAME}:/root/" 11 | ssh_cmd "${GENESIS_NAME}" mkdir -p /mnt/sonobuoy 12 | kubectl_apply "${GENESIS_NAME}" /root/sonobuoy.yaml 13 | 14 | if kubectl_wait_for_pod "${GENESIS_NAME}" heptio-sonobuoy sonobuoy 7200; then 15 | log Pod succeeded 16 | SUCCESS=1 17 | else 18 | log Pod failed 19 | SUCCESS=0 20 | fi 21 | 22 | FILENAME=$(ssh_cmd "${GENESIS_NAME}" ls /mnt/sonobuoy || echo "") 23 | if [[ ! -z ${FILENAME} ]]; then 24 | if rsync_cmd "${GENESIS_NAME}:/mnt/sonobuoy/${FILENAME}" "${WORKSPACE}/conformance/sonobuoy.tgz"; then 25 | tar xf "${WORKSPACE}/conformance/sonobuoy.tgz" -C "${WORKSPACE}/conformance" 26 | fi 27 | fi 28 | 29 | if [[ ${SUCCESS} = "1" ]]; then 30 | tail -n 1 conformance/plugins/e2e/results/e2e.log | grep '^SUCCESS!' 31 | else 32 | if [[ -s conformance/plugins/e2e/results/e2e.log ]]; then 33 | tail -n 50 conformance/plugins/e2e/results/e2e.log 34 | exit 1 35 | fi 36 | fi 37 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/usr/local/bin/kubectl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -o pipefail 5 | 6 | ADDITIONAL_DOCKER_ARGS= 7 | TRANSLATE_CR=1 8 | 9 | for item in "$@"; do 10 | if [[ $item =~ ^-[^-].*t.* ]]; then 11 | ADDITIONAL_DOCKER_ARGS="$ADDITIONAL_DOCKER_ARGS -t" 12 | TRANSLATE_CR=0 13 | break 14 | elif [[ $item == "--" ]]; then 15 | break 16 | fi 17 | done 18 | 19 | if [[ $TRANSLATE_CR == 1 ]]; then 20 | docker run --rm -i \ 21 | $ADDITIONAL_DOCKER_ARGS \ 22 | --net host \ 23 | -v /etc/kubernetes/admin:/etc/kubernetes/admin \ 24 | -e KUBECONFIG=/etc/kubernetes/admin/kubeconfig.yaml \ 25 | {{ config['HostSystem:images.kubernetes.kubectl'] }} \ 26 | /kubectl \ 27 | "$@" \ 28 | | sed "s/\r//" 29 | else 30 | exec docker run --rm -i \ 31 | $ADDITIONAL_DOCKER_ARGS \ 32 | --net host \ 33 | -v /etc/kubernetes/admin:/etc/kubernetes/admin \ 34 | -e KUBECONFIG=/etc/kubernetes/admin/kubeconfig.yaml \ 35 | {{ config['HostSystem:images.kubernetes.kubectl'] }} \ 36 | /kubectl \ 37 | "$@" 38 | fi 39 | -------------------------------------------------------------------------------- /charts/promenade/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.rbac }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: ServiceAccount 22 | metadata: 23 | name: promenade 24 | --- 25 | kind: ClusterRoleBinding 26 | apiVersion: rbac.authorization.k8s.io/v1 27 | metadata: 28 | name: promenade 29 | subjects: 30 | - kind: ServiceAccount 31 | name: promenade 32 | namespace: {{ .Release.Namespace }} 33 | roleRef: 34 | kind: ClusterRole 35 | name: cluster-admin 36 | apiGroup: rbac.authorization.k8s.io 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /tests/unit/test_generator.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from promenade import generator 16 | 17 | 18 | def test_get_host_list(): 19 | service_fqdns = [ 20 | 'kubernetes.default.svc.cluster.local', 21 | ] 22 | expected_parts = [ 23 | 'kubernetes', 24 | 'kubernetes.default', 25 | 'kubernetes.default.svc', 26 | 'kubernetes.default.svc.cluster', 27 | 'kubernetes.default.svc.cluster.local', 28 | ] 29 | 30 | actual_parts = generator.get_host_list(service_fqdns) 31 | assert actual_parts == expected_parts 32 | -------------------------------------------------------------------------------- /tools/g2/stages/fail-join-node.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | source "${GATE_UTILS}" 6 | 7 | while getopts "n:v:" opt; do 8 | case "${opt}" in 9 | n) 10 | NODE="${OPTARG}" 11 | ;; 12 | v) 13 | VIA=${OPTARG} 14 | ;; 15 | *) 16 | echo "Unknown option" 17 | exit 1 18 | ;; 19 | esac 20 | done 21 | shift $((OPTIND-1)) 22 | 23 | if [ $# -gt 0 ]; then 24 | echo "Unknown arguments specified: ${*}" 25 | exit 1 26 | fi 27 | 28 | SCRIPT_DIR="${TEMP_DIR}/join-fail-curled-scripts" 29 | 30 | mkdir -p "${SCRIPT_DIR}" 31 | 32 | CURL_ARGS=("-v" "--fail" "--max-time" "300") 33 | 34 | promenade_health_check "${VIA}" 35 | 36 | LABELS=( 37 | "foo=bar" 38 | ) 39 | 40 | USE_DECKHAND=0 41 | JOIN_CURL_URL="$(promenade_render_curl_url "${NODE}" "${USE_DECKHAND}" "" "${LABELS[@]}")" 42 | log "Attempting to get join script (should fail) via: ${JOIN_CURL_URL}" 43 | if ! ssh_cmd "${VIA}" curl "${CURL_ARGS[@]}" \ 44 | "${JOIN_CURL_URL}" > "${SCRIPT_DIR}/join-${NODE}.sh"; then 45 | log "Failed to get join script" 46 | else 47 | log "No failure when fetching join script" 48 | exit 1 49 | fi 50 | -------------------------------------------------------------------------------- /tests/unit/api/test_versions.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import falcon 16 | from falcon import testing 17 | import pytest 18 | 19 | from promenade.control.api import VersionsResource 20 | from promenade import promenade 21 | 22 | 23 | @pytest.fixture() 24 | def client(): 25 | return testing.TestClient(promenade.start_promenade(disable='keystone')) 26 | 27 | 28 | def test_get_versions(client): 29 | response = client.simulate_get('/versions') 30 | assert response.status == falcon.HTTP_200 31 | assert response.json == {'v1.0': {'path': '/api/v1.0', 'status': 'stable'}} 32 | -------------------------------------------------------------------------------- /tools/g2/lib/config.sh: -------------------------------------------------------------------------------- 1 | export TEMP_DIR=${TEMP_DIR:-$(mktemp -d)} 2 | export BASE_IMAGE_SIZE=${BASE_IMAGE_SIZE:-68719476736} 3 | export BASE_IMAGE_URL=${BASE_IMAGE_URL:-https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img} 4 | export IMAGE_PROMENADE=${IMAGE_PROMENADE:-quay.io/attcomdev/promenade:latest} 5 | export NGINX_DIR="${TEMP_DIR}/nginx" 6 | export NGINX_URL="http://192.168.77.1:7777" 7 | export PROMENADE_BASE_URL="http://promenade-api.ucp.svc.cluster.local" 8 | export PROMENADE_DEBUG=${PROMENADE_DEBUG:-0} 9 | export REGISTRY_DATA_DIR=${REGISTRY_DATA_DIR:-/mnt/registry} 10 | export VIRSH_POOL=${VIRSH_POOL:-promenade} 11 | export VIRSH_POOL_PATH=${VIRSH_POOL_PATH:-/var/lib/libvirt/promenade} 12 | 13 | config_configuration() { 14 | # XXX Do I need ' | @sh' now? 15 | jq -cr '.configuration[]' < "${GATE_MANIFEST}" 16 | } 17 | 18 | config_vm_memory() { 19 | jq -cr '.vm.memory' < "${GATE_MANIFEST}" 20 | } 21 | 22 | config_vm_names() { 23 | jq -cr '.vm.names[]' < "${GATE_MANIFEST}" 24 | } 25 | 26 | config_vm_ip() { 27 | NAME=${1} 28 | echo "192.168.77.1${NAME:1}" 29 | } 30 | 31 | config_vm_vcpus() { 32 | jq -cr '.vm.vcpus' < "${GATE_MANIFEST}" 33 | } 34 | -------------------------------------------------------------------------------- /charts/etcd/templates/secret-keys.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.secret }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: Secret 22 | metadata: 23 | name: {{ $envAll.Values.service.name }}-keys 24 | type: Opaque 25 | data: 26 | anchor-etcd-client-key.pem: {{ $envAll.Values.secrets.anchor.tls.key | b64enc }} 27 | {{- range .Values.nodes }} 28 | {{- $node := . }} 29 | {{ $node.name }}-etcd-client-key.pem: {{ $node.tls.client.key | b64enc }} 30 | {{ $node.name }}-etcd-peer-key.pem: {{ $node.tls.peer.key | b64enc }} 31 | {{- end }} 32 | {{- end }} 33 | -------------------------------------------------------------------------------- /examples/basic/Genesis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/Genesis/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: genesis 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | data: 10 | hostname: n0 11 | ip: 192.168.77.10 12 | armada: 13 | target_manifest: cluster-bootstrap 14 | labels: 15 | dynamic: 16 | - calico-etcd=enabled 17 | - coredns=enabled 18 | - kubernetes-apiserver=enabled 19 | - kubernetes-controller-manager=enabled 20 | - kubernetes-etcd=enabled 21 | - kubernetes-scheduler=enabled 22 | - promenade-genesis=enabled 23 | - ucp-control-plane=enabled 24 | images: 25 | armada: quay.io/attcomdev/armada:latest 26 | helm: 27 | tiller: gcr.io/kubernetes-helm/tiller:v2.7.2 28 | kubernetes: 29 | apiserver: gcr.io/google_containers/hyperkube-amd64:v1.10.2 30 | controller-manager: gcr.io/google_containers/hyperkube-amd64:v1.10.2 31 | etcd: quay.io/coreos/etcd:v3.2.14 32 | scheduler: gcr.io/google_containers/hyperkube-amd64:v1.10.2 33 | files: 34 | - path: /var/lib/anchor/calico-etcd-bootstrap 35 | content: "# placeholder for triggering calico etcd bootstrapping" 36 | mode: 0644 37 | ... 38 | -------------------------------------------------------------------------------- /tools/g2/stages/teardown-nodes.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | source "${GATE_UTILS}" 6 | 7 | declare -a ETCD_CLUSTERS 8 | declare -a NODES 9 | 10 | RECREATE=0 11 | 12 | while getopts "e:n:rv:" opt; do 13 | case "${opt}" in 14 | e) 15 | ETCD_CLUSTERS+=("${OPTARG}") 16 | ;; 17 | n) 18 | NODES+=("${OPTARG}") 19 | ;; 20 | r) 21 | RECREATE=1 22 | ;; 23 | v) 24 | VIA=${OPTARG} 25 | ;; 26 | *) 27 | echo "Unknown option" 28 | exit 1 29 | ;; 30 | esac 31 | done 32 | shift $((OPTIND-1)) 33 | 34 | if [ $# -gt 0 ]; then 35 | echo "Unknown arguments specified: ${*}" 36 | exit 1 37 | fi 38 | 39 | for NAME in "${NODES[@]}"; do 40 | log Tearing down node "${NAME}" 41 | promenade_teardown_node "${NAME}" "${VIA}" 42 | vm_clean "${NAME}" 43 | if [[ ${RECREATE} == "1" ]]; then 44 | vm_create "${NAME}" 45 | fi 46 | done 47 | 48 | for etcd_validation_string in "${ETCD_CLUSTERS[@]}"; do 49 | IFS=' ' read -a etcd_validation_args <<<"${etcd_validation_string}" 50 | validate_etcd_membership "${etcd_validation_args[@]}" 51 | done 52 | -------------------------------------------------------------------------------- /charts/etcd/templates/configmap-bin.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_bin }} 18 | {{- $envAll := . }} 19 | 20 | --- 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: {{ .Values.service.name }}-bin 25 | data: 26 | etcdctl_anchor: |+ 27 | {{ tuple "bin/_etcdctl_anchor.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 28 | pre_stop: |+ 29 | {{ tuple "bin/_pre_stop.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 30 | readiness: |+ 31 | {{ tuple "bin/_readiness.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 32 | {{- end }} 33 | -------------------------------------------------------------------------------- /charts/scheduler/templates/etc/_kubeconfig.yaml.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | */}} 16 | 17 | --- 18 | apiVersion: v1 19 | clusters: 20 | - cluster: 21 | server: https://{{ .Values.network.kubernetes_netloc }} 22 | certificate-authority: cluster-ca.pem 23 | name: kubernetes 24 | contexts: 25 | - context: 26 | cluster: kubernetes 27 | user: scheduler 28 | name: scheduler@kubernetes 29 | current-context: scheduler@kubernetes 30 | kind: Config 31 | preferences: {} 32 | users: 33 | - name: scheduler 34 | user: 35 | client-certificate: scheduler.pem 36 | client-key: scheduler-key.pem 37 | -------------------------------------------------------------------------------- /charts/apiserver/templates/configmap-certs.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_certs }} 18 | {{- $envAll := . }} 19 | 20 | --- 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: {{ .Values.service.name }}-certs 25 | data: 26 | cluster-ca.pem: {{ .Values.secrets.tls.ca | quote }} 27 | apiserver.pem: {{ .Values.secrets.tls.cert | quote }} 28 | etcd-client-ca.pem: {{ .Values.secrets.etcd.tls.ca | quote }} 29 | etcd-client.pem: {{ .Values.secrets.etcd.tls.cert | quote }} 30 | service-account.pub: {{ .Values.secrets.service_account.public_key | quote }} 31 | {{- end }} 32 | -------------------------------------------------------------------------------- /charts/haproxy/templates/configmap-etc.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2018 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | --- 17 | apiVersion: v1 18 | kind: ConfigMap 19 | metadata: 20 | name: haproxy-etc 21 | data: 22 | haproxy.cfg.header: | 23 | global 24 | {{- range .Values.conf.haproxy.conf_parts.global }} 25 | {{ . }} 26 | {{- end }} 27 | 28 | stats socket /tmp/haproxy.sock mode 700 level admin expose-fd listeners 29 | 30 | defaults 31 | {{- range .Values.conf.haproxy.conf_parts.defaults }} 32 | {{ . }} 33 | {{- end }} 34 | haproxy.yaml: | 35 | {{ tuple "etc/_haproxy.yaml.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 36 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2017 AT&T Intellectual Property. 3 | All Rights Reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | not use this file except in compliance with the License. You may obtain 7 | a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | License for the specific language governing permissions and limitations 15 | under the License. 16 | 17 | ===================================== 18 | Welcome to Promenade's documentation! 19 | ===================================== 20 | 21 | Promenade is a tool for bootstrapping a resilient Kubernetes cluster and 22 | managing its life-cycle. 23 | 24 | User's Guide 25 | ============ 26 | 27 | Promenade Configuration Guide 28 | ----------------------------- 29 | 30 | .. toctree:: 31 | :maxdepth: 2 32 | 33 | design 34 | getting-started 35 | configuration/index 36 | troubleshooting/index 37 | api 38 | exceptions 39 | -------------------------------------------------------------------------------- /charts/promenade/templates/configmap-bin.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. */}} 15 | 16 | {{- if .Values.manifests.configmap_bin }} 17 | --- 18 | apiVersion: v1 19 | kind: ConfigMap 20 | metadata: 21 | name: promenade-bin 22 | data: 23 | ks-service.sh: | 24 | {{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} 25 | ks-endpoints.sh: | 26 | {{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} 27 | ks-user.sh: | 28 | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} 29 | ks-domain-user.sh: | 30 | {{- include "helm-toolkit.scripts.keystone_domain_user" . | indent 4 }} 31 | ... 32 | {{- end -}} 33 | -------------------------------------------------------------------------------- /charts/controller_manager/templates/etc/_kubeconfig.yaml.tpl: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | --- 16 | apiVersion: v1 17 | clusters: 18 | - cluster: 19 | server: https://{{ .Values.network.kubernetes_netloc }} 20 | certificate-authority: cluster-ca.pem 21 | name: kubernetes 22 | contexts: 23 | - context: 24 | cluster: kubernetes 25 | user: controller-manager 26 | name: controller-manager@kubernetes 27 | current-context: controller-manager@kubernetes 28 | kind: Config 29 | preferences: {} 30 | users: 31 | - name: controller-manager 32 | user: 33 | client-certificate: controller-manager.pem 34 | client-key: controller-manager-key.pem 35 | -------------------------------------------------------------------------------- /charts/proxy/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # limitations under the License. 15 | 16 | apiVersion: v1 17 | kind: ServiceAccount 18 | metadata: 19 | name: kube-proxy 20 | namespace: kube-system 21 | labels: 22 | addonmanager.kubernetes.io/mode: Reconcile 23 | --- 24 | kind: ClusterRoleBinding 25 | apiVersion: rbac.authorization.k8s.io/v1beta1 26 | metadata: 27 | name: system:kube-proxy 28 | labels: 29 | addonmanager.kubernetes.io/mode: Reconcile 30 | subjects: 31 | - kind: ServiceAccount 32 | name: kube-proxy 33 | namespace: kube-system 34 | roleRef: 35 | kind: ClusterRole 36 | name: system:node-proxier 37 | apiGroup: rbac.authorization.k8s.io -------------------------------------------------------------------------------- /promenade/schemas/KubernetesNode.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/DataSchema/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: promenade/KubernetesNode/v1 6 | labels: 7 | application: promenade 8 | data: 9 | $schema: http://json-schema.org/schema# 10 | definitions: 11 | hostname: 12 | type: string 13 | pattern: '^[a-z][a-z0-9-]+$' 14 | ip_address: 15 | type: string 16 | pattern: '^(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))$' 17 | kubernetes_label: 18 | type: string 19 | # XXX add regex 20 | 21 | type: object 22 | properties: 23 | hostname: 24 | $ref: '#/definitions/hostname' 25 | 26 | ip: 27 | $ref: '#/definitions/ip_address' 28 | 29 | join_ip: 30 | $ref: '#/definitions/ip_address' 31 | 32 | labels: 33 | properties: 34 | static: 35 | type: array 36 | items: 37 | $ref: '#/definitions/kubernetes_label' 38 | dynamic: 39 | type: array 40 | items: 41 | $ref: '#/definitions/kubernetes_label' 42 | additionalProperties: false 43 | 44 | required: 45 | - ip 46 | - join_ip 47 | additionalProperties: false 48 | ... 49 | -------------------------------------------------------------------------------- /tools/gate/config-templates/genesis-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/Genesis/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: genesis 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | storagePolicy: cleartext 10 | data: 11 | hostname: ${GENESIS_HOSTNAME} 12 | ip: ${GENESIS_IP} 13 | labels: 14 | dynamic: 15 | - calico-etcd=enabled 16 | - ceph-mds=enabled 17 | - ceph-mon=enabled 18 | - ceph-osd=enabled 19 | - ceph-rgw=enabled 20 | - ceph-mgr=enabled 21 | - coredns=enabled 22 | - kubernetes-apiserver=enabled 23 | - kubernetes-controller-manager=enabled 24 | - kubernetes-etcd=enabled 25 | - kubernetes-scheduler=enabled 26 | - promenade-genesis=enabled 27 | - openstack-compute-node=enabled 28 | - openstack-control-plane=enabled 29 | - openvswitch=enabled 30 | - ucp-control-plane=enabled 31 | images: 32 | armada: ${IMAGE_ARMADA} 33 | helm: 34 | tiller: ${IMAGE_TILLER} 35 | kubernetes: 36 | apiserver: ${IMAGE_HYPERKUBE} 37 | controller-manager: ${IMAGE_HYPERKUBE} 38 | etcd: ${IMAGE_ETCD} 39 | scheduler: ${IMAGE_HYPERKUBE} 40 | files: 41 | - path: /var/lib/anchor/calico-etcd-bootstrap 42 | content: "" 43 | mode: 0644 44 | ... 45 | -------------------------------------------------------------------------------- /charts/controller_manager/templates/configmap-etc.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_etc }} 18 | {{- $envAll := . }} 19 | 20 | --- 21 | apiVersion: v1 22 | kind: ConfigMap 23 | metadata: 24 | name: {{ .Values.service.name }}-etc 25 | data: 26 | cluster-ca.pem: {{ .Values.secrets.tls.ca | quote }} 27 | controller-manager.pem: {{ .Values.secrets.tls.cert | quote }} 28 | kubeconfig.yaml: |+ 29 | {{ tuple "etc/_kubeconfig.yaml.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 30 | kubernetes-controller-manager.yaml: |+ 31 | {{ tuple "etc/_kubernetes-controller-manager.yaml.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} 32 | {{- end }} 33 | -------------------------------------------------------------------------------- /tools/g2/lib/nginx.sh: -------------------------------------------------------------------------------- 1 | nginx_down() { 2 | REGISTRY_ID=$(docker ps -qa -f name=promenade-nginx) 3 | if [ "x${REGISTRY_ID}" != "x" ]; then 4 | log Removing nginx server 5 | docker rm -fv "${REGISTRY_ID}" &>> "${LOG_FILE}" 6 | fi 7 | } 8 | 9 | nginx_up() { 10 | log Starting nginx server to serve configuration files 11 | mkdir -p "${NGINX_DIR}" 12 | docker run -d \ 13 | -p 7777:80 \ 14 | --restart=always \ 15 | --name promenade-nginx \ 16 | -v "${TEMP_DIR}/nginx:/usr/share/nginx/html:ro" \ 17 | nginx:stable &>> "${LOG_FILE}" 18 | } 19 | 20 | nginx_cache_and_replace_tar_urls() { 21 | log "Finding tar_url options to cache.." 22 | TAR_NUM=0 23 | mkdir -p "${NGINX_DIR}" 24 | for file in "$@"; do 25 | grep -Po "^ +tar_url: \K.+$" "${file}" | while read tar_url ; do 26 | # NOTE(mark-burnet): Does not yet ignore repeated files. 27 | DEST_PATH="${NGINX_DIR}/cached-tar-${TAR_NUM}.tgz" 28 | log "Caching ${tar_url} in file: ${DEST_PATH}" 29 | REPLACEMENT_URL="${NGINX_URL}/cached-tar-${TAR_NUM}.tgz" 30 | curl -Lo "${DEST_PATH}" "${tar_url}" 31 | sed -i "s;${tar_url};${REPLACEMENT_URL};" "${file}" 32 | TAR_NUM=$((TAR_NUM + 1)) 33 | done 34 | done 35 | } 36 | -------------------------------------------------------------------------------- /promenade/promenade.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | from promenade.control import api 15 | from promenade import options 16 | from promenade import logging 17 | from promenade import policy 18 | 19 | 20 | def start_promenade(disable=False): 21 | options.setup(disable_keystone=disable) 22 | 23 | # Setup root logger 24 | logging.setup(verbose=True) 25 | 26 | # Setup policy 27 | policy.policy_engine = policy.PromenadePolicy() 28 | policy.policy_engine.register_policy() 29 | 30 | # Start the API 31 | return api.start_api() 32 | 33 | 34 | # Initialization compatible with PasteDeploy 35 | def paste_start_promenade(global_conf, **kwargs): 36 | return start_promenade(**kwargs) 37 | -------------------------------------------------------------------------------- /charts/etcd/templates/configmap-certs.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.configmap_certs }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: ConfigMap 22 | metadata: 23 | name: {{ $envAll.Values.service.name }}-certs 24 | data: 25 | anchor-etcd-client.pem: {{ $envAll.Values.secrets.anchor.tls.cert | quote }} 26 | client-ca.pem: {{ $envAll.Values.secrets.tls.client.ca | quote }} 27 | peer-ca.pem: {{ $envAll.Values.secrets.tls.peer.ca | quote }} 28 | {{- range .Values.nodes }} 29 | {{- $node := . }} 30 | {{ $node.name }}-etcd-client.pem: {{ $node.tls.client.cert | quote }} 31 | {{ $node.name }}-etcd-peer.pem: {{ $node.tls.peer.cert | quote }} 32 | {{- end }} 33 | {{- end }} 34 | -------------------------------------------------------------------------------- /tools/g2/lib/ssh.sh: -------------------------------------------------------------------------------- 1 | rsync_cmd() { 2 | rsync -e "ssh -F ${SSH_CONFIG_DIR}/config" "${@}" 3 | } 4 | 5 | ssh_cmd() { 6 | HOST=${1} 7 | shift 8 | args=$(shell-quote -- "${@}") 9 | if [[ -v GATE_DEBUG && ${GATE_DEBUG} = "1" ]]; then 10 | ssh -F "${SSH_CONFIG_DIR}/config" -v "${HOST}" "${args}" 11 | else 12 | ssh -F "${SSH_CONFIG_DIR}/config" "${HOST}" "${args}" 13 | fi 14 | } 15 | 16 | ssh_config_declare() { 17 | log Validating SSH config exists 18 | if [ ! -s "${SSH_CONFIG_DIR}/config" ]; then 19 | log Creating SSH config 20 | env -i \ 21 | "SSH_CONFIG_DIR=${SSH_CONFIG_DIR}" \ 22 | envsubst < "${TEMPLATE_DIR}/ssh-config.sub" > "${SSH_CONFIG_DIR}/config" 23 | fi 24 | } 25 | 26 | ssh_keypair_declare() { 27 | log Validating SSH keypair exists 28 | if [ ! -s "${SSH_CONFIG_DIR}/id_rsa" ]; then 29 | log Generating SSH keypair 30 | ssh-keygen -N '' -f "${SSH_CONFIG_DIR}/id_rsa" &>> "${LOG_FILE}" 31 | fi 32 | } 33 | 34 | ssh_load_pubkey() { 35 | cat "${SSH_CONFIG_DIR}/id_rsa.pub" 36 | } 37 | 38 | ssh_setup_declare() { 39 | mkdir -p "${SSH_CONFIG_DIR}" 40 | ssh_keypair_declare 41 | ssh_config_declare 42 | } 43 | 44 | ssh_wait() { 45 | NAME=${1} 46 | while ! ssh_cmd "${NAME}" /bin/true; do 47 | sleep 0.5 48 | done 49 | } 50 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = lint,unit,bandit,docs 3 | 4 | [testenv] 5 | basepython=python3 6 | 7 | [testenv:unit] 8 | setenv = 9 | PYTHONWARNING=all 10 | deps = -r{toxinidir}/requirements-frozen.txt 11 | -r{toxinidir}/test-requirements.txt 12 | commands = 13 | pytest 14 | 15 | [testenv:bandit] 16 | deps = bandit==1.4.0 17 | commands = 18 | bandit -r promenade 19 | 20 | [testenv:docs] 21 | whitelist_externals = rm 22 | deps = 23 | sphinx>=1.6.2 24 | sphinx_rtd_theme==0.2.4 25 | -r{toxinidir}/requirements-frozen.txt 26 | -r{toxinidir}/test-requirements.txt 27 | commands = 28 | rm -rf docs/build 29 | sphinx-build -b html docs/source docs/build 30 | 31 | [testenv:fmt] 32 | deps = yapf==0.20.0 33 | commands = 34 | yapf -ir {toxinidir}/promenade {toxinidir}/tests 35 | 36 | [testenv:freeze] 37 | deps = -r{toxinidir}/requirements-direct.txt 38 | recreate = True 39 | whitelist_externals = sh 40 | commands= 41 | sh -c "pip freeze | grep -v '^promenade' > {toxinidir}/requirements-frozen.txt" 42 | 43 | [testenv:gate-lint] 44 | deps = 45 | jsonschema==2.6.0 46 | whitelist_externals = sh 47 | commands = 48 | {toxinidir}/tools/lint_gate.sh 49 | 50 | [testenv:lint] 51 | deps = 52 | yapf==0.20.0 53 | flake8==3.5.0 54 | commands = 55 | yapf -rd {toxinidir}/promenade {toxinidir}/tests 56 | flake8 {toxinidir}/promenade 57 | -------------------------------------------------------------------------------- /examples/complete/Genesis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: promenade/Genesis/v1 3 | metadata: 4 | schema: metadata/Document/v1 5 | name: genesis 6 | layeringDefinition: 7 | abstract: false 8 | layer: site 9 | storagePolicy: cleartext 10 | data: 11 | hostname: n0 12 | ip: 192.168.77.10 13 | armada: 14 | target_manifest: cluster-bootstrap 15 | labels: 16 | dynamic: 17 | - calico-etcd=enabled 18 | - ceph-mds=enabled 19 | - ceph-mon=enabled 20 | - ceph-osd=enabled 21 | - ceph-rgw=enabled 22 | - ceph-mgr=enabled 23 | - coredns=enabled 24 | - kubernetes-apiserver=enabled 25 | - kubernetes-controller-manager=enabled 26 | - kubernetes-etcd=enabled 27 | - kubernetes-scheduler=enabled 28 | - promenade-genesis=enabled 29 | - ucp-control-plane=enabled 30 | images: 31 | armada: quay.io/attcomdev/armada:latest 32 | helm: 33 | tiller: gcr.io/kubernetes-helm/tiller:v2.7.2 34 | kubernetes: 35 | apiserver: gcr.io/google_containers/hyperkube-amd64:v1.10.2 36 | controller-manager: gcr.io/google_containers/hyperkube-amd64:v1.10.2 37 | etcd: quay.io/coreos/etcd:v3.2.14 38 | scheduler: gcr.io/google_containers/hyperkube-amd64:v1.10.2 39 | files: 40 | - path: /var/lib/anchor/calico-etcd-bootstrap 41 | content: "# placeholder for triggering calico etcd bootstrapping" 42 | mode: 0644 43 | ... 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Promenade 2 | 3 | Promenade is a tool for bootstrapping a resilient Kubernetes cluster and 4 | managing its life-cycle via Helm charts. 5 | 6 | Documentation can be found [here](https://promenade.readthedocs.io). 7 | 8 | ## Roadmap 9 | 10 | The detailed Roadmap can be viewed on the 11 | [LCOO JIRA](https://openstack-lcoo.atlassian.net/secure/RapidBoard.jspa?projectKey=PROM&rapidView=37). 12 | 13 | - Cluster bootstrapping 14 | - Initial Genesis process results in a single node Kubernetes cluster with 15 | Under-cloud components deployed using 16 | [Armada](https://github.com/att-comdev/armada). 17 | - Joining sufficient master nodes results in a resilient Kubernetes cluster. 18 | - Destroy Genesis node after bootstrapping and re-provision as a normal node 19 | to ensure consistency. 20 | - Life-cycle management 21 | - Decommissioning of nodes. 22 | - Updating Kubernetes version. 23 | 24 | ## Getting Started 25 | 26 | To get started, see 27 | [getting started](https://promenade.readthedocs.io/en/latest/getting-started.html). 28 | 29 | Configuration is documented 30 | [here](https://promenade.readthedocs.io/en/latest/configuration/index.html). 31 | 32 | ## Bugs 33 | 34 | Bugs are tracked in 35 | [LCOO JIRA](https://openstack-lcoo.atlassian.net/secure/RapidBoard.jspa?projectKey=PROM&rapidView=37). 36 | If you find a bug, feel free to create a GitHub issue and it will be synced to 37 | JIRA. 38 | -------------------------------------------------------------------------------- /docs/source/api.rst: -------------------------------------------------------------------------------- 1 | Promenade API 2 | ============= 3 | 4 | 5 | /v1.0/health 6 | ------------ 7 | 8 | Allows other components to validate Promenade's health status. 9 | 10 | GET /v1.0/health 11 | 12 | Returns the health status. 13 | 14 | Responses: 15 | 16 | + 204 No Content 17 | 18 | 19 | /v1.0/join-scripts 20 | ------------------ 21 | 22 | Generates join scripts and for Drydock. 23 | 24 | GET /v1.0/join-scripts 25 | 26 | Generates script to be consumed by Drydock. 27 | 28 | Query parameters 29 | 30 | hostname 31 | Name of the node 32 | ip 33 | IP address of the node 34 | design_ref 35 | Endpoint containing configuration documents 36 | dynamic.labels 37 | Used to set configuration options in the generated script 38 | static.labels 39 | Used to set configuration options in the generated script 40 | 41 | Responses: 42 | 43 | + 200 OK: Script returned as response body 44 | + 400 Bad Request: One or more query parameters is missing or misspelled 45 | 46 | 47 | /v1.0/validatedesign 48 | -------------------- 49 | 50 | Performs validations against specified documents. 51 | 52 | POST /v1.0/validatedesign 53 | 54 | Performs validation against specified documents. 55 | 56 | Message Body 57 | 58 | href 59 | Location of the document to be validated 60 | 61 | Responses: 62 | 63 | + 200 OK: Documents were successfully validated 64 | + 400 Bad Request: Documents were not successfully validated 65 | -------------------------------------------------------------------------------- /charts/coredns/values.yaml: -------------------------------------------------------------------------------- 1 | conf: 2 | coredns: 3 | corefile: | 4 | .:53 { 5 | errors 6 | health 7 | autopath @kubernetes 8 | kubernetes cluster.local 10.96.0.0/16 10.97.0.0/16 { 9 | pods disabled 10 | fallthrough in-addr.arpa ip6.arpa 11 | upstream 8.8.8.8 12 | upstream 8.8.4.4 13 | } 14 | prometheus :9253 15 | forward . 8.8.8.8 8.8.4.4 16 | cache 30 17 | } 18 | 19 | test: 20 | names_to_resolve: 21 | - att.com 22 | - kubernetes.default.svc.cluster.local 23 | 24 | images: 25 | tags: 26 | coredns: coredns/coredns:1.1.2 27 | test: coredns/coredns:1.1.2 28 | pull_policy: "IfNotPresent" 29 | 30 | labels: 31 | coredns: 32 | node_selector_key: coredns 33 | node_selector_value: enabled 34 | 35 | service: 36 | name: coredns 37 | ip: 10.96.0.10 38 | 39 | pod: 40 | resources: 41 | enabled: false 42 | coredns: 43 | requests: 44 | memory: "128Mi" 45 | cpu: "100m" 46 | limits: 47 | memory: "1024Mi" 48 | cpu: "2000m" 49 | pod_test: 50 | requests: 51 | memory: "128Mi" 52 | cpu: "100m" 53 | limits: 54 | memory: "1024Mi" 55 | cpu: "2000m" 56 | 57 | monitoring: 58 | prometheus: 59 | enabled: false 60 | coredns: 61 | scrape: true 62 | port: 9253 63 | -------------------------------------------------------------------------------- /promenade/tar_bundler.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import io 3 | import tarfile 4 | import time 5 | 6 | from promenade import logging 7 | 8 | __all__ = ['TarBundler'] 9 | 10 | LOG = logging.getLogger(__name__) 11 | 12 | 13 | class TarBundler: 14 | def __init__(self): 15 | self._tar_blob = io.BytesIO() 16 | self._tf = tarfile.open(fileobj=self._tar_blob, mode='w|gz') 17 | 18 | def add(self, *, path, data, mode): 19 | if path.startswith('/'): 20 | path = path[1:] 21 | 22 | tar_info = tarfile.TarInfo(name=path) 23 | if isinstance(data, str): 24 | data_bytes = data.encode('utf-8') 25 | else: 26 | data_bytes = data 27 | tar_info.size = len(data_bytes) 28 | tar_info.mode = mode 29 | tar_info.mtime = int(time.time()) 30 | 31 | if tar_info.size > 0: 32 | # Ignore bandit false positive: B303:blacklist 33 | # This is a basic checksum for debugging not a secure hash. 34 | LOG.debug( # nosec 35 | 'Adding file path=%s size=%s md5=%s', path, tar_info.size, 36 | hashlib.md5(data_bytes).hexdigest()) 37 | else: 38 | LOG.warning('Zero length file added to path=%s', path) 39 | 40 | self._tf.addfile(tar_info, io.BytesIO(data_bytes)) 41 | 42 | def as_blob(self): 43 | self._tf.close() 44 | return self._tar_blob.getvalue() 45 | -------------------------------------------------------------------------------- /docs/source/exceptions.rst: -------------------------------------------------------------------------------- 1 | .. 2 | Copyright 2017 AT&T Intellectual Property. 3 | All Rights Reserved. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | not use this file except in compliance with the License. You may obtain 7 | a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | License for the specific language governing permissions and limitations 15 | under the License. 16 | 17 | 18 | Promenade Exceptions 19 | ==================== 20 | 21 | .. list-table:: 22 | :widths: 5 50 23 | :header-rows: 1 24 | 25 | * - Exception Name 26 | - Description 27 | * - ApiError 28 | - .. autoexception:: promenade.exceptions.ApiError 29 | :members: 30 | :show-inheritance: 31 | :undoc-members: 32 | * - InvalidFormatError 33 | - .. autoexception:: promenade.exceptions.InvalidFormatError 34 | :members: 35 | :show-inheritance: 36 | :undoc-members: 37 | * - ValidationException 38 | - .. autoexception:: promenade.exceptions.ValidationException 39 | :members: 40 | :show-inheritance: 41 | :undoc-members: 42 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/kubernetes/manifests/kubernetes-controller-manager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: kubernetes-controller-manager 6 | namespace: kube-system 7 | labels: 8 | tier: control-plane 9 | component: kube-controller-manager 10 | annotations: 11 | scheduler.alpha.kubernetes.io/critical-pod: '' 12 | spec: 13 | hostNetwork: true 14 | containers: 15 | - name: kube-controller-manager 16 | image: {{ config['Genesis:images.kubernetes.controller-manager'] }} 17 | command: 18 | - kube-controller-manager 19 | - --allocate-node-cidrs=true 20 | - --cluster-cidr={{ config['KubernetesNetwork:kubernetes.pod_cidr'] }} 21 | - --configure-cloud-routes=false 22 | - --leader-elect=true 23 | - --kubeconfig=/etc/kubernetes/controller-manager/kubeconfig.yaml 24 | - --root-ca-file=/etc/kubernetes/controller-manager/pki/cluster-ca.pem 25 | - --service-account-private-key-file=/etc/kubernetes/controller-manager/pki/service-account.key 26 | - --service-cluster-ip-range={{ config['KubernetesNetwork:kubernetes.service_cidr'] }} 27 | - --use-service-account-credentials=true 28 | - --v=5 29 | volumeMounts: 30 | - name: config 31 | mountPath: /etc/kubernetes/controller-manager 32 | readOnly: true 33 | volumes: 34 | - name: config 35 | hostPath: 36 | path: /etc/genesis/controller-manager 37 | -------------------------------------------------------------------------------- /tools/g2/lib/kube.sh: -------------------------------------------------------------------------------- 1 | kubectl_apply() { 2 | VIA=${1} 3 | FILE=${2} 4 | ssh_cmd "${VIA}" "cat ${FILE} | kubectl apply -f -" 5 | } 6 | 7 | kubectl_cmd() { 8 | VIA=${1} 9 | 10 | shift 11 | 12 | ssh_cmd "${VIA}" kubectl "${@}" 13 | } 14 | 15 | kubectl_wait_for_pod() { 16 | VIA=${1} 17 | NAMESPACE=${2} 18 | POD_NAME=${3} 19 | SEC=${4:-600} 20 | log Waiting "${SEC}" seconds for termination of pod "${POD_NAME}" 21 | 22 | POD_PHASE_JSONPATH='{.status.phase}' 23 | 24 | end=$(($(date +%s) + SEC)) 25 | while true; do 26 | POD_PHASE=$(kubectl_cmd "${VIA}" --request-timeout 10s --namespace "${NAMESPACE}" get -o jsonpath="${POD_PHASE_JSONPATH}" pod "${POD_NAME}") 27 | if [[ ${POD_PHASE} = "Succeeded" ]]; then 28 | log Pod "${POD_NAME}" succeeded. 29 | break 30 | elif [[ $POD_PHASE = "Failed" ]]; then 31 | log Pod "${POD_NAME}" failed. 32 | kubectl_cmd "${VIA}" --request-timeout 10s --namespace "${NAMESPACE}" get -o yaml pod "${POD_NAME}" 1>&2 33 | exit 1 34 | else 35 | now=$(date +%s) 36 | if [[ $now -gt $end ]]; then 37 | log Pod did not terminate before timeout. 38 | kubectl_cmd "${VIA}" --request-timeout 10s --namespace "${NAMESPACE}" get -o yaml pod "${POD_NAME}" 1>&2 39 | exit 1 40 | fi 41 | sleep 1 42 | fi 43 | done 44 | } 45 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/usr/local/bin/promenade-teardown: -------------------------------------------------------------------------------- 1 | {% include "header.sh" with context %} 2 | 3 | {% set hostname = config.get_first('Genesis:hostname', 'KubernetesNode:hostname') -%} 4 | 5 | set -xe 6 | 7 | if [ $(kubectl get nodes | grep '\bReady\b' | wc -l) -lt 2 ]; then 8 | echo Not enough live nodes to proceed with teardown. 1>&2 9 | exit 1 10 | fi 11 | 12 | # Evict pods 13 | kubectl drain --force --timeout 3600s --grace-period 1800 --ignore-daemonsets --delete-local-data {{ hostname }} || true 14 | 15 | LABELS=() 16 | for attempt in $(seq 5); do 17 | LABELS=($(kubectl get node {{ hostname }} -o 'jsonpath={.metadata.labels}' | sed 's/map\[//' | sed 's/\]//' | tr ' ' '\n' | sed 's/:.*/-/g' | grep -v 'kubernetes.io')) 18 | if [[ ! -z "${LABELS[@]}" ]]; then 19 | log "Got labels for host." 20 | break 21 | fi 22 | log "Didn't get labels for host, retrying.." 23 | sleep 5 24 | done 25 | 26 | if [[ -z "${LABELS[@]}" ]]; then 27 | log "Failed to get labels for host. Aborting teardown." 28 | exit 1 29 | fi 30 | 31 | for attempt in $(seq 5); do 32 | if kubectl label node {{ hostname }} "${LABELS[@]}"; then 33 | break 34 | fi 35 | log "Failed to remove labels from node, retrying.." 36 | sleep 5 37 | done 38 | 39 | sleep 30 40 | 41 | # Stop kubelet 42 | systemctl stop kubelet 43 | systemctl disable kubelet 44 | 45 | # Stop remaining containers processes 46 | docker rm -f $(docker ps -aq) || true 47 | -------------------------------------------------------------------------------- /charts/apiserver/templates/bin/_anchor.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -x 17 | 18 | compare_copy_files() { 19 | 20 | {{range .Values.anchor.files_to_copy}} 21 | if [ ! -e /host{{ .dest }} ] || ! cmp -s {{ .source }} /host{{ .dest }}; then 22 | mkdir -p $(dirname /host{{ .dest }}) 23 | cp {{ .source }} /host{{ .dest }} 24 | fi 25 | {{end}} 26 | } 27 | 28 | cleanup() { 29 | 30 | {{range .Values.anchor.files_to_copy}} 31 | rm -f /host{{ .dest }} 32 | {{end}} 33 | } 34 | 35 | while true; do 36 | 37 | if [ -e /tmp/stop ]; then 38 | echo Stopping 39 | cleanup 40 | break 41 | fi 42 | 43 | # Compare and replace files on Genesis host if needed 44 | # Copy files to other master nodes 45 | compare_copy_files 46 | 47 | sleep {{ .Values.anchor.period }} 48 | done 49 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM python:3.6 16 | 17 | VOLUME /etc/promenade 18 | VOLUME /target 19 | 20 | RUN mkdir /opt/promenade 21 | WORKDIR /opt/promenade 22 | 23 | ENV PORT 9000 24 | EXPOSE $PORT 25 | 26 | ENTRYPOINT ["/opt/promenade/entrypoint.sh"] 27 | 28 | RUN set -ex \ 29 | && curl -Lo /usr/local/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 \ 30 | && chmod 555 /usr/local/bin/cfssl \ 31 | && apt-get update -q \ 32 | && apt-get install --no-install-recommends -y \ 33 | libyaml-dev \ 34 | rsync \ 35 | && useradd -u 1000 -g users -d /opt/promenade promenade \ 36 | && rm -rf /var/lib/apt/lists/* 37 | 38 | COPY requirements-frozen.txt /opt/promenade 39 | RUN pip install --no-cache-dir -r requirements-frozen.txt 40 | 41 | COPY . /opt/promenade 42 | RUN pip install -e /opt/promenade 43 | 44 | USER promenade 45 | -------------------------------------------------------------------------------- /charts/controller_manager/templates/bin/_anchor.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -x 17 | 18 | compare_copy_files() { 19 | 20 | {{range .Values.anchor.files_to_copy}} 21 | if [ ! -e /host{{ .dest }} ] || ! cmp -s {{ .source }} /host{{ .dest }}; then 22 | mkdir -p $(dirname /host{{ .dest }}) 23 | cp {{ .source }} /host{{ .dest }} 24 | fi 25 | {{end}} 26 | } 27 | 28 | cleanup() { 29 | 30 | {{range .Values.anchor.files_to_copy}} 31 | rm -f /host{{ .dest }} 32 | {{end}} 33 | } 34 | 35 | while true; do 36 | 37 | if [ -e /tmp/stop ]; then 38 | echo Stopping 39 | cleanup 40 | break 41 | fi 42 | 43 | # Compare and replace files on Genesis host if needed 44 | # Copy files to other master nodes 45 | compare_copy_files 46 | 47 | sleep {{ .Values.anchor.period }} 48 | done 49 | -------------------------------------------------------------------------------- /charts/scheduler/templates/bin/_anchor.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | {{/* 3 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | */}} 17 | 18 | set -x 19 | 20 | compare_copy_files() { 21 | {{- range .Values.anchor.files_to_copy }} 22 | if [ ! -e /host{{ .dest }} ] || ! cmp -s {{ .source }} /host{{ .dest }}; then 23 | mkdir -p $(dirname /host{{ .dest }}) 24 | cp {{ .source }} /host{{ .dest }} 25 | fi 26 | {{- end }} 27 | } 28 | 29 | cleanup() { 30 | {{- range .Values.anchor.files_to_copy }} 31 | rm -f /host{{ .dest }} 32 | {{- end }} 33 | } 34 | 35 | while true; do 36 | if [ -e /tmp/stop ]; then 37 | echo Stopping 38 | cleanup 39 | break 40 | fi 41 | 42 | # Compare and replace files on Genesis host if needed 43 | # Copy files to other master nodes 44 | compare_copy_files 45 | 46 | sleep {{ .Values.anchor.period }} 47 | done 48 | -------------------------------------------------------------------------------- /promenade/design_ref.py: -------------------------------------------------------------------------------- 1 | from . import logging 2 | from oslo_config import cfg 3 | import keystoneauth1.identity.v3 4 | import keystoneauth1.session 5 | import requests 6 | import yaml 7 | 8 | LOG = logging.getLogger(__name__) 9 | 10 | __all__ = ['get_documents'] 11 | 12 | _DECKHAND_PREFIX = 'deckhand+' 13 | 14 | DH_TIMEOUT = 10 * 60 # 10 Minute timeout for fetching from Deckhand. 15 | 16 | 17 | def get_documents(design_ref): 18 | LOG.debug('Fetching design_ref="%s"', design_ref) 19 | if design_ref.startswith(_DECKHAND_PREFIX): 20 | response = _get_from_deckhand(design_ref) 21 | use_dh_engine = False 22 | else: 23 | response = _get_from_basic_web(design_ref) 24 | use_dh_engine = True 25 | LOG.debug('Got response for design_ref="%s"', design_ref) 26 | 27 | response.raise_for_status() 28 | 29 | return list(yaml.safe_load_all(response.text)), use_dh_engine 30 | 31 | 32 | def _get_from_basic_web(design_ref): 33 | return requests.get(design_ref) 34 | 35 | 36 | def _get_from_deckhand(design_ref): 37 | keystone_args = {} 38 | for attr in ('auth_url', 'password', 'project_domain_name', 'project_name', 39 | 'username', 'user_domain_name'): 40 | keystone_args[attr] = cfg.CONF.get('keystone_authtoken', {}).get(attr) 41 | auth = keystoneauth1.identity.v3.Password(**keystone_args) 42 | session = keystoneauth1.session.Session(auth=auth) 43 | 44 | return session.get(design_ref[len(_DECKHAND_PREFIX):], timeout=DH_TIMEOUT) 45 | -------------------------------------------------------------------------------- /promenade/schemas/DeckhandPlaceholders.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | schema: deckhand/DataSchema/v1 3 | metadata: 4 | schema: metadata/Control/v1 5 | name: deckhand/Certificate/v1 6 | labels: 7 | application: deckhand 8 | data: 9 | $schema: http://json-schema.org/schema# 10 | type: string 11 | --- 12 | schema: deckhand/DataSchema/v1 13 | metadata: 14 | schema: metadata/Control/v1 15 | name: deckhand/CertificateKey/v1 16 | labels: 17 | application: deckhand 18 | data: 19 | $schema: http://json-schema.org/schema# 20 | type: string 21 | --- 22 | schema: deckhand/DataSchema/v1 23 | metadata: 24 | schema: metadata/Control/v1 25 | name: deckhand/CertificateAuthority/v1 26 | labels: 27 | application: deckhand 28 | data: 29 | $schema: http://json-schema.org/schema# 30 | type: string 31 | --- 32 | schema: deckhand/DataSchema/v1 33 | metadata: 34 | schema: metadata/Control/v1 35 | name: deckhand/CertificateAuthorityKey/v1 36 | labels: 37 | application: deckhand 38 | data: 39 | $schema: http://json-schema.org/schema# 40 | type: string 41 | --- 42 | schema: deckhand/DataSchema/v1 43 | metadata: 44 | schema: metadata/Control/v1 45 | name: deckhand/PublicKey/v1 46 | labels: 47 | application: deckhand 48 | data: 49 | $schema: http://json-schema.org/schema# 50 | type: string 51 | --- 52 | schema: deckhand/DataSchema/v1 53 | metadata: 54 | schema: metadata/Control/v1 55 | name: deckhand/PrivateKey/v1 56 | labels: 57 | application: deckhand 58 | data: 59 | $schema: http://json-schema.org/schema# 60 | type: string 61 | ... 62 | -------------------------------------------------------------------------------- /charts/haproxy/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2018 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- $envAll := . }} 18 | 19 | --- 20 | apiVersion: v1 21 | kind: ServiceAccount 22 | metadata: 23 | name: haproxy-anchor 24 | {{- range $namespace, $services := $envAll.Values.conf.anchor.services }} 25 | --- 26 | kind: Role 27 | apiVersion: rbac.authorization.k8s.io/v1 28 | metadata: 29 | name: haproxy-anchor 30 | namespace: {{ $namespace }} 31 | rules: 32 | - apiGroups: [""] 33 | resources: 34 | - endpoints 35 | verbs: 36 | - get 37 | --- 38 | kind: RoleBinding 39 | apiVersion: rbac.authorization.k8s.io/v1 40 | metadata: 41 | name: haproxy-anchor 42 | namespace: {{ $namespace }} 43 | subjects: 44 | - kind: ServiceAccount 45 | name: haproxy-anchor 46 | namespace: {{ $envAll.Release.Namespace }} 47 | apiGroup: "" 48 | roleRef: 49 | kind: Role 50 | name: haproxy-anchor 51 | apiGroup: rbac.authorization.k8s.io 52 | {{- end }} 53 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/systemd/system/kubelet.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Worker Process 3 | Requires=network-online.target 4 | After=network-online.target 5 | 6 | [Service] 7 | ExecStart=/opt/kubernetes/bin/kubelet \ 8 | --allow-privileged=true \ 9 | --client-ca-file=/etc/kubernetes/pki/cluster-ca.pem \ 10 | --cluster-dns={{ config['KubernetesNetwork:dns.service_ip'] }} \ 11 | --cluster-domain={{ config['KubernetesNetwork:dns.cluster_domain'] }} \ 12 | --hostname-override={{ config.get_first('Genesis:hostname', 'KubernetesNode:hostname') }} \ 13 | --kubeconfig=/etc/kubernetes/kubeconfig \ 14 | --node-ip={{ config.get_first('Genesis:ip', 'KubernetesNode:ip') }} \ 15 | --pod-manifest-path=/etc/kubernetes/manifests \ 16 | --tls-cert-file=/etc/kubernetes/pki/kubelet.pem \ 17 | --tls-private-key-file=/etc/kubernetes/pki/kubelet-key.pem \ 18 | {%- if config['Genesis:labels.static'] is defined %} 19 | --node-labels={{ config['Genesis:labels.static'] | join(',') }} \ 20 | {%- elif config['KubernetesNode:labels.static'] is defined %} 21 | --node-labels={{ config['KubernetesNode:labels.static'] | join(',') }} \ 22 | {%- endif %} 23 | {%- if config['Kubelet:arguments'] is defined %} 24 | {%- for argument in config['Kubelet:arguments'] %} 25 | {{ argument }} \ 26 | {%- endfor %} 27 | {%- endif %} 28 | --pod-infra-container-image={{ config['Kubelet:images.pause'] }} 29 | 30 | Restart=always 31 | StartLimitInterval=0 32 | RestartSec=10 33 | KillMode=process 34 | 35 | [Install] 36 | WantedBy=multi-user.target 37 | -------------------------------------------------------------------------------- /charts/apiserver/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.service }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: {{ .Values.service.name }} 24 | spec: 25 | ports: 26 | {{ if .Values.network.kubernetes_apiserver.enable_node_port }} 27 | - name: https 28 | nodePort: {{ .Values.network.kubernetes_apiserver.node_port }} 29 | port: {{ .Values.network.kubernetes_apiserver.port }} 30 | protocol: TCP 31 | targetPort: {{ .Values.network.kubernetes_apiserver.port }} 32 | {{ else }} 33 | - name: https 34 | port: {{ .Values.network.kubernetes_apiserver.port }} 35 | protocol: TCP 36 | targetPort: {{ .Values.network.kubernetes_apiserver.port }} 37 | {{ end }} 38 | selector: 39 | {{ .Values.service.name }}-service: enabled 40 | {{- if .Values.service.ip }} 41 | clusterIP: {{ .Values.service.ip }} 42 | {{- end }} 43 | {{- end }} 44 | -------------------------------------------------------------------------------- /charts/etcd/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | 17 | {{- if .Values.manifests.service }} 18 | {{- $envAll := . }} 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: {{ $envAll.Values.service.name }} 24 | spec: 25 | ports: 26 | {{ if .Values.network.service_client.enable_node_port }} 27 | - name: etcd 28 | nodePort: {{ .Values.network.service_client.node_port }} 29 | port: {{ .Values.network.service_client.port }} 30 | protocol: TCP 31 | targetPort: {{ .Values.network.service_client.target_port }} 32 | {{ else }} 33 | - name: etcd 34 | port: {{ .Values.network.service_client.port }} 35 | protocol: TCP 36 | targetPort: {{ .Values.network.service_client.target_port }} 37 | {{ end }} 38 | selector: 39 | {{ $envAll.Values.service.name }}-service: enabled 40 | {{- if $envAll.Values.service.ip }} 41 | clusterIP: {{ $envAll.Values.service.ip }} 42 | {{- end }} 43 | {{- end }} 44 | -------------------------------------------------------------------------------- /docs/source/configuration/kubernetes-node.rst: -------------------------------------------------------------------------------- 1 | Kubernetes Node 2 | =============== 3 | 4 | Configuration for a basic node in the cluster. 5 | 6 | 7 | Sample Document 8 | --------------- 9 | 10 | Here is a sample document: 11 | 12 | .. code-block:: yaml 13 | 14 | schema: promenade/KubernetesNode/v1 15 | metadata: 16 | schema: metadata/Document/v1 17 | name: n1 18 | layeringDefinition: 19 | abstract: false 20 | layer: site 21 | data: 22 | hostname: n1 23 | ip: 192.168.77.11 24 | join_ip: 192.168.77.10 25 | labels: 26 | static: 27 | - node-role.kubernetes.io/master= 28 | dynamic: 29 | - calico-etcd=enabled 30 | - kubernetes-apiserver=enabled 31 | - kubernetes-controller-manager=enabled 32 | - kubernetes-etcd=enabled 33 | - kubernetes-scheduler=enabled 34 | - ucp-control-plane=enabled 35 | 36 | 37 | Host Information 38 | ---------------- 39 | 40 | Essential host-specific information is specified in this document, including 41 | the ``hostname``, ``ip``, and ``join_ip``. 42 | 43 | The ``join_ip`` is used to specify which host should be used when adding a node 44 | to the cluster. 45 | 46 | 47 | Labels 48 | ------ 49 | 50 | Kubernetes labels can be specified under the ``labels`` key in two ways: 51 | 52 | 1. Via the ``static`` key, which is a list of labels to be applied immediately 53 | when the ``kubelet`` process starts. 54 | 2. Via the ``dynamic`` key, which is a list of labels to be applied after the 55 | node is marked as `Ready` by Kubernetes. 56 | -------------------------------------------------------------------------------- /charts/etcd/templates/bin/_pre_stop.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -x 17 | 18 | function cleanup_host { 19 | rm -f $MANIFEST_PATH 20 | rm -rf /etcd-etc/tls/ 21 | {{- if .Values.etcd.cleanup_data }} 22 | rm -rf /etcd-data/* 23 | {{- end }} 24 | } 25 | 26 | # Let the anchor process know it should not try to start the server. 27 | touch /tmp/stopping 28 | 29 | while true; do 30 | if etcdctl member list > /tmp/stop_members; then 31 | if grep $PEER_ENDPOINT /tmp/stop_members; then 32 | # Find and remove the member from the cluster. 33 | MEMBER_ID=$(grep $PEER_ENDPOINT /tmp/stop_members | awk -F ', ' '{ print $1 }') 34 | etcdctl member remove $MEMBER_ID 35 | else 36 | cleanup_host 37 | touch /tmp/stopped 38 | exit 0 39 | fi 40 | else 41 | echo Failed to locate existing cluster 42 | fi 43 | 44 | sleep {{ .Values.anchor.period }} 45 | done 46 | -------------------------------------------------------------------------------- /charts/calico/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: calico-cni-plugin 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: calico-cni-plugin 10 | subjects: 11 | - kind: ServiceAccount 12 | name: calico-cni-plugin 13 | namespace: kube-system 14 | 15 | --- 16 | kind: ClusterRole 17 | apiVersion: rbac.authorization.k8s.io/v1beta1 18 | metadata: 19 | name: calico-cni-plugin 20 | namespace: kube-system 21 | rules: 22 | - apiGroups: [""] 23 | resources: 24 | - pods 25 | - nodes 26 | verbs: 27 | - get 28 | --- 29 | apiVersion: v1 30 | kind: ServiceAccount 31 | metadata: 32 | name: calico-cni-plugin 33 | namespace: kube-system 34 | 35 | --- 36 | apiVersion: rbac.authorization.k8s.io/v1beta1 37 | kind: ClusterRoleBinding 38 | metadata: 39 | name: calico-policy-controller 40 | roleRef: 41 | apiGroup: rbac.authorization.k8s.io 42 | kind: ClusterRole 43 | name: calico-policy-controller 44 | subjects: 45 | - kind: ServiceAccount 46 | name: calico-policy-controller 47 | namespace: kube-system 48 | 49 | --- 50 | kind: ClusterRole 51 | apiVersion: rbac.authorization.k8s.io/v1beta1 52 | metadata: 53 | name: calico-policy-controller 54 | namespace: kube-system 55 | rules: 56 | - apiGroups: 57 | - "" 58 | - extensions 59 | resources: 60 | - pods 61 | - namespaces 62 | - networkpolicies 63 | verbs: 64 | - watch 65 | - list 66 | 67 | --- 68 | apiVersion: v1 69 | kind: ServiceAccount 70 | metadata: 71 | name: calico-policy-controller 72 | namespace: kube-system 73 | -------------------------------------------------------------------------------- /charts/proxy/values.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # limitations under the License. 15 | 16 | manifests: 17 | daemonset_proxy: true 18 | rbac: true 19 | 20 | pod: 21 | lifecycle: 22 | upgrades: 23 | daemonsets: 24 | pod_replacement_strategy: RollingUpdate 25 | proxy: 26 | enabled: true 27 | min_ready_seconds: 0 28 | max_unavailable: 1 29 | termination_grace_period: 30 | proxy: 31 | timeout: 30 32 | resources: 33 | enabled: false 34 | proxy: 35 | requests: 36 | memory: "128Mi" 37 | cpu: "100m" 38 | limits: 39 | memory: "1024Mi" 40 | cpu: "2000m" 41 | 42 | images: 43 | tags: 44 | proxy: gcr.io/google_containers/hyperkube-amd64:v1.10.2 45 | pull_policy: "IfNotPresent" 46 | 47 | command_prefix: 48 | - /proxy 49 | - --proxy-mode=iptables 50 | - --cluster-cidr=10.97.0.0/16 51 | 52 | network: 53 | kubernetes_netloc: 10.96.0.1 54 | 55 | kube_service: 56 | host: 127.0.0.1 57 | port: 6553 58 | -------------------------------------------------------------------------------- /promenade/templates/roles/common/etc/promenade/haproxy/haproxy.cfg: -------------------------------------------------------------------------------- 1 | # Copyright 2018 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | global 16 | maxconn 10240 17 | 18 | defaults 19 | mode tcp 20 | timeout connect 5000ms 21 | timeout client 24h 22 | timeout server 24h 23 | 24 | frontend default-kubernetes-fe 25 | bind *:{{ config['KubernetesNetwork:kubernetes.haproxy_port'] }} 26 | default_backend default-kubernetes-be 27 | 28 | {% set ip = config.get_first('KubernetesNode:join_ip', 'Genesis:ip') -%} 29 | 30 | backend default-kubernetes-be 31 | option tcp-check 32 | {%- set port = config['KubernetesNetwork:kubernetes.apiserver_port'] %} 33 | server s{{ ip }} {{ ip }}:{{ port }} check port {{ port }} 34 | 35 | frontend kube-system-kubernetes-etcd-fe 36 | bind *:{{ config['KubernetesNetwork:etcd.haproxy_port'] }} 37 | default_backend kube-system-kubernetes-etcd-be 38 | 39 | backend kube-system-kubernetes-etcd-be 40 | option tcp-check 41 | {%- set port = config['KubernetesNetwork:etcd.container_port'] %} 42 | server s{{ ip }} {{ ip }}:{{ port }} check port {{ port }} 43 | -------------------------------------------------------------------------------- /charts/coredns/templates/pod-test.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | Copyright 2018 AT&T Intellectual Property. All other rights reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */}} 16 | --- 17 | apiVersion: v1 18 | kind: Pod 19 | metadata: 20 | name: {{ print .Release.Name "-test" }} 21 | annotations: 22 | "helm.sh/hook": test-success 23 | spec: 24 | restartPolicy: Never 25 | containers: 26 | - name: {{ .Release.Name }}-test 27 | image: {{ .Values.images.tags.test }} 28 | imagePullPolicy: {{ .Values.images.pull_policy }} 29 | {{ tuple . .Values.pod.resources.pod_test | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} 30 | command: 31 | - /bin/sh 32 | - -c 33 | - | 34 | SUCCESS=1 35 | {{- range .Values.conf.test.names_to_resolve }} 36 | if dig {{ . }}; then 37 | echo "Successfully resolved {{ . }}" 38 | else 39 | echo "Failed to resolve {{ . }}" 40 | SUCCESS=0 41 | fi 42 | {{- end }} 43 | if [ "$SUCCESS" != "1" ]; then 44 | echo "Test failed to resolve all names." 45 | exit 1 46 | fi 47 | -------------------------------------------------------------------------------- /tools/gate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(realpath "$(dirname "${0}")") 6 | WORKSPACE=$(realpath "${SCRIPT_DIR}/..") 7 | GATE_UTILS=${WORKSPACE}/tools/g2/lib/all.sh 8 | 9 | GATE_COLOR=${GATE_COLOR:-1} 10 | 11 | MANIFEST_ARG=${1:-resiliency} 12 | GATE_MANIFEST=${WORKSPACE}/tools/g2/manifests/${MANIFEST_ARG}.json 13 | 14 | export GATE_COLOR 15 | export GATE_MANIFEST 16 | export GATE_UTILS 17 | export WORKSPACE 18 | 19 | source "${GATE_UTILS}" 20 | 21 | chmod -R 755 "${TEMP_DIR}" 22 | 23 | STAGES_DIR=${WORKSPACE}/tools/g2/stages 24 | 25 | log_temp_dir 26 | echo 27 | 28 | STAGES=$(mktemp) 29 | jq -cr '.stages | .[]' "${GATE_MANIFEST}" > "${STAGES}" 30 | 31 | # NOTE(mark-burnett): It is necessary to use a non-stdin file descriptor for 32 | # the read below, since we will be calling SSH, which will consume the 33 | # remaining data on STDIN. 34 | exec 3< "$STAGES" 35 | while read -u 3 stage; do 36 | NAME=$(echo "${stage}" | jq -r .name) 37 | STAGE_CMD=${STAGES_DIR}/$(echo "${stage}" | jq -r .script) 38 | 39 | log_stage_header "${NAME}" 40 | if echo "${stage}" | jq -r '.arguments | @sh' | xargs "${STAGE_CMD}" ; then 41 | log_stage_success 42 | else 43 | log_color_reset 44 | log_stage_error "${NAME}" "${LOG_FILE}" 45 | if echo "${stage}" | jq -e .on_error > /dev/null; then 46 | log_stage_diagnostic_header 47 | ON_ERROR=${WORKSPACE}/tools/g2/on_error/$(echo "${stage}" | jq -r .on_error) 48 | set +e 49 | $ON_ERROR 50 | fi 51 | log_stage_error "${NAME}" "${TEMP_DIR}" 52 | exit 1 53 | fi 54 | log_stage_footer "${NAME}" 55 | echo 56 | done 57 | 58 | echo 59 | log_huge_success 60 | -------------------------------------------------------------------------------- /promenade/templates/scripts/genesis.sh: -------------------------------------------------------------------------------- 1 | {% include "header.sh" with context %} 2 | 3 | {% include "basic-host-validation.sh" with context %} 4 | 5 | {% include "up.sh" with context %} 6 | 7 | mkdir -p /var/log/armada 8 | touch /var/log/armada/bootstrap-armada.log 9 | chmod 777 /var/log/armada/bootstrap-armada.log 10 | 11 | set +x 12 | log 13 | log === Waiting for Kubernetes API availablity === 14 | set -x 15 | wait_for_kubernetes_api 3600 16 | 17 | 18 | {%- if config['Genesis:labels.dynamic'] is defined %} 19 | set +x 20 | log 21 | log === Registering dynamic labels for node === 22 | set -x 23 | register_labels {{ config['Genesis:hostname'] }} 3600 {{ config['Genesis:labels.dynamic'] | join(' ') }} 24 | {%- endif %} 25 | 26 | set +x 27 | log 28 | log === Deploying bootstrap manifest via Armada === 29 | set -x 30 | 31 | while [[ ! -e /var/log/armada/bootstrap-armada.log ]]; do 32 | sleep 5 33 | done 34 | tail -f /var/log/armada/bootstrap-armada.log & 35 | 36 | set +x 37 | end=$(($(date +%s) + 3600)) 38 | while true; do 39 | if [[ -e /etc/kubernetes/manifests/bootstrap-armada.yaml ]]; then 40 | now=$(date +%s) 41 | if [ $now -gt $end ]; then 42 | log Armada static pod manifest still in place after expected duration 43 | fail 44 | fi 45 | sleep 5 46 | else 47 | log Armada static pod manifest removed 48 | break 49 | fi 50 | done 51 | set -x 52 | 53 | # Terminate background job (tear down exit trap?) 54 | kill %1 55 | 56 | set +x 57 | log 58 | log === Waiting for Node to be Ready === 59 | set -x 60 | wait_for_node_ready {{ config['Genesis:hostname'] }} 3600 61 | 62 | {% include "cleanup.sh" with context %} 63 | 64 | set +x 65 | log 66 | log === Finished genesis process === 67 | -------------------------------------------------------------------------------- /tools/setup_gate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(realpath "$(dirname "${0}")") 6 | WORKSPACE=$(realpath "${SCRIPT_DIR}/..") 7 | GATE_UTILS=${WORKSPACE}/tools/g2/lib/all.sh 8 | 9 | GATE_COLOR=${GATE_COLOR:-1} 10 | 11 | export GATE_COLOR 12 | export GATE_UTILS 13 | export WORKSPACE 14 | 15 | source "${GATE_UTILS}" 16 | 17 | REQUIRE_RELOG=0 18 | 19 | log_stage_header "Installing Packages" 20 | export DEBIAN_FRONTEND=noninteractive 21 | sudo apt-get update -qq 22 | sudo apt-get install -q -y --no-install-recommends \ 23 | curl \ 24 | docker.io \ 25 | fio \ 26 | genisoimage \ 27 | jq \ 28 | libstring-shellquote-perl \ 29 | libvirt-bin \ 30 | qemu-kvm \ 31 | qemu-utils \ 32 | virtinst 33 | 34 | log_stage_header "Joining User Groups" 35 | for grp in docker libvirtd libvirt; do 36 | if ! groups | grep $grp > /dev/null; then 37 | sudo adduser "$(id -un)" $grp || echo "Group $grp not found, not added to user" 38 | REQUIRE_RELOG=1 39 | fi 40 | done 41 | 42 | log_stage_header "Setting Kernel Parameters" 43 | if [ "xY" != "x$(cat /sys/module/kvm_intel/parameters/nested)" ]; then 44 | log_note Enabling nested virtualization. 45 | sudo modprobe -r kvm_intel 46 | sudo modprobe kvm_intel nested=1 47 | echo "options kvm-intel nested=1" | sudo tee /etc/modprobe.d/kvm-intel.conf 48 | fi 49 | 50 | if ! sudo virt-host-validate qemu &> /dev/null; then 51 | log_note Host did not validate virtualization check: 52 | sudo virt-host-validate qemu || true 53 | fi 54 | 55 | if [[ ! -d ${VIRSH_POOL_PATH} ]]; then 56 | sudo mkdir -p "${VIRSH_POOL_PATH}" 57 | fi 58 | 59 | if [[ ${REQUIRE_RELOG} -eq 1 ]]; then 60 | echo 61 | log_note "You must ${C_HEADER}log out${C_CLEAR} and back in before the gate is ready to run." 62 | fi 63 | 64 | log_huge_success 65 | -------------------------------------------------------------------------------- /charts/haproxy/templates/tests/test-haproxy-health.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | */}} 16 | {{/* 17 | Test that HAProxy is running and the config is valid */}} 18 | {{- if .Values.manifests.test_haproxy }} 19 | --- 20 | apiVersion: v1 21 | kind: Pod 22 | metadata: 23 | name: "{{ .Release.Name }}-haproxy-test" 24 | annotations: 25 | "helm.sh/hook": "test-success" 26 | spec: 27 | restartPolicy: Never 28 | containers: 29 | - name: "{{ .Release.Name }}-haproxy-test" 30 | env: 31 | - name: HOST_IP 32 | valueFrom: 33 | fieldRef: 34 | fieldPath: status.hostIP 35 | - name: 'HAPROXY_URL' 36 | value: https://$(HOST_IP):{{ .Values.endpoints.health.port }} 37 | image: {{ .Values.images.tags.test }} 38 | imagePullPolicy: {{ .Values.images.pull_policy }} 39 | {{ tuple . .Values.pod.resources.test | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} 40 | command: 41 | - /bin/bash 42 | - -c 43 | - |- 44 | CODE=$(curl -k -s -o /dev/null -w "%{http_code}" ${HAPROXY_URL}) 45 | if [ $CODE -ne 000 ]; then 46 | exit 0 47 | fi 48 | exit 1 49 | ... 50 | {{- end }} 51 | -------------------------------------------------------------------------------- /tools/g2/manifests/integration.json: -------------------------------------------------------------------------------- 1 | { 2 | "configuration": [ 3 | "examples/complete", 4 | "promenade/schemas" 5 | ], 6 | "stages": [ 7 | { 8 | "name": "Gate Setup", 9 | "script": "gate-setup.sh" 10 | }, 11 | { 12 | "name": "Build Image", 13 | "script": "build-image.sh" 14 | }, 15 | { 16 | "name": "Generate Certificates", 17 | "script": "generate-certificates.sh" 18 | }, 19 | { 20 | "name": "Build Scripts", 21 | "script": "build-scripts.sh" 22 | }, 23 | { 24 | "name": "Create VMs", 25 | "script": "create-vms.sh" 26 | }, 27 | { 28 | "name": "Genesis", 29 | "script": "genesis.sh", 30 | "on_error": "collect_genesis_info.sh" 31 | }, 32 | { 33 | "name": "Load Site Configuration", 34 | "script": "load-site-config.sh", 35 | "arguments": [ 36 | "-v", "n0" 37 | ] 38 | }, 39 | { 40 | "name": "Join Master", 41 | "script": "join-nodes.sh", 42 | "arguments": [ 43 | "-v", "n0", 44 | "-t", 45 | "-d", "1", 46 | "-n", "n1", 47 | "-l", "calico-etcd=enabled", 48 | "-l", "kubernetes-apiserver=enabled", 49 | "-l", "kubernetes-controller-manager=enabled", 50 | "-l", "kubernetes-etcd=enabled", 51 | "-l", "kubernetes-scheduler=enabled", 52 | "-l", "ceph-mds=enabled", 53 | "-l", "ceph-mgr=enabled", 54 | "-l", "ceph-mon=enabled", 55 | "-l", "ceph-osd=enabled", 56 | "-l", "ceph-rgw=enabled", 57 | "-l", "coredns=enabled", 58 | "-l", "ucp-control-plane=enabled", 59 | "-e", "kubernetes n0 genesis n1", 60 | "-e", "calico n0 n0 n1" 61 | ] 62 | } 63 | ], 64 | "vm": { 65 | "memory": 12288, 66 | "names": [ 67 | "n0", 68 | "n1" 69 | ], 70 | "vcpus": 4 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /charts/promenade/templates/tests/test-promenade-api.yaml: -------------------------------------------------------------------------------- 1 | {{/* 2 | # Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | */}} 16 | {{/* 17 | Test that the API is up and the health endpoint returns a 2XX code */}} 18 | {{- if .Values.manifests.test_promenade_api }} 19 | {{- $envAll := . }} 20 | {{- $mounts_promenade_api_init := .Values.pod.mounts.promenade_api.init_container }} 21 | --- 22 | apiVersion: v1 23 | kind: Pod 24 | metadata: 25 | name: "{{ .Release.Name }}-api-test" 26 | annotations: 27 | "helm.sh/hook": "test-success" 28 | spec: 29 | restartPolicy: Never 30 | initContainers: 31 | {{ tuple $envAll "test" $mounts_promenade_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} 32 | containers: 33 | - name: "{{ .Release.Name }}-api-test" 34 | env: 35 | - name: 'PROM_URL' 36 | value: {{ tuple "kubernetesprovisioner" "internal" "api" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | quote }} 37 | image: {{ .Values.images.tags.promenade }} 38 | imagePullPolicy: {{ .Values.images.pull_policy }} 39 | {{ tuple . .Values.pod.resources.test | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} 40 | command: ["/bin/bash", "-c", "curl -v -X GET --fail ${PROM_URL}/api/v1.0/health; exit $?"] 41 | ... 42 | {{- end }} 43 | -------------------------------------------------------------------------------- /tools/simple-deployment.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eux 4 | 5 | IMAGE_PROMENADE=${IMAGE_PROMENADE:-quay.io/attcomdev/promenade:latest} 6 | PROMENADE_DEBUG=${PROMENADE_DEBUG:-0} 7 | 8 | SCRIPT_DIR=$(realpath $(dirname $0)) 9 | CONFIG_SOURCE=$(realpath ${1:-${SCRIPT_DIR}/../examples/basic}) 10 | BUILD_DIR=$(realpath ${2:-${SCRIPT_DIR}/../build}) 11 | REPLACE=${3:-false} 12 | HOSTNAME=$(hostname) 13 | # If not provided, it takes a guess at the host IP Address 14 | HOSTIP=${4:-$(hostname -I | cut -d' ' -f 1)} 15 | # Ceph CIDR provide like 10.0.0.0\\\/24 16 | HOSTCIDR=${5:-"$(hostname -I | cut -d'.' -f 1,2,3).0\/24"} 17 | 18 | 19 | echo === Cleaning up old data === 20 | rm -rf ${BUILD_DIR} 21 | mkdir -p ${BUILD_DIR} 22 | chmod 777 ${BUILD_DIR} 23 | 24 | cp "${CONFIG_SOURCE}"/*.yaml ${BUILD_DIR} 25 | 26 | if [ ${REPLACE} == 'replace' ] 27 | then 28 | sed -i "s/-n0/-${HOSTNAME}/g" "${BUILD_DIR}"/*.yaml 29 | sed -i "s/- n0/- ${HOSTNAME}/g" "${BUILD_DIR}"/*.yaml 30 | sed -i "s/: n0/: ${HOSTNAME}/g" "${BUILD_DIR}"/*.yaml 31 | sed -i "s/:n0/:${HOSTNAME}/g" "${BUILD_DIR}"/*.yaml 32 | sed -i "s/192.168.77.10/${HOSTIP}/g" "${BUILD_DIR}"/*.yaml 33 | sed -i "s/192.168.77.0\/24/${HOSTCIDR}/g" "${BUILD_DIR}"/*.yaml 34 | fi 35 | 36 | echo === Generating updated certificates === 37 | docker run --rm -t \ 38 | -w /target \ 39 | -e PROMENADE_DEBUG=$PROMENADE_DEBUG \ 40 | -v ${BUILD_DIR}:/target \ 41 | ${IMAGE_PROMENADE} \ 42 | promenade \ 43 | generate-certs \ 44 | -o /target \ 45 | $(ls ${BUILD_DIR}) 46 | 47 | echo === Building bootstrap scripts === 48 | docker run --rm -t \ 49 | -w /target \ 50 | -e PROMENADE_DEBUG=$PROMENADE_DEBUG \ 51 | -v ${BUILD_DIR}:/target \ 52 | ${IMAGE_PROMENADE} \ 53 | promenade \ 54 | build-all \ 55 | -o /target \ 56 | --validators \ 57 | $(ls ${BUILD_DIR}) 58 | 59 | echo === Done === 60 | -------------------------------------------------------------------------------- /tools/g2/lib/log.sh: -------------------------------------------------------------------------------- 1 | if [[ -v GATE_COLOR && ${GATE_COLOR} = "1" ]]; then 2 | C_CLEAR="\e[0m" 3 | C_ERROR="\e[38;5;160m" 4 | C_HEADER="\e[38;5;164m" 5 | C_HILIGHT="\e[38;5;27m" 6 | C_MUTE="\e[38;5;238m" 7 | C_SUCCESS="\e[38;5;46m" 8 | C_TEMP="\e[38;5;226m" 9 | else 10 | C_CLEAR="" 11 | C_ERROR="" 12 | C_HEADER="" 13 | C_HILIGHT="" 14 | C_MUTE="" 15 | C_SUCCESS="" 16 | C_TEMP="" 17 | fi 18 | 19 | log() { 20 | d=$(date --utc) 21 | echo -e "${C_MUTE}${d}${C_CLEAR} ${*}" 1>&2 22 | echo -e "${d} ${*}" >> "${LOG_FILE}" 23 | } 24 | 25 | log_warn() { 26 | d=$(date --utc) 27 | echo -e "${C_MUTE}${d}${C_CLEAR} ${C_HILIGHT}WARN${C_CLEAR} ${*}" 1>&2 28 | echo -e "${d} ${*}" >> "${LOG_FILE}" 29 | } 30 | 31 | log_stage_diagnostic_header() { 32 | echo -e " ${C_ERROR}= Diagnostic Report =${C_CLEAR}" 33 | } 34 | 35 | log_color_reset() { 36 | echo -e "${C_CLEAR}" 37 | } 38 | 39 | log_huge_success() { 40 | echo -e "${C_SUCCESS}=== HUGE SUCCESS ===${C_CLEAR}" 41 | } 42 | 43 | log_note() { 44 | echo -e "${C_HILIGHT}NOTE:${C_CLEAR} ${*}" 45 | } 46 | 47 | log_stage_error() { 48 | NAME=${1} 49 | echo -e " ${C_ERROR}== Error in stage ${C_HILIGHT}${NAME}${C_ERROR} ( ${C_TEMP}${LOG_FILE}${C_ERROR} ) ==${C_CLEAR}" 50 | } 51 | 52 | log_stage_footer() { 53 | NAME=${1} 54 | echo -e "${C_HEADER}=== Finished stage ${C_HILIGHT}${NAME}${C_HEADER} ===${C_CLEAR}" 55 | } 56 | 57 | log_stage_header() { 58 | NAME=${1} 59 | echo -e "${C_HEADER}=== Executing stage ${C_HILIGHT}${NAME}${C_HEADER} ===${C_CLEAR}" 60 | } 61 | 62 | log_stage_success() { 63 | echo -e " ${C_SUCCESS}== Stage Success ==${C_CLEAR}" 64 | } 65 | 66 | log_temp_dir() { 67 | echo -e "Working in ${C_TEMP}${TEMP_DIR}${C_CLEAR}" 68 | } 69 | 70 | if [[ -v GATE_DEBUG && ${GATE_DEBUG} = "1" ]]; then 71 | export LOG_FILE=/dev/stderr 72 | elif [[ -v TEMP_DIR ]]; then 73 | export LOG_FILE=${TEMP_DIR}/gate.log 74 | else 75 | export LOG_FILE=/dev/null 76 | fi 77 | -------------------------------------------------------------------------------- /tools/helm_tk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2017 AT&T Intellectual Property. All other rights reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | 17 | set -eux 18 | 19 | HELM=${1} 20 | HELM_PIDFILE=${2} 21 | SERVE_DIR=$(mktemp -d) 22 | 23 | ${HELM} init --client-only 24 | 25 | if [[ -s ${HELM_PIDFILE} ]]; then 26 | HELM_PID=$(cat "${HELM_PIDFILE}") 27 | if ps "${HELM_PID}"; then 28 | kill "${HELM_PID}" 29 | sleep 0.5 30 | if ps "${HELM_PID}"; then 31 | echo Failed to terminate Helm, PID = "${HELM_PID}" 32 | exit 1 33 | fi 34 | fi 35 | fi 36 | 37 | ${HELM} serve & > /dev/null 38 | HELM_PID=${!} 39 | echo Started Helm, PID = "${HELM_PID}" 40 | echo "${HELM_PID}" > "${HELM_PIDFILE}" 41 | 42 | set +x 43 | if [[ -z $(curl -s 127.0.0.1:8879 | grep 'Helm Repository') ]]; then 44 | while [[ -z $(curl -s 127.0.0.1:8879 | grep 'Helm Repository') ]]; do 45 | sleep 1 46 | echo "Waiting for Helm Repository" 47 | done 48 | else 49 | echo "Helm serve already running" 50 | fi 51 | set -x 52 | 53 | if ${HELM} repo list | grep -q "^stable" ; then 54 | ${HELM} repo remove stable 55 | fi 56 | 57 | ${HELM} repo add local http://localhost:8879/charts 58 | 59 | { 60 | cd "${SERVE_DIR}" 61 | git clone --depth 1 https://git.openstack.org/openstack/openstack-helm-infra.git || true 62 | cd openstack-helm-infra 63 | 64 | make helm-toolkit 65 | } 66 | 67 | rm -rf "${SERVE_DIR}" 68 | -------------------------------------------------------------------------------- /tools/gate/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | GATE_DIR=$(realpath $(dirname $0)) 6 | pushd $GATE_DIR 7 | 8 | ENV_PATH=$GATE_DIR/config-env 9 | IMAGE_PROMENADE=${IMAGE_PROMENADE:-$1} 10 | 11 | if [ ! -s $ENV_PATH ]; then 12 | echo Environment variables for config substitution in $ENV_PATH are required. 13 | exit 1 14 | fi 15 | 16 | if [ "x$IMAGE_PROMENADE" = "x" ]; then 17 | echo IMAGE_PROMENADE environment variable must be supplied. 18 | exit 1 19 | fi 20 | 21 | echo === Building assets for testing === 22 | echo Usinag image ${IMAGE_PROMENADE}. 23 | 24 | echo === Cleaning up old data === 25 | rm -f config/* 26 | rm -f promenade-bundle/* 27 | mkdir -p config 28 | chmod 777 config 29 | mkdir -p promenade-bundle 30 | chmod 777 promenade-bundle 31 | 32 | echo === Validating test environment === 33 | env -i - $(cat default-config-env) env $(cat $ENV_PATH) $GATE_DIR/util/validate-test-env.sh 34 | 35 | echo === Substituting variables into configuration === 36 | for template in config-templates/*; do 37 | OUTPUT_PATH=config/$(basename $template) 38 | env -i - $(cat default-config-env) env IMAGE_PROMENADE=$IMAGE_PROMENADE $(cat $ENV_PATH) envsubst < $template > $OUTPUT_PATH 39 | 40 | cat $OUTPUT_PATH 41 | echo 42 | echo 43 | done 44 | 45 | echo === Generating certificates === 46 | docker run --rm -t \ 47 | -w /target \ 48 | -v $GATE_DIR:/target \ 49 | ${IMAGE_PROMENADE} \ 50 | promenade \ 51 | generate-certs \ 52 | -o config \ 53 | config/*.yaml 54 | 55 | echo === Building genesis and join scripts 56 | docker run --rm -t \ 57 | -w /target \ 58 | -v $GATE_DIR:/target \ 59 | ${IMAGE_PROMENADE} \ 60 | promenade \ 61 | build-all \ 62 | --validators \ 63 | --leave-kubectl \ 64 | -o promenade-bundle \ 65 | config/*.yaml 66 | 67 | echo === Bundling assets for delivery === 68 | cp $GATE_DIR/final-validation.sh promenade-bundle 69 | tar czf promenade-bundle.tgz promenade-bundle/* 70 | 71 | echo === Done === 72 | -------------------------------------------------------------------------------- /charts/calico/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # Calico Version v2.2.1 3 | # http://docs.projectcalico.org/v2.2/releases#v2.2.1 4 | # This manifest includes the following component versions: 5 | # calico/node:v1.2.1 6 | # calico/cni:v1.8.3 7 | # calico/kube-policy-controller:v0.6.0 8 | 9 | {{- if eq .Values.calico.ipip "off" }} 10 | {{- $_ := set .Values "__calicoMTU" .Values.calico.mtu -}} 11 | {{- else }} 12 | {{- $_ := set .Values "__calicoMTU" (sub .Values.calico.mtu 20) -}} 13 | {{- end }} 14 | 15 | # This ConfigMap is used to configure a self-hosted Calico installation. 16 | kind: ConfigMap 17 | apiVersion: v1 18 | metadata: 19 | name: calico-config 20 | namespace: kube-system 21 | data: 22 | # The location of your etcd cluster. This uses the Service clusterIP 23 | # defined below. 24 | etcd_endpoints: https://{{ .Values.etcd.service.ip }}:{{ .Values.etcd.service.port }} 25 | 26 | # Configure the Calico backend to use. 27 | calico_backend: "bird" 28 | 29 | # The CNI network configuration to install on each node. 30 | cni_network_config: |- 31 | { 32 | "name": "k8s-pod-network", 33 | "cniVersion": "0.1.0", 34 | "type": "calico", 35 | "etcd_endpoints": "__ETCD_ENDPOINTS__", 36 | "etcd_key_file": "__ETCD_KEY_FILE__", 37 | "etcd_cert_file": "__ETCD_CERT_FILE__", 38 | "etcd_ca_cert_file": "__ETCD_CA_CERT_FILE__", 39 | "log_level": "info", 40 | "mtu": {{ .Values.__calicoMTU }}, 41 | "ipam": { 42 | "type": "calico-ipam" 43 | }, 44 | "policy": { 45 | "type": "k8s", 46 | "k8s_api_root": "https://__KUBERNETES_SERVICE_HOST__:__KUBERNETES_SERVICE_PORT__", 47 | "k8s_auth_token": "__SERVICEACCOUNT_TOKEN__" 48 | }, 49 | "kubernetes": { 50 | "kubeconfig": "/etc/cni/net.d/__KUBECONFIG_FILENAME__" 51 | } 52 | } 53 | 54 | # If you're using TLS enabled etcd uncomment the following. 55 | # You must also populate the Secret below with these files. 56 | etcd_ca: "/calico-secrets/etcd-ca" 57 | etcd_cert: "/calico-secrets/etcd-cert" 58 | etcd_key: "/calico-secrets/etcd-key" 59 | -------------------------------------------------------------------------------- /charts/scheduler/values.yaml: -------------------------------------------------------------------------------- 1 | release_group: null 2 | 3 | anchor: 4 | dns_policy: Default 5 | kubelet: 6 | manifest_path: /etc/kubernetes/manifests 7 | period: 15 8 | termination_grace_period: 3600 9 | files_to_copy: 10 | - source: /configmap/cluster-ca.pem 11 | dest: /etc/kubernetes/scheduler/cluster-ca.pem 12 | - source: /configmap/scheduler.pem 13 | dest: /etc/kubernetes/scheduler/scheduler.pem 14 | - source: /configmap/kubeconfig.yaml 15 | dest: /etc/kubernetes/scheduler/kubeconfig.yaml 16 | - source: /secret/scheduler-key.pem 17 | dest: /etc/kubernetes/scheduler/scheduler-key.pem 18 | - source: /configmap/kubernetes-scheduler.yaml 19 | dest: /etc/kubernetes/manifests/kubernetes-scheduler.yaml 20 | 21 | labels: 22 | scheduler: 23 | node_selector_key: kubernetes-scheduler 24 | node_selector_value: enabled 25 | 26 | pod: 27 | lifecycle: 28 | upgrades: 29 | daemonsets: 30 | pod_replacement_strategy: RollingUpdate 31 | scheduler: 32 | enabled: true 33 | min_ready_seconds: 0 34 | max_unavailable: 1 35 | termination_grace_period: 36 | scheduler: 37 | timeout: 3600 38 | resources: 39 | enabled: false 40 | anchor_daemonset: 41 | requests: 42 | memory: "128Mi" 43 | cpu: "100m" 44 | limits: 45 | memory: "1024Mi" 46 | cpu: "2000m" 47 | scheduler_pod: 48 | requests: 49 | memory: "128Mi" 50 | cpu: "100m" 51 | limits: 52 | memory: "1024Mi" 53 | cpu: "2000m" 54 | 55 | scheduler: 56 | host_etc_path: /etc/kubernetes/scheduler 57 | 58 | secrets: 59 | tls: 60 | ca: placeholder 61 | cert: placeholder 62 | key: placeholder 63 | 64 | images: 65 | tags: 66 | anchor: gcr.io/google_containers/hyperkube-amd64:v1.10.2 67 | scheduler: gcr.io/google_containers/hyperkube-amd64:v1.10.2 68 | pull_policy: "IfNotPresent" 69 | 70 | network: 71 | kubernetes_netloc: 10.96.0.1 72 | kubernetes_scheduler: 73 | port: 10251 74 | 75 | service: 76 | name: kubernetes-scheduler 77 | 78 | command_prefix: 79 | - /scheduler 80 | - --v=5 81 | -------------------------------------------------------------------------------- /tools/g2/lib/promenade.sh: -------------------------------------------------------------------------------- 1 | promenade_teardown_node() { 2 | TARGET=${1} 3 | VIA=${2} 4 | 5 | ssh_cmd "${TARGET}" /usr/local/bin/promenade-teardown 6 | kubectl_cmd "${VIA}" delete node "${TARGET}" 7 | } 8 | 9 | promenade_render_curl_url() { 10 | NAME=${1} 11 | USE_DECKHAND=${2} 12 | DECKHAND_REVISION=${3} 13 | shift 3 14 | LABELS=(${@}) 15 | 16 | LABEL_PARAMS= 17 | for label in "${LABELS[@]}"; do 18 | LABEL_PARAMS+="&labels.dynamic=${label}" 19 | done 20 | 21 | BASE_URL="${PROMENADE_BASE_URL}/api/v1.0/join-scripts" 22 | if [[ ${USE_DECKHAND} == 1 ]]; then 23 | DESIGN_REF="design_ref=deckhand%2Bhttp://deckhand-int.ucp.svc.cluster.local:9000/api/v1.0/revisions/${DECKHAND_REVISION}/rendered-documents" 24 | else 25 | DESIGN_REF="design_ref=${NGINX_URL}/promenade.yaml" 26 | fi 27 | HOST_PARAMS="hostname=${NAME}&ip=$(config_vm_ip "${NAME}")" 28 | 29 | echo "${BASE_URL}?${DESIGN_REF}&${HOST_PARAMS}&leave_kubectl=true${LABEL_PARAMS}" 30 | } 31 | 32 | promenade_render_validate_url() { 33 | echo "${PROMENADE_BASE_URL}/api/v1.0/validatedesign" 34 | } 35 | 36 | promenade_render_validate_body() { 37 | USE_DECKHAND=${1} 38 | DECKHAND_REVISION=${2} 39 | 40 | if [[ ${USE_DECKHAND} == 1 ]]; then 41 | JSON="{\"rel\":\"design\",\"href\":\"deckhand+http://deckhand-int.ucp.svc.cluster.local:9000/api/v1.0/revisions/${DECKHAND_REVISION}/rendered-documents\",\"type\":\"application/x-yaml\"}" 42 | else 43 | JSON="{\"rel\":\"design\",\"href\":\"${NGINX_URL}/promenade.yaml\",\"type\":\"application/x-yaml\"}" 44 | fi 45 | 46 | echo "${JSON}" 47 | } 48 | 49 | promenade_health_check() { 50 | VIA=${1} 51 | log "Checking Promenade API health" 52 | MAX_HEALTH_ATTEMPTS=6 53 | for attempt in $(seq ${MAX_HEALTH_ATTEMPTS}); do 54 | if ssh_cmd "${VIA}" curl -v --fail "${PROMENADE_BASE_URL}/api/v1.0/health"; then 55 | log "Promenade API healthy" 56 | break 57 | elif [[ $attempt == "${MAX_HEALTH_ATTEMPTS}" ]]; then 58 | log "Promenade health check failed, max retries (${MAX_HEALTH_ATTEMPTS}) exceeded." 59 | exit 1 60 | fi 61 | sleep 10 62 | done 63 | } 64 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2018 AT&T Intellectual Property. All other rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | HELM ?= helm 16 | HELM_PIDFILE ?= $(abspath ./.helm-pid) 17 | 18 | CHARTS := $(patsubst charts/%/.,%,$(wildcard charts/*/.)) 19 | 20 | .PHONY: all 21 | all: charts lint 22 | 23 | .PHONY: tests 24 | tests: gate-lint 25 | tox 26 | 27 | chartbanner: 28 | @echo Building charts: $(CHARTS) 29 | 30 | .PHONY: charts 31 | charts: $(CHARTS) 32 | @echo Done building charts. 33 | 34 | .PHONY: helm-init 35 | helm-init: $(addprefix helm-init-,$(CHARTS)) 36 | 37 | .PHONY: helm-init-% 38 | helm-init-%: helm-serve 39 | @echo Initializing chart $* 40 | cd charts;if [ -s $*/requirements.yaml ]; then echo "Initializing $*";$(HELM) dep up $*; fi 41 | 42 | .PHONY: lint 43 | lint: helm-lint gate-lint 44 | 45 | .PHONY: gate-lint 46 | gate-lint: gate-lint-deps 47 | tox -e gate-lint 48 | 49 | .PHONY: gate-lint-deps 50 | gate-lint-deps: 51 | sudo apt-get install -y --no-install-recommends shellcheck 52 | 53 | .PHONY: helm-lint 54 | helm-lint: $(addprefix helm-lint-,$(CHARTS)) 55 | 56 | .PHONY: helm-lint-% 57 | helm-lint-%: helm-init-% 58 | @echo Linting chart $* 59 | cd charts;$(HELM) lint $* 60 | 61 | .PHONY: dry-run 62 | dry-run: $(addprefix dry-run-,$(CHARTS)) 63 | 64 | .PHONY: dry-run-% 65 | dry-run-%: helm-lint-% 66 | echo Running Dry-Run on chart $* 67 | cd charts;$(HELM) template --set pod.resources.enabled=true $* 68 | 69 | .PHONY: $(CHARTS) 70 | $(CHARTS): $(addprefix dry-run-,$(CHARTS)) chartbanner 71 | $(HELM) package -d charts charts/$@ 72 | 73 | .PHONY: helm-serve 74 | helm-serve: 75 | ./tools/helm_tk.sh $(HELM) $(HELM_PIDFILE) 76 | 77 | .PHONY: clean 78 | clean: 79 | rm -f charts/*.tgz 80 | rm -f charts/*/requirements.lock 81 | rm -rf charts/*/charts 82 | -------------------------------------------------------------------------------- /promenade/logging.py: -------------------------------------------------------------------------------- 1 | import copy 2 | import logging 3 | import logging.config 4 | 5 | __all__ = ['getLogger', 'setup'] 6 | 7 | LOG_FORMAT = '%(asctime)s %(levelname)-8s %(request_id)s %(external_id)s %(user)s %(name)s:%(funcName)s [%(lineno)3d] %(message)s' # noqa 8 | 9 | BLANK_CONTEXT_VALUES = [ 10 | 'external_id', 11 | 'request_id', 12 | 'user', 13 | ] 14 | 15 | DEFAULT_CONFIG = { 16 | 'version': 1, 17 | 'disable_existing_loggers': True, 18 | 'filters': { 19 | 'blank_context': { 20 | '()': 'promenade.logging.BlankContextFilter', 21 | }, 22 | }, 23 | 'formatters': { 24 | 'standard': { 25 | 'format': LOG_FORMAT, 26 | }, 27 | }, 28 | 'handlers': { 29 | 'default': { 30 | 'level': 'DEBUG', 31 | 'formatter': 'standard', 32 | 'class': 'logging.StreamHandler', 33 | 'filters': ['blank_context'], 34 | }, 35 | }, 36 | 'loggers': { 37 | 'deckhand': { 38 | 'handlers': ['default'], 39 | 'level': 'INFO', 40 | 'propagate': False, 41 | }, 42 | 'promenade': { 43 | 'handlers': ['default'], 44 | 'level': 'INFO', 45 | 'propagate': False, 46 | }, 47 | }, 48 | 'root': { 49 | 'handlers': ['default'], 50 | 'level': 'INFO', 51 | }, 52 | } 53 | 54 | 55 | class BlankContextFilter(logging.Filter): 56 | def filter(self, record): 57 | for key in BLANK_CONTEXT_VALUES: 58 | if getattr(record, key, None) is None: 59 | setattr(record, key, '-') 60 | return True 61 | 62 | 63 | class Adapter(logging.LoggerAdapter): 64 | def process(self, msg, kwargs): 65 | extra = kwargs.get('extra', {}) 66 | 67 | ctx = kwargs.pop('ctx', None) 68 | if ctx is not None: 69 | extra.update(ctx.to_log_context()) 70 | 71 | kwargs['extra'] = extra 72 | 73 | return msg, kwargs 74 | 75 | 76 | def setup(*, verbose): 77 | log_config = copy.deepcopy(DEFAULT_CONFIG) 78 | if verbose: 79 | log_config['loggers']['promenade']['level'] = 'DEBUG' 80 | 81 | logging.config.dictConfig(log_config) 82 | 83 | 84 | def getLogger(*args, **kwargs): 85 | return Adapter(logging.getLogger(*args, **kwargs), {}) 86 | -------------------------------------------------------------------------------- /tools/g2/manifests/conformance.json: -------------------------------------------------------------------------------- 1 | { 2 | "configuration": [ 3 | "examples/basic", 4 | "promenade/schemas" 5 | ], 6 | "stages": [ 7 | { 8 | "name": "Gate Setup", 9 | "script": "gate-setup.sh" 10 | }, 11 | { 12 | "name": "Build Image", 13 | "script": "build-image.sh" 14 | }, 15 | { 16 | "name": "Generate Certificates", 17 | "script": "generate-certificates.sh" 18 | }, 19 | { 20 | "name": "Build Scripts", 21 | "script": "build-scripts.sh" 22 | }, 23 | { 24 | "name": "Create VMs", 25 | "script": "create-vms.sh" 26 | }, 27 | { 28 | "name": "Genesis", 29 | "script": "genesis.sh" 30 | }, 31 | { 32 | "name": "Join Masters", 33 | "script": "join-nodes.sh", 34 | "arguments": [ 35 | "-v", "n0", 36 | "-n", "n1", 37 | "-n", "n2", 38 | "-n", "n3", 39 | "-l", "calico-etcd=enabled", 40 | "-l", "coredns=enabled", 41 | "-l", "kubernetes-apiserver=enabled", 42 | "-l", "kubernetes-controller-manager=enabled", 43 | "-l", "kubernetes-etcd=enabled", 44 | "-l", "kubernetes-scheduler=enabled", 45 | "-l", "ucp-control-plane=enabled", 46 | "-e", "kubernetes n0 genesis n1 n2 n3", 47 | "-e", "calico n0 n0 n1 n2 n3" 48 | ] 49 | }, 50 | { 51 | "name": "Teardown Genesis", 52 | "script": "teardown-nodes.sh", 53 | "arguments": [ 54 | "-v", "n1", 55 | "-n", "n0", 56 | "-r", 57 | "-e", "kubernetes n1 n1 n2 n3", 58 | "-e", "calico n1 n1 n2 n3" 59 | ] 60 | }, 61 | { 62 | "name": "Join n0 as Worker", 63 | "script": "join-nodes.sh", 64 | "arguments": [ 65 | "-v", "n1", 66 | "-n", "n0", 67 | "-l", "ucp-control-plane=enabled", 68 | "-e", "kubernetes n1 n1 n2 n3", 69 | "-e", "calico n1 n1 n2 n3" 70 | ] 71 | }, 72 | { 73 | "name": "Check Conformance", 74 | "script": "conformance.sh", 75 | "publish": { 76 | "junit": [ 77 | "conformance/plugins/e2e/results/junit_01.xml" 78 | ] 79 | } 80 | } 81 | ], 82 | "vm": { 83 | "memory": 2048, 84 | "names": [ 85 | "n0", 86 | "n1", 87 | "n2", 88 | "n3" 89 | ], 90 | "vcpus": 2 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /promenade/templates/roles/genesis/etc/kubernetes/manifests/kubernetes-apiserver.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: kubernetes-apiserver 6 | namespace: kube-system 7 | labels: 8 | kubernetes-apiserver-service: enabled 9 | annotations: 10 | scheduler.alpha.kubernetes.io/critical-pod: '' 11 | spec: 12 | hostNetwork: true 13 | containers: 14 | - name: kube-apiserver 15 | image: {{ config['Genesis:images.kubernetes.apiserver'] }} 16 | command: 17 | {%- for argument in config.bootstrap_apiserver_prefix() %} 18 | - "{{ argument }}" 19 | {%- endfor %} 20 | - --advertise-address={{ config['Genesis:ip'] }} 21 | - --authorization-mode=Node,RBAC 22 | - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds 23 | - --anonymous-auth=false 24 | - --client-ca-file=/etc/kubernetes/apiserver/pki/cluster-ca.pem 25 | - --kubelet-certificate-authority=/etc/kubernetes/apiserver/pki/cluster-ca.pem 26 | - --kubelet-client-certificate=/etc/kubernetes/apiserver/pki/apiserver.pem 27 | - --kubelet-client-key=/etc/kubernetes/apiserver/pki/apiserver-key.pem 28 | - --insecure-port=0 29 | - --bind-address=0.0.0.0 30 | - --secure-port=6443 31 | - --runtime-config=batch/v2alpha1=true 32 | - --allow-privileged=true 33 | - --etcd-servers=https://localhost:2379 34 | - --etcd-cafile=/etc/kubernetes/apiserver/pki/etcd-client-ca.pem 35 | - --etcd-certfile=/etc/kubernetes/apiserver/pki/etcd-client.pem 36 | - --etcd-keyfile=/etc/kubernetes/apiserver/pki/etcd-client-key.pem 37 | - --service-cluster-ip-range={{ config['KubernetesNetwork:kubernetes.service_cidr'] }} 38 | - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname 39 | - --service-account-key-file=/etc/kubernetes/apiserver/pki/service-account.pub 40 | - --tls-cert-file=/etc/kubernetes/apiserver/pki/apiserver.pem 41 | - --tls-private-key-file=/etc/kubernetes/apiserver/pki/apiserver-key.pem 42 | volumeMounts: 43 | - name: config 44 | mountPath: /etc/kubernetes/apiserver 45 | readOnly: true 46 | volumes: 47 | - name: config 48 | hostPath: 49 | path: /etc/genesis/apiserver 50 | -------------------------------------------------------------------------------- /requirements-frozen.txt: -------------------------------------------------------------------------------- 1 | Babel==2.5.3 2 | Jinja2==2.9.6 3 | Mako==1.0.7 4 | MarkupSafe==1.0 5 | Paste==2.0.3 6 | PasteDeploy==1.5.2 7 | PyYAML==3.12 8 | Routes==2.4.1 9 | SQLAlchemy==1.2.6 10 | Tempita==0.5.2 11 | WebOb==1.8.0 12 | Werkzeug==0.14.1 13 | alembic==0.9.9 14 | amqp==2.2.2 15 | cachetools==2.0.1 16 | certifi==2018.1.18 17 | chardet==3.0.4 18 | click==6.7 19 | cliff==2.11.0 20 | cmd2==0.8.2 21 | contextlib2==0.5.5 22 | debtcollector==1.19.0 23 | decorator==4.2.1 24 | dogpile.cache==0.6.5 25 | enum-compat==0.0.2 26 | eventlet==0.20.0 27 | extras==1.0.0 28 | falcon==1.2.0 29 | fasteners==0.14.1 30 | fixtures==3.0.0 31 | flake8==2.5.5 32 | futurist==1.6.0 33 | git+https://github.com/att-comdev/deckhand.git@c962eeb975af5ecf9793f794d536538d210b7735#egg=deckhand 34 | google-auth==1.4.1 35 | greenlet==0.4.13 36 | hacking==1.0.0 37 | idna==2.6 38 | ipaddress==1.0.19 39 | iso8601==0.1.12 40 | jsonpath-ng==1.4.3 41 | jsonschema==2.6.0 42 | keystoneauth1==3.2.0 43 | keystonemiddleware==4.17.0 44 | kombu==4.1.0 45 | kubernetes==3.0.0 46 | linecache2==1.0.0 47 | mccabe==0.2.1 48 | monotonic==1.4 49 | msgpack==0.5.6 50 | netaddr==0.7.19 51 | netifaces==0.10.6 52 | networkx==2.1 53 | oslo.cache==1.30.0 54 | oslo.concurrency==3.26.0 55 | oslo.config==6.0.1 56 | oslo.context==2.19.2 57 | oslo.db==4.35.0 58 | oslo.i18n==3.20.0 59 | oslo.log==3.37.0 60 | oslo.messaging==6.0.0 61 | oslo.middleware==3.35.0 62 | oslo.policy==1.22.1 63 | oslo.serialization==2.25.0 64 | oslo.service==1.30.0 65 | oslo.utils==3.36.0 66 | pbr==3.0.1 67 | pep8==1.5.7 68 | ply==3.11 69 | positional==1.2.1 70 | prettytable==0.7.2 71 | psycopg2==2.7.4 72 | pyasn1-modules==0.2.1 73 | pyasn1==0.4.2 74 | pycadf==2.7.0 75 | pyflakes==0.8.1 76 | pyinotify==0.9.6 77 | pyparsing==2.2.0 78 | pyperclip==1.6.0 79 | python-barbicanclient==4.6.0 80 | python-dateutil==2.7.2 81 | python-editor==1.0.3 82 | python-keystoneclient==3.15.0 83 | python-memcached==1.59 84 | python-mimeparse==1.6.0 85 | pytz==2018.3 86 | repoze.lru==0.7 87 | requests==2.18.4 88 | rfc3986==1.1.0 89 | rsa==3.4.2 90 | six==1.11.0 91 | sqlalchemy-migrate==0.11.0 92 | sqlparse==0.2.4 93 | statsd==3.2.2 94 | stevedore==1.28.0 95 | tenacity==4.9.0 96 | testresources==2.0.1 97 | testscenarios==0.5.0 98 | testtools==2.3.0 99 | traceback2==1.4.0 100 | uWSGI==2.0.15 101 | unittest2==1.1.0 102 | urllib3==1.22 103 | vine==1.1.4 104 | websocket-client==0.40.0 105 | wrapt==1.10.11 106 | --------------------------------------------------------------------------------