diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index a5fca06c..75c78ba0 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - + - uses: azure/setup-kubectl@v3 id: install diff --git a/compiled/dev-sockshop/manifests/carts-bundle.yml b/compiled/dev-sockshop/manifests/carts-bundle.yml index 7c5d3531..0403cc92 100644 --- a/compiled/dev-sockshop/manifests/carts-bundle.yml +++ b/compiled/dev-sockshop/manifests/carts-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: carts app.kubernetes.io/part-of: sock-shop name: carts name: carts diff --git a/compiled/dev-sockshop/manifests/carts-db-bundle.yml b/compiled/dev-sockshop/manifests/carts-db-bundle.yml index c7fc57ba..be5ebe50 100644 --- a/compiled/dev-sockshop/manifests/carts-db-bundle.yml +++ b/compiled/dev-sockshop/manifests/carts-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: carts-db app.kubernetes.io/part-of: sock-shop name: carts-db name: carts-db diff --git a/compiled/dev-sockshop/manifests/carts-db-service.yml b/compiled/dev-sockshop/manifests/carts-db-service.yml index cdb7d7ee..30161c96 100644 --- a/compiled/dev-sockshop/manifests/carts-db-service.yml +++ b/compiled/dev-sockshop/manifests/carts-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: carts-db app.kubernetes.io/part-of: sock-shop name: carts-db name: carts-db diff --git a/compiled/dev-sockshop/manifests/carts-service.yml b/compiled/dev-sockshop/manifests/carts-service.yml index c50a3dee..663ef859 100644 --- a/compiled/dev-sockshop/manifests/carts-service.yml +++ b/compiled/dev-sockshop/manifests/carts-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: carts app.kubernetes.io/part-of: sock-shop name: carts name: carts diff --git a/compiled/dev-sockshop/manifests/catalogue-bundle.yml b/compiled/dev-sockshop/manifests/catalogue-bundle.yml index f40a274d..6a53dfbe 100644 --- a/compiled/dev-sockshop/manifests/catalogue-bundle.yml +++ b/compiled/dev-sockshop/manifests/catalogue-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: catalogue app.kubernetes.io/part-of: sock-shop name: catalogue name: catalogue diff --git a/compiled/dev-sockshop/manifests/catalogue-db-bundle.yml b/compiled/dev-sockshop/manifests/catalogue-db-bundle.yml index 4299db69..9d9d5dcd 100644 --- a/compiled/dev-sockshop/manifests/catalogue-db-bundle.yml +++ b/compiled/dev-sockshop/manifests/catalogue-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: catalogue-db app.kubernetes.io/part-of: sock-shop name: catalogue-db name: catalogue-db diff --git a/compiled/dev-sockshop/manifests/catalogue-db-service.yml b/compiled/dev-sockshop/manifests/catalogue-db-service.yml index bee96f3a..247c1fbf 100644 --- a/compiled/dev-sockshop/manifests/catalogue-db-service.yml +++ b/compiled/dev-sockshop/manifests/catalogue-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: catalogue-db app.kubernetes.io/part-of: sock-shop name: catalogue-db name: catalogue-db diff --git a/compiled/dev-sockshop/manifests/catalogue-service.yml b/compiled/dev-sockshop/manifests/catalogue-service.yml index a1b1e8ed..074632c4 100644 --- a/compiled/dev-sockshop/manifests/catalogue-service.yml +++ b/compiled/dev-sockshop/manifests/catalogue-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: catalogue app.kubernetes.io/part-of: sock-shop name: catalogue name: catalogue diff --git a/compiled/dev-sockshop/manifests/frontend-bundle.yml b/compiled/dev-sockshop/manifests/frontend-bundle.yml index d9b42e70..eca25f95 100644 --- a/compiled/dev-sockshop/manifests/frontend-bundle.yml +++ b/compiled/dev-sockshop/manifests/frontend-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: frontend app.kubernetes.io/part-of: sock-shop name: frontend name: frontend diff --git a/compiled/dev-sockshop/manifests/frontend-service.yml b/compiled/dev-sockshop/manifests/frontend-service.yml index b6f6d9b6..c7a991b7 100644 --- a/compiled/dev-sockshop/manifests/frontend-service.yml +++ b/compiled/dev-sockshop/manifests/frontend-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: frontend app.kubernetes.io/part-of: sock-shop name: frontend name: frontend diff --git a/compiled/dev-sockshop/manifests/orders-bundle.yml b/compiled/dev-sockshop/manifests/orders-bundle.yml index 80593517..331e4f43 100644 --- a/compiled/dev-sockshop/manifests/orders-bundle.yml +++ b/compiled/dev-sockshop/manifests/orders-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: orders app.kubernetes.io/part-of: sock-shop name: orders name: orders diff --git a/compiled/dev-sockshop/manifests/orders-db-bundle.yml b/compiled/dev-sockshop/manifests/orders-db-bundle.yml index 0724a7ca..b16bb745 100644 --- a/compiled/dev-sockshop/manifests/orders-db-bundle.yml +++ b/compiled/dev-sockshop/manifests/orders-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: orders-db app.kubernetes.io/part-of: sock-shop name: orders-db name: orders-db diff --git a/compiled/dev-sockshop/manifests/orders-db-service.yml b/compiled/dev-sockshop/manifests/orders-db-service.yml index c34f719e..f212291b 100644 --- a/compiled/dev-sockshop/manifests/orders-db-service.yml +++ b/compiled/dev-sockshop/manifests/orders-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: orders-db app.kubernetes.io/part-of: sock-shop name: orders-db name: orders-db diff --git a/compiled/dev-sockshop/manifests/orders-service.yml b/compiled/dev-sockshop/manifests/orders-service.yml index 6a098782..7bfdad9d 100644 --- a/compiled/dev-sockshop/manifests/orders-service.yml +++ b/compiled/dev-sockshop/manifests/orders-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: orders app.kubernetes.io/part-of: sock-shop name: orders name: orders diff --git a/compiled/dev-sockshop/manifests/payment-bundle.yml b/compiled/dev-sockshop/manifests/payment-bundle.yml index d0988775..474d814a 100644 --- a/compiled/dev-sockshop/manifests/payment-bundle.yml +++ b/compiled/dev-sockshop/manifests/payment-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: payment app.kubernetes.io/part-of: sock-shop name: payment name: payment diff --git a/compiled/dev-sockshop/manifests/payment-service.yml b/compiled/dev-sockshop/manifests/payment-service.yml index 87baf042..d7f8a510 100644 --- a/compiled/dev-sockshop/manifests/payment-service.yml +++ b/compiled/dev-sockshop/manifests/payment-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: payment app.kubernetes.io/part-of: sock-shop name: payment name: payment diff --git a/compiled/dev-sockshop/manifests/queue-master-bundle.yml b/compiled/dev-sockshop/manifests/queue-master-bundle.yml index d67f8c84..2a9f5efe 100644 --- a/compiled/dev-sockshop/manifests/queue-master-bundle.yml +++ b/compiled/dev-sockshop/manifests/queue-master-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: queue-master app.kubernetes.io/part-of: sock-shop name: queue-master name: queue-master diff --git a/compiled/dev-sockshop/manifests/queue-master-service.yml b/compiled/dev-sockshop/manifests/queue-master-service.yml index 6666e51f..8bfbd48c 100644 --- a/compiled/dev-sockshop/manifests/queue-master-service.yml +++ b/compiled/dev-sockshop/manifests/queue-master-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: queue-master app.kubernetes.io/part-of: sock-shop name: queue-master name: queue-master diff --git a/compiled/dev-sockshop/manifests/rabbit-mq-bundle.yml b/compiled/dev-sockshop/manifests/rabbit-mq-bundle.yml index 8ccf1970..9e6ddf8e 100644 --- a/compiled/dev-sockshop/manifests/rabbit-mq-bundle.yml +++ b/compiled/dev-sockshop/manifests/rabbit-mq-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: rabbit-mq app.kubernetes.io/part-of: sock-shop name: rabbit-mq name: rabbit-mq diff --git a/compiled/dev-sockshop/manifests/rabbit-mq-service.yml b/compiled/dev-sockshop/manifests/rabbit-mq-service.yml index 5e711373..510a01ed 100644 --- a/compiled/dev-sockshop/manifests/rabbit-mq-service.yml +++ b/compiled/dev-sockshop/manifests/rabbit-mq-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: rabbit-mq app.kubernetes.io/part-of: sock-shop name: rabbit-mq name: rabbit-mq diff --git a/compiled/dev-sockshop/manifests/session-db-bundle.yml b/compiled/dev-sockshop/manifests/session-db-bundle.yml index e8339a98..c8728a9b 100644 --- a/compiled/dev-sockshop/manifests/session-db-bundle.yml +++ b/compiled/dev-sockshop/manifests/session-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: session-db name: session-db name: session-db namespace: dev-sockshop diff --git a/compiled/dev-sockshop/manifests/session-db-service.yml b/compiled/dev-sockshop/manifests/session-db-service.yml index 25a71795..de3570e9 100644 --- a/compiled/dev-sockshop/manifests/session-db-service.yml +++ b/compiled/dev-sockshop/manifests/session-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: session-db name: session-db name: session-db namespace: dev-sockshop diff --git a/compiled/dev-sockshop/manifests/shipping-bundle.yml b/compiled/dev-sockshop/manifests/shipping-bundle.yml index bcb73145..97019986 100644 --- a/compiled/dev-sockshop/manifests/shipping-bundle.yml +++ b/compiled/dev-sockshop/manifests/shipping-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: shipping name: shipping name: shipping namespace: dev-sockshop diff --git a/compiled/dev-sockshop/manifests/shipping-service.yml b/compiled/dev-sockshop/manifests/shipping-service.yml index a36e49f6..b19beecb 100644 --- a/compiled/dev-sockshop/manifests/shipping-service.yml +++ b/compiled/dev-sockshop/manifests/shipping-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: shipping name: shipping name: shipping namespace: dev-sockshop diff --git a/compiled/dev-sockshop/manifests/user-bundle.yml b/compiled/dev-sockshop/manifests/user-bundle.yml index bc72cc87..1f5f7ab9 100644 --- a/compiled/dev-sockshop/manifests/user-bundle.yml +++ b/compiled/dev-sockshop/manifests/user-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: user name: user name: user namespace: dev-sockshop diff --git a/compiled/dev-sockshop/manifests/user-db-bundle.yml b/compiled/dev-sockshop/manifests/user-db-bundle.yml index 4399f274..f7836ebe 100644 --- a/compiled/dev-sockshop/manifests/user-db-bundle.yml +++ b/compiled/dev-sockshop/manifests/user-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: user-db name: user-db name: user-db namespace: dev-sockshop diff --git a/compiled/dev-sockshop/manifests/user-db-service.yml b/compiled/dev-sockshop/manifests/user-db-service.yml index 1f72917f..ccea46a7 100644 --- a/compiled/dev-sockshop/manifests/user-db-service.yml +++ b/compiled/dev-sockshop/manifests/user-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: user-db name: user-db name: user-db namespace: dev-sockshop diff --git a/compiled/dev-sockshop/manifests/user-service.yml b/compiled/dev-sockshop/manifests/user-service.yml index 6d981f3f..b87ed8fa 100644 --- a/compiled/dev-sockshop/manifests/user-service.yml +++ b/compiled/dev-sockshop/manifests/user-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: user name: user name: user namespace: dev-sockshop diff --git a/compiled/echo-server/manifests/echo-server-bundle.yml b/compiled/echo-server/manifests/echo-server-bundle.yml index 98fa1077..7d118260 100644 --- a/compiled/echo-server/manifests/echo-server-bundle.yml +++ b/compiled/echo-server/manifests/echo-server-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: echo-server name: echo-server name: echo-server namespace: echo-server diff --git a/compiled/echo-server/manifests/echo-server-security.yml b/compiled/echo-server/manifests/echo-server-security.yml index c60fa6c2..c5d4608b 100644 --- a/compiled/echo-server/manifests/echo-server-security.yml +++ b/compiled/echo-server/manifests/echo-server-security.yml @@ -15,6 +15,7 @@ spec: protocol: TCP podSelector: matchLabels: + app.kapicorp.dev/component: echo-server name: echo-server policyTypes: - Ingress diff --git a/compiled/echo-server/manifests/echo-server-service.yml b/compiled/echo-server/manifests/echo-server-service.yml index 83082a19..9d515cf3 100644 --- a/compiled/echo-server/manifests/echo-server-service.yml +++ b/compiled/echo-server/manifests/echo-server-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: echo-server name: echo-server name: echo-server namespace: echo-server diff --git a/compiled/echo-server/manifests/global-ingress.yml b/compiled/echo-server/manifests/global-ingress.yml index ca14c63a..10ec7556 100644 --- a/compiled/echo-server/manifests/global-ingress.yml +++ b/compiled/echo-server/manifests/global-ingress.yml @@ -4,7 +4,6 @@ metadata: labels: name: global name: global - namespace: echo-server spec: rules: - http: diff --git a/compiled/examples/manifests/base64-as-base64.yml b/compiled/examples/manifests/base64-as-base64-secret.yml similarity index 100% rename from compiled/examples/manifests/base64-as-base64.yml rename to compiled/examples/manifests/base64-as-base64-secret.yml diff --git a/compiled/examples/manifests/base64-as-plain.yml b/compiled/examples/manifests/base64-as-plain-secret.yml similarity index 100% rename from compiled/examples/manifests/base64-as-plain.yml rename to compiled/examples/manifests/base64-as-plain-secret.yml diff --git a/compiled/examples/manifests/filebeat-bundle.yml b/compiled/examples/manifests/filebeat-bundle.yml index 8e45a2a2..5df0032e 100644 --- a/compiled/examples/manifests/filebeat-bundle.yml +++ b/compiled/examples/manifests/filebeat-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: filebeat name: filebeat name: filebeat namespace: examples diff --git a/compiled/examples/manifests/filebeat-rbac.yml b/compiled/examples/manifests/filebeat-rbac.yml index d2d7ef7b..2229e564 100644 --- a/compiled/examples/manifests/filebeat-rbac.yml +++ b/compiled/examples/manifests/filebeat-rbac.yml @@ -1,9 +1,20 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kapicorp.dev/component: filebeat + name: filebeat + name: filebeat + namespace: examples +--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: + app.kapicorp.dev/component: filebeat name: filebeat name: filebeat + namespace: examples rules: - apiGroups: - '' @@ -28,8 +39,10 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: + app.kapicorp.dev/component: filebeat name: filebeat name: filebeat + namespace: examples roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole @@ -38,11 +51,3 @@ subjects: - kind: ServiceAccount name: filebeat namespace: examples ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - name: filebeat - name: filebeat - namespace: examples diff --git a/compiled/examples/manifests/logstash-bundle.yml b/compiled/examples/manifests/logstash-bundle.yml index 103bd13e..699c0ad8 100644 --- a/compiled/examples/manifests/logstash-bundle.yml +++ b/compiled/examples/manifests/logstash-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: logstash name: logstash name: logstash namespace: examples diff --git a/compiled/examples/manifests/logstash-config-config.yml b/compiled/examples/manifests/logstash-config-config.yml new file mode 100644 index 00000000..98afec2f --- /dev/null +++ b/compiled/examples/manifests/logstash-config-config.yml @@ -0,0 +1,12 @@ +apiVersion: v1 +data: + logstash.yml: "log.level: info\nqueue.max_bytes: 4gb\nqueue.type: persisted\nhttp.host:\ + \ 0.0.0.0" + pipelines.yml: "- pipeline.id: example\n path.config: \"/usr/share/logstash/pipeline/example.conf\"\ + \n pipeline.workers: 1\n pipeline.batch.size: 200\n queue.type: persisted" +kind: ConfigMap +metadata: + labels: + name: logstash + name: logstash-config + namespace: examples diff --git a/compiled/examples/manifests/logstash-config.yml b/compiled/examples/manifests/logstash-config.yml deleted file mode 100644 index 1e638723..00000000 --- a/compiled/examples/manifests/logstash-config.yml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: v1 -data: - logstash.yml: "log.level: info\nqueue.max_bytes: 4gb\nqueue.type: persisted\nhttp.host:\ - \ 0.0.0.0" - pipelines.yml: "- pipeline.id: example\n path.config: \"/usr/share/logstash/pipeline/example.conf\"\ - \n pipeline.workers: 1\n pipeline.batch.size: 200\n queue.type: persisted" -kind: ConfigMap -metadata: - labels: - name: logstash-config - name: logstash-config - namespace: examples ---- -apiVersion: v1 -data: - example.conf: "input { stdin { } }\n\nfilter {\n grok {\n match => { \"message\"\ - \ => \"%{COMBINEDAPACHELOG}\" }\n }\n date {\n match => [ \"timestamp\" ,\ - \ \"dd/MMM/yyyy:HH:mm:ss Z\" ]\n }\n}\n\noutput {\n elasticsearch { hosts =>\ - \ [\"localhost:9200\"] }\n stdout { codec => rubydebug }\n}" -kind: ConfigMap -metadata: - labels: - name: logstash-pipelines - name: logstash-pipelines - namespace: examples diff --git a/compiled/examples/manifests/logstash-pipelines-config.yml b/compiled/examples/manifests/logstash-pipelines-config.yml new file mode 100644 index 00000000..4dd82b8f --- /dev/null +++ b/compiled/examples/manifests/logstash-pipelines-config.yml @@ -0,0 +1,12 @@ +apiVersion: v1 +data: + example.conf: "input { stdin { } }\n\nfilter {\n grok {\n match => { \"message\"\ + \ => \"%{COMBINEDAPACHELOG}\" }\n }\n date {\n match => [ \"timestamp\" ,\ + \ \"dd/MMM/yyyy:HH:mm:ss Z\" ]\n }\n}\n\noutput {\n elasticsearch { hosts =>\ + \ [\"localhost:9200\"] }\n stdout { codec => rubydebug }\n}" +kind: ConfigMap +metadata: + labels: + name: logstash + name: logstash-pipelines + namespace: examples diff --git a/compiled/examples/manifests/mysql-bundle.yml b/compiled/examples/manifests/mysql-bundle.yml index fb1ed557..f7d7ef3c 100644 --- a/compiled/examples/manifests/mysql-bundle.yml +++ b/compiled/examples/manifests/mysql-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: mysql name: mysql name: mysql namespace: examples diff --git a/compiled/examples/manifests/plain-base64.yml b/compiled/examples/manifests/plain-base64-secret.yml similarity index 100% rename from compiled/examples/manifests/plain-base64.yml rename to compiled/examples/manifests/plain-base64-secret.yml diff --git a/compiled/examples/manifests/plain-plain-connection-b64.yml b/compiled/examples/manifests/plain-plain-connection-b64-secret.yml similarity index 100% rename from compiled/examples/manifests/plain-plain-connection-b64.yml rename to compiled/examples/manifests/plain-plain-connection-b64-secret.yml diff --git a/compiled/examples/manifests/plain-plain-connection-non-b64.yml b/compiled/examples/manifests/plain-plain-connection-non-b64-secret.yml similarity index 100% rename from compiled/examples/manifests/plain-plain-connection-non-b64.yml rename to compiled/examples/manifests/plain-plain-connection-non-b64-secret.yml diff --git a/compiled/examples/manifests/plain-plain-connection.yml b/compiled/examples/manifests/plain-plain-connection-secret.yml similarity index 100% rename from compiled/examples/manifests/plain-plain-connection.yml rename to compiled/examples/manifests/plain-plain-connection-secret.yml diff --git a/compiled/examples/manifests/trivy-bundle.yml b/compiled/examples/manifests/trivy-bundle.yml index 1757208a..93113e27 100644 --- a/compiled/examples/manifests/trivy-bundle.yml +++ b/compiled/examples/manifests/trivy-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: trivy app.kubernetes.io/component: go app.kubernetes.io/version: 0.18.1 name: trivy diff --git a/compiled/examples/manifests/trivy-rbac.yml b/compiled/examples/manifests/trivy-rbac.yml index 3c61bd7b..d59de786 100644 --- a/compiled/examples/manifests/trivy-rbac.yml +++ b/compiled/examples/manifests/trivy-rbac.yml @@ -1,7 +1,17 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kapicorp.dev/component: trivy + name: trivy + name: trivy + namespace: examples +--- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: + app.kapicorp.dev/component: trivy name: trivy name: trivy namespace: examples @@ -19,21 +29,14 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: + app.kapicorp.dev/component: trivy name: trivy name: trivy namespace: examples roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: trivy subjects: - kind: ServiceAccount name: trivy ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - name: trivy - name: trivy - namespace: examples + namespace: examples diff --git a/compiled/examples/manifests/trivy-service.yml b/compiled/examples/manifests/trivy-service.yml index 7600eef7..afc8d298 100644 --- a/compiled/examples/manifests/trivy-service.yml +++ b/compiled/examples/manifests/trivy-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: trivy app.kubernetes.io/component: go app.kubernetes.io/version: 0.18.1 name: trivy diff --git a/compiled/gke-pvm-killer/manifests/gke-pvm-killer-bundle.yml b/compiled/gke-pvm-killer/manifests/gke-pvm-killer-bundle.yml index 7265c426..4a63b6f5 100644 --- a/compiled/gke-pvm-killer/manifests/gke-pvm-killer-bundle.yml +++ b/compiled/gke-pvm-killer/manifests/gke-pvm-killer-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: gke-pvm-killer name: gke-pvm-killer name: gke-pvm-killer namespace: gke-pvm-killer diff --git a/compiled/mysql/manifests/mysql-bundle.yml b/compiled/mysql/manifests/mysql-bundle.yml index b4906e7f..3b754f88 100644 --- a/compiled/mysql/manifests/mysql-bundle.yml +++ b/compiled/mysql/manifests/mysql-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: mysql name: mysql name: mysql namespace: mysql diff --git a/compiled/postgres-proxy/manifests/postgres-proxy-bundle.yml b/compiled/postgres-proxy/manifests/postgres-proxy-bundle.yml index 4458d331..88d16989 100644 --- a/compiled/postgres-proxy/manifests/postgres-proxy-bundle.yml +++ b/compiled/postgres-proxy/manifests/postgres-proxy-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: postgres-proxy name: postgres-proxy tier: db name: postgres-proxy diff --git a/compiled/postgres-proxy/manifests/postgres-proxy-scaling.yml b/compiled/postgres-proxy/manifests/postgres-proxy-scaling.yml index 8ed025a6..d8b48d83 100644 --- a/compiled/postgres-proxy/manifests/postgres-proxy-scaling.yml +++ b/compiled/postgres-proxy/manifests/postgres-proxy-scaling.yml @@ -2,6 +2,7 @@ apiVersion: autoscaling.k8s.io/v1beta2 kind: VerticalPodAutoscaler metadata: labels: + app.kapicorp.dev/component: postgres-proxy name: postgres-proxy tier: db name: postgres-proxy @@ -22,6 +23,7 @@ apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: labels: + app.kapicorp.dev/component: postgres-proxy name: postgres-proxy name: postgres-proxy namespace: postgres-proxy @@ -36,6 +38,7 @@ apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: labels: + app.kapicorp.dev/component: postgres-proxy name: postgres-proxy name: postgres-proxy namespace: postgres-proxy diff --git a/compiled/postgres-proxy/manifests/postgres-proxy-service.yml b/compiled/postgres-proxy/manifests/postgres-proxy-service.yml index f62a3674..88e3764c 100644 --- a/compiled/postgres-proxy/manifests/postgres-proxy-service.yml +++ b/compiled/postgres-proxy/manifests/postgres-proxy-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: postgres-proxy name: postgres-proxy tier: db name: postgres-proxy diff --git a/compiled/pritunl/manifests/pritunl-bundle.yml b/compiled/pritunl/manifests/pritunl-bundle.yml index 805291fc..3698221d 100644 --- a/compiled/pritunl/manifests/pritunl-bundle.yml +++ b/compiled/pritunl/manifests/pritunl-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: pritunl name: pritunl name: pritunl namespace: pritunl diff --git a/compiled/pritunl/manifests/pritunl-mongo-bundle.yml b/compiled/pritunl/manifests/pritunl-mongo-bundle.yml index 5d7ae191..396b4f96 100644 --- a/compiled/pritunl/manifests/pritunl-mongo-bundle.yml +++ b/compiled/pritunl/manifests/pritunl-mongo-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: pritunl-mongo name: pritunl-mongo name: pritunl-mongo namespace: pritunl diff --git a/compiled/pritunl/manifests/pritunl-mongo-rbac.yml b/compiled/pritunl/manifests/pritunl-mongo-rbac.yml index 0fb7f8b2..0a61a8c1 100644 --- a/compiled/pritunl/manifests/pritunl-mongo-rbac.yml +++ b/compiled/pritunl/manifests/pritunl-mongo-rbac.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: ServiceAccount metadata: labels: + app.kapicorp.dev/component: pritunl-mongo name: pritunl-mongo name: pritunl-mongo namespace: pritunl diff --git a/compiled/pritunl/manifests/pritunl-mongo-service.yml b/compiled/pritunl/manifests/pritunl-mongo-service.yml index e79a3413..ebb9527e 100644 --- a/compiled/pritunl/manifests/pritunl-mongo-service.yml +++ b/compiled/pritunl/manifests/pritunl-mongo-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: pritunl-mongo name: pritunl-mongo name: pritunl-mongo namespace: pritunl diff --git a/compiled/pritunl/manifests/pritunl-service.yml b/compiled/pritunl/manifests/pritunl-service.yml index 6eb9d083..47554733 100644 --- a/compiled/pritunl/manifests/pritunl-service.yml +++ b/compiled/pritunl/manifests/pritunl-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: pritunl name: pritunl name: pritunl namespace: pritunl diff --git a/compiled/prod-sockshop/manifests/carts-bundle.yml b/compiled/prod-sockshop/manifests/carts-bundle.yml index 6c6072f3..84417fb1 100644 --- a/compiled/prod-sockshop/manifests/carts-bundle.yml +++ b/compiled/prod-sockshop/manifests/carts-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: carts app.kubernetes.io/part-of: sock-shop name: carts name: carts diff --git a/compiled/prod-sockshop/manifests/carts-db-bundle.yml b/compiled/prod-sockshop/manifests/carts-db-bundle.yml index ae450545..08c9f602 100644 --- a/compiled/prod-sockshop/manifests/carts-db-bundle.yml +++ b/compiled/prod-sockshop/manifests/carts-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: carts-db app.kubernetes.io/part-of: sock-shop name: carts-db name: carts-db diff --git a/compiled/prod-sockshop/manifests/carts-db-service.yml b/compiled/prod-sockshop/manifests/carts-db-service.yml index 2bec4427..6f0da1f0 100644 --- a/compiled/prod-sockshop/manifests/carts-db-service.yml +++ b/compiled/prod-sockshop/manifests/carts-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: carts-db app.kubernetes.io/part-of: sock-shop name: carts-db name: carts-db diff --git a/compiled/prod-sockshop/manifests/carts-service.yml b/compiled/prod-sockshop/manifests/carts-service.yml index dfb36db8..5af6e5c9 100644 --- a/compiled/prod-sockshop/manifests/carts-service.yml +++ b/compiled/prod-sockshop/manifests/carts-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: carts app.kubernetes.io/part-of: sock-shop name: carts name: carts diff --git a/compiled/prod-sockshop/manifests/catalogue-bundle.yml b/compiled/prod-sockshop/manifests/catalogue-bundle.yml index edc2df04..8644c0b4 100644 --- a/compiled/prod-sockshop/manifests/catalogue-bundle.yml +++ b/compiled/prod-sockshop/manifests/catalogue-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: catalogue app.kubernetes.io/part-of: sock-shop name: catalogue name: catalogue diff --git a/compiled/prod-sockshop/manifests/catalogue-db-bundle.yml b/compiled/prod-sockshop/manifests/catalogue-db-bundle.yml index 71cb1be3..3ce68a36 100644 --- a/compiled/prod-sockshop/manifests/catalogue-db-bundle.yml +++ b/compiled/prod-sockshop/manifests/catalogue-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: catalogue-db app.kubernetes.io/part-of: sock-shop name: catalogue-db name: catalogue-db diff --git a/compiled/prod-sockshop/manifests/catalogue-db-service.yml b/compiled/prod-sockshop/manifests/catalogue-db-service.yml index 10f1c091..37c1da42 100644 --- a/compiled/prod-sockshop/manifests/catalogue-db-service.yml +++ b/compiled/prod-sockshop/manifests/catalogue-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: catalogue-db app.kubernetes.io/part-of: sock-shop name: catalogue-db name: catalogue-db diff --git a/compiled/prod-sockshop/manifests/catalogue-service.yml b/compiled/prod-sockshop/manifests/catalogue-service.yml index 4a374c8c..8a0d1a45 100644 --- a/compiled/prod-sockshop/manifests/catalogue-service.yml +++ b/compiled/prod-sockshop/manifests/catalogue-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: catalogue app.kubernetes.io/part-of: sock-shop name: catalogue name: catalogue diff --git a/compiled/prod-sockshop/manifests/frontend-bundle.yml b/compiled/prod-sockshop/manifests/frontend-bundle.yml index d1cfa34f..68500a68 100644 --- a/compiled/prod-sockshop/manifests/frontend-bundle.yml +++ b/compiled/prod-sockshop/manifests/frontend-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: frontend app.kubernetes.io/part-of: sock-shop name: frontend name: frontend diff --git a/compiled/prod-sockshop/manifests/frontend-service.yml b/compiled/prod-sockshop/manifests/frontend-service.yml index e8c4f661..64f7b2d1 100644 --- a/compiled/prod-sockshop/manifests/frontend-service.yml +++ b/compiled/prod-sockshop/manifests/frontend-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: frontend app.kubernetes.io/part-of: sock-shop name: frontend name: frontend diff --git a/compiled/prod-sockshop/manifests/gke-managed-certificate-ingress.yml b/compiled/prod-sockshop/manifests/gke-managed-certificate-ingress.yml index 3108fd63..a3ffbc7c 100644 --- a/compiled/prod-sockshop/manifests/gke-managed-certificate-ingress.yml +++ b/compiled/prod-sockshop/manifests/gke-managed-certificate-ingress.yml @@ -7,7 +7,6 @@ metadata: labels: name: gke-managed-certificate name: gke-managed-certificate - namespace: prod-sockshop spec: backend: service: diff --git a/compiled/prod-sockshop/manifests/gke-managed-certificate-managed-certificate.yml b/compiled/prod-sockshop/manifests/gke-managed-certificate-managed-certificate.yml index 2a6485dd..ae6d8dd6 100644 --- a/compiled/prod-sockshop/manifests/gke-managed-certificate-managed-certificate.yml +++ b/compiled/prod-sockshop/manifests/gke-managed-certificate-managed-certificate.yml @@ -4,7 +4,6 @@ metadata: labels: name: managed-sockshop.kapicorp.com name: managed-sockshop.kapicorp.com - namespace: prod-sockshop spec: domains: - managed-sockshop.kapicorp.com diff --git a/compiled/prod-sockshop/manifests/orders-bundle.yml b/compiled/prod-sockshop/manifests/orders-bundle.yml index f5ef5d66..8153db8d 100644 --- a/compiled/prod-sockshop/manifests/orders-bundle.yml +++ b/compiled/prod-sockshop/manifests/orders-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: orders app.kubernetes.io/part-of: sock-shop name: orders name: orders diff --git a/compiled/prod-sockshop/manifests/orders-db-bundle.yml b/compiled/prod-sockshop/manifests/orders-db-bundle.yml index a7faf1c0..7ef5e537 100644 --- a/compiled/prod-sockshop/manifests/orders-db-bundle.yml +++ b/compiled/prod-sockshop/manifests/orders-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: orders-db app.kubernetes.io/part-of: sock-shop name: orders-db name: orders-db diff --git a/compiled/prod-sockshop/manifests/orders-db-service.yml b/compiled/prod-sockshop/manifests/orders-db-service.yml index 40be16da..3a27603e 100644 --- a/compiled/prod-sockshop/manifests/orders-db-service.yml +++ b/compiled/prod-sockshop/manifests/orders-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: orders-db app.kubernetes.io/part-of: sock-shop name: orders-db name: orders-db diff --git a/compiled/prod-sockshop/manifests/orders-service.yml b/compiled/prod-sockshop/manifests/orders-service.yml index e3a780b7..2a9e6991 100644 --- a/compiled/prod-sockshop/manifests/orders-service.yml +++ b/compiled/prod-sockshop/manifests/orders-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: orders app.kubernetes.io/part-of: sock-shop name: orders name: orders diff --git a/compiled/prod-sockshop/manifests/payment-bundle.yml b/compiled/prod-sockshop/manifests/payment-bundle.yml index 93a8e715..eda284db 100644 --- a/compiled/prod-sockshop/manifests/payment-bundle.yml +++ b/compiled/prod-sockshop/manifests/payment-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: payment app.kubernetes.io/part-of: sock-shop name: payment name: payment diff --git a/compiled/prod-sockshop/manifests/payment-service.yml b/compiled/prod-sockshop/manifests/payment-service.yml index f3fe9f27..c36d2197 100644 --- a/compiled/prod-sockshop/manifests/payment-service.yml +++ b/compiled/prod-sockshop/manifests/payment-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: payment app.kubernetes.io/part-of: sock-shop name: payment name: payment diff --git a/compiled/prod-sockshop/manifests/queue-master-bundle.yml b/compiled/prod-sockshop/manifests/queue-master-bundle.yml index aa0c0233..79f554ec 100644 --- a/compiled/prod-sockshop/manifests/queue-master-bundle.yml +++ b/compiled/prod-sockshop/manifests/queue-master-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: queue-master app.kubernetes.io/part-of: sock-shop name: queue-master name: queue-master diff --git a/compiled/prod-sockshop/manifests/queue-master-service.yml b/compiled/prod-sockshop/manifests/queue-master-service.yml index 680cf911..35dff31f 100644 --- a/compiled/prod-sockshop/manifests/queue-master-service.yml +++ b/compiled/prod-sockshop/manifests/queue-master-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: queue-master app.kubernetes.io/part-of: sock-shop name: queue-master name: queue-master diff --git a/compiled/prod-sockshop/manifests/rabbit-mq-bundle.yml b/compiled/prod-sockshop/manifests/rabbit-mq-bundle.yml index dd4e1920..ca614944 100644 --- a/compiled/prod-sockshop/manifests/rabbit-mq-bundle.yml +++ b/compiled/prod-sockshop/manifests/rabbit-mq-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: rabbit-mq app.kubernetes.io/part-of: sock-shop name: rabbit-mq name: rabbit-mq diff --git a/compiled/prod-sockshop/manifests/rabbit-mq-service.yml b/compiled/prod-sockshop/manifests/rabbit-mq-service.yml index 961879a2..9b96c957 100644 --- a/compiled/prod-sockshop/manifests/rabbit-mq-service.yml +++ b/compiled/prod-sockshop/manifests/rabbit-mq-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: rabbit-mq app.kubernetes.io/part-of: sock-shop name: rabbit-mq name: rabbit-mq diff --git a/compiled/prod-sockshop/manifests/session-db-bundle.yml b/compiled/prod-sockshop/manifests/session-db-bundle.yml index cdaddbbb..2c7bf643 100644 --- a/compiled/prod-sockshop/manifests/session-db-bundle.yml +++ b/compiled/prod-sockshop/manifests/session-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: session-db name: session-db name: session-db namespace: prod-sockshop diff --git a/compiled/prod-sockshop/manifests/session-db-service.yml b/compiled/prod-sockshop/manifests/session-db-service.yml index 3e0def48..01654076 100644 --- a/compiled/prod-sockshop/manifests/session-db-service.yml +++ b/compiled/prod-sockshop/manifests/session-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: session-db name: session-db name: session-db namespace: prod-sockshop diff --git a/compiled/prod-sockshop/manifests/shipping-bundle.yml b/compiled/prod-sockshop/manifests/shipping-bundle.yml index 5b127c3b..0da3301b 100644 --- a/compiled/prod-sockshop/manifests/shipping-bundle.yml +++ b/compiled/prod-sockshop/manifests/shipping-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: shipping name: shipping name: shipping namespace: prod-sockshop diff --git a/compiled/prod-sockshop/manifests/shipping-service.yml b/compiled/prod-sockshop/manifests/shipping-service.yml index d514caab..5835f1b9 100644 --- a/compiled/prod-sockshop/manifests/shipping-service.yml +++ b/compiled/prod-sockshop/manifests/shipping-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: shipping name: shipping name: shipping namespace: prod-sockshop diff --git a/compiled/prod-sockshop/manifests/sockshop.kapicorp.com.yml b/compiled/prod-sockshop/manifests/sockshop.kapicorp.com-secret.yml similarity index 100% rename from compiled/prod-sockshop/manifests/sockshop.kapicorp.com.yml rename to compiled/prod-sockshop/manifests/sockshop.kapicorp.com-secret.yml diff --git a/compiled/prod-sockshop/manifests/tls-certificate-ingress.yml b/compiled/prod-sockshop/manifests/tls-certificate-ingress.yml index ea32d12b..2900d88f 100644 --- a/compiled/prod-sockshop/manifests/tls-certificate-ingress.yml +++ b/compiled/prod-sockshop/manifests/tls-certificate-ingress.yml @@ -6,7 +6,6 @@ metadata: labels: name: tls-certificate name: tls-certificate - namespace: prod-sockshop spec: backend: service: diff --git a/compiled/prod-sockshop/manifests/user-bundle.yml b/compiled/prod-sockshop/manifests/user-bundle.yml index 11b7f48d..43e98130 100644 --- a/compiled/prod-sockshop/manifests/user-bundle.yml +++ b/compiled/prod-sockshop/manifests/user-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: user name: user name: user namespace: prod-sockshop diff --git a/compiled/prod-sockshop/manifests/user-db-bundle.yml b/compiled/prod-sockshop/manifests/user-db-bundle.yml index 1994869f..498f5b2d 100644 --- a/compiled/prod-sockshop/manifests/user-db-bundle.yml +++ b/compiled/prod-sockshop/manifests/user-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: user-db name: user-db name: user-db namespace: prod-sockshop diff --git a/compiled/prod-sockshop/manifests/user-db-service.yml b/compiled/prod-sockshop/manifests/user-db-service.yml index a85031ae..46a27e34 100644 --- a/compiled/prod-sockshop/manifests/user-db-service.yml +++ b/compiled/prod-sockshop/manifests/user-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: user-db name: user-db name: user-db namespace: prod-sockshop diff --git a/compiled/prod-sockshop/manifests/user-service.yml b/compiled/prod-sockshop/manifests/user-service.yml index c8ffdbd9..d5e7c424 100644 --- a/compiled/prod-sockshop/manifests/user-service.yml +++ b/compiled/prod-sockshop/manifests/user-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: user name: user name: user namespace: prod-sockshop diff --git a/compiled/sock-shop/manifests/carts-bundle.yml b/compiled/sock-shop/manifests/carts-bundle.yml index 6be370f3..64e5372b 100644 --- a/compiled/sock-shop/manifests/carts-bundle.yml +++ b/compiled/sock-shop/manifests/carts-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: carts app.kubernetes.io/part-of: sock-shop name: carts name: carts diff --git a/compiled/sock-shop/manifests/carts-db-bundle.yml b/compiled/sock-shop/manifests/carts-db-bundle.yml index dbefb0a3..828ea7f6 100644 --- a/compiled/sock-shop/manifests/carts-db-bundle.yml +++ b/compiled/sock-shop/manifests/carts-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: carts-db app.kubernetes.io/part-of: sock-shop name: carts-db name: carts-db diff --git a/compiled/sock-shop/manifests/carts-db-service.yml b/compiled/sock-shop/manifests/carts-db-service.yml index 98b3a2e8..c5ed0e31 100644 --- a/compiled/sock-shop/manifests/carts-db-service.yml +++ b/compiled/sock-shop/manifests/carts-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: carts-db app.kubernetes.io/part-of: sock-shop name: carts-db name: carts-db diff --git a/compiled/sock-shop/manifests/carts-service.yml b/compiled/sock-shop/manifests/carts-service.yml index 9e035412..f2ad052f 100644 --- a/compiled/sock-shop/manifests/carts-service.yml +++ b/compiled/sock-shop/manifests/carts-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: carts app.kubernetes.io/part-of: sock-shop name: carts name: carts diff --git a/compiled/sock-shop/manifests/catalogue-bundle.yml b/compiled/sock-shop/manifests/catalogue-bundle.yml index 805d7e31..083f0653 100644 --- a/compiled/sock-shop/manifests/catalogue-bundle.yml +++ b/compiled/sock-shop/manifests/catalogue-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: catalogue app.kubernetes.io/part-of: sock-shop name: catalogue name: catalogue diff --git a/compiled/sock-shop/manifests/catalogue-db-bundle.yml b/compiled/sock-shop/manifests/catalogue-db-bundle.yml index bff3f229..505da4fa 100644 --- a/compiled/sock-shop/manifests/catalogue-db-bundle.yml +++ b/compiled/sock-shop/manifests/catalogue-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: catalogue-db app.kubernetes.io/part-of: sock-shop name: catalogue-db name: catalogue-db diff --git a/compiled/sock-shop/manifests/catalogue-db-service.yml b/compiled/sock-shop/manifests/catalogue-db-service.yml index 6076811d..284a51ff 100644 --- a/compiled/sock-shop/manifests/catalogue-db-service.yml +++ b/compiled/sock-shop/manifests/catalogue-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: catalogue-db app.kubernetes.io/part-of: sock-shop name: catalogue-db name: catalogue-db diff --git a/compiled/sock-shop/manifests/catalogue-service.yml b/compiled/sock-shop/manifests/catalogue-service.yml index 9051d4b5..c92b12d4 100644 --- a/compiled/sock-shop/manifests/catalogue-service.yml +++ b/compiled/sock-shop/manifests/catalogue-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: catalogue app.kubernetes.io/part-of: sock-shop name: catalogue name: catalogue diff --git a/compiled/sock-shop/manifests/frontend-bundle.yml b/compiled/sock-shop/manifests/frontend-bundle.yml index b79e0dcf..9810d96b 100644 --- a/compiled/sock-shop/manifests/frontend-bundle.yml +++ b/compiled/sock-shop/manifests/frontend-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: frontend app.kubernetes.io/part-of: sock-shop name: frontend name: frontend diff --git a/compiled/sock-shop/manifests/frontend-service.yml b/compiled/sock-shop/manifests/frontend-service.yml index 80b2c77e..302e1812 100644 --- a/compiled/sock-shop/manifests/frontend-service.yml +++ b/compiled/sock-shop/manifests/frontend-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: frontend app.kubernetes.io/part-of: sock-shop name: frontend name: frontend diff --git a/compiled/sock-shop/manifests/orders-bundle.yml b/compiled/sock-shop/manifests/orders-bundle.yml index 81ae3f78..19618855 100644 --- a/compiled/sock-shop/manifests/orders-bundle.yml +++ b/compiled/sock-shop/manifests/orders-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: orders app.kubernetes.io/part-of: sock-shop name: orders name: orders diff --git a/compiled/sock-shop/manifests/orders-db-bundle.yml b/compiled/sock-shop/manifests/orders-db-bundle.yml index 6a040cfc..40d017cc 100644 --- a/compiled/sock-shop/manifests/orders-db-bundle.yml +++ b/compiled/sock-shop/manifests/orders-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: orders-db app.kubernetes.io/part-of: sock-shop name: orders-db name: orders-db diff --git a/compiled/sock-shop/manifests/orders-db-service.yml b/compiled/sock-shop/manifests/orders-db-service.yml index 5fa129cb..3df60b44 100644 --- a/compiled/sock-shop/manifests/orders-db-service.yml +++ b/compiled/sock-shop/manifests/orders-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: orders-db app.kubernetes.io/part-of: sock-shop name: orders-db name: orders-db diff --git a/compiled/sock-shop/manifests/orders-service.yml b/compiled/sock-shop/manifests/orders-service.yml index 6b6ab3a4..bce5334e 100644 --- a/compiled/sock-shop/manifests/orders-service.yml +++ b/compiled/sock-shop/manifests/orders-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: orders app.kubernetes.io/part-of: sock-shop name: orders name: orders diff --git a/compiled/sock-shop/manifests/payment-bundle.yml b/compiled/sock-shop/manifests/payment-bundle.yml index 641d7672..ac99d066 100644 --- a/compiled/sock-shop/manifests/payment-bundle.yml +++ b/compiled/sock-shop/manifests/payment-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: payment app.kubernetes.io/part-of: sock-shop name: payment name: payment diff --git a/compiled/sock-shop/manifests/payment-service.yml b/compiled/sock-shop/manifests/payment-service.yml index aaf79ce1..318ce762 100644 --- a/compiled/sock-shop/manifests/payment-service.yml +++ b/compiled/sock-shop/manifests/payment-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: payment app.kubernetes.io/part-of: sock-shop name: payment name: payment diff --git a/compiled/sock-shop/manifests/queue-master-bundle.yml b/compiled/sock-shop/manifests/queue-master-bundle.yml index e3535216..65b89fd0 100644 --- a/compiled/sock-shop/manifests/queue-master-bundle.yml +++ b/compiled/sock-shop/manifests/queue-master-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: queue-master app.kubernetes.io/part-of: sock-shop name: queue-master name: queue-master diff --git a/compiled/sock-shop/manifests/queue-master-service.yml b/compiled/sock-shop/manifests/queue-master-service.yml index bafc41f9..6360cbb6 100644 --- a/compiled/sock-shop/manifests/queue-master-service.yml +++ b/compiled/sock-shop/manifests/queue-master-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: queue-master app.kubernetes.io/part-of: sock-shop name: queue-master name: queue-master diff --git a/compiled/sock-shop/manifests/rabbit-mq-bundle.yml b/compiled/sock-shop/manifests/rabbit-mq-bundle.yml index 02c5c5a4..87566f33 100644 --- a/compiled/sock-shop/manifests/rabbit-mq-bundle.yml +++ b/compiled/sock-shop/manifests/rabbit-mq-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: rabbit-mq app.kubernetes.io/part-of: sock-shop name: rabbit-mq name: rabbit-mq diff --git a/compiled/sock-shop/manifests/rabbit-mq-service.yml b/compiled/sock-shop/manifests/rabbit-mq-service.yml index 03ba87e0..d367de2f 100644 --- a/compiled/sock-shop/manifests/rabbit-mq-service.yml +++ b/compiled/sock-shop/manifests/rabbit-mq-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: rabbit-mq app.kubernetes.io/part-of: sock-shop name: rabbit-mq name: rabbit-mq diff --git a/compiled/sock-shop/manifests/session-db-bundle.yml b/compiled/sock-shop/manifests/session-db-bundle.yml index 3f061e5d..19dee536 100644 --- a/compiled/sock-shop/manifests/session-db-bundle.yml +++ b/compiled/sock-shop/manifests/session-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: session-db name: session-db name: session-db namespace: sock-shop diff --git a/compiled/sock-shop/manifests/session-db-service.yml b/compiled/sock-shop/manifests/session-db-service.yml index 4a6b4e2b..87bf5335 100644 --- a/compiled/sock-shop/manifests/session-db-service.yml +++ b/compiled/sock-shop/manifests/session-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: session-db name: session-db name: session-db namespace: sock-shop diff --git a/compiled/sock-shop/manifests/shipping-bundle.yml b/compiled/sock-shop/manifests/shipping-bundle.yml index 5c84ba96..1d93ba5b 100644 --- a/compiled/sock-shop/manifests/shipping-bundle.yml +++ b/compiled/sock-shop/manifests/shipping-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: shipping name: shipping name: shipping namespace: sock-shop diff --git a/compiled/sock-shop/manifests/shipping-service.yml b/compiled/sock-shop/manifests/shipping-service.yml index 19fc9bd0..a9c393bf 100644 --- a/compiled/sock-shop/manifests/shipping-service.yml +++ b/compiled/sock-shop/manifests/shipping-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: shipping name: shipping name: shipping namespace: sock-shop diff --git a/compiled/sock-shop/manifests/user-bundle.yml b/compiled/sock-shop/manifests/user-bundle.yml index 832f03c1..534493fc 100644 --- a/compiled/sock-shop/manifests/user-bundle.yml +++ b/compiled/sock-shop/manifests/user-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: user name: user name: user namespace: sock-shop diff --git a/compiled/sock-shop/manifests/user-db-bundle.yml b/compiled/sock-shop/manifests/user-db-bundle.yml index e3c92801..b4182613 100644 --- a/compiled/sock-shop/manifests/user-db-bundle.yml +++ b/compiled/sock-shop/manifests/user-db-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: user-db name: user-db name: user-db namespace: sock-shop diff --git a/compiled/sock-shop/manifests/user-db-service.yml b/compiled/sock-shop/manifests/user-db-service.yml index dce59d88..174b3a3b 100644 --- a/compiled/sock-shop/manifests/user-db-service.yml +++ b/compiled/sock-shop/manifests/user-db-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: user-db name: user-db name: user-db namespace: sock-shop diff --git a/compiled/sock-shop/manifests/user-service.yml b/compiled/sock-shop/manifests/user-service.yml index 4f41027a..c4f557c0 100644 --- a/compiled/sock-shop/manifests/user-service.yml +++ b/compiled/sock-shop/manifests/user-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: user name: user name: user namespace: sock-shop diff --git a/compiled/tesoro/manifests/tesoro-bundle.yml b/compiled/tesoro/manifests/tesoro-bundle.yml index e2cf031a..6a1e9009 100644 --- a/compiled/tesoro/manifests/tesoro-bundle.yml +++ b/compiled/tesoro/manifests/tesoro-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: tesoro name: tesoro name: tesoro namespace: tesoro @@ -56,12 +57,14 @@ spec: defaultMode: 420 secretName: tesoro --- -apiVersion: admissionregistration.k8s.io/v1beta1 +apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: labels: + app.kapicorp.dev/component: tesoro name: tesoro name: tesoro + namespace: tesoro webhooks: - clientConfig: caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUV1akNDQXFJQ0NRRDZIdzJDZld6ZVp6QU5CZ2txaGtpRzl3MEJBUXNGQURBZk1SMHdHd1lEVlFRRERCUkQKUVMxMFpYTnZjbTh1ZEdWemIzSnZMbk4yWXpBZUZ3MHlNREV4TWpFeU1ERTVNemhhRncweU16QTVNVEV5TURFNQpNemhhTUI4eEhUQWJCZ05WQkFNTUZFTkJMWFJsYzI5eWJ5NTBaWE52Y204dWMzWmpNSUlDSWpBTkJna3Foa2lHCjl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUEzbVlZNXIvTVYrSU9hMy9DZGxuRGVrdk9yQnVpeUd5MXUwZUYKOHU2RGQzdkNRcnp3MytLUmZrSXlHOW1lcDl3NW16bm5IMjdDZzVDN0t5Y040NVRaTnE3cHFESmhHVXVMWC9uRwpqNmxvM01qdnVpS0dtTG5JaHlEVjQyS1hDamxnbWVRaGhOdjFScFQ0cTFZeWhBWlF5RDU1a2FHUHQ0UmtQd21pCnkxMU04TTBXTUZDeW50OFhYZUNqcHVYVXdTV1V3cVE2ZVNJRFFnM1d1cnp6V1dJbVVwWTNPUDVTVWNYSHhFd2UKakFaT1hqSEJkZzJwWHVFK2hYN2VwektJUXMwbkpnbmFtakVPRlZhNnMxNDlEWkpjOU82VTg4dmVJMTNyZ3A4QwpPVUphdUlDOHBQNDdyZ2xadkNadEo2YmRPSDhaK1E2SEl1UGRic2tUM2JkS1dlTmMzTnBZSGI5U0tRNW82M3NqCmhBWUNpU3Q4YUVjbEtLdDF6U0xXMm5qZkU5NVhjZndyU25BRlNvU1pFdyt6RnNZbkxwMEdmWDlaWllPM1kzRzYKM2lPUjM4alRzMkpuamU0R1RxQ0Y1V1JMVUpZdU1jNTMwZTlDOWxjaTFYZ21WdkVtbCsrNUpkalN5dkdtSnBDQwpEMitKemR4WlJ4dE9tRkdVWnJKQVBsR2hqK0hXNGpEUHBDTnJ4VlhJdjJQSWhIWVdiTEhqNU9CVFNUM2xaTk0xCjY0ZFV6a3ZveDhBOThzcUlQM0JYdEVOU21qSDJkK25jYjREcTJsVWhwbWs2ZmE1WWN6YXpET3lESHRPa3pZSlMKRmtQaHMwOHFSTTZPclc5WlVPUGJMVmcvSllKUHB3NVRtZ3dNTUVLVXFtNzhob3drK1B3ejRxYUVyanNzb3djZwpqaDdudkdNQ0F3RUFBVEFOQmdrcWhraUc5dzBCQVFzRkFBT0NBZ0VBUEJMWEcvREZ3U3JYV1pGMU9nNGpVWnlXCjV4NTUxT1NNbVNJOUc0ZllhaGY5dEYrME9aTFpBYUxCdlhCNUNNK1lWajRDWDl1V3Y0NGlDZW5EZDY1T1l0dkoKTU1nM2tyWGV2dWFVOUEyeVVSMEdZWHhSWHJ2ZTFQY1JBK1V3bE1ldkd5aHpHR1hMSjg0dHRka2I5OGZad3VlTwp2aG0wOWl3RDcxTmtMeGJKVGVSQk5DUFZVcmVBZUQ1SVYvUjlJZTE5akhIOU5STzFMZ1l0SDNhODRvNTYzUXR1CkNpcGtNZ0s2L1pFSFlVZnZMOVo4MjlyYkFqM1hWVXdOSGsvTk5CR2czZDFWcHpPenNZMFBRa01aTitGU0NTYkcKdWhSbHdvc2N6R09qclBDcDlpbWVPT0llQlZJY0NBcUpuSnE1ZlVCSzF2OSs3RDRFMGdSR3hXbXVrV2xxYTQ2KwozcHg1RUdZajN4c1AveTVnWDg3cGsrQnRBcVBJUGJtOGQ4MWo3dTVGYUVScTViaEcwQkplNG83U25Ed0VNWkRKCnJPdlMxZWh6N29XM2RxYmxNODNLRjM3b0xzNFlDSURXckp3SFYwVThHa0hWQTZMdU1lM05Sc3Y1WGRZL2QydEoKSlhLNFFYL082WWlHRFpCeGtlZVJDVzMwWFhMTWw1REJWTUFGK2o2WUg1M3BjSnE4R2NHdkVDUk8zSGxCSmJVMwp2a3FFVFV0L1Q3ZE5LRFFISzM2azhuMWdlTEhJVndqRm16NHIzdkVieWdZZUlNVGRaZTQ3c2hTcjhTajNITm4rCklWRnhSZlV4anpuTXdSNjB3bm5JVk5lM2t0YmFMM1lFMFFmdnJiV2xaanAwZG1zQWh6UE5qYWJob0JBVFVCVWUKd0NpMk5vQzVJRU5pSU1MY1VjUT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= @@ -98,6 +101,7 @@ apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: + app.kapicorp.dev/component: tesoro name: tesoro-metrics name: tesoro-metrics namespace: tesoro @@ -118,12 +122,13 @@ apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: labels: - name: tesoro.rules - name: tesoro.rules + app.kapicorp.dev/component: tesoro + name: tesoro + name: tesoro namespace: tesoro spec: groups: - - name: tesoro.rules + - name: tesoro rules: - alert: TesoroFailedRequests annotations: diff --git a/compiled/tesoro/manifests/tesoro-rbac.yml b/compiled/tesoro/manifests/tesoro-rbac.yml index 4b2fd79b..b0e416c7 100644 --- a/compiled/tesoro/manifests/tesoro-rbac.yml +++ b/compiled/tesoro/manifests/tesoro-rbac.yml @@ -1,9 +1,20 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kapicorp.dev/component: tesoro + name: tesoro + name: tesoro + namespace: tesoro +--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: + app.kapicorp.dev/component: tesoro name: tesoro name: tesoro + namespace: tesoro rules: - apiGroups: - '' @@ -28,21 +39,14 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: + app.kapicorp.dev/component: tesoro name: tesoro name: tesoro + namespace: tesoro roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: tesoro subjects: - kind: ServiceAccount name: tesoro namespace: tesoro ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - name: tesoro - name: tesoro - namespace: tesoro diff --git a/compiled/tesoro/manifests/tesoro-service.yml b/compiled/tesoro/manifests/tesoro-service.yml index e0774912..bada1679 100644 --- a/compiled/tesoro/manifests/tesoro-service.yml +++ b/compiled/tesoro/manifests/tesoro-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: tesoro name: tesoro name: tesoro namespace: tesoro diff --git a/compiled/tutorial/manifests/echo-server-bundle.yml b/compiled/tutorial/manifests/echo-server-bundle.yml index a0cc2e9c..f9383df3 100644 --- a/compiled/tutorial/manifests/echo-server-bundle.yml +++ b/compiled/tutorial/manifests/echo-server-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: echo-server name: echo-server name: echo-server namespace: tutorial diff --git a/compiled/tutorial/manifests/echo-server-secret.yml b/compiled/tutorial/manifests/echo-server-secret.yml index 9576a471..a0b8cd59 100644 --- a/compiled/tutorial/manifests/echo-server-secret.yml +++ b/compiled/tutorial/manifests/echo-server-secret.yml @@ -1,12 +1,11 @@ apiVersion: v1 +data: + better_secret: ?{base64:eyJkYXRhIjogIlpXMVdRazlYWkdsVE1tTjNWV3BDYlZkSWJGbGlWamxtVVZaQk5VOUZNVlppTVdkNFZFUmtTMkZ1VWpWT1ZHaEVWVlZ3UTJWR1dqVmFkejA5IiwgImVuY29kaW5nIjogImJhc2U2NCIsICJ0eXBlIjogImJhc2U2NCJ9:embedded} + encoded_secret: bXlfc2VjcmV0 kind: Secret metadata: labels: name: echo-server - tesoro.kapicorp.com: enabled name: echo-server namespace: tutorial -stringData: - better_secret: ?{base64:eyJkYXRhIjogIlpXMVdRazlYWkdsVE1tTjNWV3BDYlZkSWJGbGlWamxtVVZaQk5VOUZNVlppTVdkNFZFUmtTMkZ1VWpWT1ZHaEVWVlZ3UTJWR1dqVmFkejA5IiwgImVuY29kaW5nIjogImJhc2U2NCIsICJ0eXBlIjogImJhc2U2NCJ9:embedded} - encoded_secret: my_secret type: Opaque diff --git a/compiled/tutorial/manifests/echo-server-security.yml b/compiled/tutorial/manifests/echo-server-security.yml index c60fa6c2..c5d4608b 100644 --- a/compiled/tutorial/manifests/echo-server-security.yml +++ b/compiled/tutorial/manifests/echo-server-security.yml @@ -15,6 +15,7 @@ spec: protocol: TCP podSelector: matchLabels: + app.kapicorp.dev/component: echo-server name: echo-server policyTypes: - Ingress diff --git a/compiled/tutorial/manifests/echo-server-service.yml b/compiled/tutorial/manifests/echo-server-service.yml index 182acd1a..5d50c441 100644 --- a/compiled/tutorial/manifests/echo-server-service.yml +++ b/compiled/tutorial/manifests/echo-server-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: echo-server name: echo-server name: echo-server namespace: tutorial diff --git a/compiled/tutorial/manifests/global-ingress.yml b/compiled/tutorial/manifests/global-ingress.yml index cd6cb31c..10ec7556 100644 --- a/compiled/tutorial/manifests/global-ingress.yml +++ b/compiled/tutorial/manifests/global-ingress.yml @@ -4,7 +4,6 @@ metadata: labels: name: global name: global - namespace: tutorial spec: rules: - http: diff --git a/compiled/vault/manifests/vault-bundle.yml b/compiled/vault/manifests/vault-bundle.yml index 103bb57f..0ed9abe8 100644 --- a/compiled/vault/manifests/vault-bundle.yml +++ b/compiled/vault/manifests/vault-bundle.yml @@ -4,6 +4,7 @@ metadata: annotations: manifests.kapicorp.com/generated: 'true' labels: + app.kapicorp.dev/component: vault app.kubernetes.io/component: go app.kubernetes.io/version: 1.7.3 name: vault diff --git a/compiled/vault/manifests/vault-rbac.yml b/compiled/vault/manifests/vault-rbac.yml index 51a0cf3b..a654bc8c 100644 --- a/compiled/vault/manifests/vault-rbac.yml +++ b/compiled/vault/manifests/vault-rbac.yml @@ -1,7 +1,17 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kapicorp.dev/component: vault + name: vault + name: vault + namespace: vault +--- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: + app.kapicorp.dev/component: vault name: vault name: vault namespace: vault @@ -21,23 +31,26 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: + app.kapicorp.dev/component: vault name: vault name: vault namespace: vault roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: vault subjects: - kind: ServiceAccount name: vault + namespace: vault --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: + app.kapicorp.dev/component: vault name: vault name: vault + namespace: vault rules: - apiGroups: - admissionregistration.k8s.io @@ -53,21 +66,14 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: labels: + app.kapicorp.dev/component: vault name: vault name: vault + namespace: vault roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: vault subjects: - kind: ServiceAccount name: vault namespace: vault ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - name: vault - name: vault - namespace: vault diff --git a/compiled/vault/manifests/vault-service.yml b/compiled/vault/manifests/vault-service.yml index c288d704..1a66ce3d 100644 --- a/compiled/vault/manifests/vault-service.yml +++ b/compiled/vault/manifests/vault-service.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: vault app.kubernetes.io/component: go app.kubernetes.io/version: 1.7.3 name: vault-internal @@ -30,6 +31,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: vault app.kubernetes.io/component: go app.kubernetes.io/version: 1.7.3 name: vault-active @@ -58,6 +60,7 @@ apiVersion: v1 kind: Service metadata: labels: + app.kapicorp.dev/component: vault app.kubernetes.io/component: go app.kubernetes.io/version: 1.7.3 name: vault-standby diff --git a/components/generators/kubernetes/__init__.py b/components/generators/kubernetes/__init__.py index 25d924d1..ccd027e9 100644 --- a/components/generators/kubernetes/__init__.py +++ b/components/generators/kubernetes/__init__.py @@ -1,37 +1,148 @@ -import base64 -import hashlib -import os +import logging +from typing import Any -from kapitan.cached import args -from kapitan.inputs.kadet import BaseObj, CompileError, inventory -from kapitan.utils import render_jinja2_file +from kapitan.inputs.kadet import ( + BaseModel, + BaseObj, + CompileError, + Dict, + inventory, + load_from_search_paths, +) -from . import k8s +from .common import Base, KubernetesResource, ResourceTypes +from .networking import NetworkPolicy +from .rbac import ClusterRole, ClusterRoleBinding, Role, RoleBinding +from .storage import ConfigMap, Secret, SharedConfig -search_paths = args.get("search_paths") +logger = logging.getLogger(__name__) + +kgenlib = load_from_search_paths("generators") inv = inventory(lazy=True) -def j2(filename, ctx): - return render_jinja2_file(filename, ctx, search_paths=search_paths) +class Workload(KubernetesResource): + + @classmethod + def create_workflow(cls, name, config): + config = config + name = name + if config.type == "deployment": + workload = Deployment(name=name, config=config) + elif config.type == "statefulset": + workload = StatefulSet(name=name, config=config) + elif config.type == "daemonset": + workload = DaemonSet(name=name, config=config) + elif config.type == "job": + workload = Job(name=name, config=config) + else: + raise () + if config.get("namespace") or inv.parameters.get("namespace"): + workload.root.metadata.namespace = config.setdefault( + "namespace", inv.parameters.namespace + ) + workload.add_annotations(config.setdefault("annotations", {})) + workload.root.spec.template.metadata.annotations = config.get( + "pod_annotations", {} + ) + workload.add_labels(config.setdefault("labels", {})) + workload.add_volumes(config.setdefault("volumes", {})) + workload.add_volume_claims(config.setdefault("volume_claims", {})) + workload.root.spec.template.spec.securityContext = ( + config.workload_security_context + ) + workload.root.spec.minReadySeconds = config.min_ready_seconds + if config.service_account.enabled: + workload.root.spec.template.spec.serviceAccountName = ( + config.service_account.get("name", name) + ) -def merge(source, destination): - for key, value in source.items(): - if isinstance(value, dict): - node = destination.setdefault(key, value) - if node is None: - destination[key] = value - else: - merge(value, node) - else: - destination[key] = destination.setdefault(key, value) + container = Container(name=name, container=config) + additional_containers = [ + Container(name=name, container=component) + for name, component in config.additional_containers.items() + ] + workload.add_containers([container]) + workload.add_containers(additional_containers) + init_containers = [ + Container(name=name, container=component) + for name, component in config.init_containers.items() + ] + + workload.add_init_containers(init_containers) + if config.image_pull_secrets or inv.parameters.image_pull_secrets: + workload.root.spec.template.spec.imagePullSecrets = config.get( + "image_pull_secrets", inv.parameters.image_pull_secrets + ) + workload.root.spec.template.spec.dnsPolicy = config.dns_policy + workload.root.spec.template.spec.terminationGracePeriodSeconds = config.get( + "grace_period", 30 + ) + + if config.node_selector: + workload.root.spec.template.spec.nodeSelector = config.node_selector + + if config.tolerations: + workload.root.spec.template.spec.tolerations = config.tolerations + + affinity = workload.root.spec.template.spec.affinity + if ( + config.prefer_pods_in_node_with_expression + and not config.node_selector + ): + affinity.nodeAffinity.setdefault( + "preferredDuringSchedulingIgnoredDuringExecutio", [] + ) + affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.append( + { + "preference": { + "matchExpressions": [ + config.prefer_pods_in_node_with_expression + ] + }, + "weight": 1, + } + ) - return destination + if config.prefer_pods_in_different_nodes: + affinity.podAntiAffinity.setdefault( + "preferredDuringSchedulingIgnoredDuringExecution", [] + ) + affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.append( + { + "podAffinityTerm": { + "labelSelector": { + "matchExpressions": [ + {"key": "app", "operator": "In", "values": [name]} + ] + }, + "topologyKey": "kubernetes.io/hostname", + }, + "weight": 1, + } + ) + if config.prefer_pods_in_different_zones: + affinity.podAntiAffinity.setdefault( + "preferredDuringSchedulingIgnoredDuringExecution", [] + ) + affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.append( + { + "podAffinityTerm": { + "labelSelector": { + "matchExpressions": [ + {"key": "app", "operator": "In", "values": [name]} + ] + }, + "topologyKey": "failure-domain.beta.kubernetes.io/zone", + }, + "weight": 1, + } + ) -class WorkloadCommon(BaseObj): + return workload def set_replicas(self, replicas): self.root.spec.replicas = replicas @@ -47,265 +158,128 @@ def add_init_containers(self, containers): def add_volumes(self, volumes): for key, value in volumes.items(): - merge({"name": key}, value) + kgenlib.merge({"name": key}, value) self.root.spec.template.spec.setdefault("volumes", []).append(value) def add_volume_claims(self, volume_claims): self.root.spec.setdefault("volumeClaimTemplates", []) for key, value in volume_claims.items(): - merge({"metadata": {"name": key, "labels": {"name": key}}}, value) + kgenlib.merge({"metadata": {"name": key, "labels": {"name": key}}}, value) self.root.spec.volumeClaimTemplates += [value] - def add_volumes_for_objects(self, objects): - for object in objects.root: - object_name = object.name - rendered_name = object.root.metadata.name - - if type(object) == ComponentConfig: - key = "configMap" - name_key = "name" - else: - key = "secret" - name_key = "secretName" - - template = self.root.spec.template - if isinstance(self, CronJob): - template = self.root.spec.jobTemplate.spec.template - - template.spec.setdefault("volumes", []).append( - { - "name": object_name, - key: { - "defaultMode": object.config.get("default_mode", 420), - name_key: rendered_name, - "items": [ - {"key": value, "path": value} for value in object.items - ], - }, - } - ) + def add_volumes_for_object(self, object): + object_name = object.object_name + rendered_name = object.rendered_name + if type(object) == ComponentConfig: + key = "configMap" + name_key = "name" + else: + key = "secret" + name_key = "secretName" -class NetworkPolicy(k8s.Base): - def new(self): - self.need("config") - self.need("workload") - self.kwargs.apiVersion = "networking.k8s.io/v1" - self.kwargs.kind = "NetworkPolicy" - super().new() + template = self.root.spec.template + if isinstance(self, CronJob): + template = self.root.spec.jobTemplate.spec.template - def body(self): - super().body() - policy = self.kwargs.config - workload = self.kwargs.workload - self.root.spec.podSelector.matchLabels = workload.metadata.labels - self.root.spec.ingress = policy.ingress - self.root.spec.egress = policy.egress - if self.root.spec.ingress: - self.root.spec.setdefault("policyTypes", []).append("Ingress") + template.spec.setdefault("volumes", []).append( + { + "name": object_name, + key: { + "defaultMode": object.config.get("default_mode", 420), + name_key: rendered_name, + "items": [{"key": value, "path": value} for value in object.items], + }, + } + ) - if self.root.spec.egress: - self.root.spec.setdefault("policyTypes", []).append("Egress") +class ServiceAccount(KubernetesResource): + resource_type = ResourceTypes.SERVICE_ACCOUNT.value -class ServiceAccount(k8s.Base): def new(self): - self.need("component") - self.kwargs.apiVersion = "v1" - self.kwargs.kind = "ServiceAccount" super().new() def body(self): super().body() - component = self.kwargs.component - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - self.add_annotations(component.service_account.annotations) - if component.image_pull_secrets or inv.parameters.pull_secret.name: + config = self.config + self.add_annotations(config.service_account.annotations) + if config.image_pull_secrets or inv.parameters.pull_secret.name: self.root.imagePullSecrets = [ { - "name": component.get( + "name": config.get( "image_pull_secrets", inv.parameters.pull_secret.name ) } ] -class SharedConfig: - """Shared class to use for both Secrets and ConfigMaps classes. - - containt anything needed by both classes, so that their behavious is basically the same. - Each subclass will then implement its own way of adding the data depending on their implementation. - """ - - @staticmethod - def encode_string(unencoded_string): - return base64.b64encode(unencoded_string.encode("ascii")).decode("ascii") - - def setup_metadata(self): - self.add_namespace( - self.config.get( - "namespace", - self.kwargs.component.get("namespace", inv.parameters.namespace), - ) - ) - - self.add_annotations(self.config.annotations) - self.add_labels(self.config.labels) - - self.items = self.config["items"] - try: - if isinstance(self, ConfigMap): - globals = ( - inv.parameters.generators.manifest.default_config.globals.config_maps - ) - else: - globals = ( - inv.parameters.generators.manifest.default_config.globals.secrets - ) - self.add_annotations(globals.get("annotations", {})) - self.add_labels(globals.get("labels", {})) - except AttributeError: - pass - - def add_directory(self, directory, encode=False): - stringdata = inv.parameters.get("use_tesoro", False) - if directory and os.path.isdir(directory): - for filename in os.listdir(directory): - with open(f"{directory}/{filename}", "r") as f: - file_content = f.read() - self.add_item( - filename, - file_content, - request_encode=encode, - stringdata=stringdata, - ) - - def add_data(self, data): - stringdata = inv.parameters.get("use_tesoro", False) - - for key, spec in data.items(): - encode = spec.get("b64_encode", False) - - if "value" in spec: - value = spec.get("value") - if "template" in spec: - value = j2(spec.template, spec.get("values", {})) - if "file" in spec: - with open(spec.file, "r") as f: - value = f.read() - - self.add_item(key, value, request_encode=encode, stringdata=stringdata) - - def add_string_data(self, string_data, encode=False): - stringdata = True - - for key, spec in string_data.items(): - - if "value" in spec: - value = spec.get("value") - if "template" in spec: - value = j2(spec.template, spec.get("values", {})) - if "file" in spec: - with open(spec.file, "r") as f: - value = f.read() - - self.add_item(key, value, request_encode=encode, stringdata=stringdata) - - def versioning(self, enabled=False): - if enabled: - keys_of_interest = ["data", "binaryData", "stringData"] - subset = { - key: value - for key, value in self.root.to_dict().items() - if key in keys_of_interest - } - self.hash = hashlib.sha256(str(subset).encode()).hexdigest()[:8] - self.root.metadata.name += f"-{self.hash}" - - -class ConfigMap(k8s.Base, SharedConfig): - def new(self): - self.kwargs.apiVersion = "v1" - self.kwargs.kind = "ConfigMap" - super().new() - - def body(self): - super().body() - - def add_item(self, key, value, request_encode=False, stringdata=False): - encode = request_encode - - self.root["data"][key] = self.encode_string(value) if encode else value - - class ComponentConfig(ConfigMap, SharedConfig): + config: Dict + def new(self): - self.need("config") super().new() def body(self): super().body() - self.config = self.kwargs.config - - self.setup_metadata() + self.versioning_enabled = self.config.get("versioned", False) + self.setup_metadata(inventory=inv) + if getattr(self, "workload", None) and self.workload.root.metadata.name: + self.add_label("name", self.workload.root.metadata.name) self.add_data(self.config.data) self.add_directory(self.config.directory, encode=False) - self.versioning(self.config.get("versioned", False)) -class Secret(k8s.Base): - def new(self): - self.kwargs.apiVersion = "v1" - self.kwargs.kind = "Secret" - super().new() - +@kgenlib.register_generator(path="generators.kubernetes.config_maps") +class ConfigGenerator(kgenlib.BaseStore): def body(self): - super().body() - - def add_item(self, key, value, request_encode=False, stringdata=False): - encode = not stringdata and request_encode - field = "stringData" if stringdata else "data" - self.root[field][key] = self.encode_string(value) if encode else value + self.add(ComponentConfig(name=self.name, config=self.config)) class ComponentSecret(Secret, SharedConfig): + config: Dict + def new(self): - self.need("config") super().new() def body(self): super().body() - self.config = self.kwargs.config self.root.type = self.config.get("type", "Opaque") - - self.setup_metadata() + self.versioning_enabled = self.config.get("versioned", False) + if getattr(self, "workload", None) and self.workload.root.metadata.name: + self.add_label("name", self.workload.root.metadata.name) + self.setup_metadata(inventory=inv) if self.config.data: self.add_data(self.config.data) if self.config.string_data: self.add_string_data(self.config.string_data) self.add_directory(self.config.directory, encode=True) - self.versioning(self.config.get("versioned", False)) -class Service(k8s.Base): +@kgenlib.register_generator(path="generators.kubernetes.secrets") +class SecretGenerator(kgenlib.BaseStore): + def body(self): + self.add(ComponentSecret(name=self.name, config=self.config)) + + +class Service(KubernetesResource): + + resource_type = ResourceTypes.SERVICE.value + workload: Workload + service_spec: dict + def new(self): - self.need("component") - self.need("workload") - self.need("service_spec") - self.kwargs.apiVersion = "v1" - self.kwargs.kind = "Service" super().new() def body(self): - component = self.kwargs.component - workload = self.kwargs.workload - service_spec = self.kwargs.service_spec + config = self.config + workload = self.workload.root + service_spec = self.service_spec - self.kwargs.name = service_spec.get("service_name", self.kwargs.name) + self.name = service_spec.get("service_name", self.name) super().body() - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - self.add_labels(component.get("labels", {})) + self.add_labels(config.get("labels", {})) self.add_annotations(service_spec.annotations) self.root.spec.setdefault("selector", {}).update( workload.spec.template.metadata.labels @@ -318,9 +292,9 @@ def body(self): self.root.spec.clusterIP = "None" self.root.spec.clusterIP self.root.spec.sessionAffinity = service_spec.get("session_affinity", "None") - all_ports = [component.ports] + [ + all_ports = [config.ports] + [ container.ports - for container in component.additional_containers.values() + for container in config.additional_containers.values() if "ports" in container ] @@ -348,52 +322,50 @@ def body(self): ) -class Ingress(k8s.Base): +class Ingress(KubernetesResource): + resource_type = ResourceTypes.INGRESS.value + def new(self): - self.need("name") - self.need("ingress") - self.kwargs.apiVersion = "networking.k8s.io/v1" - self.kwargs.kind = "Ingress" super().new() def body(self): super().body() - ingress = self.kwargs.ingress - self.add_namespace(ingress.get("namespace", inv.parameters.namespace)) - import json - - self.add_annotations(ingress.get("annotations", {})) - self.add_labels(ingress.get("labels", {})) - if "default_backend" in ingress: - self.root.spec.backend.service.name = ingress.default_backend.get("name") - self.root.spec.backend.service.port = ingress.default_backend.get( + config = self.config + + self.add_annotations(config.get("annotations", {})) + self.add_labels(config.get("labels", {})) + if "default_backend" in config: + self.root.spec.backend.service.name = config.default_backend.get("name") + self.root.spec.backend.service.port = config.default_backend.get( "port", 80 ) - if "paths" in ingress: - host = ingress.host - paths = ingress.paths - self.root.spec.rules = [{"host": host, "http": {"paths": paths}}] - if ingress.tls: - self.root.spec.tls = ingress.tls + if "paths" in config: + host = config.host + paths = config.paths + self.root.spec.setdefault("rules", []).extend( + [{"host": host, "http": {"paths": paths}}] + ) + if "rules" in config: + self.root.spec.setdefault("rules", []).extend(config.rules) + if config.tls: + self.root.spec.tls = config.tls -class ManagedCertificate(k8s.Base): +class GoogleManagedCertificate(KubernetesResource): + resource_type = ResourceTypes.GOOGLE_MANAGED_CERTIFICATE.value + def new(self): - self.need("name") - self.need("domains") - self.kwargs.apiVersion = "networking.gke.io/v1beta1" - self.kwargs.kind = "ManagedCertificate" super().new() def body(self): super().body() - name = self.kwargs.name - domains = self.kwargs.domains - self.add_namespace(inv.parameters.namespace) - self.root.spec.domains = domains + name = self.name + config= self.config + self.root.spec.domains = config.get("domains", []) -class CertManagerIssuer(k8s.Base): +@kgenlib.register_generator(path="certmanager.issuer") +class CertManagerIssuer(Base): def new(self): self.need("config_spec") self.kwargs.apiVersion = "cert-manager.io/v1" @@ -402,12 +374,12 @@ def new(self): def body(self): config_spec = self.kwargs.config_spec - self.add_namespace(config_spec.get("namespace", inv.parameters.namespace)) super().body() self.root.spec = config_spec.get("spec") -class CertManagerClusterIssuer(k8s.Base): +@kgenlib.register_generator(path="certmanager.cluster_issuer") +class CertManagerClusterIssuer(Base): def new(self): self.need("config_spec") self.kwargs.apiVersion = "cert-manager.io/v1" @@ -420,7 +392,8 @@ def body(self): self.root.spec = config_spec.get("spec") -class CertManagerCertificate(k8s.Base): +@kgenlib.register_generator(path="certmanager.certificate") +class CertManagerCertificate(Base): def new(self): self.need("config_spec") self.kwargs.apiVersion = "cert-manager.io/v1" @@ -429,12 +402,11 @@ def new(self): def body(self): config_spec = self.kwargs.config_spec - self.add_namespace(config_spec.get("namespace", inv.parameters.namespace)) super().body() self.root.spec = config_spec.get("spec") -class IstioPolicy(k8s.Base): +class IstioPolicy(Base): def new(self): self.need("component") self.need("workload") @@ -444,7 +416,6 @@ def new(self): def body(self): config_spec = self.kwargs.config_spec - self.add_namespace(config_spec.get("namespace", inv.parameters.namespace)) super().body() component = self.kwargs.component name = self.kwargs.name @@ -453,27 +424,32 @@ def body(self): self.root.spec.targets = [{"name": name}] -class NameSpace(k8s.Base): +@kgenlib.register_generator(path="generators.kubernetes.namespace") +class NamespaceGenerator(kgenlib.BaseStore): + def body(self): + name = self.config.get("name", self.name) + self.add(Namespace(name=name, config=self.config)) + + +class Namespace(KubernetesResource): + resource_type = ResourceTypes.NAMESPACE.value + def new(self): - self.need("name") - self.kwargs.apiVersion = "v1" - self.kwargs.kind = "Namespace" super().new() def body(self): super().body() - name = self.kwargs.name - labels = inv.parameters.generators.kubernetes.namespace.labels - annotations = inv.parameters.generators.kubernetes.namespace.annotations + config = self.config + labels = config.get("labels", {}) + annotations = config.get("annotations", {}) self.add_labels(labels) self.add_annotations(annotations) -class Deployment(k8s.Base, WorkloadCommon): +class Deployment(Workload): + resource_type = ResourceTypes.DEPLOYMENT.value + def new(self): - self.need("component") - self.kwargs.apiVersion = "apps/v1" - self.kwargs.kind = "Deployment" super().new() def body(self): @@ -482,138 +458,130 @@ def body(self): "rollingUpdate": {"maxSurge": "25%", "maxUnavailable": "25%"}, } super().body() - component = self.kwargs.component + config = self.config self.root.spec.template.metadata.setdefault("labels", {}).update( - component.labels + self.root.metadata.labels + config.labels + self.root.metadata.labels ) self.root.spec.selector.setdefault("matchLabels", {}).update( - component.labels + self.root.metadata.labels + config.labels + self.root.metadata.labels ) - self.root.spec.template.spec.restartPolicy = component.get( + self.root.spec.template.spec.restartPolicy = config.get( "restart_policy", "Always" ) - if "host_network" in component: - self.root.spec.template.spec.hostNetwork = component.host_network - if "host_pid" in component: - self.root.spec.template.spec.hostPID = component.host_pid - self.root.spec.strategy = component.get("update_strategy", default_strategy) - self.root.spec.revisionHistoryLimit = component.revision_history_limit + if "host_network" in config: + self.root.spec.template.spec.hostNetwork = config.host_network + if "host_pid" in config: + self.root.spec.template.spec.hostPID = config.host_pid + self.root.spec.strategy = config.get("update_strategy", default_strategy) + self.root.spec.revisionHistoryLimit = config.revision_history_limit self.root.spec.progressDeadlineSeconds = ( - component.deployment_progress_deadline_seconds + config.deployment_progress_deadline_seconds ) - self.set_replicas(component.get("replicas", 1)) + self.set_replicas(config.get("replicas", 1)) + +class StatefulSet(Workload): + resource_type = ResourceTypes.STATEFUL_SET.value -class StatefulSet(k8s.Base, WorkloadCommon): def new(self): - self.need("component") - self.kwargs.apiVersion = "apps/v1" - self.kwargs.kind = "StatefulSet" super().new() - + def body(self): default_strategy = {} update_strategy = {"rollingUpdate": {"partition": 0}, "type": "RollingUpdate"} super().body() - name = self.kwargs.name - component = self.kwargs.component + name = self.name + config = self.config self.root.spec.template.metadata.setdefault("labels", {}).update( - component.labels + self.root.metadata.labels + config.labels + self.root.metadata.labels ) self.root.spec.selector.setdefault("matchLabels", {}).update( - component.labels + self.root.metadata.labels + config.labels + self.root.metadata.labels ) - self.root.spec.template.spec.restartPolicy = component.get( + self.root.spec.template.spec.restartPolicy = config.get( "restart_policy", "Always" ) - if "host_network" in component: - self.root.spec.template.spec.hostNetwork = component.host_network - if "host_pid" in component: - self.root.spec.template.spec.hostPID = component.host_pid - self.root.spec.revisionHistoryLimit = component.revision_history_limit - self.root.spec.strategy = component.get("strategy", default_strategy) - self.root.spec.updateStrategy = component.get( + if "host_network" in config: + self.root.spec.template.spec.hostNetwork = config.host_network + if "host_pid" in config: + self.root.spec.template.spec.hostPID = config.host_pid + self.root.spec.revisionHistoryLimit = config.revision_history_limit + self.root.spec.strategy = config.get("strategy", default_strategy) + self.root.spec.updateStrategy = config.get( "update_strategy", update_strategy ) - self.root.spec.serviceName = component.service.get("service_name", name) - self.set_replicas(component.get("replicas", 1)) + self.root.spec.serviceName = config.service.get("service_name", name) + self.set_replicas(config.get("replicas", 1)) -class DaemonSet(k8s.Base, WorkloadCommon): +class DaemonSet(Workload): + resource_type = ResourceTypes.DAEMON_SET.value + def new(self): - self.need("component") - self.kwargs.apiVersion = "apps/v1" - self.kwargs.kind = "DaemonSet" super().new() def body(self): - default_strategy = { - "type": "RollingUpdate", - "rollingUpdate": {"maxSurge": "25%", "maxUnavailable": "25%"}, - } super().body() - component = self.kwargs.component + config = self.config self.root.spec.template.metadata.setdefault("labels", {}).update( - component.labels + self.root.metadata.labels + config.labels + self.root.metadata.labels ) self.root.spec.selector.setdefault("matchLabels", {}).update( - component.labels + self.root.metadata.labels + config.labels + self.root.metadata.labels ) - self.root.spec.template.spec.restartPolicy = component.get( + self.root.spec.template.spec.restartPolicy = config.get( "restart_policy", "Always" ) - if "host_network" in component: - self.root.spec.template.spec.hostNetwork = component.host_network - if "host_pid" in component: - self.root.spec.template.spec.hostPID = component.host_pid - self.root.spec.revisionHistoryLimit = component.revision_history_limit + if "host_network" in config: + self.root.spec.template.spec.hostNetwork = config.host_network + if "host_pid" in config: + self.root.spec.template.spec.hostPID = config.host_pid + self.root.spec.revisionHistoryLimit = config.revision_history_limit self.root.spec.progressDeadlineSeconds = ( - component.deployment_progress_deadline_seconds + config.deployment_progress_deadline_seconds ) -class Job(k8s.Base, WorkloadCommon): +class Job(Workload): + resource_type = ResourceTypes.JOB.value + def new(self): - self.kwargs.apiVersion = "batch/v1" - self.kwargs.kind = "Job" super().new() - self.need("component") def body(self): super().body() - name = self.kwargs.name - component = self.kwargs.component + name = self.name + config = self.config self.root.spec.template.metadata.setdefault("labels", {}).update( - component.labels + self.root.metadata.labels + config.labels + self.root.metadata.labels ) - self.root.spec.template.spec.restartPolicy = component.get( + self.root.spec.template.spec.restartPolicy = config.get( "restart_policy", "Never" ) - if "host_network" in component: - self.root.spec.template.spec.hostNetwork = component.host_network - if "host_pid" in component: - self.root.spec.template.spec.hostPID = component.host_pid - self.root.spec.backoffLimit = component.get("backoff_limit", 1) - self.root.spec.completions = component.get("completions", 1) - self.root.spec.parallelism = component.get("parallelism", 1) + if "host_network" in config: + self.root.spec.template.spec.hostNetwork = config.host_network + if "host_pid" in config: + self.root.spec.template.spec.hostPID = config.host_pid + self.root.spec.backoffLimit = config.get("backoff_limit", 1) + self.root.spec.completions = config.get("completions", 1) + self.root.spec.parallelism = config.get("parallelism", 1) + +class CronJob(Workload): + resource_type = ResourceTypes.CRON_JOB.value -class CronJob(k8s.Base, WorkloadCommon): def new(self): - self.need("component") - self.need("job") - self.kwargs.apiVersion = "batch/v1beta1" - self.kwargs.kind = "CronJob" super().new() def body(self): super().body() - component = self.kwargs.component - job = self.kwargs.job + name = self.name + config = self.config + job = self.job self.root.metadata = job.root.metadata self.root.spec.jobTemplate.spec = job.root.spec - self.root.spec.schedule = component.schedule + self.root.spec.schedule = config.schedule class Container(BaseObj): @@ -715,7 +683,7 @@ def add_volume_mounts_from_configs(self): def add_volume_mounts(self, volume_mounts): for key, value in volume_mounts.items(): - merge({"name": key}, value) + kgenlib.merge({"name": key}, value) self.root.setdefault("volumeMounts", []).append(value) @staticmethod @@ -780,132 +748,10 @@ def body(self): self.process_envs(container) -class Workload(WorkloadCommon): - def new(self): - self.need("name") - self.need("component") - - def body(self): - component = self.kwargs.component - name = self.kwargs.name - if component.type == "deployment": - workload = Deployment(name=name, component=self.kwargs.component) - elif component.type == "statefulset": - workload = StatefulSet(name=name, component=self.kwargs.component) - elif component.type == "daemonset": - workload = DaemonSet(name=name, component=self.kwargs.component) - elif component.type == "job": - workload = Job(name=name, component=self.kwargs.component) - else: - raise () - if component.get("namespace") or inv.parameters.get("namespace"): - workload.root.metadata.namespace = component.setdefault( - "namespace", inv.parameters.namespace - ) - workload.add_annotations(component.setdefault("annotations", {})) - workload.root.spec.template.metadata.annotations = component.get( - "pod_annotations", {} - ) - workload.add_labels(component.setdefault("labels", {})) - workload.add_volumes(component.setdefault("volumes", {})) - workload.add_volume_claims(component.setdefault("volume_claims", {})) - workload.root.spec.template.spec.securityContext = ( - component.workload_security_context - ) - workload.root.spec.minReadySeconds = component.min_ready_seconds - if component.service_account.enabled: - workload.root.spec.template.spec.serviceAccountName = ( - component.service_account.get("name", name) - ) - container = Container(name=name, container=component) - additional_containers = [ - Container(name=name, container=component) - for name, component in component.additional_containers.items() - ] - workload.add_containers([container]) - workload.add_containers(additional_containers) - init_containers = [ - Container(name=name, container=component) - for name, component in component.init_containers.items() - ] - workload.add_init_containers(init_containers) - if component.image_pull_secrets or inv.parameters.image_pull_secrets: - workload.root.spec.template.spec.imagePullSecrets = component.get( - "image_pull_secrets", inv.parameters.image_pull_secrets - ) - workload.root.spec.template.spec.dnsPolicy = component.dns_policy - workload.root.spec.template.spec.terminationGracePeriodSeconds = component.get( - "grace_period", 30 - ) - - if component.node_selector: - workload.root.spec.template.spec.nodeSelector = component.node_selector - - if component.tolerations: - workload.root.spec.template.spec.tolerations = component.tolerations - - affinity = workload.root.spec.template.spec.affinity - if ( - component.prefer_pods_in_node_with_expression - and not component.node_selector - ): - affinity.nodeAffinity.setdefault( - "preferredDuringSchedulingIgnoredDuringExecutio", [] - ) - affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.append( - { - "preference": { - "matchExpressions": [ - component.prefer_pods_in_node_with_expression - ] - }, - "weight": 1, - } - ) - - if component.prefer_pods_in_different_nodes: - affinity.podAntiAffinity.setdefault( - "preferredDuringSchedulingIgnoredDuringExecution", [] - ) - affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.append( - { - "podAffinityTerm": { - "labelSelector": { - "matchExpressions": [ - {"key": "app", "operator": "In", "values": [name]} - ] - }, - "topologyKey": "kubernetes.io/hostname", - }, - "weight": 1, - } - ) - - if component.prefer_pods_in_different_zones: - affinity.podAntiAffinity.setdefault( - "preferredDuringSchedulingIgnoredDuringExecution", [] - ) - affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution.append( - { - "podAffinityTerm": { - "labelSelector": { - "matchExpressions": [ - {"key": "app", "operator": "In", "values": [name]} - ] - }, - "topologyKey": "failure-domain.beta.kubernetes.io/zone", - }, - "weight": 1, - } - ) - - self.root = workload.root - - -class GenerateMultipleObjectsForClass(BaseObj): +class GenerateMultipleObjectsForClass(kgenlib.BaseStore): """Helper to generate multiple classes As a convention for generators we have that if you define only one policy/config/secret configuration @@ -916,243 +762,142 @@ class GenerateMultipleObjectsForClass(BaseObj): This class helps achieve that for policies/config/secrets to avoid duplication. """ - def new(self): - self.need("name") - self.need("component") - self.need("objects") - self.need("generating_class") - self.need("workload") - self.root = [] + component_config: dict + generating_class: Any + workload: Any def body(self): - objects = self.kwargs.objects - name = self.kwargs.name - component = self.kwargs.component - generating_class = self.kwargs.generating_class - workload = self.kwargs.workload + component_config = self.component_config + name = self.name + objects_configs = self.config + generating_class = self.generating_class + workload = self.workload - for object_name, object_config in objects.items(): + for object_name, object_config in objects_configs.items(): if object_config == None: raise CompileError( f"error with '{object_name}' for component {name}: configuration cannot be empty!" ) - if len(objects.items()) == 1: - rendered_name = f"{name}" + if len(objects_configs.items()) == 1: + name = f"{self.name}" else: - rendered_name = f"{name}-{object_name}" - - self.root.append( - generating_class( - name=object_name, - rendered_name=rendered_name, - config=object_config, - component=component, - workload=workload, - ) + name = f"{self.name}-{object_name}" + + generated_object = generating_class( + name=name, + object_name=object_name, + config=object_config, + component=component_config, + workload=workload, ) + if generated_object.resource_type in ( + ResourceTypes.CONFIG_MAP.value, + ResourceTypes.SECRET.value, + ): + workload.add_volumes_for_object(generated_object) + self.add(generated_object) + + +class PrometheusRule(KubernetesResource): + resource_type = ResourceTypes.PROMETHEUS_RULE.value -class PrometheusRule(k8s.Base): def new(self): - self.need("component") - self.kwargs.apiVersion = "monitoring.coreos.com/v1" - self.kwargs.kind = "PrometheusRule" super().new() def body(self): - # TODO(ademaria) This name mangling is here just to simplify diff. - # Change it once done - component_name = self.kwargs.name - self.kwargs.name = "{}.rules".format(component_name) + name = self.name super().body() - name = self.kwargs.name - component = self.kwargs.component - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - - # TODO(ademaria): use `name` instead of `tesoro.rules` + config = self.config self.root.spec.setdefault("groups", []).append( - {"name": "tesoro.rules", "rules": component.prometheus_rules.rules} + {"name": name, "rules": config.prometheus_rules.rules} ) -class BackendConfig(k8s.Base): +class BackendConfig(KubernetesResource): + resource_type = ResourceTypes.BACKEND_CONFIG.value def new(self): - self.need("component") - self.kwargs.apiVersion = "cloud.google.com/v1" - self.kwargs.kind = "BackendConfig" super().new() def body(self): - component_name = self.kwargs.name - self.kwargs.name = f"{component_name}-backend-config" super().body() - name = self.kwargs.name - component = self.kwargs.component - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - self.root.spec = component.backend_config + name = self.name + config = self.config + self.root.spec = config.backend_config -class ServiceMonitor(k8s.Base): +class ServiceMonitor(KubernetesResource): + resource_type = ResourceTypes.SERVICE_MONITOR.value + workload: Workload + def new(self): - self.need("component") - self.need("workload") - self.kwargs.apiVersion = "monitoring.coreos.com/v1" - self.kwargs.kind = "ServiceMonitor" super().new() def body(self): # TODO(ademaria) This name mangling is here just to simplify diff. # Change it once done - component_name = self.kwargs.name - workload = self.kwargs.workload - self.kwargs.name = "{}-metrics".format(component_name) + name = self.name + workload = self.workload + self.name = "{}-metrics".format(name) super().body() - name = self.kwargs.name - component = self.kwargs.component - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - self.root.spec.endpoints = component.service_monitors.endpoints + name = self.name + config = self.config + self.root.spec.endpoints = config.service_monitors.endpoints self.root.spec.jobLabel = name - self.root.spec.namespaceSelector.matchNames = [inv.parameters.namespace] - self.root.spec.selector.matchLabels = workload.spec.template.metadata.labels + self.root.spec.namespaceSelector.matchNames = [self.namespace] + self.root.spec.selector.matchLabels = workload.root.spec.template.metadata.labels -class MutatingWebhookConfiguration(k8s.Base): +class MutatingWebhookConfiguration(KubernetesResource): + resource_type = ResourceTypes.MUTATING_WEBHOOK_CONFIGURATION.value + def new(self): - self.need("component") - self.kwargs.apiVersion = "admissionregistration.k8s.io/v1beta1" - self.kwargs.kind = "MutatingWebhookConfiguration" super().new() def body(self): super().body() - name = self.kwargs.name - component = self.kwargs.component - self.root.webhooks = component.webhooks - - -class Role(k8s.Base): - def new(self): - self.need("component") - self.kwargs.apiVersion = "rbac.authorization.k8s.io/v1" - self.kwargs.kind = "Role" - super().new() + name = self.name + config = self.config + self.root.webhooks = config.webhooks - def body(self): - super().body() - name = self.kwargs.name - component = self.kwargs.component - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - self.root.rules = component.role.rules +class PodDisruptionBudget(KubernetesResource): + resource_type = ResourceTypes.POD_DISRUPTION_BUDGET.value + workload: Workload -class RoleBinding(k8s.Base): def new(self): - self.need("component") - self.kwargs.apiVersion = "rbac.authorization.k8s.io/v1" - self.kwargs.kind = "RoleBinding" super().new() def body(self): super().body() - default_role_ref = { - "apiGroup": "rbac.authorization.k8s.io", - "kind": "Role", - "name": self.kwargs.component.name, - } - default_subject = [ - { - "kind": "ServiceAccount", - "name": self.kwargs.component.name, - } - ] - name = self.kwargs.name - component = self.kwargs.component - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - self.root.roleRef = component.get("roleRef", default_role_ref) - self.root.subjects = component.get("subject", default_subject) - - -class ClusterRole(k8s.Base): - def new(self): - self.need("component") - self.kwargs.apiVersion = "rbac.authorization.k8s.io/v1" - self.kwargs.kind = "ClusterRole" - super().new() - - def body(self): - super().body() - name = self.kwargs.name - component = self.kwargs.component - self.root.rules = component.cluster_role.rules - - -class ClusterRoleBinding(k8s.Base): - def new(self): - self.need("component") - self.kwargs.apiVersion = "rbac.authorization.k8s.io/v1" - self.kwargs.kind = "ClusterRoleBinding" - super().new() - - def body(self): - super().body() - default_role_ref = { - "apiGroup": "rbac.authorization.k8s.io", - "kind": "ClusterRole", - "name": self.kwargs.component.name, - } - default_subject = [ - { - "kind": "ServiceAccount", - "name": self.kwargs.component.name, - "namespace": inv.parameters.namespace, - } - ] - name = self.kwargs.name - component = self.kwargs.component - self.root.roleRef = component.get("roleRef", default_role_ref) - self.root.subjects = component.get("subject", default_subject) - - -class PodDisruptionBudget(k8s.Base): - def new(self): - self.need("component") - self.need("workload") - self.kwargs.apiVersion = "policy/v1beta1" - self.kwargs.kind = "PodDisruptionBudget" - super().new() - - def body(self): - super().body() - component = self.kwargs.component - workload = self.kwargs.workload - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - if component.auto_pdb: + config = self.config + workload = self.workload + self.add_namespace(config.get("namespace", inv.parameters.namespace)) + if config.auto_pdb: self.root.spec.maxUnavailable = 1 else: - self.root.spec.minAvailable = component.pdb_min_available - self.root.spec.selector.matchLabels = workload.spec.template.metadata.labels + self.root.spec.minAvailable = config.pdb_min_available + self.root.spec.selector.matchLabels = workload.root.spec.template.metadata.labels + +class VerticalPodAutoscaler(KubernetesResource): + resource_type = ResourceTypes.VERTICAL_POD_AUTOSCALER.value + workload: Workload -class VerticalPodAutoscaler(k8s.Base): def new(self): - self.need("component") - self.need("workload") - self.kwargs.apiVersion = "autoscaling.k8s.io/v1beta2" - self.kwargs.kind = "VerticalPodAutoscaler" super().new() def body(self): super().body() - component = self.kwargs.component - workload = self.kwargs.workload - self.add_namespace(inv.parameters.namespace) - self.add_labels(workload.metadata.labels) - self.root.spec.targetRef.apiVersion = workload.apiVersion + config = self.config + workload = self.workload + self.add_labels(workload.root.metadata.labels) + self.root.spec.targetRef.apiVersion = workload.api_version self.root.spec.targetRef.kind = workload.kind - self.root.spec.targetRef.name = workload.metadata.name - self.root.spec.updatePolicy.updateMode = component.vpa + self.root.spec.targetRef.name = workload.name + self.root.spec.updatePolicy.updateMode = config.vpa # TODO(ademaria) Istio blacklist is always desirable but add way to make it configurable. self.root.spec.resourcePolicy.containerPolicies = [ @@ -1160,121 +905,56 @@ def body(self): ] -class HorizontalPodAutoscaler(k8s.Base): +class HorizontalPodAutoscaler(KubernetesResource): + resource_type = ResourceTypes.HORIZONTAL_POD_AUTOSCALER.value + workload: Workload + def new(self): - self.need("component") - self.need("workload") - self.kwargs.apiVersion = "autoscaling/v2beta2" - self.kwargs.kind = "HorizontalPodAutoscaler" super().new() def body(self): super().body() - component = self.kwargs.component - workload = self.kwargs.workload + config = self.config + workload = self.workload self.add_namespace(inv.parameters.namespace) - self.add_labels(workload.metadata.labels) - self.root.spec.scaleTargetRef.apiVersion = workload.apiVersion + self.add_labels(workload.root.metadata.labels) + self.root.spec.scaleTargetRef.apiVersion = workload.api_version self.root.spec.scaleTargetRef.kind = workload.kind - self.root.spec.scaleTargetRef.name = workload.metadata.name - self.root.spec.minReplicas = component.hpa.min_replicas - self.root.spec.maxReplicas = component.hpa.max_replicas - self.root.spec.metrics = component.hpa.metrics + self.root.spec.scaleTargetRef.name = workload.name + self.root.spec.minReplicas = config.hpa.min_replicas + self.root.spec.maxReplicas = config.hpa.max_replicas + self.root.spec.metrics = config.hpa.metrics -class VerticalPodAutoscaler(k8s.Base): - def new(self): - self.need("component") - self.need("workload") - self.kwargs.apiVersion = "autoscaling.k8s.io/v1beta2" - self.kwargs.kind = "VerticalPodAutoscaler" - super().new() +class PodSecurityPolicy(KubernetesResource): + resource_type = ResourceTypes.POD_SECURITY_POLICY.value + workload: Workload - def body(self): - super().body() - component = self.kwargs.component - workload = self.kwargs.workload - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - self.add_labels(workload.metadata.labels) - self.root.spec.targetRef.apiVersion = workload.apiVersion - self.root.spec.targetRef.kind = workload.kind - self.root.spec.targetRef.name = workload.metadata.name - self.root.spec.updatePolicy.updateMode = component.vpa - - # TODO(ademaria) Istio blacklist is always desirable but add way to make it configurable. - self.root.spec.resourcePolicy.containerPolicies = [ - {"containerName": "istio-proxy", "mode": "Off"} - ] - - -class PodSecurityPolicy(k8s.Base): def new(self): - self.need("component") - self.need("workload") - self.kwargs.apiVersion = "policy/v1beta1" - self.kwargs.kind = "PodSecurityPolicy" super().new() def body(self): super().body() - component = self.kwargs.component - workload = self.kwargs.workload - self.add_namespace(component.get("namespace", inv.parameters.namespace)) - # relativly RAW input here, there is not much to be automatically generated - self.root.spec = component.pod_security_policy.spec + config = self.config + self.root.spec = config.pod_security_policy.spec # Merge Dicts into PSP Annotations self.root.metadata.annotations = { - **component.get("annotations", {}), - **component.pod_security_policy.get("annotations", {}), + **config.get("annotations", {}), + **config.pod_security_policy.get("annotations", {}), } # Merge Dicts into PSP Labels self.root.metadata.labels = { - **component.get("labels", {}), - **component.pod_security_policy.get("labels", {}), + **config.get("labels", {}), + **config.pod_security_policy.get("labels", {}), } -def get_components(): - if "components" in inv.parameters: - generator_defaults = inv.parameters.generators.manifest.default_config - - for name, component in inv.parameters.components.items(): - if component.get("enabled", True): - if "application" in component: - application_defaults = inv.parameters.applications.get( - component.application, {} - ).get("component_defaults", {}) - merge(generator_defaults, application_defaults) - if component.get("type", "undefined") in component.globals: - merge( - application_defaults, - component.globals.get(component.type, {}), - ) - merge(application_defaults, component) - - merge(generator_defaults, component) - component_type = component.get("type", generator_defaults.type) - if ( - component_type - in inv.parameters.generators.manifest.resource_defaults - ): - component_defaults = ( - inv.parameters.generators.manifest.resource_defaults[ - component_type - ] - ) - merge(component_defaults, component) - - component.name = name - yield name, component - - def generate_docs(input_params): obj = BaseObj() template = input_params.get("template_path", None) if template: for name, component in get_components(): - obj.root["{}-readme.md".format(name)] = j2( + obj.root["{}-readme.md".format(name)] = kgenlib.render_jinja( template, { "service_component": component.to_dict(), @@ -1284,244 +964,193 @@ def generate_docs(input_params): return obj -def generate_resource_manifests(input_params): - obj = BaseObj() - namespace_name = inv.parameters.namespace - namespace = NameSpace(name=namespace_name) - if namespace_name != "": - obj.root["{}-namespace".format(namespace_name)] = namespace - - for ( - secret_name, - secret_spec, - ) in inv.parameters.generators.kubernetes.secrets.items(): - name = secret_spec.get("name", secret_name) - secret = ComponentSecret(name=name, config=secret_spec) - obj.root[f"{name}"] = secret - - if inv.parameters.generators.kubernetes.cert_manager: - cert_manager = inv.parameters.generators.kubernetes.cert_manager - - for cert_name, cert_spec in cert_manager.certs.items(): - if cert_spec.get("type", "certmanager") == "certmanager": - name = cert_spec.get("name", cert_name) - cmc = CertManagerCertificate(name=name, config_spec=cert_spec) - obj.root[f"{name}-cm-cert"] = cmc - - for issuer_name, issuer_spec in cert_manager.issuers.items(): - if issuer_spec.get("type", "certmanager") == "certmanager": - name = issuer_spec.get("name", issuer_name) - cmi = CertManagerIssuer(name=name, config_spec=issuer_spec) - obj.root[f"{name}-cm-issuer"] = cmi - - for issuer_name, issuer_spec in cert_manager.clusterissuers.items(): - if issuer_spec.get("type", "certmanager") == "certmanager": - name = issuer_spec.get("name", issuer_name) - cmci = CertManagerClusterIssuer(name=name, config_spec=issuer_spec) - obj.root[f"{name}-cmc-issuer"] = cmci - return obj - - -def generate_ingress(input_params): - # Only generate ingress manifest if istio not enabled - if not inv.parameters.istio.enabled: - obj = BaseObj() - bundle = list() - ingresses = inv.parameters.ingresses - for name in ingresses.keys(): - ingress = Ingress(name=name, ingress=ingresses[name]) - - if "managed_certificate" in ingresses[name]: - certificate_spec = ingresses[name] - certificate_name = certificate_spec.managed_certificate - additional_domains = certificate_spec.get("additional_domains", []) - domains = [certificate_name] + additional_domains - ingress.add_annotations( - {"networking.gke.io/managed-certificates": certificate_name} - ) - certificate = ManagedCertificate(name=certificate_name, domains=domains) - obj.root["{}-managed-certificate".format(name)] = certificate - - obj.root["{}-ingress".format(name)] = ingress - - return obj - - -def generate_component_manifests(input_params): - obj = BaseObj() - for name, component in get_components(): - bundle_workload = [] - bundle_configs = [] - bundle_secrets = [] - bundle_service = [] - bundle_rbac = [] - bundle_scaling = [] - bundle_security = [] +@kgenlib.register_generator(path="ingresses") +class IngressComponent(kgenlib.BaseStore): + name: str + config: Any - workload = Workload(name=name, component=component) + def body(self): + name = self.name + config = self.config + ingress = Ingress(name=name, config=config) + self.add(ingress) + + if "managed_certificate" in config: + certificate_name = config.managed_certificate + additional_domains = config.get("additional_domains", []) + domains = [certificate_name] + additional_domains + ingress.add_annotations( + {"networking.gke.io/managed-certificates": certificate_name} + ) + self.add( + GoogleManagedCertificate(name=certificate_name, config={"domains": domains}) + ) - if component.schedule: - workload = CronJob(name=name, component=component, job=workload) - workload_spec = workload.root +@kgenlib.register_generator( + path="components", + apply_patches=[ + "generators.manifest.default_config", + "applications.{application}.component_defaults", + ], +) +class Components(kgenlib.BaseStore): + def body(self): + name = self.name + config = self.config + workload = Workload.create_workflow(name=name, config=config) - bundle_workload += [workload_spec] + logging.debug(f"Generating component {name} from {config}") + if config.schedule: + workload = CronJob(name=name, config=config, job=workload) + workload.add_label("app.kapicorp.dev/component", name) + configs = GenerateMultipleObjectsForClass( name=name, - component=component, + component_config=config, generating_class=ComponentConfig, - objects=component.config_maps, - workload=workload_spec, + config=config.config_maps, + workload=workload, ) + map(lambda x: x.add_label("app.kapicorp.dev/component", name), configs) + secrets = GenerateMultipleObjectsForClass( name=name, - component=component, + component_config=config, generating_class=ComponentSecret, - objects=component.secrets, - workload=workload_spec, + config=config.secrets, + workload=workload, ) + + map(lambda x: x.add_label("app.kapicorp.dev/component", name), secrets) - workload.add_volumes_for_objects(configs) - workload.add_volumes_for_objects(secrets) - - bundle_configs += configs.root - bundle_secrets += secrets.root + self.add(workload) + self.add(configs) + self.add(secrets) if ( - component.vpa + config.vpa and inv.parameters.get("enable_vpa", True) - and component.type != "job" + and config.type != "job" ): - vpa = VerticalPodAutoscaler( - name=name, component=component, workload=workload_spec - ).root - bundle_scaling += [vpa] - - if component.pdb_min_available: - pdb = PodDisruptionBudget( - name=name, component=component, workload=workload_spec - ).root - bundle_scaling += [pdb] - - if component.hpa: + vpa = VerticalPodAutoscaler(name=name, config=config, workload=workload) + vpa.add_label("app.kapicorp.dev/component", name) + self.add(vpa) + + if config.pdb_min_available: + pdb = PodDisruptionBudget(name=name, config=config, workload=workload) + pdb.add_label("app.kapicorp.dev/component", name) + self.add(pdb) + + if config.hpa: hpa = HorizontalPodAutoscaler( - name=name, component=component, workload=workload_spec - ).root - bundle_scaling += [hpa] + name=name, config=config, workload=workload + ) + hpa.add_label("app.kapicorp.dev/component", name) + self.add(hpa) - if component.type != "job": - if component.pdb_min_available or component.auto_pdb: + if config.type != "job": + if config.pdb_min_available or config.auto_pdb: pdb = PodDisruptionBudget( - name=name, component=component, workload=workload_spec - ).root - bundle_scaling += [pdb] - if component.istio_policy: - istio_policy = IstioPolicy( - name=name, component=component, workload=workload_spec - ).root - bundle_security += [istio_policy] - - if component.pod_security_policy: - psp = PodSecurityPolicy( - name=name, component=component, workload=workload_spec - ).root - bundle_security += [psp] - - if component.service: + name=name, config=config, workload=workload + ) + pdb.add_label("app.kapicorp.dev/component", name) + self.add(pdb) + + if config.istio_policy: + istio_policy = IstioPolicy(name=name, config=config, workload=workload) + istio_policy.add_label("app.kapicorp.dev/component", name) + self.add(istio_policy) + + if config.pod_security_policy: + psp = PodSecurityPolicy(name=name, config=config, workload=workload) + psp.add_label("app.kapicorp.dev/component", name) + self.add(psp) + + if config.service: service = Service( name=name, - component=component, - workload=workload_spec, - service_spec=component.service, - ).root - bundle_service += [service] - - if component.additional_services: - for service_name, service_spec in component.additional_services.items(): + config=config, + workload=workload, + service_spec=config.service, + ) + service.add_label("app.kapicorp.dev/component", name) + self.add(service) + + if config.additional_services: + for service_name, service_spec in config.additional_services.items(): service = Service( name=service_name, - component=component, - workload=workload_spec, + config=config, + workload=workload, service_spec=service_spec, - ).root - bundle_service += [service] + ) + service.add_label("app.kapicorp.dev/component", name) + self.add(service) - if component.network_policies: + if config.network_policies: policies = GenerateMultipleObjectsForClass( name=name, - component=component, + component_config=config, generating_class=NetworkPolicy, - objects=component.network_policies, - workload=workload_spec, - ).root - bundle_security += policies + config=config.network_policies, + workload=workload, + ) + map(lambda x: x.add_label("app.kapicorp.dev/component", name), policies) + self.add(policies) - if component.webhooks: - webhooks = MutatingWebhookConfiguration(name=name, component=component).root - bundle_workload += [webhooks] + if config.webhooks: + webhooks = MutatingWebhookConfiguration(name=name, config=config) + webhooks.add_label("app.kapicorp.dev/component", name) + self.add(webhooks) - if component.service_monitors: + if config.service_monitors: service_monitor = ServiceMonitor( - name=name, component=component, workload=workload_spec - ).root - bundle_workload += [service_monitor] - - if component.prometheus_rules: - prometheus_rule = PrometheusRule(name=name, component=component).root - bundle_workload += [prometheus_rule] - - if component.role: - role = Role(name=name, component=component).root - bundle_rbac += [role] - role_binding = RoleBinding(name=name, component=component).root - bundle_rbac += [role_binding] - - if component.cluster_role: - cluster_role = ClusterRole(name=name, component=component).root - bundle_rbac += [cluster_role] - cluster_role_binding = ClusterRoleBinding( - name=name, component=component - ).root - bundle_rbac += [cluster_role_binding] - - if component.backend_config: - backend_config = BackendConfig(name=name, component=component).root - bundle_workload += [backend_config] - - if component.service_account.get("create", False): - sa_name = component.service_account.get("name", name) - sa = ServiceAccount(name=sa_name, component=component).root - bundle_rbac += [sa] - - obj.root["{}-bundle".format(name)] = bundle_workload - obj.root["{}-config".format(name)] = bundle_configs - obj.root["{}-secret".format(name)] = bundle_secrets - obj.root["{}-service".format(name)] = bundle_service - obj.root["{}-rbac".format(name)] = bundle_rbac - obj.root["{}-scaling".format(name)] = bundle_scaling - obj.root["{}-security".format(name)] = bundle_security - - return obj - - -def generate_manifests(input_params): - all_manifests = BaseObj() - - component_manifests = generate_component_manifests(input_params) - ingress_manifests = generate_ingress(input_params) - resource_manifests = generate_resource_manifests(input_params) + name=name, config=config, workload=workload + ) + service_monitor.add_label("app.kapicorp.dev/component", name) + self.add(service_monitor) + + if config.prometheus_rules: + prometheus_rule = PrometheusRule(name=name, config=config) + prometheus_rule.add_label("app.kapicorp.dev/component", name) + self.add(prometheus_rule) + + if config.service_account.get("create", False): + sa_name = config.service_account.get("name", name) + sa = ServiceAccount(name=sa_name, config=config) + sa.add_label("app.kapicorp.dev/component", name) + self.add(sa) + + if config.role: + role = Role(name=name, config=config) + role.add_label("app.kapicorp.dev/component", name) + self.add(role) + role_binding = RoleBinding(name=name, config=config, sa=sa) + role_binding.add_label("app.kapicorp.dev/component", name) + self.add(role_binding) + + if config.cluster_role: + cluster_role = ClusterRole(name=name, config=config) + self.add(cluster_role) + cluster_role.add_label("app.kapicorp.dev/component", name) + cluster_role_binding = ClusterRoleBinding(name=name, config=config, sa=sa) + cluster_role_binding.add_label("app.kapicorp.dev/component", name) + self.add(cluster_role_binding) + + if config.backend_config: + backend_config = BackendConfig(name=name, config=config) + backend_config.add_label("app.kapicorp.dev/component", name) + self.add(backend_config) - all_manifests.root = component_manifests.root - all_manifests.root.update(ingress_manifests.root) - all_manifests.root.update(resource_manifests.root) - return all_manifests def main(input_params): - whitelisted_functions = ["generate_manifests", "generate_docs"] - function = input_params.get("function", "generate_manifests") - if function in whitelisted_functions: - return globals()[function](input_params) + kgenlib.BaseGenerator.inventory = inventory + store = kgenlib.BaseGenerator.generate() + store.process_mutations(input_params.get("mutations", {})) + + return store.dump() diff --git a/components/generators/kubernetes/common.py b/components/generators/kubernetes/common.py new file mode 100644 index 00000000..4f8cdadd --- /dev/null +++ b/components/generators/kubernetes/common.py @@ -0,0 +1,150 @@ +from enum import Enum + +from kapitan.inputs.kadet import BaseModel, BaseObj, Dict, load_from_search_paths + +kgenlib = load_from_search_paths("generators") + + +class ResourceType(BaseModel): + kind: str + id: str + api_version: str + + +class ResourceTypes(Enum): + CONFIG_MAP = ResourceType(kind="ConfigMap", api_version="v1", id="config_map") + VERTICAL_POD_AUTOSCALER = ResourceType(kind="VerticalPodAutoscaler", api_version="autoscaling.k8s.io/v1beta2", id="vertical_pod_autoscaler") + MUTATING_WEBHOOK_CONFIGURATION = ResourceType(kind="MutatingWebhookConfiguration", api_version="admissionregistration.k8s.io/v1", id="mutating_webhook_configuration") + BACKEND_CONFIG = ResourceType(kind="BackendConfig", api_version="cloud.google.com/v1", id="backend_config") + PROMETHEUS_RULE = ResourceType(kind="PrometheusRule", api_version="monitoring.coreos.com/v1", id="prometheus_rule") + HORIZONTAL_POD_AUTOSCALER = ResourceType(kind="HorizontalPodAutoscaler", api_version="autoscaling.k8s.io/v2beta2", id="horizontal_pod_autoscaler") + SERVICE_MONITOR = ResourceType(kind="ServiceMonitor", api_version="monitoring.coreos.com/v1", id="service_monitor") + POD_DISRUPTION_BUDGET = ResourceType(kind="PodDisruptionBudget", api_version="policy/v1beta1", id="pod_disruption_budget") + NAMESPACE = ResourceType(kind="Namespace", api_version="v1", id="namespace") + INGRESS = ResourceType(kind="Ingress", api_version="networking.k8s.io/v1", id="ingress") + DEPLOYMENT = ResourceType(kind="Deployment", api_version="apps/v1", id="deployment") + DAEMON_SET = ResourceType(kind="DaemonSet", api_version="apps/v1", id="daemon_set") + GOOGLE_MANAGED_CERTIFICATE = ResourceType(kind="ManagedCertificate", api_version="networking.gke.io/v1beta1", id="google_managed_certificate") + POD_SECURITY_POLICY = ResourceType(kind="PodSecurityPolicy", api_version="policy/v1beta1", id="pod_security_policy") + JOB = ResourceType(kind="Job", api_version="batch/v1", id="job") + CRON_JOB = ResourceType(kind="Job", api_version="batch/v1beta1", id="cronjob") + STATEFUL_SET = ResourceType(kind="StatefulSet", api_version="apps/v1", id="stateful_set") + SERVICE_ACCOUNT = ResourceType(kind="ServiceAccount", api_version="v1", id="service_account") + SECRET = ResourceType(kind="Secret", api_version="v1", id="secret") + SERVICE = ResourceType(kind="Service", api_version="v1", id="service") + CLUSTER_ROLE_BINDING = ResourceType( + kind="ClusterRoleBinding", + api_version="rbac.authorization.k8s.io/v1", + id="cluster_role_binding", + ) + CLUSTER_ROLE = ResourceType( + kind="ClusterRole", + api_version="rbac.authorization.k8s.io/v1", + id="cluster_role", + ) + ROLE_BINDING = ResourceType( + kind="RoleBinding", + api_version="rbac.authorization.k8s.io/v1", + id="role_binding", + ) + ROLE = ResourceType( + kind="Role", api_version="rbac.authorization.k8s.io/v1", id="role" + ) + NETWORK_POLICY = ResourceType( + kind="NetworkPolicy", api_version="networking.k8s.io/v1", id="network_policy" + ) + + +class KubernetesResource(kgenlib.BaseContent): + resource_type: ResourceType + name: str + api_version: str = None + kind: str = None + rendered_name: str = None + id: str = None + + + @property + def component_name(self): + return self.root.metadata.labels.get("app.kapicorp.dev/component", self.name) + + def new(self): + self.kind = self.resource_type.kind + self.api_version = self.resource_type.api_version + self.id = self.resource_type.id + self.namespace = self.config.get("namespace", None) + + def body(self): + self.root.apiVersion = self.api_version + self.root.kind = self.kind + self.name = self.name + self.rendered_name = self.config.get("rendered_name", self.name) + self.root.metadata.namespace = self.namespace + self.root.metadata.name = self.rendered_name + self.add_label("name", self.name) + + def add_label(self, key: str, value: str): + self.root.metadata.labels[key] = value + + def add_labels(self, labels: dict): + for key, value in labels.items(): + self.add_label(key, value) + + def add_annotation(self, key: str, value: str): + self.root.metadata.annotations[key] = value + + def add_annotations(self, annotations: dict): + for key, value in annotations.items(): + self.add_annotation(key, value) + + def add_namespace(self, namespace: str): + self.root.metadata.namespace = namespace + + def set_labels(self, labels: dict): + self.root.metadata.labels = labels + + def set_annotations(self, annotations: dict): + self.root.metadata.annotations = annotations + + def setup_global_defaults(self, inventory): + try: + globals = ( + inventory.parameters.generators.manifest.default_config.globals.get( + self.id, {} + ) + ) + self.add_annotations(globals.get("annotations", {})) + self.add_labels(globals.get("labels", {})) + except AttributeError: + pass + + +class Base(BaseObj): + def new(self): + self.need("apiVersion") + self.need("kind") + self.need("name") + + def body(self): + self.root.apiVersion = self.kwargs.apiVersion + self.root.kind = self.kwargs.kind + self.name = self.kwargs.name + self.root.metadata.name = self.kwargs.get("rendered_name", self.name) + self.add_label("name", self.root.metadata.name) + + def add_labels(self, labels): + for key, value in labels.items(): + self.add_label(key, value) + + def add_label(self, key, value): + self.root.metadata.labels[key] = value + + def add_namespace(self, namespace): + self.root.metadata.namespace = namespace + + def add_annotations(self, annotations): + for key, value in annotations.items(): + self.add_annotation(key, value) + + def add_annotation(self, key, value): + self.root.metadata.annotations[key] = value diff --git a/components/generators/kubernetes/k8s.py b/components/generators/kubernetes/k8s.py deleted file mode 100644 index 2516be6b..00000000 --- a/components/generators/kubernetes/k8s.py +++ /dev/null @@ -1,32 +0,0 @@ -from kapitan.inputs.kadet import BaseObj - - -class Base(BaseObj): - def new(self): - self.need("apiVersion") - self.need("kind") - self.need("name") - - def body(self): - self.root.apiVersion = self.kwargs.apiVersion - self.root.kind = self.kwargs.kind - self.name = self.kwargs.name - self.root.metadata.name = self.kwargs.get("rendered_name", self.name) - self.add_label("name", self.root.metadata.name) - - def add_labels(self, labels): - for key, value in labels.items(): - self.add_label(key, value) - - def add_label(self, key, value): - self.root.metadata.labels[key] = value - - def add_namespace(self, namespace): - self.root.metadata.namespace = namespace - - def add_annotations(self, annotations): - for key, value in annotations.items(): - self.add_annotation(key, value) - - def add_annotation(self, key, value): - self.root.metadata.annotations[key] = value diff --git a/components/generators/kubernetes/networking.py b/components/generators/kubernetes/networking.py new file mode 100644 index 00000000..6ecb3d13 --- /dev/null +++ b/components/generators/kubernetes/networking.py @@ -0,0 +1,25 @@ +from kapitan.inputs.kadet import load_from_search_paths + +from .common import KubernetesResource, ResourceTypes + +kgenlib = load_from_search_paths("generators") + + +class NetworkPolicy(KubernetesResource): + resource_type = ResourceTypes.NETWORK_POLICY.value + + def new(self): + super().new() + + def body(self): + super().body() + policy = self.config + workload = self.workload + self.root.spec.podSelector.matchLabels = workload.root.metadata.labels + self.root.spec.ingress = policy.ingress + self.root.spec.egress = policy.egress + if self.root.spec.ingress: + self.root.spec.setdefault("policyTypes", []).append("Ingress") + + if self.root.spec.egress: + self.root.spec.setdefault("policyTypes", []).append("Egress") diff --git a/components/generators/kubernetes/rbac.py b/components/generators/kubernetes/rbac.py new file mode 100644 index 00000000..d230c992 --- /dev/null +++ b/components/generators/kubernetes/rbac.py @@ -0,0 +1,81 @@ +from kapitan.inputs.kadet import load_from_search_paths + +from .common import KubernetesResource, ResourceTypes + +kgenlib = load_from_search_paths("generators") + + +class Role(KubernetesResource): + resource_type = ResourceTypes.ROLE.value + + def new(self): + super().new() + + def body(self): + super().body() + config = self.config + self.root.rules = config.role.rules + + +class RoleBinding(KubernetesResource): + resource_type = ResourceTypes.ROLE_BINDING.value + + def new(self): + super().new() + + def body(self): + super().body() + config = self.config + sa = self.sa + default_role_ref = { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "Role", + "name": config.name, + } + default_subject = [ + { + "kind": "ServiceAccount", + "name": sa.name, + "namespace": sa.namespace, + } + ] + self.root.roleRef = config.get("roleRef", default_role_ref) + self.root.subjects = config.get("subject", default_subject) + + +class ClusterRole(KubernetesResource): + resource_type = ResourceTypes.CLUSTER_ROLE.value + + def new(self): + super().new() + + def body(self): + super().body() + config = self.config + self.root.rules = config.cluster_role.rules + + +class ClusterRoleBinding(KubernetesResource): + resource_type = ResourceTypes.CLUSTER_ROLE_BINDING.value + + def new(self): + super().new() + + def body(self): + super().body() + config = self.config + sa = self.sa + default_role_ref = { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "ClusterRole", + "name": config.name, + } + default_subject = [ + { + "kind": "ServiceAccount", + "name": sa.name, + "namespace": sa.namespace, + } + ] + self.root.roleRef = config.get("roleRef", default_role_ref) + self.root.subjects = config.get("subject", default_subject) diff --git a/components/generators/kubernetes/storage.py b/components/generators/kubernetes/storage.py new file mode 100644 index 00000000..acd0c04f --- /dev/null +++ b/components/generators/kubernetes/storage.py @@ -0,0 +1,126 @@ +import base64 +import hashlib +import logging +import os + +from kapitan.inputs.kadet import BaseModel, Dict, load_from_search_paths + +from .common import KubernetesResource, ResourceTypes + +logger = logging.getLogger(__name__) +kgenlib = load_from_search_paths("generators") + + +class SharedConfig(BaseModel): + """Shared class to use for both Secrets and ConfigMaps classes. + + containt anything needed by both classes, so that their behavious is basically the same. + Each subclass will then implement its own way of adding the data depending on their implementation. + """ + + component: Dict = None + versioning_enabled: bool = False + + @staticmethod + def encode_string(unencoded_string): + return base64.b64encode(unencoded_string.encode("ascii")).decode("ascii") + + def setup_metadata(self, inventory): + namespace = inventory.parameters.get("namespace", None) + + if self.component: + namespace = self.component.get("namespace", namespace) + + namespace = self.config.get("namespace", namespace) + + if namespace: + self.add_namespace(namespace) + + self.add_annotations(self.config.get("annotations", {}).copy()) + self.add_labels(self.config.get("labels", {}).copy()) + self.setup_global_defaults(inventory=inventory) + + self.items = self.config["items"] + + def add_directory(self, directory, encode=False, stringdata=False): + if directory and os.path.isdir(directory): + for filename in os.listdir(directory): + with open(f"{directory}/{filename}", "r") as f: + file_content = f.read() + self.add_item( + filename, + file_content, + request_encode=encode, + stringdata=stringdata, + ) + self.versioning(enabled=self.versioning_enabled) + + def add_data(self, data, stringdata=False): + for key, spec in data.items(): + encode = spec.get("b64_encode", False) + + if "value" in spec: + value = spec.get("value") + if "template" in spec: + value = kgenlib.render_jinja(spec.template, spec.get("values", {})) + if "file" in spec: + with open(spec.file, "r") as f: + value = f.read() + + self.add_item(key, value, request_encode=encode, stringdata=stringdata) + self.versioning(enabled=self.versioning_enabled) + + def add_item(self, key, value, request_encode=False, stringdata=False): + encode = not stringdata and request_encode + field = "stringData" if stringdata else "data" + + self.root[field][key] = self.encode_string(value) if encode else value + + def add_string_data(self, string_data, encode=False, stringdata=True): + + for key, spec in string_data.items(): + + if "value" in spec: + value = spec.get("value") + if "template" in spec: + value = kgenlib.render_jinja(spec.template, spec.get("values", {})) + if "file" in spec: + with open(spec.file, "r") as f: + value = f.read() + + self.add_item(key, value, request_encode=encode, stringdata=stringdata) + + self.versioning(enabled=self.versioning_enabled) + + def versioning(self, enabled=False): + if enabled: + keys_of_interest = ["data", "binaryData", "stringData"] + subset = { + key: value + for key, value in self.root.to_dict().items() + if key in keys_of_interest + } + self.hash = hashlib.sha256(str(subset).encode()).hexdigest()[:8] + self.rendered_name = f"{self.name}-{self.hash}" + self.root.metadata.name = self.rendered_name + + +class ConfigMap(KubernetesResource): + resource_type = ResourceTypes.CONFIG_MAP.value + + def new(self): + super().new() + + def body(self): + super().body() + +class Secret(KubernetesResource): + resource_type = ResourceTypes.SECRET.value + + def new(self): + super().new() + + def body(self): + super().body() + + diff --git a/inventory/classes/kapitan/generators/kubernetes.yml b/inventory/classes/kapitan/generators/kubernetes.yml index 5e602b1d..ffcaebf1 100644 --- a/inventory/classes/kapitan/generators/kubernetes.yml +++ b/inventory/classes/kapitan/generators/kubernetes.yml @@ -12,25 +12,48 @@ parameters: output_type: yml input_paths: - components/generators/kubernetes - - output_path: docs - input_type: kadet - output_type: plain - input_params: - function: generate_docs - template_path: templates/docs/service_component.md.j2 - input_paths: - - components/generators/kubernetes - - output_path: pre-deploy - input_type: kadet - output_type: yml input_params: - function: generate_pre_deploy - input_paths: - - components/generators/kubernetes + mutations: + bundle: + - conditions: + kind: [Ingress] + filename: '{content.component_name}-ingress' + - conditions: + kind: [Namespace] + filename: '{content.component_name}-namespace' + - conditions: + kind: [Secret] + filename: '{content.component_name}-secret' + - conditions: + kind: [ConfigMap] + filename: '{content.component_name}-config' + - conditions: + kind: [Service] + filename: '{content.component_name}-service' + - conditions: + kind: [ServiceAccount, ClusterRole, ClusterRoleBinding, Role, RoleBinding] + filename: '{content.component_name}-rbac' + - conditions: + kind: [NetworkPolicy] + filename: '{content.component_name}-security' + - conditions: + kind: [ManagedCertificate] + filename: 'gke-managed-certificate-managed-certificate' + - conditions: + kind: [HorizontalPodAutoscaler, PodDisruptionBudget, VerticalPodAutoscaler] + filename: '{content.component_name}-scaling' + - conditions: + kind: ["*"] + filename: '{content.component_name}-bundle' generators: + kubernetes: + namespace: + name: + name: ${namespace} manifest: default_config: + namespace: ${namespace} type: deployment service_account: create: false diff --git a/kapitan b/kapitan index 7a0c8168..0f1e687f 100755 --- a/kapitan +++ b/kapitan @@ -3,11 +3,10 @@ set -o nounset -o pipefail -o noclobber -o errexit DIR=$(dirname ${BASH_SOURCE[0]}) ABS_PATH=$(cd "${DIR}"; pwd) - KAPITAN_IMAGE=kapicorp/kapitan:v0.31.1-rc.3 -KAPITAN_BINARY="docker run --rm -i -u $UID --network host -w /src \ - -v $PWD:/src:delegated \ +KAPITAN_BINARY="docker run --rm -i -u $UID --network host -w $PWD \ + -v $PWD:$PWD:delegated \ $KAPITAN_IMAGE" exec ${KAPITAN_BINARY} "$@" diff --git a/lib/generators/__init__.py b/lib/generators/__init__.py new file mode 100644 index 00000000..79458ba1 --- /dev/null +++ b/lib/generators/__init__.py @@ -0,0 +1,302 @@ +import functools +import logging +from enum import Enum +from types import FunctionType +from typing import List + +import yaml +from box.exceptions import BoxValueError +from kapitan.cached import args +from kapitan.inputs.helm import HelmChart +from kapitan.inputs.kadet import ( + BaseModel, + BaseObj, + CompileError, + Dict, + inventory, + inventory_global, +) +from kapitan.utils import render_jinja2_file + +logger = logging.getLogger(__name__) +inventory = inventory(lazy=True) +inventory_global = inventory_global(lazy=True) + +search_paths = args.get("search_paths") + + +class BaseGenerator: + inventory: Dict + functions: List[FunctionType] = [] + + @classmethod + def run(cls, output): + store = BaseStore() + if isinstance(output, BaseStore): + store.add(output) + + elif isinstance(output, list): + store.add(output) + + elif isinstance(output, BaseContent): + store.add(output) + + elif isinstance(output.root, list): + store.add(output.root) + + elif isinstance(output, BaseObj): + store.add([]) + else: + raise CompileError(f"Unknown output type {output.__class__.__name__}") + return store + + @classmethod + def generate(cls): + store = BaseStore() + logging.debug(f"{len(cls.functions)} functions registered as generators") + for func in cls.functions: + store.add(cls.run(func())) + return store + + @classmethod + def register_function(cls, func): + cls.functions.append(func) + + +def merge(source, destination): + for key, value in source.items(): + if isinstance(value, dict): + node = destination.setdefault(key, value) + if node is None: + destination[key] = value + else: + merge(value, node) + else: + destination[key] = destination.setdefault(key, value) + + return destination + + +def render_jinja(filename, ctx): + return render_jinja2_file(filename, ctx, search_paths=search_paths) + + +def findpath(obj, path, default=None): + path_parts = path.split(".") + try: + value = getattr(obj, path_parts[0]) + except KeyError as e: + if default is not None: + return default + raise CompileError(f"Key {e} not found in {obj}") + + if len(path_parts) == 1: + return value + else: + return findpath(value, ".".join(path_parts[1:])) + + +def register_generator(*args, **kwargs): + def wrapper(func): + @functools.wraps(func) + def wrapped_func(): + path = kwargs.get("path") + configs = findpath(inventory.parameters, path) + + store = BaseStore() + for name, config in configs.items(): + patched_config = Dict(config) + apply_patches_paths = kwargs.get("apply_patches", []) + patches_applied = [] + for path in apply_patches_paths: + try: + path = path.format(**config) + except KeyError: + # Silently ignore missing keys + continue + patch = findpath(inventory.parameters, path, {}) + patches_applied.append(patch) + + patched_config = merge(patch, patched_config) + + store.add( + BaseGenerator.run( + func( + name=name, + config=patched_config, + patches_applied=patches_applied, + original_config=config, + ) + ) + ) + return store + + BaseGenerator.register_function(wrapped_func) + return wrapped_func + + return wrapper + + +class ContentType(Enum): + YAML = 1 + KUBERNETES_RESOURCE = 2 + TERRAFORM_BLOCK = 3 + + +class BaseContent(BaseModel): + content_type: ContentType = ContentType.YAML + filename: str = "output" + + @classmethod + def from_baseobj(cls, baseobj: BaseObj): + """Return a BaseContent initialised with baseobj.""" + return cls.from_dict(baseobj.root) + + @classmethod + def from_yaml(cls, file_path) -> List: + """Returns a list of BaseContent initialised with the content of file_path data.""" + + content_list = list() + with open(file_path) as fp: + yaml_objs = yaml.safe_load_all(fp) + for yaml_obj in yaml_objs: + if yaml_obj: + content_list.append(BaseContent.from_dict(yaml_obj)) + + return content_list + + @classmethod + def from_dict(cls, dict_value): + """Return a KubernetesResource initialise with dict_value.""" + + if dict_value: + try: + obj = cls() + obj.parse(Dict(dict_value)) + return obj + except BoxValueError as e: + raise CompileError( + f"error when importing item '{dict_value}' of type {type(dict_value)}: {e}" + ) + + def parse(self, content: Dict): + self.root = content + + @staticmethod + def findpath(obj, path): + path_parts = path.split(".") + value = getattr(obj, path_parts[0]) + if len(path_parts) == 1: + return value + else: + return BaseContent.findpath(value, ".".join(path_parts[1:])) + + def mutate(self, mutations: List): + for action, conditions in mutations.items(): + if action == "patch": + for condition in conditions: + if self.match(condition["conditions"]): + self.patch(condition["patch"]) + if action == "delete": + for condition in conditions: + if self.match(condition["conditions"]): + self = None + if action == "bundle": + for condition in conditions: + if self.match(condition["conditions"]): + self.filename = condition["filename"].format(content=self) + if condition.get("break", True): + break + + def match(self, match_conditions): + for key, values in match_conditions.items(): + if "*" in values: + return True + value = self.findpath(self.root, key) + if value in values: + continue + else: + return False + return True + + def patch(self, patch): + self.root.merge_update(Dict(patch)) + + +class BaseStore(BaseModel): + content_list: List[BaseContent] = [] + + @classmethod + def from_yaml_file(cls, file_path): + store = cls() + with open(file_path) as fp: + yaml_objs = yaml.safe_load_all(fp) + for yaml_obj in yaml_objs: + if yaml_obj: + store.add(BaseContent.from_dict(yaml_obj)) + return store + + def add(self, object): + logging.debug(f"Adding {type(object)} to store") + if isinstance(object, BaseContent): + self.content_list.append(object) + elif isinstance(object, BaseStore): + self.content_list.extend(object.content_list) + + elif isinstance(object, list): + for item in object: + if isinstance(item, BaseObj): + self.add(BaseContent.from_baseobj(item)) + else: + self.add_list(item) + + elif isinstance(object, BaseObj): + self.add(BaseContent.from_baseobj(object)) + + else: + self.content_list.append(object) + + def add_list(self, contents: List[BaseContent]): + for content in contents: + self.add(content) + + def import_from_helm_chart(self, **kwargs): + self.add_list( + [ + BaseContent.from_baseobj(resource) + for resource in HelmChart(**kwargs).root.values() + ] + ) + + def apply_patch(self, patch: Dict): + for content in self.get_content_list(): + content.patch(patch) + + def process_mutations(self, mutations: Dict): + for content in self.get_content_list(): + try: + content.mutate(mutations) + except: + raise CompileError(f"Error when processing mutations on {content}") + + def get_content_list(self): + return self.content_list + + def dump(self, output_filename=None): + """Return object dict/list.""" + logging.debug(f"Dumping {len(self.get_content_list())} items") + for content in self.get_content_list(): + if output_filename: + output_format = output_filename + else: + output_format = getattr(content, "filename", "output") + + filename = output_format.format(content=content) + self.root.setdefault(filename, []).append(content) + + return super().dump() + + +class KubernetesGenerator(BaseStore): + name: str + config: Dict