From 1301018655cedc2332b7541621d9232a4e6b1aa4 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 14 Oct 2020 15:05:42 -0700 Subject: [PATCH] Support installing concierge and supervisor into existing namespace - New optional ytt value called `into_namespace` means install into that preexisting namespace rather than creating a new namespace for each app - Also ensure that every resource that is created statically by our yaml at install-time by either app is labeled consistently - Also support adding custom labels to all of those resources from a new ytt value called `custom_labels` --- deploy/concierge/deployment.yaml | 70 +++++----- deploy/concierge/helpers.lib.yaml | 30 ++++ deploy/concierge/rbac.yaml | 143 +++++++++++--------- deploy/concierge/values.yaml | 15 +- deploy/concierge/z0_crd_overlay.yaml | 17 +++ deploy/local-user-authenticator/values.yaml | 2 +- deploy/supervisor/deployment.yaml | 47 +++---- deploy/supervisor/helpers.lib.yaml | 30 ++++ deploy/supervisor/rbac.yaml | 21 ++- deploy/supervisor/service.yaml | 31 ++--- deploy/supervisor/values.yaml | 15 +- deploy/supervisor/z0_crd_overlay.yaml | 11 ++ 12 files changed, 274 insertions(+), 158 deletions(-) create mode 100644 deploy/concierge/helpers.lib.yaml create mode 100644 deploy/concierge/z0_crd_overlay.yaml create mode 100644 deploy/supervisor/helpers.lib.yaml create mode 100644 deploy/supervisor/z0_crd_overlay.yaml diff --git a/deploy/concierge/deployment.yaml b/deploy/concierge/deployment.yaml index 75cfd923..1b54a34f 100644 --- a/deploy/concierge/deployment.yaml +++ b/deploy/concierge/deployment.yaml @@ -2,28 +2,30 @@ #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:data", "data") +#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") +#@ if not data.values.into_namespace: --- apiVersion: v1 kind: Namespace metadata: name: #@ data.values.namespace - labels: - name: #@ data.values.namespace + labels: #@ labels() +#@ end --- apiVersion: v1 kind: ServiceAccount metadata: - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() --- apiVersion: v1 kind: ConfigMap metadata: - name: #@ data.values.app_name + "-config" - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceNameWithSuffix("config") + namespace: #@ namespace() + labels: #@ labels() data: #! If names.apiService is changed in this ConfigMap, must also change name of the ClusterIP Service resource below. #@yaml/text-templated-strings @@ -35,11 +37,11 @@ data: durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @) renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @) names: - servingCertificateSecret: (@= data.values.app_name + "-api-tls-serving-certificate" @) - credentialIssuerConfig: (@= data.values.app_name + "-config" @) - apiService: (@= data.values.app_name + "-api" @) + servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @) + credentialIssuerConfig: (@= defaultResourceNameWithSuffix("config") @) + apiService: (@= defaultResourceNameWithSuffix("api") @) kubeCertAgent: - namePrefix: (@= data.values.app_name + "-kube-cert-agent-" @) + namePrefix: (@= defaultResourceNameWithSuffix("kube-cert-agent-") @) (@ if data.values.kube_cert_agent_image: @) image: (@= data.values.kube_cert_agent_image @) (@ else: @) @@ -59,9 +61,8 @@ apiVersion: v1 kind: Secret metadata: name: image-pull-secret - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + namespace: #@ namespace() + labels: #@ labels() type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson @@ -70,29 +71,26 @@ data: apiVersion: apps/v1 kind: Deployment metadata: - name: #@ data.values.app_name - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() spec: replicas: #@ data.values.replicas selector: - matchLabels: - app: #@ data.values.app_name + matchLabels: #@ defaultLabel() template: metadata: - labels: - app: #@ data.values.app_name + labels: #@ defaultLabel() annotations: scheduler.alpha.kubernetes.io/critical-pod: "" spec: - serviceAccountName: #@ data.values.app_name + serviceAccountName: #@ defaultResourceName() #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": imagePullSecrets: - name: image-pull-secret #@ end containers: - - name: pinniped + - name: #@ defaultResourceName() #@ if data.values.image_digest: image: #@ data.values.image_repo + "@" + data.values.image_digest #@ else: @@ -131,7 +129,7 @@ spec: volumes: - name: config-volume configMap: - name: #@ data.values.app_name + "-config" + name: #@ defaultResourceNameWithSuffix("config") - name: podinfo downwardAPI: items: @@ -157,22 +155,19 @@ spec: - weight: 50 podAffinityTerm: labelSelector: - matchLabels: - app: #@ data.values.app_name + matchLabels: #@ defaultLabel() topologyKey: kubernetes.io/hostname --- apiVersion: v1 kind: Service metadata: #! If name is changed, must also change names.apiService in the ConfigMap above and spec.service.name in the APIService below. - name: #@ data.values.app_name + "-api" - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceNameWithSuffix("api") + namespace: #@ namespace() + labels: #@ labels() spec: type: ClusterIP - selector: - app: #@ data.values.app_name + selector: #@ defaultLabel() ports: - protocol: TCP port: 443 @@ -182,8 +177,7 @@ apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata: name: v1alpha1.login.pinniped.dev - labels: - app: #@ data.values.app_name + labels: #@ labels() spec: version: v1alpha1 group: login.pinniped.dev @@ -191,6 +185,6 @@ spec: versionPriority: 10 #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code. service: - name: #@ data.values.app_name + "-api" - namespace: #@ data.values.namespace + name: #@ defaultResourceNameWithSuffix("api") + namespace: #@ namespace() port: 443 diff --git a/deploy/concierge/helpers.lib.yaml b/deploy/concierge/helpers.lib.yaml new file mode 100644 index 00000000..f893152e --- /dev/null +++ b/deploy/concierge/helpers.lib.yaml @@ -0,0 +1,30 @@ +#! Copyright 2020 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") +#@ load("@ytt:template", "template") + +#@ def defaultResourceName(): +#@ return data.values.app_name +#@ end + +#@ def defaultResourceNameWithSuffix(suffix): +#@ return data.values.app_name + "-" + suffix +#@ end + +#@ def namespace(): +#@ if data.values.into_namespace: +#@ return data.values.into_namespace +#@ else: +#@ return data.values.namespace +#@ end +#@ end + +#@ def defaultLabel(): +app: #@ data.values.app_name +#@ end + +#@ def labels(): +_: #@ template.replace(defaultLabel()) +_: #@ template.replace(data.values.custom_labels) +#@ end diff --git a/deploy/concierge/rbac.yaml b/deploy/concierge/rbac.yaml index 99750b5c..2df79e31 100644 --- a/deploy/concierge/rbac.yaml +++ b/deploy/concierge/rbac.yaml @@ -2,35 +2,38 @@ #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:data", "data") +#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") #! Give permission to various cluster-scoped objects --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: #@ data.values.app_name + "-aggregated-api-server" + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + labels: #@ labels() rules: - - apiGroups: [""] - resources: [namespaces] - verbs: [get, list, watch] - - apiGroups: [apiregistration.k8s.io] - resources: [apiservices] - verbs: [create, get, list, patch, update, watch] - - apiGroups: [admissionregistration.k8s.io] - resources: [validatingwebhookconfigurations, mutatingwebhookconfigurations] - verbs: [get, list, watch] + - apiGroups: [ "" ] + resources: [ namespaces ] + verbs: [ get, list, watch ] + - apiGroups: [ apiregistration.k8s.io ] + resources: [ apiservices ] + verbs: [ create, get, list, patch, update, watch ] + - apiGroups: [ admissionregistration.k8s.io ] + resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ] + verbs: [ get, list, watch ] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name + "-aggregated-api-server" + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + labels: #@ labels() subjects: - kind: ServiceAccount - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() roleRef: kind: ClusterRole - name: #@ data.values.app_name + "-aggregated-api-server" + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") apiGroup: rbac.authorization.k8s.io #! Give permission to various objects within the app's own namespace @@ -38,39 +41,41 @@ roleRef: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: #@ data.values.app_name + "-aggregated-api-server" - namespace: #@ data.values.namespace + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + namespace: #@ namespace() + labels: #@ labels() rules: - - apiGroups: [""] - resources: [services] - verbs: [create, get, list, patch, update, watch] - - apiGroups: [""] - resources: [secrets] - verbs: [create, get, list, patch, update, watch, delete] + - apiGroups: [ "" ] + resources: [ services ] + verbs: [ create, get, list, patch, update, watch ] + - apiGroups: [ "" ] + resources: [ secrets ] + verbs: [ create, get, list, patch, update, watch, delete ] #! We need to be able to CRUD pods in our namespace so we can reconcile the kube-cert-agent pods. - - apiGroups: [""] - resources: [pods] - verbs: [create, get, list, patch, update, watch, delete] + - apiGroups: [ "" ] + resources: [ pods ] + verbs: [ create, get, list, patch, update, watch, delete ] #! We need to be able to exec into pods in our namespace so we can grab the API server's private key - - apiGroups: [""] - resources: [pods/exec] - verbs: [create] - - apiGroups: [config.pinniped.dev, idp.pinniped.dev] - resources: ["*"] - verbs: [create, get, list, update, watch] + - apiGroups: [ "" ] + resources: [ pods/exec ] + verbs: [ create ] + - apiGroups: [ config.pinniped.dev, idp.pinniped.dev ] + resources: [ "*" ] + verbs: [ create, get, list, update, watch ] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name + "-aggregated-api-server" - namespace: #@ data.values.namespace + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + namespace: #@ namespace() + labels: #@ labels() subjects: - kind: ServiceAccount - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() roleRef: kind: Role - name: #@ data.values.app_name + "-aggregated-api-server" + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") apiGroup: rbac.authorization.k8s.io #! Give permission to read pods in the kube-system namespace so we can find the API server's private key @@ -78,25 +83,27 @@ roleRef: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: #@ data.values.app_name + "-kube-system-pod-read" + name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") namespace: kube-system + labels: #@ labels() rules: - - apiGroups: [""] - resources: [pods] - verbs: [get, list, watch] + - apiGroups: [ "" ] + resources: [ pods ] + verbs: [ get, list, watch ] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name + "-kube-system-pod-read" + name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") namespace: kube-system + labels: #@ labels() subjects: - kind: ServiceAccount - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() roleRef: kind: Role - name: #@ data.values.app_name + "-kube-system-pod-read" + name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") apiGroup: rbac.authorization.k8s.io #! Allow both authenticated and unauthenticated TokenCredentialRequests (i.e. allow all requests) @@ -104,16 +111,18 @@ roleRef: apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: #@ data.values.app_name + "-create-token-credential-requests" + name: #@ defaultResourceNameWithSuffix("create-token-credential-requests") + labels: #@ labels() rules: - - apiGroups: [login.pinniped.dev] - resources: [tokencredentialrequests] - verbs: [create] + - apiGroups: [ login.pinniped.dev ] + resources: [ tokencredentialrequests ] + verbs: [ create ] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name + "-create-token-credential-requests" + name: #@ defaultResourceNameWithSuffix("create-token-credential-requests") + labels: #@ labels() subjects: - kind: Group name: system:authenticated @@ -123,7 +132,7 @@ subjects: apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole - name: #@ data.values.app_name + "-create-token-credential-requests" + name: #@ defaultResourceNameWithSuffix("create-token-credential-requests") apiGroup: rbac.authorization.k8s.io #! Give permissions for subjectaccessreviews, tokenreview that is needed by aggregated api servers @@ -131,12 +140,13 @@ roleRef: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() subjects: - kind: ServiceAccount - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() roleRef: kind: ClusterRole name: system:auth-delegator @@ -147,12 +157,13 @@ roleRef: kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name + "-extension-apiserver-authentication-reader" + name: #@ defaultResourceNameWithSuffix("extension-apiserver-authentication-reader") namespace: kube-system + labels: #@ labels() subjects: - kind: ServiceAccount - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() roleRef: kind: Role name: extension-apiserver-authentication-reader @@ -163,23 +174,25 @@ roleRef: kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name + "-cluster-info-lister-watcher" + name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") namespace: kube-public + labels: #@ labels() rules: - - apiGroups: [""] - resources: [configmaps] - verbs: [list, watch] + - apiGroups: [ "" ] + resources: [ configmaps ] + verbs: [ list, watch ] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name + "-cluster-info-lister-watcher" + name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") namespace: kube-public + labels: #@ labels() subjects: - kind: ServiceAccount - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() roleRef: kind: Role - name: #@ data.values.app_name + "-cluster-info-lister-watcher" + name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") apiGroup: rbac.authorization.k8s.io diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 49271f0f..bcb16a7a 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -5,7 +5,20 @@ --- app_name: pinniped-concierge + +#! Creates a new namespace statically in yaml with the given name and installs the app into that namespace. namespace: pinniped-concierge +#! If specified, assumes that a namespace of the given name already exists and installs the app into that namespace. +#! If both `namespace` and `into_namespace` are specified, then only `into_namespace` is used. +into_namespace: #! e.g. my-preexisting-namespace + +#! All resources created statically by yaml at install-time and all resources created dynamically +#! by controllers at runtime will be labelled with `app: $app_name` and also with the labels +#! specified here. The app can be uninstalled either by: +#! 1. Deleting the static install-time yaml resources including the static namespace, which will cascade and also delete +#! resources that were dynamically created by controllers at runtime +#! 2. Or, deleting all resources by label, which does not assume that there was a static install-time yaml namespace. +custom_labels: {} #! e.g. {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} #! Specify how many replicas of the Pinniped server to run. replicas: 2 @@ -20,7 +33,7 @@ image_tag: latest #! By default, the same image specified for image_repo/image_digest/image_tag will be re-used. kube_cert_agent_image: -#! Specifies a secret to be used when pulling the above container image. +#! Specifies a secret to be used when pulling the above `image_repo` container image. #! Can be used when the above image_repo is a private registry. #! Typically the value would be the output of: kubectl create secret docker-registry x --docker-server=https://example.io --docker-username="USERNAME" --docker-password="PASSWORD" --dry-run=client -o json | jq -r '.data[".dockerconfigjson"]' #! Optional. diff --git a/deploy/concierge/z0_crd_overlay.yaml b/deploy/concierge/z0_crd_overlay.yaml new file mode 100644 index 00000000..dfece13b --- /dev/null +++ b/deploy/concierge/z0_crd_overlay.yaml @@ -0,0 +1,17 @@ +#! Copyright 2020 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:overlay", "overlay") +#@ load("helpers.lib.yaml", "labels") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"credentialissuerconfigs.config.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"webhookidentityproviders.idp.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() diff --git a/deploy/local-user-authenticator/values.yaml b/deploy/local-user-authenticator/values.yaml index 9d4b96ed..19c6f237 100644 --- a/deploy/local-user-authenticator/values.yaml +++ b/deploy/local-user-authenticator/values.yaml @@ -9,7 +9,7 @@ image_repo: docker.io/getpinniped/pinniped-server image_digest: #! e.g. sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 image_tag: latest -#! Specifies a secret to be used when pulling the above container image. +#! Specifies a secret to be used when pulling the above `image_repo` container image. #! Can be used when the above image_repo is a private registry. #! Typically the value would be the output of: kubectl create secret docker-registry x --docker-server=https://example.io --docker-username="USERNAME" --docker-password="PASSWORD" --dry-run=client -o json | jq -r '.data[".dockerconfigjson"]' #! Optional. diff --git a/deploy/supervisor/deployment.yaml b/deploy/supervisor/deployment.yaml index 459276fb..bec84c79 100644 --- a/deploy/supervisor/deployment.yaml +++ b/deploy/supervisor/deployment.yaml @@ -2,42 +2,43 @@ #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:data", "data") +#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") +#@ if not data.values.into_namespace: --- apiVersion: v1 kind: Namespace metadata: name: #@ data.values.namespace - labels: - name: #@ data.values.namespace + labels: #@ labels() +#@ end --- apiVersion: v1 kind: ServiceAccount metadata: - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() --- apiVersion: v1 kind: ConfigMap metadata: - name: #@ data.values.app_name + "-static-config" - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceNameWithSuffix("static-config") + namespace: #@ namespace() + labels: #@ labels() data: #@yaml/text-templated-strings pinniped.yaml: | names: - dynamicConfigMap: (@= data.values.app_name + "-dynamic-config" @) + dynamicConfigMap: (@= defaultResourceNameWithSuffix("dynamic-config") @) --- #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": apiVersion: v1 kind: Secret metadata: name: image-pull-secret - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + namespace: #@ namespace() + labels: #@ labels() type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson @@ -46,27 +47,24 @@ data: apiVersion: apps/v1 kind: Deployment metadata: - name: #@ data.values.app_name - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() spec: replicas: #@ data.values.replicas selector: - matchLabels: - app: #@ data.values.app_name + matchLabels: #@ defaultLabel() template: metadata: - labels: - app: #@ data.values.app_name + labels: #@ defaultLabel() spec: - serviceAccountName: #@ data.values.app_name + serviceAccountName: #@ defaultResourceName() #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": imagePullSecrets: - name: image-pull-secret #@ end containers: - - name: pinniped-supervisor + - name: #@ defaultResourceName() #@ if data.values.image_digest: image: #@ data.values.image_repo + "@" + data.values.image_digest #@ else: @@ -89,7 +87,7 @@ spec: volumes: - name: config-volume configMap: - name: #@ data.values.app_name + "-static-config" + name: #@ defaultResourceNameWithSuffix("static-config") - name: podinfo downwardAPI: items: @@ -107,6 +105,5 @@ spec: - weight: 50 podAffinityTerm: labelSelector: - matchLabels: - app: #@ data.values.app_name + matchLabels: #@ defaultLabel() topologyKey: kubernetes.io/hostname diff --git a/deploy/supervisor/helpers.lib.yaml b/deploy/supervisor/helpers.lib.yaml new file mode 100644 index 00000000..f893152e --- /dev/null +++ b/deploy/supervisor/helpers.lib.yaml @@ -0,0 +1,30 @@ +#! Copyright 2020 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") +#@ load("@ytt:template", "template") + +#@ def defaultResourceName(): +#@ return data.values.app_name +#@ end + +#@ def defaultResourceNameWithSuffix(suffix): +#@ return data.values.app_name + "-" + suffix +#@ end + +#@ def namespace(): +#@ if data.values.into_namespace: +#@ return data.values.into_namespace +#@ else: +#@ return data.values.namespace +#@ end +#@ end + +#@ def defaultLabel(): +app: #@ data.values.app_name +#@ end + +#@ def labels(): +_: #@ template.replace(defaultLabel()) +_: #@ template.replace(data.values.custom_labels) +#@ end diff --git a/deploy/supervisor/rbac.yaml b/deploy/supervisor/rbac.yaml index bfa4ac95..3ac82d5f 100644 --- a/deploy/supervisor/rbac.yaml +++ b/deploy/supervisor/rbac.yaml @@ -2,16 +2,16 @@ #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:data", "data") +#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") #! Give permission to various objects within the app's own namespace --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: #@ data.values.app_name - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() rules: - apiGroups: [config.pinniped.dev] resources: [oidcproviderconfigs] @@ -20,15 +20,14 @@ rules: kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: #@ data.values.app_name - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() subjects: - kind: ServiceAccount - name: #@ data.values.app_name - namespace: #@ data.values.namespace + name: #@ defaultResourceName() + namespace: #@ namespace() roleRef: kind: Role - name: #@ data.values.app_name + name: #@ defaultResourceName() apiGroup: rbac.authorization.k8s.io diff --git a/deploy/supervisor/service.yaml b/deploy/supervisor/service.yaml index 6acbe7fc..eb5e0127 100644 --- a/deploy/supervisor/service.yaml +++ b/deploy/supervisor/service.yaml @@ -1,14 +1,17 @@ +#! Copyright 2020 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + #@ load("@ytt:data", "data") +#@ load("helpers.lib.yaml", "defaultLabel", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") #@ if data.values.service_nodeport_port: --- apiVersion: v1 kind: Service metadata: - name: #@ data.values.app_name + "-nodeport" - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceNameWithSuffix("nodeport") + namespace: #@ namespace() + labels: #@ labels() spec: type: NodePort selector: @@ -25,14 +28,12 @@ spec: apiVersion: v1 kind: Service metadata: - name: #@ data.values.app_name + "-clusterip" - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceNameWithSuffix("clusterip") + namespace: #@ namespace() + labels: #@ labels() spec: type: ClusterIP - selector: - app: #@ data.values.app_name + selector: #@ defaultLabel() ports: - protocol: TCP port: #@ data.values.service_clusterip_port @@ -44,14 +45,12 @@ spec: apiVersion: v1 kind: Service metadata: - name: #@ data.values.app_name + "-loadbalancer" - namespace: #@ data.values.namespace - labels: - app: #@ data.values.app_name + name: #@ defaultResourceNameWithSuffix("loadbalancer") + namespace: #@ namespace() + labels: #@ labels() spec: type: LoadBalancer - selector: - app: #@ data.values.app_name + selector: #@ defaultLabel() ports: - protocol: TCP port: #@ data.values.service_loadbalancer_port diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 6e74ca36..732d9759 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -5,7 +5,20 @@ --- app_name: pinniped-supervisor + +#! Creates a new namespace statically in yaml with the given name and installs the app into that namespace. namespace: pinniped-supervisor +#! If specified, assumes that a namespace of the given name already exists and installs the app into that namespace. +#! If both `namespace` and `into_namespace` are specified, then only `into_namespace` is used. +into_namespace: #! e.g. my-preexisting-namespace + +#! All resources created statically by yaml at install-time and all resources created dynamically +#! by controllers at runtime will be labelled with `app: $app_name` and also with the labels +#! specified here. The app can be uninstalled either by: +#! 1. Deleting the static install-time yaml resources including the static namespace, which will cascade and also delete +#! resources that were dynamically created by controllers at runtime +#! 2. Or, deleting all resources by label, which does not assume that there was a static install-time yaml namespace. +custom_labels: {} #! e.g. {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} #! Specify how many replicas of the Pinniped server to run. replicas: 2 @@ -15,7 +28,7 @@ image_repo: docker.io/getpinniped/pinniped-server image_digest: #! e.g. sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 image_tag: latest -#! Specifies a secret to be used when pulling the above container image. +#! Specifies a secret to be used when pulling the above `image_repo` container image. #! Can be used when the above image_repo is a private registry. #! Typically the value would be the output of: kubectl create secret docker-registry x --docker-server=https://example.io --docker-username="USERNAME" --docker-password="PASSWORD" --dry-run=client -o json | jq -r '.data[".dockerconfigjson"]' #! Optional. diff --git a/deploy/supervisor/z0_crd_overlay.yaml b/deploy/supervisor/z0_crd_overlay.yaml new file mode 100644 index 00000000..dc111105 --- /dev/null +++ b/deploy/supervisor/z0_crd_overlay.yaml @@ -0,0 +1,11 @@ +#! Copyright 2020 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:overlay", "overlay") +#@ load("helpers.lib.yaml", "labels") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcproviderconfigs.config.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels()