From 0ce54bb2f3ec382baef8de5525c37106a9926811 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 28 Sep 2023 14:48:06 -0400 Subject: [PATCH 01/40] add kind-registry.local:5000 to kind cluster - update kind config to include local registry - configure kind cluster to talk to local registry - docker build & push pinniped dev code to local registry - deploy dev code of the following via the local registry: - concierge - supervisor - local-user-authenticator --- hack/kind-up.sh | 29 +++++++++++++++++++++++++++ hack/lib/kind-config/single-node.yaml | 8 ++++++++ hack/prepare-for-integration-tests.sh | 18 ++++++++++++++--- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/hack/kind-up.sh b/hack/kind-up.sh index 1bf70216..035eeab2 100755 --- a/hack/kind-up.sh +++ b/hack/kind-up.sh @@ -8,6 +8,15 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" +# create registry container unless it already exists +reg_name='kind-registry.local' +reg_port='5000' +if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then + docker run \ + -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \ + registry:2 +fi + if [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then echo "Adding Contour port mapping to Kind config." ytt -f "${ROOT}/hack/lib/kind-config/single-node.yaml" \ @@ -18,3 +27,23 @@ else # To debug the kind config, add this option to the command below: `-v 10` kind create cluster --config "hack/lib/kind-config/single-node.yaml" --name pinniped fi + + +# connect the registry to the cluster network if not already connected +if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then + docker network connect "kind" "${reg_name}" +fi + +# Document the local registry +# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry +cat <> /etc/hosts\"" +log_note "When you are finished with your Kind cluster, you can remove these lines from /etc/hosts." From b4f64443db940711752beca761e08f08379183b9 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 28 Sep 2023 16:43:05 -0400 Subject: [PATCH 02/40] Update values.yaml for supervisor,concierge to schema files --- deploy/concierge/values.yaml | 153 ++++++++++++++++++------------- deploy/supervisor/values.yaml | 167 +++++++++++++++++++++------------- 2 files changed, 197 insertions(+), 123 deletions(-) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 9267b0fc..1203839b 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -1,75 +1,96 @@ #! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 -#@data/values +#@data/values-schema --- - +#@schema/desc "Name of pinniped-concierge." app_name: pinniped-concierge -#! Creates a new namespace statically in yaml with the given name and installs the app into that namespace. +#@schema/desc "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 +#@ into_namespace_desc = "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." +#@schema/desc into_namespace_desc +#@schema/nullable +into_namespace: 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 value of `custom_labels` must be a map of string keys to string values. -#! 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} +#@ custom_labels_desc = "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 value of `custom_labels` must be a map of string keys to string values. \ +#@ 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." +#@schema/desc custom_labels_desc +#@schema/type any=True +#@schema/nullable +custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} -#! Specify how many replicas of the Pinniped server to run. +#@schema/desc "Specify how many replicas of the Pinniped server to run." replicas: 2 -#! Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." image_repo: projects.registry.vmware.com/pinniped/pinniped-server -image_digest: #! e.g. sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +#@schema/nullable +image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." image_tag: latest -#! Optionally specify a different image for the "kube-cert-agent" pod which is scheduled -#! on the control plane. This image needs only to include `sleep` and `cat` binaries. -#! By default, the same image specified for image_repo/image_digest/image_tag will be re-used. -kube_cert_agent_image: +#@ kube_cert_agent_image = "Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled \ +#@ on the control plane. This image needs only to include `sleep` and `cat` binaries. \ +#@ By default, the same image specified for image_repo/image_digest/image_tag will be re-used." +#@schema/desc kube_cert_agent_image +#@schema/nullable +kube_cert_agent_image: projects.registry.vmware.com/pinniped/pinniped-server -#! 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. -image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +#@ image_pull_dockerconfigjson_desc = "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." +#@schema/desc image_pull_dockerconfigjson_desc +#@schema/nullable +image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} -#! Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. -#! This setting allows the guess to be overridden. -#! Optional. -discovery_url: #! e.g., https://example.com +#@schema/desc "Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden." +#@schema/nullable +discovery_url: https://example.com -#! Specify the duration and renewal interval for the API serving certificate. -#! The defaults are set to expire the cert about every 30 days, and to rotate it -#! about every 25 days. + +#@ api_serving_certificate_desc = "Specify the duration and renewal interval for the API serving certificate. \ +#@ The defaults are set to expire the cert about every 30 days, and to rotate it \ +#@ about every 25 days." +#@schema/desc api_serving_certificate_desc api_serving_certificate_duration_seconds: 2592000 +#@schema/desc api_serving_certificate_desc api_serving_certificate_renew_before_seconds: 2160000 -#! Specify the verbosity of logging: info ("nice to know" information), debug (developer -#! information), trace (timing information), all (kitchen sink). -log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. -#! Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). -#! By default, when this value is left unset, logs are formatted in json. -#! This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json. -deprecated_log_format: +#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information), +#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged. +#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." +#@schema/nullable +log_level: info +#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ +#@ By default, when this value is left unset, logs are formatted in json. \ +#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." +#@schema/desc deprecated_log_format_desc +#@schema/nullable +deprecated_log_format: json -run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice -run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice +#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_user: 65532 +#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_group: 65532 -#! Specify the API group suffix for all Pinniped API groups. By default, this is set to -#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, -#! authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then -#! Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. +#@ api_group_suffix_desc = "Specify the API group suffix for all Pinniped API groups. By default, this is set to \ +#@ pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, \ +#@ authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then \ +#@ Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc." +#@schema/desc api_group_suffix_desc api_group_suffix: pinniped.dev -#! Customize CredentialIssuer.spec.impersonationProxy to change how the concierge -#! handles impersonation. + +#@schema/desc "Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation." impersonation_proxy_spec: #! options are "auto", "disabled" or "enabled". #! If auto, the impersonation proxy will run only if the cluster signing key is not available @@ -77,11 +98,14 @@ impersonation_proxy_spec: #! If disabled, the impersonation proxy will never run, which could mean that the concierge #! doesn't work at all. #! If enabled, the impersonation proxy will always run regardless of other strategies available. + #@schema/desc "If enabled, the impersonation proxy will always run regardless of other strategies available." mode: auto - #! The endpoint which the client should use to connect to the impersonation proxy. - #! If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer - #! endpoint. - external_endpoint: + #@ external_endpoint_desc = "The endpoint which the client should use to connect to the impersonation proxy. \ + #@ If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint." + #@schema/desc external_endpoint_desc + #@schema/nullable + external_endpoint: 1.2.3.4:5678 + #@schema/desc "The impersonation proxy service configuration" service: #! Options are "LoadBalancer", "ClusterIP" and "None". #! LoadBalancer automatically provisions a Service of type LoadBalancer pointing at @@ -91,17 +115,24 @@ impersonation_proxy_spec: #! impersonation proxy. #! None does not provision either and assumes that you have set the external_endpoint #! and set up your own ingress to connect to the impersonation proxy. + #@schema/desc "Options are 'LoadBalancer', 'ClusterIP' and 'None'." + #@schema/nullable type: LoadBalancer - #! The annotations that should be set on the ClusterIP or LoadBalancer Service. + #@schema/desc "The annotations that should be set on the ClusterIP or LoadBalancer Service." + #@schema/nullable annotations: {service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"} - #! When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP. - load_balancer_ip: + #@schema/desc "When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP." + #@schema/nullable + load_balancer_ip: 1.2.3.4:5678 -#! Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Concierge containers. -#! These will be used when the Concierge makes backend-to-backend calls to authenticators using HTTPS, -#! e.g. when the Concierge fetches discovery documents, JWKS keys, and POSTs to token webhooks. -#! The Concierge never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. -#! Optional. -https_proxy: #! e.g. http://proxy.example.com +#@ https_proxy_desc = "Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. \ +#@ These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, \ +#@ e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. \ +#@ The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. \ +#@ Optional." +#@schema/desc https_proxy_desc +#@schema/nullable +https_proxy: http://proxy.example.com +#@schema/desc "do not proxy Kubernetes endpoints" no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 888d5038..99741cdf 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -1,39 +1,49 @@ #! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 -#@data/values +#@data/values-schema --- - +#@schema/desc "Name of pinniped-supervisor." app_name: pinniped-supervisor -#! Creates a new namespace statically in yaml with the given name and installs the app into that namespace. +#@schema/desc "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 +#@ into_namespace_desc = "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." +#@schema/desc into_namespace_desc +#@schema/nullable +into_namespace: 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 value of `custom_labels` must be a map of string keys to string values. -#! 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} +#@ custom_labels_desc = "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 value of `custom_labels` must be a map of string keys to string values. \ +#@ 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." +#@schema/desc custom_labels_desc +#@schema/type any=True +#@schema/nullable +custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} -#! Specify how many replicas of the Pinniped server to run. +#@schema/desc "Specify how many replicas of the Pinniped server to run." replicas: 2 -#! Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." image_repo: projects.registry.vmware.com/pinniped/pinniped-server -image_digest: #! e.g. sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +#@schema/nullable +image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." image_tag: latest -#! 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. -image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +#@ image_pull_dockerconfigjson_desc = "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." +#@schema/desc image_pull_dockerconfigjson_desc +#@schema/nullable +image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} #! Specify how to expose the Supervisor app's HTTPS port as a Service. #! Typically, you would set a value for only one of the following service types. @@ -41,43 +51,70 @@ image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{" #! Note that all port numbers should be numbers (not strings), i.e. use ytt's `--data-value-yaml` instead of `--data-value`. #! Several of these values have been deprecated and will be removed in a future release. Their names have been changed to #! mark them as deprecated and to make it obvious upon upgrade to anyone who was using them that they have been deprecated. -deprecated_service_http_nodeport_port: #! will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`; e.g. 31234 -deprecated_service_http_nodeport_nodeport: #! will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified; e.g. 31234 -deprecated_service_http_loadbalancer_port: #! will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443 -deprecated_service_http_clusterip_port: #! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`; e.g. 8443 -service_https_nodeport_port: #! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`; e.g. 31243 -service_https_nodeport_nodeport: #! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified; e.g. 31243 -service_https_loadbalancer_port: #! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443 -service_https_clusterip_port: #! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`; e.g. 8443 -#! The `loadBalancerIP` value of the LoadBalancer Service. -#! Ignored unless service_https_loadbalancer_port is provided. -#! Optional. -service_loadbalancer_ip: #! e.g. 1.2.3.4 +#@schema/desc "will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/nullable +deprecated_service_http_nodeport_port: 31234 +#@schema/desc "will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified" +#@schema/nullable +deprecated_service_http_nodeport_nodeport: 31234 +#@schema/desc "will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/nullable +deprecated_service_http_loadbalancer_port: 8443 +#@schema/desc "#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/nullable +deprecated_service_http_clusterip_port: 8443 +#@schema/desc "#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/nullable +service_https_nodeport_port: 31243 +#@schema/desc "#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified" +#@schema/nullable +service_https_nodeport_nodeport: 31243 +#@schema/desc "#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/nullable +service_https_loadbalancer_port: 8443 +#@schema/desc "#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/nullable +service_https_clusterip_port: 8443 +#@ service_loadbalancer_ip_desc="The `loadBalancerIP` value of the LoadBalancer Service. \ +#@ Ignored unless service_https_loadbalancer_port is provided." +#@schema/desc service_loadbalancer_ip_desc +#@schema/nullable +service_loadbalancer_ip: 1.2.3.4 #! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information), #! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged. -log_level: #! By default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. -#! Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). -#! By default, when this value is left unset, logs are formatted in json. -#! This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json. -deprecated_log_format: +#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." +#@schema/nullable +log_level: info +#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ +#@ By default, when this value is left unset, logs are formatted in json. \ +#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." +#@schema/desc deprecated_log_format_desc +#@schema/nullable +deprecated_log_format: json -run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice -run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice +#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_user: 65532 +#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_group: 65532 -#! Specify the API group suffix for all Pinniped API groups. By default, this is set to -#! pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, -#! authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then -#! Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. +#@ api_group_suffix_desc = "Specify the API group suffix for all Pinniped API groups. By default, this is set to \ +#@ pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, \ +#@ authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then \ +#@ Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc." +#@schema/desc api_group_suffix_desc api_group_suffix: pinniped.dev -#! Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. -#! These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, -#! e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. -#! The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. -#! Optional. -https_proxy: #! e.g. http://proxy.example.com -no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints +#@ https_proxy_desc = "Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. \ +#@ These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, \ +#@ e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. \ +#@ The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. \ +#@ Optional." +#@schema/desc https_proxy_desc +#@schema/nullable +https_proxy: http://proxy.example.com +#@schema/desc "do not proxy Kubernetes endpoints" +no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! Control the HTTP and HTTPS listeners of the Supervisor. #! @@ -118,16 +155,22 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,. #! Changing the HTTPS port number must be accompanied by matching changes to the service and deployment #! manifests. Changes to the HTTPS listener must be coordinated with the deployment health checks. #! -#! Optional. +#@schema/desc "Control the HTTP and HTTPS listeners of the Supervisor." +#@schema/nullable endpoints: + https: + network: tcp + address: 1.2.3.4:5678 -#! Optionally override the validation on the endpoints.http value which checks that only loopback interfaces are used. -#! When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any -#! interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced -#! to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time -#! to change their ingress strategy to avoid using plain HTTP into the Supervisor pods. -#! This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time -#! traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available. -#! Allowed values are true (boolean), "true" (string), false (boolean), and "false" (string). The default is false. -#! Optional. +#! deprecated_insecure_accept_external_unencrypted_http_requests_desc = "Optionally override the validation on the endpoints. \ +#! http value which checks that only loopback interfaces are used. \ +#! When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any \ +#! interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced \ +#! to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time \ +#! to change their ingress strategy to avoid using plain HTTP into the Supervisor pods. \ +#! This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time \ +#! traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available. \ +#! Allowed values are true (boolean), "true" (string), false (boolean), and "false" (string). The default is false. \ +#! Optional." +#@schema/desc https_proxy_desc deprecated_insecure_accept_external_unencrypted_http_requests: false From 44356b0db33d01b99bb19034b7cee8e73bcc5302 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 28 Sep 2023 16:43:35 -0400 Subject: [PATCH 03/40] Add deploy_carvel dir with symlink to deploy/{supervisor,concierge} --- deploy_carvel/concierge/README.md | 3 +++ deploy_carvel/concierge/config | 1 + deploy_carvel/local-user-authenticator/README.md | 3 +++ deploy_carvel/local-user-authenticator/config | 1 + deploy_carvel/supervisor/README.md | 3 +++ deploy_carvel/supervisor/config | 1 + 6 files changed, 12 insertions(+) create mode 100644 deploy_carvel/concierge/README.md create mode 120000 deploy_carvel/concierge/config create mode 100644 deploy_carvel/local-user-authenticator/README.md create mode 120000 deploy_carvel/local-user-authenticator/config create mode 100644 deploy_carvel/supervisor/README.md create mode 120000 deploy_carvel/supervisor/config diff --git a/deploy_carvel/concierge/README.md b/deploy_carvel/concierge/README.md new file mode 100644 index 00000000..b22f18a6 --- /dev/null +++ b/deploy_carvel/concierge/README.md @@ -0,0 +1,3 @@ +# README + +- the ./config symlink points to /deploy/concierge diff --git a/deploy_carvel/concierge/config b/deploy_carvel/concierge/config new file mode 120000 index 00000000..de0a5c1b --- /dev/null +++ b/deploy_carvel/concierge/config @@ -0,0 +1 @@ +deploy/concierge \ No newline at end of file diff --git a/deploy_carvel/local-user-authenticator/README.md b/deploy_carvel/local-user-authenticator/README.md new file mode 100644 index 00000000..c6cda34e --- /dev/null +++ b/deploy_carvel/local-user-authenticator/README.md @@ -0,0 +1,3 @@ +# README + +- the ./config symlink points to /deploy/local-user-authenticator diff --git a/deploy_carvel/local-user-authenticator/config b/deploy_carvel/local-user-authenticator/config new file mode 120000 index 00000000..fa3d8c99 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/config @@ -0,0 +1 @@ +deploy/local-user-authenticator \ No newline at end of file diff --git a/deploy_carvel/supervisor/README.md b/deploy_carvel/supervisor/README.md new file mode 100644 index 00000000..5e1a39a9 --- /dev/null +++ b/deploy_carvel/supervisor/README.md @@ -0,0 +1,3 @@ +# README + +- the ./config symlink points to /deploy/supervisor diff --git a/deploy_carvel/supervisor/config b/deploy_carvel/supervisor/config new file mode 120000 index 00000000..cedaa4bd --- /dev/null +++ b/deploy_carvel/supervisor/config @@ -0,0 +1 @@ +deploy/supervisor \ No newline at end of file From 5e798f2af4c576aae67029f1f533d6c057069e10 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 12:42:01 -0400 Subject: [PATCH 04/40] Update values.yaml for local-user-authenticator to schema file --- deploy/local-user-authenticator/values.yaml | 29 +++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/deploy/local-user-authenticator/values.yaml b/deploy/local-user-authenticator/values.yaml index 1f65baa4..c0591304 100644 --- a/deploy/local-user-authenticator/values.yaml +++ b/deploy/local-user-authenticator/values.yaml @@ -1,19 +1,26 @@ -#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. +#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 -#@data/values +#@data/values-schema --- -#! Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." image_repo: projects.registry.vmware.com/pinniped/pinniped-server -image_digest: #! e.g. sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +#@schema/nullable +image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." image_tag: latest -#! 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. -image_pull_dockerconfigjson: #! e.g. {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +#@ image_pull_dockerconfigjson_desc = "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." +#@schema/desc image_pull_dockerconfigjson_desc +#@schema/nullable +image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} -run_as_user: 65532 #! run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice -run_as_group: 65532 #! run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice +#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_user: 65532 +#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_group: 65532 From 6d13de173b7a9710f0001a5ed613debbe73ea515 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 12:51:24 -0400 Subject: [PATCH 05/40] Add ytt openapi-v3 generation to build carvel package script --- deploy_carvel/concierge/schema-openapi.yaml | 155 +++++++++++++++++ .../schema-openapi.yaml | 55 ++++++ deploy_carvel/supervisor/schema-openapi.yaml | 164 ++++++++++++++++++ 3 files changed, 374 insertions(+) create mode 100644 deploy_carvel/concierge/schema-openapi.yaml create mode 100644 deploy_carvel/local-user-authenticator/schema-openapi.yaml create mode 100644 deploy_carvel/supervisor/schema-openapi.yaml diff --git a/deploy_carvel/concierge/schema-openapi.yaml b/deploy_carvel/concierge/schema-openapi.yaml new file mode 100644 index 00000000..fa5915cb --- /dev/null +++ b/deploy_carvel/concierge/schema-openapi.yaml @@ -0,0 +1,155 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-concierge. + default: pinniped-concierge + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-concierge + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: null + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + kube_cert_agent_image: + type: string + nullable: true + description: Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled on the control plane. This image needs only to include `sleep` and `cat` binaries. By default, the same image specified for image_repo/image_digest/image_tag will be re-used. + default: null + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + discovery_url: + type: string + nullable: true + description: Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden. + default: null + api_serving_certificate_duration_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2592000 + api_serving_certificate_renew_before_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2160000 + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + impersonation_proxy_spec: + type: object + additionalProperties: false + description: Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation. + properties: + mode: + type: string + description: If enabled, the impersonation proxy will always run regardless of other strategies available. + default: auto + external_endpoint: + type: string + nullable: true + description: The endpoint which the client should use to connect to the impersonation proxy. If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint. + default: null + service: + type: object + additionalProperties: false + description: The impersonation proxy service configuration + properties: + type: + type: string + nullable: true + description: Options are 'LoadBalancer', 'ClusterIP' and 'None'. + default: null + annotations: + type: object + additionalProperties: false + nullable: true + description: The annotations that should be set on the ClusterIP or LoadBalancer Service. + properties: + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: + type: string + default: "4000" + load_balancer_ip: + type: string + nullable: true + description: When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP. + default: null + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local diff --git a/deploy_carvel/local-user-authenticator/schema-openapi.yaml b/deploy_carvel/local-user-authenticator/schema-openapi.yaml new file mode 100644 index 00000000..6dfcff7f --- /dev/null +++ b/deploy_carvel/local-user-authenticator/schema-openapi.yaml @@ -0,0 +1,55 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 diff --git a/deploy_carvel/supervisor/schema-openapi.yaml b/deploy_carvel/supervisor/schema-openapi.yaml new file mode 100644 index 00000000..3d174612 --- /dev/null +++ b/deploy_carvel/supervisor/schema-openapi.yaml @@ -0,0 +1,164 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-supervisor. + default: pinniped-supervisor + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-supervisor + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: null + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + deprecated_service_http_nodeport_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_nodeport_nodeport: + type: integer + nullable: true + description: will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified + default: null + deprecated_service_http_loadbalancer_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_clusterip_port: + type: integer + nullable: true + description: '#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`' + default: null + service_https_nodeport_port: + type: integer + nullable: true + description: '#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_nodeport_nodeport: + type: integer + nullable: true + description: '#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified' + default: null + service_https_loadbalancer_port: + type: integer + nullable: true + description: '#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_clusterip_port: + type: integer + nullable: true + description: '#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_loadbalancer_ip: + type: string + nullable: true + description: The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided. + default: null + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local + endpoints: + type: object + additionalProperties: false + nullable: true + description: Control the HTTP and HTTPS listeners of the Supervisor. + properties: + https: + type: object + additionalProperties: false + properties: + network: + type: string + default: tcp + address: + type: string + default: 1.2.3.4:5678 + deprecated_insecure_accept_external_unencrypted_http_requests: + type: boolean + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: false From 538f6b5b3fab7b15acc903feae07d3d4cef6eb95 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 13:04:09 -0400 Subject: [PATCH 06/40] Add supervisor carvel package files --- deploy_carvel/supervisor/README.md | 6 +++- deploy_carvel/supervisor/build.yml | 4 +++ deploy_carvel/supervisor/metadata.yml | 10 +++++++ deploy_carvel/supervisor/package-template.yml | 29 +++++++++++++++++++ ...schema-openapi.yaml => schema-openapi.yml} | 0 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 deploy_carvel/supervisor/build.yml create mode 100644 deploy_carvel/supervisor/metadata.yml create mode 100644 deploy_carvel/supervisor/package-template.yml rename deploy_carvel/supervisor/{schema-openapi.yaml => schema-openapi.yml} (100%) diff --git a/deploy_carvel/supervisor/README.md b/deploy_carvel/supervisor/README.md index 5e1a39a9..bfd5cf46 100644 --- a/deploy_carvel/supervisor/README.md +++ b/deploy_carvel/supervisor/README.md @@ -1,3 +1,7 @@ -# README +# Pinniped Supervisor Deployment + +See [the how-to guide for details](https://pinniped.dev/docs/howto/install-supervisor/). + +## In this directory: - the ./config symlink points to /deploy/supervisor diff --git a/deploy_carvel/supervisor/build.yml b/deploy_carvel/supervisor/build.yml new file mode 100644 index 00000000..dfff2974 --- /dev/null +++ b/deploy_carvel/supervisor/build.yml @@ -0,0 +1,4 @@ +apiVersion: kbld.k14s.io/v1alpha1 +kind: Config +minimumRequiredVersion: 0.31.0 +overrides: diff --git a/deploy_carvel/supervisor/metadata.yml b/deploy_carvel/supervisor/metadata.yml new file mode 100644 index 00000000..8a9e0e81 --- /dev/null +++ b/deploy_carvel/supervisor/metadata.yml @@ -0,0 +1,10 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: supervisor.pinniped.dev +spec: + displayName: "Pinniped Supervisor" + longDescription: "Pinniped supervisor allows seamless login across one or many Kubernetes clusters including AKS, EKS and GKE" + shortDescription: "Pinniped supervisor provides login capabilities" + categories: + - auth diff --git a/deploy_carvel/supervisor/package-template.yml b/deploy_carvel/supervisor/package-template.yml new file mode 100644 index 00000000..82e1cfe4 --- /dev/null +++ b/deploy_carvel/supervisor/package-template.yml @@ -0,0 +1,29 @@ +#@ load("@ytt:data", "data") # for reading data values (generated via ytt's data-values-schema-inspect mode). +#@ load("@ytt:yaml", "yaml") # for dynamically decoding the output of ytt's data-values-schema-inspect +--- +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: Package +metadata: + name: #@ "supervisor.pinniped.dev." + data.values.version +spec: + refName: supervisor.pinniped.dev + version: #@ data.values.version + releaseNotes: | + Initial release of the pinniped supervisor package, TODO: AUTOMATE THIS?? + valuesSchema: + openAPIv3: #@ yaml.decode(data.values.openapi)["components"]["schemas"]["dataValues"] + template: + spec: + fetch: + - imgpkgBundle: + image: #@ "${REPO_HOST}/packages/pinniped-supervisor:" + data.values.version + template: + - ytt: + paths: + - "config/" + - kbld: + paths: + - ".imgpkg/images.yml" + - "-" + deploy: + - kapp: {} diff --git a/deploy_carvel/supervisor/schema-openapi.yaml b/deploy_carvel/supervisor/schema-openapi.yml similarity index 100% rename from deploy_carvel/supervisor/schema-openapi.yaml rename to deploy_carvel/supervisor/schema-openapi.yml From b4e8b6c051e1af4470dcb152b9c9dd9a7215323d Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 13:04:30 -0400 Subject: [PATCH 07/40] Add concierge carvel package files --- deploy_carvel/concierge/README.md | 6 +++- deploy_carvel/concierge/build.yml | 4 +++ deploy_carvel/concierge/metadata.yml | 10 +++++++ deploy_carvel/concierge/package-template.yml | 29 +++++++++++++++++++ ...schema-openapi.yaml => schema-openapi.yml} | 0 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 deploy_carvel/concierge/build.yml create mode 100644 deploy_carvel/concierge/metadata.yml create mode 100644 deploy_carvel/concierge/package-template.yml rename deploy_carvel/concierge/{schema-openapi.yaml => schema-openapi.yml} (100%) diff --git a/deploy_carvel/concierge/README.md b/deploy_carvel/concierge/README.md index b22f18a6..fcca81c3 100644 --- a/deploy_carvel/concierge/README.md +++ b/deploy_carvel/concierge/README.md @@ -1,3 +1,7 @@ -# README +# Pinniped Concierge Deployment + +See [the how-to guide for details](https://pinniped.dev/docs/howto/concierge/). + +## In this directory: - the ./config symlink points to /deploy/concierge diff --git a/deploy_carvel/concierge/build.yml b/deploy_carvel/concierge/build.yml new file mode 100644 index 00000000..dfff2974 --- /dev/null +++ b/deploy_carvel/concierge/build.yml @@ -0,0 +1,4 @@ +apiVersion: kbld.k14s.io/v1alpha1 +kind: Config +minimumRequiredVersion: 0.31.0 +overrides: diff --git a/deploy_carvel/concierge/metadata.yml b/deploy_carvel/concierge/metadata.yml new file mode 100644 index 00000000..f310bb31 --- /dev/null +++ b/deploy_carvel/concierge/metadata.yml @@ -0,0 +1,10 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: concierge.pinniped.dev +spec: + displayName: "Pinniped Concierge" + longDescription: "Pinniped concierge enables consistent login across Kubernetes clusters on public cloud providers such as AKS, EKS and GKE" + shortDescription: "Pinniped concierge enables consistent login across public clouds" + categories: + - auth diff --git a/deploy_carvel/concierge/package-template.yml b/deploy_carvel/concierge/package-template.yml new file mode 100644 index 00000000..4fe974c7 --- /dev/null +++ b/deploy_carvel/concierge/package-template.yml @@ -0,0 +1,29 @@ +#@ load("@ytt:data", "data") # for reading data values (generated via ytt's data-values-schema-inspect mode). +#@ load("@ytt:yaml", "yaml") # for dynamically decoding the output of ytt's data-values-schema-inspect +--- +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: Package +metadata: + name: #@ "concierge.pinniped.dev." + data.values.version +spec: + refName: concierge.pinniped.dev + version: #@ data.values.version + releaseNotes: | + Initial release of the pinniped concierge package, TODO: AUTOMATE THIS?? + valuesSchema: + openAPIv3: #@ yaml.decode(data.values.openapi)["components"]["schemas"]["dataValues"] + template: + spec: + fetch: + - imgpkgBundle: + image: #@ "${REPO_HOST}/packages/pinniped-concierge:" + data.values.version + template: + - ytt: + paths: + - "config/" + - kbld: + paths: + - ".imgpkg/images.yml" + - "-" + deploy: + - kapp: {} diff --git a/deploy_carvel/concierge/schema-openapi.yaml b/deploy_carvel/concierge/schema-openapi.yml similarity index 100% rename from deploy_carvel/concierge/schema-openapi.yaml rename to deploy_carvel/concierge/schema-openapi.yml From 97d8688753ba9069eb3e85c8fa03e34f14c30786 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 13:04:49 -0400 Subject: [PATCH 08/40] Add local-user-authenticator carvel package files --- .../local-user-authenticator/README.md | 4 ++- .../local-user-authenticator/build.yml | 4 +++ .../local-user-authenticator/metadata.yml | 11 +++++++ .../package-template.yml | 29 +++++++++++++++++++ ...schema-openapi.yaml => schema-openapi.yml} | 0 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 deploy_carvel/local-user-authenticator/build.yml create mode 100644 deploy_carvel/local-user-authenticator/metadata.yml create mode 100644 deploy_carvel/local-user-authenticator/package-template.yml rename deploy_carvel/local-user-authenticator/{schema-openapi.yaml => schema-openapi.yml} (100%) diff --git a/deploy_carvel/local-user-authenticator/README.md b/deploy_carvel/local-user-authenticator/README.md index c6cda34e..ff77ea57 100644 --- a/deploy_carvel/local-user-authenticator/README.md +++ b/deploy_carvel/local-user-authenticator/README.md @@ -1,3 +1,5 @@ -# README +# local-user-authenticator + +## In this directory: - the ./config symlink points to /deploy/local-user-authenticator diff --git a/deploy_carvel/local-user-authenticator/build.yml b/deploy_carvel/local-user-authenticator/build.yml new file mode 100644 index 00000000..dfff2974 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/build.yml @@ -0,0 +1,4 @@ +apiVersion: kbld.k14s.io/v1alpha1 +kind: Config +minimumRequiredVersion: 0.31.0 +overrides: diff --git a/deploy_carvel/local-user-authenticator/metadata.yml b/deploy_carvel/local-user-authenticator/metadata.yml new file mode 100644 index 00000000..1ad53d44 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/metadata.yml @@ -0,0 +1,11 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: local-user-authenticator.pinniped.dev +spec: + displayName: "local-user-authenticator" + longDescription: "The local-user-authenticator app is an identity provider used for integration testing and demos. Note that this is not recommended for +production use." + shortDescription: "The local-user-authenticator app is an identity provider used for integration testing and demos." + categories: + - auth diff --git a/deploy_carvel/local-user-authenticator/package-template.yml b/deploy_carvel/local-user-authenticator/package-template.yml new file mode 100644 index 00000000..c02620c6 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/package-template.yml @@ -0,0 +1,29 @@ +#@ load("@ytt:data", "data") # for reading data values (generated via ytt's data-values-schema-inspect mode). +#@ load("@ytt:yaml", "yaml") # for dynamically decoding the output of ytt's data-values-schema-inspect +--- +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: Package +metadata: + name: #@ "local-user-authenticator.pinniped.dev." + data.values.version +spec: + refName: local-user-authenticator.pinniped.dev + version: #@ data.values.version + releaseNotes: | + Initial release of the local-user-authenticator package, TODO: AUTOMATE THIS?? + valuesSchema: + openAPIv3: #@ yaml.decode(data.values.openapi)["components"]["schemas"]["dataValues"] + template: + spec: + fetch: + - imgpkgBundle: + image: #@ "${REPO_HOST}/packages/local-user-authenticator:" + data.values.version + template: + - ytt: + paths: + - "config/" + - kbld: + paths: + - ".imgpkg/images.yml" + - "-" + deploy: + - kapp: {} diff --git a/deploy_carvel/local-user-authenticator/schema-openapi.yaml b/deploy_carvel/local-user-authenticator/schema-openapi.yml similarity index 100% rename from deploy_carvel/local-user-authenticator/schema-openapi.yaml rename to deploy_carvel/local-user-authenticator/schema-openapi.yml From 7950dc4cdbdf7a2635dca8425b37baf021891c8a Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 13:05:28 -0400 Subject: [PATCH 09/40] Add hack script to build openapi-v3 files --- hack/build-carvel-packages.sh | 66 +++++++++++++++++++++++++++ hack/prepare-for-integration-tests.sh | 5 -- 2 files changed, 66 insertions(+), 5 deletions(-) create mode 100755 hack/build-carvel-packages.sh diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh new file mode 100755 index 00000000..a6694155 --- /dev/null +++ b/hack/build-carvel-packages.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +# +# This script can be used to prepare a kind cluster and deploy the app. +# You can call this script again to redeploy the app. +# It will also output instructions on how to run the integration. +# + +set -euo pipefail + +# +# Helper functions +# +function log_note() { + GREEN='\033[0;32m' + NC='\033[0m' + if [[ ${COLORTERM:-unknown} =~ ^(truecolor|24bit)$ ]]; then + echo -e "${GREEN}$*${NC}" + else + echo "$*" + fi +} + +function log_error() { + RED='\033[0;31m' + NC='\033[0m' + if [[ ${COLORTERM:-unknown} =~ ^(truecolor|24bit)$ ]]; then + echo -e "🙁${RED} Error: $* ${NC}" + else + echo ":( Error: $*" + fi +} + +function check_dependency() { + if ! command -v "$1" >/dev/null; then + log_error "Missing dependency..." + log_error "$2" + exit 1 + fi +} + +# registry="pinniped.local" +registry="kind-registry.local:5000" +repo="test/build" +registry_repo="$registry/$repo" +tag=$(uuidgen) # always a new tag to force K8s to reload the image on redeploy +registry_repo_tag="${registry_repo}:${tag}" + +# Generate the OpenAPI v3 Schema files +declare -a arr=("supervisor" "concierge" "local-user-authenticator") +for resource_name in "${arr[@]}" +do + log_note "Generating OpenAPI v3 schema for ${resource_name}..." + ytt \ + --file "deploy/${resource_name}" \ + --data-values-schema-inspect \ + --output openapi-v3 > \ + "deploy_carvel/${resource_name}/schema-openapi.yaml" +done + + +log_note "Finished." +log_note "Now run hack/prepare-for-integration-tests.sh to create a kind cluster!" diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index d571a571..3675e71d 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -220,11 +220,9 @@ else fi fi -# NOW CHANGE THIS SO WE PUSH TO THE REGISTRY? # registry="pinniped.local" registry="kind-registry.local:5000" repo="test/build" -# TODO: can we force HTTP here? HTTPS is problematic. registry_repo="$registry/$repo" tag=$(uuidgen) # always a new tag to force K8s to reload the image on redeploy @@ -258,9 +256,6 @@ fi # Load it into the cluster log_note "Loading the app's container image into the local registry ($registry)..." -# TODO: now we don't want to direct load anymore, we want to docker push to our new local registry. -# and then be sure that it pulls? -# kind load docker-image "$registry_repo_tag" --name pinniped docker push "$registry_repo_tag" # From 1f281a7d7ef840c69548c0c503d1b4b047d4410b Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 13:12:55 -0400 Subject: [PATCH 10/40] custom_labels should not be nullable --- deploy/concierge/values.yaml | 1 - deploy/supervisor/values.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 1203839b..32306740 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -23,7 +23,6 @@ into_namespace: my-preexisting-namespace #@ 2. Or, deleting all resources by label, which does not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc #@schema/type any=True -#@schema/nullable custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} #@schema/desc "Specify how many replicas of the Pinniped server to run." diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 99741cdf..04606edb 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -23,7 +23,6 @@ into_namespace: my-preexisting-namespace #@ 2. Or, deleting all resources by label, which does not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc #@schema/type any=True -#@schema/nullable custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} #@schema/desc "Specify how many replicas of the Pinniped server to run." From ff09b6136438e443ffb30f77f2025066ae09387b Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 13:13:21 -0400 Subject: [PATCH 11/40] generate .imgpkg/images.yml files for carvel packages --- deploy_carvel/concierge/.imgpkg/images.yml | 11 ++ deploy_carvel/concierge/schema-openapi.yaml | 155 +++++++++++++++++ .../.imgpkg/images.yml | 11 ++ .../schema-openapi.yaml | 55 ++++++ deploy_carvel/supervisor/.imgpkg/images.yml | 11 ++ deploy_carvel/supervisor/schema-openapi.yaml | 164 ++++++++++++++++++ hack/build-carvel-packages.sh | 5 + 7 files changed, 412 insertions(+) create mode 100644 deploy_carvel/concierge/.imgpkg/images.yml create mode 100644 deploy_carvel/concierge/schema-openapi.yaml create mode 100644 deploy_carvel/local-user-authenticator/.imgpkg/images.yml create mode 100644 deploy_carvel/local-user-authenticator/schema-openapi.yaml create mode 100644 deploy_carvel/supervisor/.imgpkg/images.yml create mode 100644 deploy_carvel/supervisor/schema-openapi.yaml diff --git a/deploy_carvel/concierge/.imgpkg/images.yml b/deploy_carvel/concierge/.imgpkg/images.yml new file mode 100644 index 00000000..adc53f2c --- /dev/null +++ b/deploy_carvel/concierge/.imgpkg/images.yml @@ -0,0 +1,11 @@ +--- +apiVersion: imgpkg.carvel.dev/v1alpha1 +images: +- annotations: + kbld.carvel.dev/id: projects.registry.vmware.com/pinniped/pinniped-server:latest + kbld.carvel.dev/origins: | + - resolved: + tag: latest + url: projects.registry.vmware.com/pinniped/pinniped-server:latest + image: projects.registry.vmware.com/pinniped/pinniped-server@sha256:a92183de893eb0b1850cc3a1d33306b96ba2cdb72a8a49c6493a58c01b4fa9cd +kind: ImagesLock diff --git a/deploy_carvel/concierge/schema-openapi.yaml b/deploy_carvel/concierge/schema-openapi.yaml new file mode 100644 index 00000000..9f18a393 --- /dev/null +++ b/deploy_carvel/concierge/schema-openapi.yaml @@ -0,0 +1,155 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-concierge. + default: pinniped-concierge + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-concierge + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: {} + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + kube_cert_agent_image: + type: string + nullable: true + description: Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled on the control plane. This image needs only to include `sleep` and `cat` binaries. By default, the same image specified for image_repo/image_digest/image_tag will be re-used. + default: null + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + discovery_url: + type: string + nullable: true + description: Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden. + default: null + api_serving_certificate_duration_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2592000 + api_serving_certificate_renew_before_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2160000 + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + impersonation_proxy_spec: + type: object + additionalProperties: false + description: Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation. + properties: + mode: + type: string + description: If enabled, the impersonation proxy will always run regardless of other strategies available. + default: auto + external_endpoint: + type: string + nullable: true + description: The endpoint which the client should use to connect to the impersonation proxy. If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint. + default: null + service: + type: object + additionalProperties: false + description: The impersonation proxy service configuration + properties: + type: + type: string + nullable: true + description: Options are 'LoadBalancer', 'ClusterIP' and 'None'. + default: null + annotations: + type: object + additionalProperties: false + nullable: true + description: The annotations that should be set on the ClusterIP or LoadBalancer Service. + properties: + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: + type: string + default: "4000" + load_balancer_ip: + type: string + nullable: true + description: When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP. + default: null + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local diff --git a/deploy_carvel/local-user-authenticator/.imgpkg/images.yml b/deploy_carvel/local-user-authenticator/.imgpkg/images.yml new file mode 100644 index 00000000..adc53f2c --- /dev/null +++ b/deploy_carvel/local-user-authenticator/.imgpkg/images.yml @@ -0,0 +1,11 @@ +--- +apiVersion: imgpkg.carvel.dev/v1alpha1 +images: +- annotations: + kbld.carvel.dev/id: projects.registry.vmware.com/pinniped/pinniped-server:latest + kbld.carvel.dev/origins: | + - resolved: + tag: latest + url: projects.registry.vmware.com/pinniped/pinniped-server:latest + image: projects.registry.vmware.com/pinniped/pinniped-server@sha256:a92183de893eb0b1850cc3a1d33306b96ba2cdb72a8a49c6493a58c01b4fa9cd +kind: ImagesLock diff --git a/deploy_carvel/local-user-authenticator/schema-openapi.yaml b/deploy_carvel/local-user-authenticator/schema-openapi.yaml new file mode 100644 index 00000000..6dfcff7f --- /dev/null +++ b/deploy_carvel/local-user-authenticator/schema-openapi.yaml @@ -0,0 +1,55 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 diff --git a/deploy_carvel/supervisor/.imgpkg/images.yml b/deploy_carvel/supervisor/.imgpkg/images.yml new file mode 100644 index 00000000..adc53f2c --- /dev/null +++ b/deploy_carvel/supervisor/.imgpkg/images.yml @@ -0,0 +1,11 @@ +--- +apiVersion: imgpkg.carvel.dev/v1alpha1 +images: +- annotations: + kbld.carvel.dev/id: projects.registry.vmware.com/pinniped/pinniped-server:latest + kbld.carvel.dev/origins: | + - resolved: + tag: latest + url: projects.registry.vmware.com/pinniped/pinniped-server:latest + image: projects.registry.vmware.com/pinniped/pinniped-server@sha256:a92183de893eb0b1850cc3a1d33306b96ba2cdb72a8a49c6493a58c01b4fa9cd +kind: ImagesLock diff --git a/deploy_carvel/supervisor/schema-openapi.yaml b/deploy_carvel/supervisor/schema-openapi.yaml new file mode 100644 index 00000000..0e0903fa --- /dev/null +++ b/deploy_carvel/supervisor/schema-openapi.yaml @@ -0,0 +1,164 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-supervisor. + default: pinniped-supervisor + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-supervisor + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: {} + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + deprecated_service_http_nodeport_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_nodeport_nodeport: + type: integer + nullable: true + description: will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified + default: null + deprecated_service_http_loadbalancer_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_clusterip_port: + type: integer + nullable: true + description: '#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`' + default: null + service_https_nodeport_port: + type: integer + nullable: true + description: '#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_nodeport_nodeport: + type: integer + nullable: true + description: '#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified' + default: null + service_https_loadbalancer_port: + type: integer + nullable: true + description: '#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_clusterip_port: + type: integer + nullable: true + description: '#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_loadbalancer_ip: + type: string + nullable: true + description: The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided. + default: null + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local + endpoints: + type: object + additionalProperties: false + nullable: true + description: Control the HTTP and HTTPS listeners of the Supervisor. + properties: + https: + type: object + additionalProperties: false + properties: + network: + type: string + default: tcp + address: + type: string + default: 1.2.3.4:5678 + deprecated_insecure_accept_external_unencrypted_http_requests: + type: boolean + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: false diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index a6694155..e785d4d8 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -59,6 +59,11 @@ do --data-values-schema-inspect \ --output openapi-v3 > \ "deploy_carvel/${resource_name}/schema-openapi.yaml" + + log_note "Generating .imgpkg/images.yml for ${resource_name}..." + ytt \ + --file "deploy/${resource_name}/" | \ + kbld -f- --imgpkg-lock-output "deploy_carvel/${resource_name}/.imgpkg/images.yml" done From 530ce433ace896679563a11aeb4e331b8df4c799 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 29 Sep 2023 15:49:49 -0400 Subject: [PATCH 12/40] add --post-install to hack/prepare-for-integration-tests.sh --- hack/prepare-for-integration-tests.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 3675e71d..37487fef 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -55,6 +55,7 @@ alternate_deploy="undefined" alternate_deploy_supervisor="undefined" alternate_deploy_concierge="undefined" alternate_deploy_local_user_authenticator="undefined" +post_install="undefined" # supported variable style: # --dockerfile-path ./foo.sh @@ -140,6 +141,15 @@ while (("$#")); do alternate_deploy_local_user_authenticator=$1 shift ;; + --post-install) + shift + if [[ "$#" == "0" || "$1" == -* ]]; then + log_error "--post-install requires a script path to be specified" + exit 1 + fi + post_install=$1 + shift + ;; -*) log_error "Unsupported flag $1" >&2 if [[ "$1" == *"active-directory"* ]]; then @@ -169,6 +179,7 @@ if [[ "$help" == "yes" ]]; then log_note " --alternate-deploy-supervisor: specify an alternate deploy script to install Pinniped Supervisor" log_note " --alternate-deploy-concierge: specify an alternate deploy script to install Pinniped Concierge" log_note " --alternate-deploy-local-user-authenticator: specify an alternate deploy script to install Pinniped local-user-authenticator" + log_note " --post-install: specify an post-install script" exit 1 fi @@ -397,6 +408,15 @@ else popd >/dev/null fi +# +# Call a post-install script +# simplifies passing the $tag which may be necessary if the current local build is to be +# referenced, for example, deploying via a Carvel package rather than our ytt mechanism +if [ "$post_install" != "undefined" ] ; then + log_note "The post-install script will be called with $tag..." + $post_install post-install-script $tag +fi + # # Download the test CA bundle that was generated in the Dex pod. # Note that this returns a base64 encoded value. From 0f0d9927c077c2930ba107b1c088d42d2ea7167e Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Mon, 2 Oct 2023 15:28:01 -0400 Subject: [PATCH 13/40] WIP: carvel package-repository & package files, package-install in scripts --- deploy_carvel/concierge-pkginstall.yml | 32 ++ deploy_carvel/concierge/config | 1 - deploy_carvel/concierge/config/README.md | 3 + ...cierge.pinniped.dev_jwtauthenticators.yaml | 175 +++++++ ...ge.pinniped.dev_webhookauthenticators.yaml | 148 ++++++ ...cierge.pinniped.dev_credentialissuers.yaml | 257 +++++++++ .../concierge/config/deployment.yaml | 355 +++++++++++++ .../concierge/config/helpers.lib.yaml | 47 ++ deploy_carvel/concierge/config/rbac.yaml | 296 +++++++++++ deploy_carvel/concierge/config/values.yaml | 137 +++++ .../concierge/config/z0_crd_overlay.yaml | 33 ++ deploy_carvel/concierge/package-template.yml | 2 +- deploy_carvel/concierge/schema-openapi.yaml | 155 ------ .../local-user-authenticator-pkginstall.yml | 32 ++ deploy_carvel/local-user-authenticator/config | 1 - .../local-user-authenticator/config/README.md | 163 ++++++ .../config/deployment.yaml | 97 ++++ .../local-user-authenticator/config/rbac.yaml | 30 ++ .../config/values.yaml | 26 + .../package-template.yml | 2 +- .../schema-openapi.yaml | 55 -- .../package_repository/.imgpkg/images.yml | 46 ++ .../concierge.pinniped.dev/metadata.yml | 10 + .../metadata.yml | 11 + .../supervisor.pinniped.dev/metadata.yml | 10 + ...-package-rbac-concierge-concierge-rbac.yml | 35 ++ ...nticator-local-user-authenticator-rbac.yml | 35 ++ ...ackage-rbac-supervisor-supervisor-rbac.yml | 35 ++ deploy_carvel/supervisor-pkginstall.yml | 35 ++ deploy_carvel/supervisor/config | 1 - deploy_carvel/supervisor/config/README.md | 3 + ...rvisor.pinniped.dev_federationdomains.yaml | 488 ++++++++++++++++++ ...g.supervisor.pinniped.dev_oidcclients.yaml | 220 ++++++++ .../supervisor/config/deployment.yaml | 236 +++++++++ .../supervisor/config/helpers.lib.yaml | 88 ++++ ....dev_activedirectoryidentityproviders.yaml | 318 ++++++++++++ ...or.pinniped.dev_ldapidentityproviders.yaml | 315 +++++++++++ ...or.pinniped.dev_oidcidentityproviders.yaml | 345 +++++++++++++ deploy_carvel/supervisor/config/rbac.yaml | 152 ++++++ deploy_carvel/supervisor/config/service.yaml | 115 +++++ deploy_carvel/supervisor/config/values.yaml | 175 +++++++ .../supervisor/config/z0_crd_overlay.yaml | 63 +++ deploy_carvel/supervisor/package-template.yml | 2 +- deploy_carvel/supervisor/schema-openapi.yaml | 164 ------ hack/build-carvel-packages.sh | 354 ++++++++++++- hack/noop.sh | 68 +++ hack/prepare-for-integration-tests.sh | 28 +- 47 files changed, 4997 insertions(+), 402 deletions(-) create mode 100644 deploy_carvel/concierge-pkginstall.yml delete mode 120000 deploy_carvel/concierge/config create mode 100644 deploy_carvel/concierge/config/README.md create mode 100644 deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml create mode 100644 deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml create mode 100644 deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml create mode 100644 deploy_carvel/concierge/config/deployment.yaml create mode 100644 deploy_carvel/concierge/config/helpers.lib.yaml create mode 100644 deploy_carvel/concierge/config/rbac.yaml create mode 100644 deploy_carvel/concierge/config/values.yaml create mode 100644 deploy_carvel/concierge/config/z0_crd_overlay.yaml delete mode 100644 deploy_carvel/concierge/schema-openapi.yaml create mode 100644 deploy_carvel/local-user-authenticator-pkginstall.yml delete mode 120000 deploy_carvel/local-user-authenticator/config create mode 100644 deploy_carvel/local-user-authenticator/config/README.md create mode 100644 deploy_carvel/local-user-authenticator/config/deployment.yaml create mode 100644 deploy_carvel/local-user-authenticator/config/rbac.yaml create mode 100644 deploy_carvel/local-user-authenticator/config/values.yaml delete mode 100644 deploy_carvel/local-user-authenticator/schema-openapi.yaml create mode 100644 deploy_carvel/package_repository/.imgpkg/images.yml create mode 100644 deploy_carvel/package_repository/packages/concierge.pinniped.dev/metadata.yml create mode 100644 deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/metadata.yml create mode 100644 deploy_carvel/package_repository/packages/supervisor.pinniped.dev/metadata.yml create mode 100644 deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml create mode 100644 deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml create mode 100644 deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml create mode 100644 deploy_carvel/supervisor-pkginstall.yml delete mode 120000 deploy_carvel/supervisor/config create mode 100644 deploy_carvel/supervisor/config/README.md create mode 100644 deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml create mode 100644 deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml create mode 100644 deploy_carvel/supervisor/config/deployment.yaml create mode 100644 deploy_carvel/supervisor/config/helpers.lib.yaml create mode 100644 deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml create mode 100644 deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml create mode 100644 deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml create mode 100644 deploy_carvel/supervisor/config/rbac.yaml create mode 100644 deploy_carvel/supervisor/config/service.yaml create mode 100644 deploy_carvel/supervisor/config/values.yaml create mode 100644 deploy_carvel/supervisor/config/z0_crd_overlay.yaml delete mode 100644 deploy_carvel/supervisor/schema-openapi.yaml create mode 100755 hack/noop.sh diff --git a/deploy_carvel/concierge-pkginstall.yml b/deploy_carvel/concierge-pkginstall.yml new file mode 100644 index 00000000..c1d876c2 --- /dev/null +++ b/deploy_carvel/concierge-pkginstall.yml @@ -0,0 +1,32 @@ +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "concierge-package-install" + namespace: "concierge-install-ns" +spec: + serviceAccountName: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" + packageRef: + refName: "concierge.pinniped.dev" + versionSelection: + constraints: "0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7" + values: + - secretRef: + name: "concierge-package-install-secret" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "concierge-package-install-secret" + namespace: "concierge-install-ns" +stringData: + values.yml: | + --- + app_name: pinniped-concierge + namespace: concierge + api_group_suffix: pinniped.dev + log_level: debug + + image_repo: kind-registry.local:5000/test/build + image_tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 diff --git a/deploy_carvel/concierge/config b/deploy_carvel/concierge/config deleted file mode 120000 index de0a5c1b..00000000 --- a/deploy_carvel/concierge/config +++ /dev/null @@ -1 +0,0 @@ -deploy/concierge \ No newline at end of file diff --git a/deploy_carvel/concierge/config/README.md b/deploy_carvel/concierge/config/README.md new file mode 100644 index 00000000..39ce06b2 --- /dev/null +++ b/deploy_carvel/concierge/config/README.md @@ -0,0 +1,3 @@ +# Pinniped Concierge Deployment + +See [the how-to guide for details](https://pinniped.dev/docs/howto/install-concierge/). diff --git a/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml new file mode 100644 index 00000000..0520898f --- /dev/null +++ b/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml @@ -0,0 +1,175 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: jwtauthenticators.authentication.concierge.pinniped.dev +spec: + group: authentication.concierge.pinniped.dev + names: + categories: + - pinniped + - pinniped-authenticator + - pinniped-authenticators + kind: JWTAuthenticator + listKind: JWTAuthenticatorList + plural: jwtauthenticators + singular: jwtauthenticator + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.issuer + name: Issuer + type: string + - jsonPath: .spec.audience + name: Audience + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: "JWTAuthenticator describes the configuration of a JWT authenticator. + \n Upon receiving a signed JWT, a JWTAuthenticator will performs some validation + on it (e.g., valid signature, existence of claims, etc.) and extract the + username and groups from the token." + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec for configuring the authenticator. + properties: + audience: + description: Audience is the required value of the "aud" JWT claim. + minLength: 1 + type: string + claims: + description: Claims allows customization of the claims that will be + mapped to user identity for Kubernetes access. + properties: + groups: + description: Groups is the name of the claim which should be read + to extract the user's group membership from the JWT token. When + not specified, it will default to "groups". + type: string + username: + description: Username is the name of the claim which should be + read to extract the username from the JWT token. When not specified, + it will default to "username". + type: string + type: object + issuer: + description: Issuer is the OIDC issuer URL that will be used to discover + public signing keys. Issuer is also used to validate the "iss" JWT + claim. + minLength: 1 + pattern: ^https:// + type: string + tls: + description: TLS configuration for communicating with the OIDC provider. + properties: + certificateAuthorityData: + description: X.509 Certificate Authority (base64-encoded PEM bundle). + If omitted, a default set of system roots will be trusted. + type: string + type: object + required: + - audience + - issuer + type: object + status: + description: Status of the authenticator. + properties: + conditions: + description: Represents the observations of the authenticator's current + state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml b/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml new file mode 100644 index 00000000..5924c6f6 --- /dev/null +++ b/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml @@ -0,0 +1,148 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: webhookauthenticators.authentication.concierge.pinniped.dev +spec: + group: authentication.concierge.pinniped.dev + names: + categories: + - pinniped + - pinniped-authenticator + - pinniped-authenticators + kind: WebhookAuthenticator + listKind: WebhookAuthenticatorList + plural: webhookauthenticators + singular: webhookauthenticator + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.endpoint + name: Endpoint + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: WebhookAuthenticator describes the configuration of a webhook + authenticator. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec for configuring the authenticator. + properties: + endpoint: + description: Webhook server endpoint URL. + minLength: 1 + pattern: ^https:// + type: string + tls: + description: TLS configuration. + properties: + certificateAuthorityData: + description: X.509 Certificate Authority (base64-encoded PEM bundle). + If omitted, a default set of system roots will be trusted. + type: string + type: object + required: + - endpoint + type: object + status: + description: Status of the authenticator. + properties: + conditions: + description: Represents the observations of the authenticator's current + state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml b/deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml new file mode 100644 index 00000000..23bb032c --- /dev/null +++ b/deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml @@ -0,0 +1,257 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: credentialissuers.config.concierge.pinniped.dev +spec: + group: config.concierge.pinniped.dev + names: + categories: + - pinniped + kind: CredentialIssuer + listKind: CredentialIssuerList + plural: credentialissuers + singular: credentialissuer + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.impersonationProxy.mode + name: ProxyMode + type: string + - jsonPath: .status.strategies[?(@.status == "Success")].type + name: DefaultStrategy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: CredentialIssuer describes the configuration and status of the + Pinniped Concierge credential issuer. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec describes the intended configuration of the Concierge. + properties: + impersonationProxy: + description: ImpersonationProxy describes the intended configuration + of the Concierge impersonation proxy. + properties: + externalEndpoint: + description: "ExternalEndpoint describes the HTTPS endpoint where + the proxy will be exposed. If not set, the proxy will be served + using the external name of the LoadBalancer service or the cluster + service DNS name. \n This field must be non-empty when spec.impersonationProxy.service.type + is \"None\"." + type: string + mode: + description: 'Mode configures whether the impersonation proxy + should be started: - "disabled" explicitly disables the impersonation + proxy. This is the default. - "enabled" explicitly enables the + impersonation proxy. - "auto" enables or disables the impersonation + proxy based upon the cluster in which it is running.' + enum: + - auto + - enabled + - disabled + type: string + service: + default: + type: LoadBalancer + description: Service describes the configuration of the Service + provisioned to expose the impersonation proxy to clients. + properties: + annotations: + additionalProperties: + type: string + description: Annotations specifies zero or more key/value + pairs to set as annotations on the provisioned Service. + type: object + loadBalancerIP: + description: LoadBalancerIP specifies the IP address to set + in the spec.loadBalancerIP field of the provisioned Service. + This is not supported on all cloud providers. + maxLength: 255 + minLength: 1 + type: string + type: + default: LoadBalancer + description: "Type specifies the type of Service to provision + for the impersonation proxy. \n If the type is \"None\", + then the \"spec.impersonationProxy.externalEndpoint\" field + must be set to a non-empty value so that the Concierge can + properly advertise the endpoint in the CredentialIssuer's + status." + enum: + - LoadBalancer + - ClusterIP + - None + type: string + type: object + tls: + description: "TLS contains information about how the Concierge + impersonation proxy should serve TLS. \n If this field is empty, + the impersonation proxy will generate its own TLS certificate." + properties: + certificateAuthorityData: + description: X.509 Certificate Authority (base64-encoded PEM + bundle). Used to advertise the CA bundle for the impersonation + proxy endpoint. + type: string + secretName: + description: SecretName is the name of a Secret in the same + namespace, of type `kubernetes.io/tls`, which contains the + TLS serving certificate for the Concierge impersonation + proxy endpoint. + minLength: 1 + type: string + type: object + required: + - mode + - service + type: object + required: + - impersonationProxy + type: object + status: + description: CredentialIssuerStatus describes the status of the Concierge. + properties: + kubeConfigInfo: + description: Information needed to form a valid Pinniped-based kubeconfig + using this credential issuer. This field is deprecated and will + be removed in a future version. + properties: + certificateAuthorityData: + description: The K8s API server CA bundle. + minLength: 1 + type: string + server: + description: The K8s API server URL. + minLength: 1 + pattern: ^https://|^http:// + type: string + required: + - certificateAuthorityData + - server + type: object + strategies: + description: List of integration strategies that were attempted by + Pinniped. + items: + description: CredentialIssuerStrategy describes the status of an + integration strategy that was attempted by Pinniped. + properties: + frontend: + description: Frontend describes how clients can connect using + this strategy. + properties: + impersonationProxyInfo: + description: ImpersonationProxyInfo describes the parameters + for the impersonation proxy on this Concierge. This field + is only set when Type is "ImpersonationProxy". + properties: + certificateAuthorityData: + description: CertificateAuthorityData is the base64-encoded + PEM CA bundle of the impersonation proxy. + minLength: 1 + type: string + endpoint: + description: Endpoint is the HTTPS endpoint of the impersonation + proxy. + minLength: 1 + pattern: ^https:// + type: string + required: + - certificateAuthorityData + - endpoint + type: object + tokenCredentialRequestInfo: + description: TokenCredentialRequestAPIInfo describes the + parameters for the TokenCredentialRequest API on this + Concierge. This field is only set when Type is "TokenCredentialRequestAPI". + properties: + certificateAuthorityData: + description: CertificateAuthorityData is the base64-encoded + Kubernetes API server CA bundle. + minLength: 1 + type: string + server: + description: Server is the Kubernetes API server URL. + minLength: 1 + pattern: ^https://|^http:// + type: string + required: + - certificateAuthorityData + - server + type: object + type: + description: Type describes which frontend mechanism clients + can use with a strategy. + enum: + - TokenCredentialRequestAPI + - ImpersonationProxy + type: string + required: + - type + type: object + lastUpdateTime: + description: When the status was last checked. + format: date-time + type: string + message: + description: Human-readable description of the current status. + minLength: 1 + type: string + reason: + description: Reason for the current status. + enum: + - Listening + - Pending + - Disabled + - ErrorDuringSetup + - CouldNotFetchKey + - CouldNotGetClusterInfo + - FetchedKey + type: string + status: + description: Status of the attempted integration strategy. + enum: + - Success + - Error + type: string + type: + description: Type of integration attempted. + enum: + - KubeClusterSigningCertificate + - ImpersonationProxy + type: string + required: + - lastUpdateTime + - message + - reason + - status + - type + type: object + type: array + required: + - strategies + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/concierge/config/deployment.yaml b/deploy_carvel/concierge/config/deployment.yaml new file mode 100644 index 00000000..bd1c690f --- /dev/null +++ b/deploy_carvel/concierge/config/deployment.yaml @@ -0,0 +1,355 @@ +#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") +#@ load("@ytt:json", "json") +#@ load("helpers.lib.yaml", "defaultLabel", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel", "pinnipedDevAPIGroupWithPrefix") +#@ load("@ytt:template", "template") + +#@ if not data.values.into_namespace: +--- +apiVersion: v1 +kind: Namespace +metadata: + name: #@ data.values.namespace + labels: + _: #@ template.replace(labels()) + #! When deploying onto a cluster which has PSAs enabled by default for namespaces, + #! effectively disable them for this namespace. The kube-cert-agent Deployment's pod + #! created by the Concierge in this namespace needs to be able to perform privileged + #! actions. The regular Concierge pod containers created by the Deployment below do + #! not need special privileges and are marked as such in their securityContext settings. + pod-security.kubernetes.io/enforce: privileged +#@ end +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: #@ defaultResourceNameWithSuffix("kube-cert-agent") + namespace: #@ namespace() + labels: #@ labels() +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: #@ defaultResourceNameWithSuffix("impersonation-proxy") + namespace: #@ namespace() + labels: #@ labels() + annotations: + #! we need to create this service account before we create the secret + kapp.k14s.io/change-group: "impersonation-proxy.concierge.pinniped.dev/serviceaccount" +secrets: #! make sure the token controller does not create any other secrets +- name: #@ defaultResourceNameWithSuffix("impersonation-proxy") +--- +apiVersion: v1 +kind: ConfigMap +metadata: + 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 + pinniped.yaml: | + discovery: + url: (@= data.values.discovery_url or "null" @) + api: + servingCertificate: + durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @) + renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @) + apiGroupSuffix: (@= data.values.api_group_suffix @) + # aggregatedAPIServerPort may be set here, although other YAML references to the default port (10250) may also need to be updated + # impersonationProxyServerPort may be set here, although other YAML references to the default port (8444) may also need to be updated + names: + servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @) + credentialIssuer: (@= defaultResourceNameWithSuffix("config") @) + apiService: (@= defaultResourceNameWithSuffix("api") @) + impersonationLoadBalancerService: (@= defaultResourceNameWithSuffix("impersonation-proxy-load-balancer") @) + impersonationClusterIPService: (@= defaultResourceNameWithSuffix("impersonation-proxy-cluster-ip") @) + impersonationTLSCertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-tls-serving-certificate") @) + impersonationCACertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-ca-certificate") @) + impersonationSignerSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-signer-ca-certificate") @) + agentServiceAccount: (@= defaultResourceNameWithSuffix("kube-cert-agent") @) + labels: (@= json.encode(labels()).rstrip() @) + kubeCertAgent: + namePrefix: (@= defaultResourceNameWithSuffix("kube-cert-agent-") @) + (@ if data.values.kube_cert_agent_image: @) + image: (@= data.values.kube_cert_agent_image @) + (@ else: @) + (@ if data.values.image_digest: @) + image: (@= data.values.image_repo + "@" + data.values.image_digest @) + (@ else: @) + image: (@= data.values.image_repo + ":" + data.values.image_tag @) + (@ end @) + (@ end @) + (@ if data.values.image_pull_dockerconfigjson: @) + imagePullSecrets: + - image-pull-secret + (@ end @) + (@ if data.values.log_level or data.values.deprecated_log_format: @) + log: + (@ if data.values.log_level: @) + level: (@= getAndValidateLogLevel() @) + (@ end @) + (@ if data.values.deprecated_log_format: @) + format: (@= data.values.deprecated_log_format @) + (@ end @) + (@ end @) +--- +#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": +apiVersion: v1 +kind: Secret +metadata: + name: image-pull-secret + namespace: #@ namespace() + labels: #@ labels() +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson +#@ end +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() +spec: + replicas: #@ data.values.replicas + selector: + #! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades. + matchLabels: #@ defaultLabel() + template: + metadata: + labels: + #! This has always included defaultLabel(), which is used by this Deployment's selector. + _: #@ template.replace(defaultLabel()) + #! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically + #! without accidentally selecting any other Deployment's Pods, especially the kube cert agent Deployment's Pods. + _: #@ template.replace(deploymentPodLabel()) + spec: + securityContext: + runAsUser: #@ data.values.run_as_user + runAsGroup: #@ data.values.run_as_group + serviceAccountName: #@ defaultResourceName() + #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": + imagePullSecrets: + - name: image-pull-secret + #@ end + containers: + - name: #@ defaultResourceName() + #@ if data.values.image_digest: + image: #@ data.values.image_repo + "@" + data.values.image_digest + #@ else: + image: #@ data.values.image_repo + ":" + data.values.image_tag + #@ end + imagePullPolicy: IfNotPresent + securityContext: + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + #! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a + #! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's + #! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error. + seccompProfile: + type: "RuntimeDefault" + resources: + requests: + cpu: "100m" + memory: "128Mi" + limits: + cpu: "100m" + memory: "128Mi" + command: + - pinniped-concierge + - --config=/etc/config/pinniped.yaml + - --downward-api-path=/etc/podinfo + volumeMounts: + - name: tmp + mountPath: /tmp + - name: config-volume + mountPath: /etc/config + readOnly: true + - name: podinfo + mountPath: /etc/podinfo + readOnly: true + - name: impersonation-proxy + mountPath: /var/run/secrets/impersonation-proxy.concierge.pinniped.dev/serviceaccount + readOnly: true + env: + #@ if data.values.https_proxy: + - name: HTTPS_PROXY + value: #@ data.values.https_proxy + #@ end + #@ if data.values.https_proxy and data.values.no_proxy: + - name: NO_PROXY + value: #@ data.values.no_proxy + #@ end + livenessProbe: + httpGet: + path: /healthz + port: 10250 + scheme: HTTPS + initialDelaySeconds: 2 + timeoutSeconds: 15 + periodSeconds: 10 + failureThreshold: 5 + readinessProbe: + httpGet: + path: /healthz + port: 10250 + scheme: HTTPS + initialDelaySeconds: 2 + timeoutSeconds: 3 + periodSeconds: 10 + failureThreshold: 3 + volumes: + - name: tmp + emptyDir: + medium: Memory + sizeLimit: 100Mi + - name: config-volume + configMap: + name: #@ defaultResourceNameWithSuffix("config") + - name: impersonation-proxy + secret: + secretName: #@ defaultResourceNameWithSuffix("impersonation-proxy") + items: #! make sure our pod does not start until the token controller has a chance to populate the secret + - key: token + path: token + - name: podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "name" + fieldRef: + fieldPath: metadata.name + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - key: node-role.kubernetes.io/master #! Allow running on master nodes too (name deprecated by kubernetes 1.20). + effect: NoSchedule + - key: node-role.kubernetes.io/control-plane #! The new name for these nodes as of Kubernetes 1.24. + effect: NoSchedule + #! This will help make sure our multiple pods run on different nodes, making + #! our deployment "more" "HA". + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 50 + podAffinityTerm: + labelSelector: + matchLabels: #@ deploymentPodLabel() + 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: #@ defaultResourceNameWithSuffix("api") + namespace: #@ namespace() + labels: #@ labels() + #! prevent kapp from altering the selector of our services to match kubectl behavior + annotations: + kapp.k14s.io/disable-default-label-scoping-rules: "" +spec: + type: ClusterIP + selector: #@ deploymentPodLabel() + ports: + - protocol: TCP + port: 443 + targetPort: 10250 +--- +apiVersion: v1 +kind: Service +metadata: + name: #@ defaultResourceNameWithSuffix("proxy") + namespace: #@ namespace() + labels: #@ labels() + #! prevent kapp from altering the selector of our services to match kubectl behavior + annotations: + kapp.k14s.io/disable-default-label-scoping-rules: "" +spec: + type: ClusterIP + selector: #@ deploymentPodLabel() + ports: + - protocol: TCP + port: 443 + targetPort: 8444 +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.login.concierge") + labels: #@ labels() +spec: + version: v1alpha1 + group: #@ pinnipedDevAPIGroupWithPrefix("login.concierge") + groupPriorityMinimum: 9900 + versionPriority: 15 + #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code. + service: + name: #@ defaultResourceNameWithSuffix("api") + namespace: #@ namespace() + port: 443 +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.identity.concierge") + labels: #@ labels() +spec: + version: v1alpha1 + group: #@ pinnipedDevAPIGroupWithPrefix("identity.concierge") + groupPriorityMinimum: 9900 + versionPriority: 15 + #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code. + service: + name: #@ defaultResourceNameWithSuffix("api") + namespace: #@ namespace() + port: 443 +--- +apiVersion: #@ pinnipedDevAPIGroupWithPrefix("config.concierge") + "/v1alpha1" +kind: CredentialIssuer +metadata: + name: #@ defaultResourceNameWithSuffix("config") + labels: #@ labels() +spec: + impersonationProxy: + mode: #@ data.values.impersonation_proxy_spec.mode + #@ if data.values.impersonation_proxy_spec.external_endpoint: + externalEndpoint: #@ data.values.impersonation_proxy_spec.external_endpoint + #@ end + service: + type: #@ data.values.impersonation_proxy_spec.service.type + #@ if data.values.impersonation_proxy_spec.service.load_balancer_ip: + loadBalancerIP: #@ data.values.impersonation_proxy_spec.service.load_balancer_ip + #@ end + annotations: #@ data.values.impersonation_proxy_spec.service.annotations +--- +apiVersion: v1 +kind: Secret +metadata: + name: #@ defaultResourceNameWithSuffix("impersonation-proxy") + namespace: #@ namespace() + labels: #@ labels() + annotations: + #! wait until the SA exists to create this secret so that the token controller does not delete it + #! we have this secret at the end so that kubectl will create the service account first + kapp.k14s.io/change-rule: "upsert after upserting impersonation-proxy.concierge.pinniped.dev/serviceaccount" + kubernetes.io/service-account.name: #@ defaultResourceNameWithSuffix("impersonation-proxy") +type: kubernetes.io/service-account-token diff --git a/deploy_carvel/concierge/config/helpers.lib.yaml b/deploy_carvel/concierge/config/helpers.lib.yaml new file mode 100644 index 00000000..542fe069 --- /dev/null +++ b/deploy_carvel/concierge/config/helpers.lib.yaml @@ -0,0 +1,47 @@ +#! Copyright 2020-2021 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 pinnipedDevAPIGroupWithPrefix(prefix): +#@ return prefix + "." + data.values.api_group_suffix +#@ end + +#@ def namespace(): +#@ if data.values.into_namespace: +#@ return data.values.into_namespace +#@ else: +#@ return data.values.namespace +#@ end +#@ end + +#@ def defaultLabel(): +#! Note that the name of this label's key is also assumed by kubecertagent.go and impersonator_config.go +app: #@ data.values.app_name +#@ end + +#@ def deploymentPodLabel(): +deployment.pinniped.dev: concierge +#@ end + +#@ def labels(): +_: #@ template.replace(defaultLabel()) +_: #@ template.replace(data.values.custom_labels) +#@ end + +#@ def getAndValidateLogLevel(): +#@ log_level = data.values.log_level +#@ if log_level != "info" and log_level != "debug" and log_level != "trace" and log_level != "all": +#@ fail("log_level '" + log_level + "' is invalid") +#@ end +#@ return log_level +#@ end diff --git a/deploy_carvel/concierge/config/rbac.yaml b/deploy_carvel/concierge/config/rbac.yaml new file mode 100644 index 00000000..61ffa57b --- /dev/null +++ b/deploy_carvel/concierge/config/rbac.yaml @@ -0,0 +1,296 @@ +#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") +#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "pinnipedDevAPIGroupWithPrefix") + +#! Give permission to various cluster-scoped objects +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + labels: #@ labels() +rules: + - apiGroups: [ "" ] + resources: [ namespaces ] + verbs: [ get, list, watch ] + - apiGroups: [ apiregistration.k8s.io ] + resources: [ apiservices ] + verbs: [ get, list, patch, update, watch ] + - apiGroups: [ admissionregistration.k8s.io ] + resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ] + verbs: [ get, list, watch ] + - apiGroups: [ flowcontrol.apiserver.k8s.io ] + resources: [ flowschemas, prioritylevelconfigurations ] + verbs: [ get, list, watch ] + - apiGroups: [ security.openshift.io ] + resources: [ securitycontextconstraints ] + verbs: [ use ] + resourceNames: [ nonroot ] + - apiGroups: [ "" ] + resources: [ nodes ] + verbs: [ list ] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("config.concierge") + resources: [ credentialissuers ] + verbs: [ get, list, watch, create ] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("config.concierge") + resources: [ credentialissuers/status ] + verbs: [ get, patch, update ] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge") + resources: [ jwtauthenticators, webhookauthenticators ] + verbs: [ get, list, watch ] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: ClusterRole + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + apiGroup: rbac.authorization.k8s.io + +#! Give minimal permissions to impersonation proxy service account +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: #@ defaultResourceNameWithSuffix("impersonation-proxy") + labels: #@ labels() +rules: + - apiGroups: [ "" ] + resources: [ "users", "groups", "serviceaccounts" ] + verbs: [ "impersonate" ] + - apiGroups: [ "authentication.k8s.io" ] + resources: [ "*" ] #! What we really want is userextras/* but the RBAC authorizer only supports */subresource, not resource/* + verbs: [ "impersonate" ] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("impersonation-proxy") + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceNameWithSuffix("impersonation-proxy") + namespace: #@ namespace() +roleRef: + kind: ClusterRole + name: #@ defaultResourceNameWithSuffix("impersonation-proxy") + apiGroup: rbac.authorization.k8s.io + +#! Give permission to the kube-cert-agent Pod to run privileged. +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: #@ defaultResourceNameWithSuffix("kube-cert-agent") + namespace: #@ namespace() + labels: #@ labels() +rules: + - apiGroups: [ policy ] + resources: [ podsecuritypolicies ] + verbs: [ use ] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("kube-cert-agent") + namespace: #@ namespace() + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceNameWithSuffix("kube-cert-agent") + namespace: #@ namespace() +roleRef: + kind: Role + name: #@ defaultResourceNameWithSuffix("kube-cert-agent") + apiGroup: rbac.authorization.k8s.io + +#! Give permission to various objects within the app's own namespace +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + namespace: #@ namespace() + labels: #@ labels() +rules: + - apiGroups: [ "" ] + resources: [ services ] + verbs: [ create, get, list, patch, update, watch, delete ] + - apiGroups: [ "" ] + resources: [ secrets ] + verbs: [ create, get, list, patch, update, watch, delete ] + #! We need to be able to watch pods in our namespace so we can find the kube-cert-agent pods. + - apiGroups: [ "" ] + resources: [ pods ] + verbs: [ get, list, watch ] + #! 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 ] + #! We need to be able to delete pods in our namespace so we can clean up legacy kube-cert-agent pods. + - apiGroups: [ "" ] + resources: [ pods ] + verbs: [ delete ] + #! We need to be able to create and update deployments in our namespace so we can manage the kube-cert-agent Deployment. + - apiGroups: [ apps ] + resources: [ deployments ] + verbs: [ create, get, list, patch, update, watch, delete ] + #! We need to be able to get replicasets so we can form the correct owner references on our generated objects. + - apiGroups: [ apps ] + resources: [ replicasets ] + verbs: [ get ] + - apiGroups: [ "" ] + resources: [ configmaps ] + verbs: [ list, get, watch ] + - apiGroups: [ coordination.k8s.io ] + resources: [ leases ] + verbs: [ create, get, update ] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + namespace: #@ namespace() + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: Role + 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 +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") + namespace: kube-system + labels: #@ labels() +rules: + - apiGroups: [ "" ] + resources: [ pods ] + verbs: [ get, list, watch ] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") + namespace: kube-system + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: Role + name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") + apiGroup: rbac.authorization.k8s.io + +#! Allow both authenticated and unauthenticated TokenCredentialRequests (i.e. allow all requests) +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: #@ defaultResourceNameWithSuffix("pre-authn-apis") + labels: #@ labels() +rules: + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("login.concierge") + resources: [ tokencredentialrequests ] + verbs: [ create, list ] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("identity.concierge") + resources: [ whoamirequests ] + verbs: [ create, list ] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("pre-authn-apis") + labels: #@ labels() +subjects: + - kind: Group + name: system:authenticated + apiGroup: rbac.authorization.k8s.io + - kind: Group + name: system:unauthenticated + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: #@ defaultResourceNameWithSuffix("pre-authn-apis") + apiGroup: rbac.authorization.k8s.io + +#! Give permissions for subjectaccessreviews, tokenreview that is needed by aggregated api servers +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceName() + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: ClusterRole + name: system:auth-delegator + apiGroup: rbac.authorization.k8s.io + +#! Give permissions for a special configmap of CA bundles that is needed by aggregated api servers +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("extension-apiserver-authentication-reader") + namespace: kube-system + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: Role + name: extension-apiserver-authentication-reader + apiGroup: rbac.authorization.k8s.io + +#! Give permission to list and watch ConfigMaps in kube-public +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") + namespace: kube-public + labels: #@ labels() +rules: + - apiGroups: [ "" ] + resources: [ configmaps ] + verbs: [ list, watch ] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") + namespace: kube-public + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: Role + name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") + apiGroup: rbac.authorization.k8s.io diff --git a/deploy_carvel/concierge/config/values.yaml b/deploy_carvel/concierge/config/values.yaml new file mode 100644 index 00000000..32306740 --- /dev/null +++ b/deploy_carvel/concierge/config/values.yaml @@ -0,0 +1,137 @@ +#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@data/values-schema +--- +#@schema/desc "Name of pinniped-concierge." +app_name: pinniped-concierge + +#@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." +namespace: pinniped-concierge +#@ into_namespace_desc = "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." +#@schema/desc into_namespace_desc +#@schema/nullable +into_namespace: my-preexisting-namespace + +#@ custom_labels_desc = "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 value of `custom_labels` must be a map of string keys to string values. \ +#@ 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." +#@schema/desc custom_labels_desc +#@schema/type any=True +custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} + +#@schema/desc "Specify how many replicas of the Pinniped server to run." +replicas: 2 + +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +image_repo: projects.registry.vmware.com/pinniped/pinniped-server +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +#@schema/nullable +image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +image_tag: latest + +#@ kube_cert_agent_image = "Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled \ +#@ on the control plane. This image needs only to include `sleep` and `cat` binaries. \ +#@ By default, the same image specified for image_repo/image_digest/image_tag will be re-used." +#@schema/desc kube_cert_agent_image +#@schema/nullable +kube_cert_agent_image: projects.registry.vmware.com/pinniped/pinniped-server + +#@ image_pull_dockerconfigjson_desc = "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." +#@schema/desc image_pull_dockerconfigjson_desc +#@schema/nullable +image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} + +#@schema/desc "Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden." +#@schema/nullable +discovery_url: https://example.com + + +#@ api_serving_certificate_desc = "Specify the duration and renewal interval for the API serving certificate. \ +#@ The defaults are set to expire the cert about every 30 days, and to rotate it \ +#@ about every 25 days." +#@schema/desc api_serving_certificate_desc +api_serving_certificate_duration_seconds: 2592000 +#@schema/desc api_serving_certificate_desc +api_serving_certificate_renew_before_seconds: 2160000 + +#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information), +#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged. +#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." +#@schema/nullable +log_level: info +#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ +#@ By default, when this value is left unset, logs are formatted in json. \ +#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." +#@schema/desc deprecated_log_format_desc +#@schema/nullable +deprecated_log_format: json + +#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_user: 65532 +#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_group: 65532 + +#@ api_group_suffix_desc = "Specify the API group suffix for all Pinniped API groups. By default, this is set to \ +#@ pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, \ +#@ authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then \ +#@ Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc." +#@schema/desc api_group_suffix_desc +api_group_suffix: pinniped.dev + + +#@schema/desc "Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation." +impersonation_proxy_spec: + #! options are "auto", "disabled" or "enabled". + #! If auto, the impersonation proxy will run only if the cluster signing key is not available + #! and the other strategy does not work. + #! If disabled, the impersonation proxy will never run, which could mean that the concierge + #! doesn't work at all. + #! If enabled, the impersonation proxy will always run regardless of other strategies available. + #@schema/desc "If enabled, the impersonation proxy will always run regardless of other strategies available." + mode: auto + #@ external_endpoint_desc = "The endpoint which the client should use to connect to the impersonation proxy. \ + #@ If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint." + #@schema/desc external_endpoint_desc + #@schema/nullable + external_endpoint: 1.2.3.4:5678 + #@schema/desc "The impersonation proxy service configuration" + service: + #! Options are "LoadBalancer", "ClusterIP" and "None". + #! LoadBalancer automatically provisions a Service of type LoadBalancer pointing at + #! the impersonation proxy. Some cloud providers will allocate + #! a public IP address by default even on private clusters. + #! ClusterIP automatically provisions a Service of type ClusterIP pointing at the + #! impersonation proxy. + #! None does not provision either and assumes that you have set the external_endpoint + #! and set up your own ingress to connect to the impersonation proxy. + #@schema/desc "Options are 'LoadBalancer', 'ClusterIP' and 'None'." + #@schema/nullable + type: LoadBalancer + #@schema/desc "The annotations that should be set on the ClusterIP or LoadBalancer Service." + #@schema/nullable + annotations: + {service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"} + #@schema/desc "When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP." + #@schema/nullable + load_balancer_ip: 1.2.3.4:5678 + +#@ https_proxy_desc = "Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. \ +#@ These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, \ +#@ e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. \ +#@ The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. \ +#@ Optional." +#@schema/desc https_proxy_desc +#@schema/nullable +https_proxy: http://proxy.example.com +#@schema/desc "do not proxy Kubernetes endpoints" +no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints diff --git a/deploy_carvel/concierge/config/z0_crd_overlay.yaml b/deploy_carvel/concierge/config/z0_crd_overlay.yaml new file mode 100644 index 00000000..935d5f8c --- /dev/null +++ b/deploy_carvel/concierge/config/z0_crd_overlay.yaml @@ -0,0 +1,33 @@ +#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:overlay", "overlay") +#@ load("helpers.lib.yaml", "labels", "pinnipedDevAPIGroupWithPrefix") +#@ load("@ytt:data", "data") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"credentialissuers.config.concierge.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("credentialissuers.config.concierge") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("config.concierge") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"webhookauthenticators.authentication.concierge.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("webhookauthenticators.authentication.concierge") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"jwtauthenticators.authentication.concierge.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("jwtauthenticators.authentication.concierge") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge") diff --git a/deploy_carvel/concierge/package-template.yml b/deploy_carvel/concierge/package-template.yml index 4fe974c7..032f023e 100644 --- a/deploy_carvel/concierge/package-template.yml +++ b/deploy_carvel/concierge/package-template.yml @@ -16,7 +16,7 @@ spec: spec: fetch: - imgpkgBundle: - image: #@ "${REPO_HOST}/packages/pinniped-concierge:" + data.values.version + image: #@ data.values.repo_host + ":" + data.values.version template: - ytt: paths: diff --git a/deploy_carvel/concierge/schema-openapi.yaml b/deploy_carvel/concierge/schema-openapi.yaml deleted file mode 100644 index 9f18a393..00000000 --- a/deploy_carvel/concierge/schema-openapi.yaml +++ /dev/null @@ -1,155 +0,0 @@ -openapi: 3.0.0 -info: - version: 0.1.0 - title: Schema for data values, generated by ytt -paths: {} -components: - schemas: - dataValues: - type: object - additionalProperties: false - properties: - app_name: - type: string - description: Name of pinniped-concierge. - default: pinniped-concierge - namespace: - type: string - description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. - default: pinniped-concierge - into_namespace: - type: string - nullable: true - description: 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. - default: null - custom_labels: - nullable: true - description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' - default: {} - replicas: - type: integer - description: Specify how many replicas of the Pinniped server to run. - default: 2 - image_repo: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: projects.registry.vmware.com/pinniped/pinniped-server - image_digest: - type: string - nullable: true - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: null - image_tag: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: latest - kube_cert_agent_image: - type: string - nullable: true - description: Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled on the control plane. This image needs only to include `sleep` and `cat` binaries. By default, the same image specified for image_repo/image_digest/image_tag will be re-used. - default: null - image_pull_dockerconfigjson: - type: object - additionalProperties: false - nullable: true - description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD - discovery_url: - type: string - nullable: true - description: Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden. - default: null - api_serving_certificate_duration_seconds: - type: integer - description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. - default: 2592000 - api_serving_certificate_renew_before_seconds: - type: integer - description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. - default: 2160000 - log_level: - type: string - nullable: true - description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. - default: null - deprecated_log_format: - type: string - nullable: true - description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' - default: null - run_as_user: - type: integer - description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - run_as_group: - type: integer - description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - api_group_suffix: - type: string - description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. - default: pinniped.dev - impersonation_proxy_spec: - type: object - additionalProperties: false - description: Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation. - properties: - mode: - type: string - description: If enabled, the impersonation proxy will always run regardless of other strategies available. - default: auto - external_endpoint: - type: string - nullable: true - description: The endpoint which the client should use to connect to the impersonation proxy. If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint. - default: null - service: - type: object - additionalProperties: false - description: The impersonation proxy service configuration - properties: - type: - type: string - nullable: true - description: Options are 'LoadBalancer', 'ClusterIP' and 'None'. - default: null - annotations: - type: object - additionalProperties: false - nullable: true - description: The annotations that should be set on the ClusterIP or LoadBalancer Service. - properties: - service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: - type: string - default: "4000" - load_balancer_ip: - type: string - nullable: true - description: When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP. - default: null - https_proxy: - type: string - nullable: true - description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. - default: null - no_proxy: - type: string - description: do not proxy Kubernetes endpoints - default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local diff --git a/deploy_carvel/local-user-authenticator-pkginstall.yml b/deploy_carvel/local-user-authenticator-pkginstall.yml new file mode 100644 index 00000000..1c53a360 --- /dev/null +++ b/deploy_carvel/local-user-authenticator-pkginstall.yml @@ -0,0 +1,32 @@ +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "local-user-authenticator-package-install" + namespace: "local-user-authenticator-install-ns" +spec: + serviceAccountName: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" + packageRef: + refName: "local-user-authenticator.pinniped.dev" + versionSelection: + constraints: "0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7" + values: + - secretRef: + name: "local-user-authenticator-package-install-secret" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "local-user-authenticator-package-install-secret" + namespace: "local-user-authenticator-install-ns" +stringData: + values.yml: | + --- + app_name: pinniped-concierge + namespace: concierge + api_group_suffix: pinniped.dev + log_level: debug + + image_repo: kind-registry.local:5000/test/build + image_tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 diff --git a/deploy_carvel/local-user-authenticator/config b/deploy_carvel/local-user-authenticator/config deleted file mode 120000 index fa3d8c99..00000000 --- a/deploy_carvel/local-user-authenticator/config +++ /dev/null @@ -1 +0,0 @@ -deploy/local-user-authenticator \ No newline at end of file diff --git a/deploy_carvel/local-user-authenticator/config/README.md b/deploy_carvel/local-user-authenticator/config/README.md new file mode 100644 index 00000000..dd54de39 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/config/README.md @@ -0,0 +1,163 @@ +# Deploying local-user-authenticator + +## What is local-user-authenticator? + +The local-user-authenticator app is an identity provider used for integration testing and demos. +If you would like to demo Pinniped, but you don't have a compatible identity provider handy, +you can use Pinniped's local-user-authenticator identity provider. Note that this is not recommended for +production use. + +The local-user-authenticator is a Kubernetes Deployment which runs a webhook server that implements the Kubernetes +[Webhook Token Authentication interface](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication). + +User accounts can be created and edited dynamically using `kubectl` commands (see below). + +## Installing the Latest Version with Default Options + +```bash +kubectl apply -f https://get.pinniped.dev/latest/install-local-user-authenticator.yaml +``` + +## Installing a Specific Version with Default Options + +Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number +and use it to replace the version number in the URL below. + +```bash +# Replace v0.4.1 with your preferred version in the URL below +kubectl apply -f https://get.pinniped.dev/v0.4.1/install-local-user-authenticator.yaml +``` + +## Installing with Custom Options + +Creating your own deployment YAML file requires `ytt` from [Carvel](https://carvel.dev/) to template the YAML files +in the `deploy/local-user-authenticator` directory. +Either [install `ytt`](https://get-ytt.io/) or use the [container image from Dockerhub](https://hub.docker.com/r/k14s/image/tags). + +1. `git clone` this repo and `git checkout` the release version tag of the release that you would like to deploy. +1. The configuration options are in [deploy/local-user-authenticator/values.yml](values.yaml). + Fill in the values in that file, or override those values using additional `ytt` command-line options in + the command below. Use the release version tag as the `image_tag` value. +2. In a terminal, cd to this `deploy/local-user-authenticator` directory +3. To generate the final YAML files, run `ytt --file .` +4. Deploy the generated YAML using your preferred deployment tool, such as `kubectl` or [`kapp`](https://get-kapp.io/). + For example: `ytt --file . | kapp deploy --yes --app local-user-authenticator --diff-changes --file -` + +## Configuring After Installing + +### Create Users + +Use `kubectl` to create, edit, and delete user accounts by creating a `Secret` for each user account in the same +namespace where local-user-authenticator is deployed. The name of the `Secret` resource is the username. +Store the user's group membership and `bcrypt` encrypted password as the contents of the `Secret`. +For example, to create a user named `pinny-the-seal` with the password `password123` +who belongs to the groups `group1` and `group2`, use: + +```bash +kubectl create secret generic pinny-the-seal \ + --namespace local-user-authenticator \ + --from-literal=groups=group1,group2 \ + --from-literal=passwordHash=$(htpasswd -nbBC 10 x password123 | sed -e "s/^x://") +``` + +Note that the above command requires a tool capable of generating a `bcrypt` hash. It uses `htpasswd`, +which is installed on most macOS systems, and can be +installed on some Linux systems via the `apache2-utils` package (e.g., `apt-get install apache2-utils`). + +### Get the local-user-authenticator App's Auto-Generated Certificate Authority Bundle + +Fetch the auto-generated CA bundle for the local-user-authenticator's HTTP TLS endpoint. + +```bash +kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \ + -o jsonpath={.data.caCertificate} \ + | base64 -d \ + | tee /tmp/local-user-authenticator-ca +``` + +### Configuring Pinniped to Use local-user-authenticator as an Identity Provider + +When installing Pinniped on the same cluster, configure local-user-authenticator as an Identity Provider for Pinniped +using the webhook URL `https://local-user-authenticator.local-user-authenticator.svc/authenticate` +along with the CA bundle fetched by the above command. See [demo](https://pinniped.dev/docs/demo/) for an example. + +## Optional: Manually Testing the Webhook Endpoint After Installing + +The following steps demonstrate the API of the local-user-authenticator app. Typically, a user would not need to +interact with this API directly. Pinniped will automatically integrate with this API if the local-user-authenticator +is configured as an identity provider for Pinniped. + + 1. Start a pod from which you can curl the endpoint from inside the cluster. + + ```bash + kubectl run curlpod --image=curlimages/curl --command -- /bin/sh -c "while true; do echo hi; sleep 120; done" + ``` + + 1. Copy the CA bundle that was fetched above onto the new pod. + + ```bash + kubectl cp /tmp/local-user-authenticator-ca curlpod:/tmp/local-user-authenticator-ca + ``` + + 1. Run a `curl` command to try to authenticate as the user created above. + + ```bash + kubectl -it exec curlpod -- curl https://local-user-authenticator.local-user-authenticator.svc/authenticate \ + --cacert /tmp/local-user-authenticator-ca \ + -H 'Content-Type: application/json' -H 'Accept: application/json' -d ' + { + "apiVersion": "authentication.k8s.io/v1beta1", + "kind": "TokenReview", + "spec": { + "token": "pinny-the-seal:password123" + } + }' + ``` + + When authentication is successful the above command should return some JSON similar to the following. + Note that the value of `authenticated` is `true` to indicate a successful authentication. + + ```json + { + "kind": "TokenReview", + "apiVersion": "authentication.k8s.io/v1beta1", + "metadata": { + "creationTimestamp": null + }, + "spec": {}, + "status": { + "authenticated": true, + "user": { + "username": "pinny-the-seal", + "uid": "19c433ec-8f58-44ca-9ef0-2d1081ccb876", + "groups": [ + "group1", + "group2" + ] + } + } + } + ``` + + Trying the above `curl` command again with the wrong username or password in the body of the request + should result in a JSON response which indicates that the authentication failed. + + ```json + { + "kind": "TokenReview", + "apiVersion": "authentication.k8s.io/v1beta1", + "metadata": { + "creationTimestamp": null + }, + "spec": {}, + "status": { + "user": {} + } + } + ``` + + 1. Remove the curl pod. + + ```bash + kubectl delete pod curlpod + ``` diff --git a/deploy_carvel/local-user-authenticator/config/deployment.yaml b/deploy_carvel/local-user-authenticator/config/deployment.yaml new file mode 100644 index 00000000..5098422a --- /dev/null +++ b/deploy_carvel/local-user-authenticator/config/deployment.yaml @@ -0,0 +1,97 @@ +#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") + +--- +apiVersion: v1 +kind: Namespace +metadata: + name: local-user-authenticator + labels: + name: local-user-authenticator +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: local-user-authenticator + namespace: local-user-authenticator +--- +#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": +apiVersion: v1 +kind: Secret +metadata: + name: image-pull-secret + namespace: local-user-authenticator + labels: + app: local-user-authenticator +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson +#@ end +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: local-user-authenticator + namespace: local-user-authenticator + labels: + app: local-user-authenticator +spec: + replicas: 1 + selector: + matchLabels: + app: local-user-authenticator + template: + metadata: + labels: + app: local-user-authenticator + spec: + securityContext: + runAsUser: #@ data.values.run_as_user + runAsGroup: #@ data.values.run_as_group + serviceAccountName: local-user-authenticator + #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": + imagePullSecrets: + - name: image-pull-secret + #@ end + containers: + - name: local-user-authenticator + #@ if data.values.image_digest: + image: #@ data.values.image_repo + "@" + data.values.image_digest + #@ else: + image: #@ data.values.image_repo + ":" + data.values.image_tag + #@ end + imagePullPolicy: IfNotPresent + command: + - local-user-authenticator + securityContext: + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + #! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a + #! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's + #! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error. + seccompProfile: + type: "RuntimeDefault" +--- +apiVersion: v1 +kind: Service +metadata: + name: local-user-authenticator + namespace: local-user-authenticator + labels: + app: local-user-authenticator + #! prevent kapp from altering the selector of our services to match kubectl behavior + annotations: + kapp.k14s.io/disable-default-label-scoping-rules: "" +spec: + type: ClusterIP + selector: + app: local-user-authenticator + ports: + - protocol: TCP + port: 443 + targetPort: 8443 diff --git a/deploy_carvel/local-user-authenticator/config/rbac.yaml b/deploy_carvel/local-user-authenticator/config/rbac.yaml new file mode 100644 index 00000000..a32d757d --- /dev/null +++ b/deploy_carvel/local-user-authenticator/config/rbac.yaml @@ -0,0 +1,30 @@ +#! Copyright 2020 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") + +#! Give permission to various objects within the app's own namespace +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: local-user-authenticator + namespace: local-user-authenticator +rules: + - apiGroups: [""] + resources: [secrets] + verbs: [create, get, list, patch, update, watch] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: local-user-authenticator + namespace: local-user-authenticator +subjects: + - kind: ServiceAccount + name: local-user-authenticator + namespace: local-user-authenticator +roleRef: + kind: Role + name: local-user-authenticator + apiGroup: rbac.authorization.k8s.io diff --git a/deploy_carvel/local-user-authenticator/config/values.yaml b/deploy_carvel/local-user-authenticator/config/values.yaml new file mode 100644 index 00000000..c0591304 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/config/values.yaml @@ -0,0 +1,26 @@ +#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@data/values-schema +--- + +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +image_repo: projects.registry.vmware.com/pinniped/pinniped-server +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +#@schema/nullable +image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +image_tag: latest + +#@ image_pull_dockerconfigjson_desc = "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." +#@schema/desc image_pull_dockerconfigjson_desc +#@schema/nullable +image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} + +#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_user: 65532 +#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_group: 65532 diff --git a/deploy_carvel/local-user-authenticator/package-template.yml b/deploy_carvel/local-user-authenticator/package-template.yml index c02620c6..cef66379 100644 --- a/deploy_carvel/local-user-authenticator/package-template.yml +++ b/deploy_carvel/local-user-authenticator/package-template.yml @@ -16,7 +16,7 @@ spec: spec: fetch: - imgpkgBundle: - image: #@ "${REPO_HOST}/packages/local-user-authenticator:" + data.values.version + image: #@ data.values.repo_host + ":" + data.values.version template: - ytt: paths: diff --git a/deploy_carvel/local-user-authenticator/schema-openapi.yaml b/deploy_carvel/local-user-authenticator/schema-openapi.yaml deleted file mode 100644 index 6dfcff7f..00000000 --- a/deploy_carvel/local-user-authenticator/schema-openapi.yaml +++ /dev/null @@ -1,55 +0,0 @@ -openapi: 3.0.0 -info: - version: 0.1.0 - title: Schema for data values, generated by ytt -paths: {} -components: - schemas: - dataValues: - type: object - additionalProperties: false - properties: - image_repo: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: projects.registry.vmware.com/pinniped/pinniped-server - image_digest: - type: string - nullable: true - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: null - image_tag: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: latest - image_pull_dockerconfigjson: - type: object - additionalProperties: false - nullable: true - description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD - run_as_user: - type: integer - description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - run_as_group: - type: integer - description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 diff --git a/deploy_carvel/package_repository/.imgpkg/images.yml b/deploy_carvel/package_repository/.imgpkg/images.yml new file mode 100644 index 00000000..ada38a60 --- /dev/null +++ b/deploy_carvel/package_repository/.imgpkg/images.yml @@ -0,0 +1,46 @@ +--- +apiVersion: imgpkg.carvel.dev/v1alpha1 +images: +- annotations: + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + kbld.carvel.dev/origins: | + - resolved: + tag: 0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + image: kind-registry.local:5000/test/build/test/build-package-concierge@sha256:666682c02d09cef2d116152d4762e8af52c03bc133d06c91f8ea1ff2db605a90 +- annotations: + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + kbld.carvel.dev/origins: | + - resolved: + tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + image: kind-registry.local:5000/test/build/test/build-package-concierge@sha256:666682c02d09cef2d116152d4762e8af52c03bc133d06c91f8ea1ff2db605a90 +- annotations: + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + kbld.carvel.dev/origins: | + - resolved: + tag: 0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator@sha256:a094c2971a8a24c3ab34e0146cbb540d6277e853bbc8fd3efb6691b174bb5709 +- annotations: + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + kbld.carvel.dev/origins: | + - resolved: + tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator@sha256:a094c2971a8a24c3ab34e0146cbb540d6277e853bbc8fd3efb6691b174bb5709 +- annotations: + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + kbld.carvel.dev/origins: | + - resolved: + tag: 0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + image: kind-registry.local:5000/test/build/test/build-package-supervisor@sha256:28488e1c9bbf8988c9a9f70ae6478188b6ebe01522fe45029940ed21a2cf221f +- annotations: + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + kbld.carvel.dev/origins: | + - resolved: + tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + image: kind-registry.local:5000/test/build/test/build-package-supervisor@sha256:28488e1c9bbf8988c9a9f70ae6478188b6ebe01522fe45029940ed21a2cf221f +kind: ImagesLock diff --git a/deploy_carvel/package_repository/packages/concierge.pinniped.dev/metadata.yml b/deploy_carvel/package_repository/packages/concierge.pinniped.dev/metadata.yml new file mode 100644 index 00000000..f310bb31 --- /dev/null +++ b/deploy_carvel/package_repository/packages/concierge.pinniped.dev/metadata.yml @@ -0,0 +1,10 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: concierge.pinniped.dev +spec: + displayName: "Pinniped Concierge" + longDescription: "Pinniped concierge enables consistent login across Kubernetes clusters on public cloud providers such as AKS, EKS and GKE" + shortDescription: "Pinniped concierge enables consistent login across public clouds" + categories: + - auth diff --git a/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/metadata.yml b/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/metadata.yml new file mode 100644 index 00000000..1ad53d44 --- /dev/null +++ b/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/metadata.yml @@ -0,0 +1,11 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: local-user-authenticator.pinniped.dev +spec: + displayName: "local-user-authenticator" + longDescription: "The local-user-authenticator app is an identity provider used for integration testing and demos. Note that this is not recommended for +production use." + shortDescription: "The local-user-authenticator app is an identity provider used for integration testing and demos." + categories: + - auth diff --git a/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/metadata.yml b/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/metadata.yml new file mode 100644 index 00000000..8a9e0e81 --- /dev/null +++ b/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/metadata.yml @@ -0,0 +1,10 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: supervisor.pinniped.dev +spec: + displayName: "Pinniped Supervisor" + longDescription: "Pinniped supervisor allows seamless login across one or many Kubernetes clusters including AKS, EKS and GKE" + shortDescription: "Pinniped supervisor provides login capabilities" + categories: + - auth diff --git a/deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml b/deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml new file mode 100644 index 00000000..bd79c4cd --- /dev/null +++ b/deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "concierge-install-ns" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" + namespace: "concierge-install-ns" +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-concierge-role-superadmin-dangerous" + namespace: "concierge-install-ns" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-concierge-role-binding-superadmin-dangerous" +subjects: +- kind: ServiceAccount + name: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" + namespace: "concierge-install-ns" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "pinniped-package-rbac-concierge-role-superadmin-dangerous" + diff --git a/deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml b/deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml new file mode 100644 index 00000000..b04a37c6 --- /dev/null +++ b/deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "local-user-authenticator-install-ns" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" + namespace: "local-user-authenticator-install-ns" +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-local-user-authenticator-role-superadmin-dangerous" + namespace: "local-user-authenticator-install-ns" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-local-user-authenticator-role-binding-superadmin-dangerous" +subjects: +- kind: ServiceAccount + name: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" + namespace: "local-user-authenticator-install-ns" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "pinniped-package-rbac-local-user-authenticator-role-superadmin-dangerous" + diff --git a/deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml b/deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml new file mode 100644 index 00000000..d3ea042a --- /dev/null +++ b/deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "supervisor-install-ns" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" + namespace: "supervisor-install-ns" +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-supervisor-role-superadmin-dangerous" + namespace: "supervisor-install-ns" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-supervisor-role-binding-superadmin-dangerous" +subjects: +- kind: ServiceAccount + name: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" + namespace: "supervisor-install-ns" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "pinniped-package-rbac-supervisor-role-superadmin-dangerous" + diff --git a/deploy_carvel/supervisor-pkginstall.yml b/deploy_carvel/supervisor-pkginstall.yml new file mode 100644 index 00000000..b166fce3 --- /dev/null +++ b/deploy_carvel/supervisor-pkginstall.yml @@ -0,0 +1,35 @@ +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "supervisor-package-install" + namespace: "supervisor-install-ns" +spec: + serviceAccountName: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" + packageRef: + refName: "supervisor.pinniped.dev" + versionSelection: + constraints: "0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7" + values: + - secretRef: + name: "supervisor-package-install-secret" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "supervisor-package-install-secret" + namespace: "supervisor-install-ns" +stringData: + values.yml: | + --- + app_name: pinniped-supervisor + namespace: supervisor + api_group_suffix: pinniped.dev + image_repo: kind-registry.local:5000/test/build + image_tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + log_level: debug + + service_https_nodeport_port: 443 + service_https_nodeport_nodeport: 31243 + service_https_clusterip_port: 443 diff --git a/deploy_carvel/supervisor/config b/deploy_carvel/supervisor/config deleted file mode 120000 index cedaa4bd..00000000 --- a/deploy_carvel/supervisor/config +++ /dev/null @@ -1 +0,0 @@ -deploy/supervisor \ No newline at end of file diff --git a/deploy_carvel/supervisor/config/README.md b/deploy_carvel/supervisor/config/README.md new file mode 100644 index 00000000..04d84b81 --- /dev/null +++ b/deploy_carvel/supervisor/config/README.md @@ -0,0 +1,3 @@ +# Pinniped Supervisor Deployment + +See [the how-to guide for details](https://pinniped.dev/docs/howto/install-supervisor/). diff --git a/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml b/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml new file mode 100644 index 00000000..6f50730c --- /dev/null +++ b/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml @@ -0,0 +1,488 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: federationdomains.config.supervisor.pinniped.dev +spec: + group: config.supervisor.pinniped.dev + names: + categories: + - pinniped + kind: FederationDomain + listKind: FederationDomainList + plural: federationdomains + singular: federationdomain + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.issuer + name: Issuer + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: FederationDomain describes the configuration of an OIDC provider. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec of the OIDC provider. + properties: + identityProviders: + description: "IdentityProviders is the list of identity providers + available for use by this FederationDomain. \n An identity provider + CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes + how to connect to a server, how to talk in a specific protocol for + authentication, and how to use the schema of that server/protocol + to extract a normalized user identity. Normalized user identities + include a username and a list of group names. In contrast, IdentityProviders + describes how to use that normalized identity in those Kubernetes + clusters which belong to this FederationDomain. Each entry in IdentityProviders + can be configured with arbitrary transformations on that normalized + identity. For example, a transformation can add a prefix to all + usernames to help avoid accidental conflicts when multiple identity + providers have different users with the same username (e.g. \"idp1:ryan\" + versus \"idp2:ryan\"). Each entry in IdentityProviders can also + implement arbitrary authentication rejection policies. Even though + a user was able to authenticate with the identity provider, a policy + can disallow the authentication to the Kubernetes clusters that + belong to this FederationDomain. For example, a policy could disallow + the authentication unless the user belongs to a specific group in + the identity provider. \n For backwards compatibility with versions + of Pinniped which predate support for multiple identity providers, + an empty IdentityProviders list will cause the FederationDomain + to use all available identity providers which exist in the same + namespace, but also to reject all authentication requests when there + is more than one identity provider currently defined. In this backwards + compatibility mode, the name of the identity provider resource (e.g. + the Name of an OIDCIdentityProvider resource) will be used as the + name of the identity provider in this FederationDomain. This mode + is provided to make upgrading from older versions easier. However, + instead of relying on this backwards compatibility mode, please + consider this mode to be deprecated and please instead explicitly + list the identity provider using this IdentityProviders field." + items: + description: FederationDomainIdentityProvider describes how an identity + provider is made available in this FederationDomain. + properties: + displayName: + description: DisplayName is the name of this identity provider + as it will appear to clients. This name ends up in the kubeconfig + of end users, so changing the name of an identity provider + that is in use by end users will be a disruptive change for + those users. + minLength: 1 + type: string + objectRef: + description: ObjectRef is a reference to a Pinniped identity + provider resource. A valid reference is required. If the reference + cannot be resolved then the identity provider will not be + made available. Must refer to a resource of one of the Pinniped + identity provider types, e.g. OIDCIdentityProvider, LDAPIdentityProvider, + ActiveDirectoryIdentityProvider. + properties: + apiGroup: + description: APIGroup is the group for the resource being + referenced. If APIGroup is not specified, the specified + Kind must be in the core API group. For any other third-party + types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + transforms: + description: Transforms is an optional way to specify transformations + to be applied during user authentication and session refresh. + properties: + constants: + description: Constants defines constant variables and their + values which will be made available to the transform expressions. + items: + description: FederationDomainTransformsConstant defines + a constant variable and its value which will be made + available to the transform expressions. This is a union + type, and Type is the discriminator field. + properties: + name: + description: Name determines the name of the constant. + It must be a valid identifier name. + maxLength: 64 + minLength: 1 + pattern: ^[a-zA-Z][_a-zA-Z0-9]*$ + type: string + stringListValue: + description: StringListValue should hold the value + when Type is "stringList", and is otherwise ignored. + items: + type: string + type: array + stringValue: + description: StringValue should hold the value when + Type is "string", and is otherwise ignored. + type: string + type: + description: Type determines the type of the constant, + and indicates which other field should be non-empty. + enum: + - string + - stringList + type: string + required: + - name + - type + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + examples: + description: Examples can optionally be used to ensure that + the sequence of transformation expressions are working + as expected. Examples define sample input identities which + are then run through the expression list, and the results + are compared to the expected results. If any example in + this list fails, then this identity provider will not + be available for use within this FederationDomain, and + the error(s) will be added to the FederationDomain status. + This can be used to help guard against programming mistakes + in the expressions, and also act as living documentation + for other administrators to better understand the expressions. + items: + description: FederationDomainTransformsExample defines + a transform example. + properties: + expects: + description: Expects is the expected output of the + entire sequence of transforms when they are run + against the input Username and Groups. + properties: + groups: + description: Groups is the expected list of group + names after the transformations have been applied. + items: + type: string + type: array + message: + description: Message is the expected error message + of the transforms. When Rejected is true, then + Message is the expected message for the policy + which rejected the authentication attempt. When + Rejected is true and Message is blank, then + Message will be treated as the default error + message for authentication attempts which are + rejected by a policy. When Rejected is false, + then Message is the expected error message for + some other non-policy transformation error, + such as a runtime error. When Rejected is false, + there is no default expected Message. + type: string + rejected: + description: Rejected is a boolean that indicates + whether authentication is expected to be rejected + by a policy expression after the transformations + have been applied. True means that it is expected + that the authentication would be rejected. The + default value of false means that it is expected + that the authentication would not be rejected + by any policy expression. + type: boolean + username: + description: Username is the expected username + after the transformations have been applied. + type: string + type: object + groups: + description: Groups is the input list of group names. + items: + type: string + type: array + username: + description: Username is the input username. + minLength: 1 + type: string + required: + - expects + - username + type: object + type: array + expressions: + description: "Expressions are an optional list of transforms + and policies to be executed in the order given during + every authentication attempt, including during every session + refresh. Each is a CEL expression. It may use the basic + CEL language as defined in https://github.com/google/cel-spec/blob/master/doc/langdef.md + plus the CEL string extensions defined in https://github.com/google/cel-go/tree/master/ext#strings. + \n The username and groups extracted from the identity + provider, and the constants defined in this CR, are available + as variables in all expressions. The username is provided + via a variable called `username` and the list of group + names is provided via a variable called `groups` (which + may be an empty list). Each user-provided constants is + provided via a variable named `strConst.varName` for string + constants and `strListConst.varName` for string list constants. + \n The only allowed types for expressions are currently + policy/v1, username/v1, and groups/v1. Each policy/v1 + must return a boolean, and when it returns false, no more + expressions from the list are evaluated and the authentication + attempt is rejected. Transformations of type policy/v1 + do not return usernames or group names, and therefore + cannot change the username or group names. Each username/v1 + transform must return the new username (a string), which + can be the same as the old username. Transformations of + type username/v1 do not return group names, and therefore + cannot change the group names. Each groups/v1 transform + must return the new groups list (list of strings), which + can be the same as the old groups list. Transformations + of type groups/v1 do not return usernames, and therefore + cannot change the usernames. After each expression, the + new (potentially changed) username or groups get passed + to the following expression. \n Any compilation or static + type-checking failure of any expression will cause an + error status on the FederationDomain. During an authentication + attempt, any unexpected runtime evaluation errors (e.g. + division by zero) cause the authentication attempt to + fail. When all expressions evaluate successfully, then + the (potentially changed) username and group names have + been decided for that authentication attempt." + items: + description: FederationDomainTransformsExpression defines + a transform expression. + properties: + expression: + description: Expression is a CEL expression that will + be evaluated based on the Type during an authentication. + minLength: 1 + type: string + message: + description: Message is only used when Type is policy/v1. + It defines an error message to be used when the + policy rejects an authentication attempt. When empty, + a default message will be used. + type: string + type: + description: Type determines the type of the expression. + It must be one of the supported types. + enum: + - policy/v1 + - username/v1 + - groups/v1 + type: string + required: + - expression + - type + type: object + type: array + type: object + required: + - displayName + - objectRef + type: object + type: array + issuer: + description: "Issuer is the OIDC Provider's issuer, per the OIDC Discovery + Metadata document, as well as the identifier that it will use for + the iss claim in issued JWTs. This field will also be used as the + base URL for any endpoints used by the OIDC Provider (e.g., if your + issuer is https://example.com/foo, then your authorization endpoint + will look like https://example.com/foo/some/path/to/auth/endpoint). + \n See https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 + for more information." + minLength: 1 + type: string + tls: + description: TLS specifies a secret which will contain Transport Layer + Security (TLS) configuration for the FederationDomain. + properties: + secretName: + description: "SecretName is an optional name of a Secret in the + same namespace, of type `kubernetes.io/tls`, which contains + the TLS serving certificate for the HTTPS endpoints served by + this FederationDomain. When provided, the TLS Secret named here + must contain keys named `tls.crt` and `tls.key` that contain + the certificate and private key to use for TLS. \n Server Name + Indication (SNI) is an extension to the Transport Layer Security + (TLS) supported by all major browsers. \n SecretName is required + if you would like to use different TLS certificates for issuers + of different hostnames. SNI requests do not include port numbers, + so all issuers with the same DNS hostname must use the same + SecretName value even if they have different port numbers. \n + SecretName is not required when you would like to use only the + HTTP endpoints (e.g. when the HTTP listener is configured to + listen on loopback interfaces or UNIX domain sockets for traffic + from a service mesh sidecar). It is also not required when you + would like all requests to this OIDC Provider's HTTPS endpoints + to use the default TLS certificate, which is configured elsewhere. + \n When your Issuer URL's host is an IP address, then this field + is ignored. SNI does not work for IP addresses." + type: string + type: object + required: + - issuer + type: object + status: + description: Status of the OIDC provider. + properties: + conditions: + description: Conditions represent the observations of an FederationDomain's + current state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + phase: + default: Pending + description: Phase summarizes the overall status of the FederationDomain. + enum: + - Pending + - Ready + - Error + type: string + secrets: + description: Secrets contains information about this OIDC Provider's + secrets. + properties: + jwks: + description: JWKS holds the name of the corev1.Secret in which + this OIDC Provider's signing/verification keys are stored. If + it is empty, then the signing/verification keys are either unknown + or they don't exist. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + stateEncryptionKey: + description: StateSigningKey holds the name of the corev1.Secret + in which this OIDC Provider's key for encrypting state parameters + is stored. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + stateSigningKey: + description: StateSigningKey holds the name of the corev1.Secret + in which this OIDC Provider's key for signing state parameters + is stored. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + tokenSigningKey: + description: TokenSigningKey holds the name of the corev1.Secret + in which this OIDC Provider's key for signing tokens is stored. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml b/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml new file mode 100644 index 00000000..c61c4b15 --- /dev/null +++ b/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml @@ -0,0 +1,220 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: oidcclients.config.supervisor.pinniped.dev +spec: + group: config.supervisor.pinniped.dev + names: + categories: + - pinniped + kind: OIDCClient + listKind: OIDCClientList + plural: oidcclients + singular: oidcclient + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.allowedScopes[?(@ == "pinniped:request-audience")] + name: Privileged Scopes + type: string + - jsonPath: .status.totalClientSecrets + name: Client Secrets + type: integer + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: OIDCClient describes the configuration of an OIDC client. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec of the OIDC client. + properties: + allowedGrantTypes: + description: "allowedGrantTypes is a list of the allowed grant_type + param values that should be accepted during OIDC flows with this + client. \n Must only contain the following values: - authorization_code: + allows the client to perform the authorization code grant flow, + i.e. allows the webapp to authenticate users. This grant must always + be listed. - refresh_token: allows the client to perform refresh + grants for the user to extend the user's session. This grant must + be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: + allows the client to perform RFC8693 token exchange, which is a + step in the process to be able to get a cluster credential for the + user. This grant must be listed if allowedScopes lists pinniped:request-audience." + items: + enum: + - authorization_code + - refresh_token + - urn:ietf:params:oauth:grant-type:token-exchange + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + allowedRedirectURIs: + description: allowedRedirectURIs is a list of the allowed redirect_uri + param values that should be accepted during OIDC flows with this + client. Any other uris will be rejected. Must be a URI with the + https scheme, unless the hostname is 127.0.0.1 or ::1 which may + use the http scheme. Port numbers are not required for 127.0.0.1 + or ::1 and are ignored when checking for a matching redirect_uri. + items: + pattern: ^https://.+|^http://(127\.0\.0\.1|\[::1\])(:\d+)?/ + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + allowedScopes: + description: "allowedScopes is a list of the allowed scopes param + values that should be accepted during OIDC flows with this client. + \n Must only contain the following values: - openid: The client + is allowed to request ID tokens. ID tokens only include the required + claims by default (iss, sub, aud, exp, iat). This scope must always + be listed. - offline_access: The client is allowed to request an + initial refresh token during the authorization code grant flow. + This scope must be listed if allowedGrantTypes lists refresh_token. + - pinniped:request-audience: The client is allowed to request a + new audience value during a RFC8693 token exchange, which is a step + in the process to be able to get a cluster credential for the user. + openid, username and groups scopes must be listed when this scope + is present. This scope must be listed if allowedGrantTypes lists + urn:ietf:params:oauth:grant-type:token-exchange. - username: The + client is allowed to request that ID tokens contain the user's username. + Without the username scope being requested and allowed, the ID token + will not contain the user's username. - groups: The client is allowed + to request that ID tokens contain the user's group membership, if + their group membership is discoverable by the Supervisor. Without + the groups scope being requested and allowed, the ID token will + not contain groups." + items: + enum: + - openid + - offline_access + - username + - groups + - pinniped:request-audience + type: string + minItems: 1 + type: array + x-kubernetes-list-type: set + required: + - allowedGrantTypes + - allowedRedirectURIs + - allowedScopes + type: object + status: + description: Status of the OIDC client. + properties: + conditions: + description: conditions represent the observations of an OIDCClient's + current state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + phase: + default: Pending + description: phase summarizes the overall status of the OIDCClient. + enum: + - Pending + - Ready + - Error + type: string + totalClientSecrets: + description: totalClientSecrets is the current number of client secrets + that are detected for this OIDCClient. + format: int32 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/supervisor/config/deployment.yaml b/deploy_carvel/supervisor/config/deployment.yaml new file mode 100644 index 00000000..30791a1b --- /dev/null +++ b/deploy_carvel/supervisor/config/deployment.yaml @@ -0,0 +1,236 @@ +#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") +#@ load("@ytt:yaml", "yaml") +#@ load("helpers.lib.yaml", +#@ "defaultLabel", +#@ "labels", +#@ "deploymentPodLabel", +#@ "namespace", +#@ "defaultResourceName", +#@ "defaultResourceNameWithSuffix", +#@ "pinnipedDevAPIGroupWithPrefix", +#@ "getPinnipedConfigMapData", +#@ "hasUnixNetworkEndpoint", +#@ ) +#@ load("@ytt:template", "template") + +#@ if not data.values.into_namespace: +--- +apiVersion: v1 +kind: Namespace +metadata: + name: #@ data.values.namespace + labels: #@ labels() +#@ end +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: #@ defaultResourceNameWithSuffix("static-config") + namespace: #@ namespace() + labels: #@ labels() +data: + #@yaml/text-templated-strings + pinniped.yaml: #@ yaml.encode(getPinnipedConfigMapData()) +--- +#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": +apiVersion: v1 +kind: Secret +metadata: + name: image-pull-secret + namespace: #@ namespace() + labels: #@ labels() +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson +#@ end +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() +spec: + replicas: #@ data.values.replicas + selector: + #! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades. + matchLabels: #@ defaultLabel() + template: + metadata: + labels: + #! This has always included defaultLabel(), which is used by this Deployment's selector. + _: #@ template.replace(defaultLabel()) + #! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically + #! without accidentally selecting pods from any future Deployments which might also want to use the defaultLabel(). + _: #@ template.replace(deploymentPodLabel()) + spec: + securityContext: + runAsUser: #@ data.values.run_as_user + runAsGroup: #@ data.values.run_as_group + serviceAccountName: #@ defaultResourceName() + #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": + imagePullSecrets: + - name: image-pull-secret + #@ end + containers: + - name: #@ defaultResourceName() + #@ if data.values.image_digest: + image: #@ data.values.image_repo + "@" + data.values.image_digest + #@ else: + image: #@ data.values.image_repo + ":" + data.values.image_tag + #@ end + imagePullPolicy: IfNotPresent + command: + - pinniped-supervisor + - /etc/podinfo + - /etc/config/pinniped.yaml + securityContext: + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + #! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a + #! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's + #! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error. + seccompProfile: + type: "RuntimeDefault" + resources: + requests: + #! If OIDCClient CRs are being used, then the Supervisor needs enough CPU to run expensive bcrypt + #! operations inside the implementation of the token endpoint for any authcode flows performed by those + #! clients, so for that use case administrators may wish to increase the requests.cpu value to more + #! closely align with their anticipated needs. Increasing this value will cause Kubernetes to give more + #! available CPU to this process during times of high CPU contention. By default, don't ask for too much + #! because that would make it impossible to install the Pinniped Supervisor on small clusters. + #! Aside from performing bcrypts at the token endpoint for those clients, the Supervisor is not a + #! particularly CPU-intensive process. + cpu: "100m" #! by default, request one-tenth of a CPU + memory: "128Mi" + limits: + #! By declaring a CPU limit that is not equal to the CPU request value, the Supervisor will be classified + #! by Kubernetes to have "burstable" quality of service. + #! See https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-burstable + #! If OIDCClient CRs are being used, and lots of simultaneous users have active sessions, then it is hard + #! pre-determine what the CPU limit should be for that use case. Guessing too low would cause the + #! pod's CPU usage to be throttled, resulting in poor performance. Guessing too high would allow clients + #! to cause the usage of lots of CPU resources. Administrators who have a good sense of anticipated usage + #! patterns may choose to set the requests.cpu and limits.cpu differently from these defaults. + cpu: "1000m" #! by default, throttle each pod's usage at 1 CPU + memory: "128Mi" + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + - name: podinfo + mountPath: /etc/podinfo + readOnly: true + #@ if hasUnixNetworkEndpoint(): + - name: socket + mountPath: /pinniped_socket + readOnly: false #! writable to allow for socket use + #@ end + ports: + - containerPort: 8443 + protocol: TCP + env: + #@ if data.values.https_proxy: + - name: HTTPS_PROXY + value: #@ data.values.https_proxy + #@ end + #@ if data.values.https_proxy and data.values.no_proxy: + - name: NO_PROXY + value: #@ data.values.no_proxy + #@ end + livenessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 2 + timeoutSeconds: 15 + periodSeconds: 10 + failureThreshold: 5 + readinessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 2 + timeoutSeconds: 3 + periodSeconds: 10 + failureThreshold: 3 + volumes: + - name: config-volume + configMap: + name: #@ defaultResourceNameWithSuffix("static-config") + - name: podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace + - path: "name" + fieldRef: + fieldPath: metadata.name + #@ if hasUnixNetworkEndpoint(): + - name: socket + emptyDir: {} + #@ end + #! This will help make sure our multiple pods run on different nodes, making + #! our deployment "more" "HA". + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 50 + podAffinityTerm: + labelSelector: + matchLabels: #@ deploymentPodLabel() + 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: #@ defaultResourceNameWithSuffix("api") + namespace: #@ namespace() + labels: #@ labels() + #! prevent kapp from altering the selector of our services to match kubectl behavior + annotations: + kapp.k14s.io/disable-default-label-scoping-rules: "" +spec: + type: ClusterIP + selector: #@ deploymentPodLabel() + ports: + - protocol: TCP + port: 443 + targetPort: 10250 +--- +apiVersion: apiregistration.k8s.io/v1 +kind: APIService +metadata: + name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.clientsecret.supervisor") + labels: #@ labels() +spec: + version: v1alpha1 + group: #@ pinnipedDevAPIGroupWithPrefix("clientsecret.supervisor") + groupPriorityMinimum: 9900 + versionPriority: 15 + #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code. + service: + name: #@ defaultResourceNameWithSuffix("api") + namespace: #@ namespace() + port: 443 diff --git a/deploy_carvel/supervisor/config/helpers.lib.yaml b/deploy_carvel/supervisor/config/helpers.lib.yaml new file mode 100644 index 00000000..fbb60a2d --- /dev/null +++ b/deploy_carvel/supervisor/config/helpers.lib.yaml @@ -0,0 +1,88 @@ +#! Copyright 2020-2022 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 pinnipedDevAPIGroupWithPrefix(prefix): +#@ return prefix + "." + data.values.api_group_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 deploymentPodLabel(): +deployment.pinniped.dev: supervisor +#@ end + +#@ def labels(): +_: #@ template.replace(defaultLabel()) +_: #@ template.replace(data.values.custom_labels) +#@ end + +#@ def getAndValidateLogLevel(): +#@ log_level = data.values.log_level +#@ if log_level != "info" and log_level != "debug" and log_level != "trace" and log_level != "all": +#@ fail("log_level '" + log_level + "' is invalid") +#@ end +#@ return log_level +#@ end + +#@ def getPinnipedConfigMapData(): +#@ config = { +#@ "apiGroupSuffix": data.values.api_group_suffix, +#@ "names": { +#@ "defaultTLSCertificateSecret": defaultResourceNameWithSuffix("default-tls-certificate"), +#@ "apiService": defaultResourceNameWithSuffix("api"), +#@ }, +#@ "labels": labels(), +#@ "insecureAcceptExternalUnencryptedHttpRequests": data.values.deprecated_insecure_accept_external_unencrypted_http_requests +#@ } +#@ if data.values.log_level or data.values.deprecated_log_format: +#@ config["log"] = {} +#@ end +#@ if data.values.log_level: +#@ config["log"]["level"] = getAndValidateLogLevel() +#@ end +#@ if data.values.deprecated_log_format: +#@ config["log"]["format"] = data.values.deprecated_log_format +#@ end +#@ if data.values.endpoints: +#@ config["endpoints"] = data.values.endpoints +#@ end +#@ return config +#@ end + +#@ def getattr_safe(val, *args): +#@ out = None +#@ for arg in args: +#@ if not hasattr(val, arg): +#@ return None +#@ end +#@ out = getattr(val, arg) +#@ val = out +#@ end +#@ return out +#@ end + +#@ def hasUnixNetworkEndpoint(): +#@ return getattr_safe(data.values.endpoints, "http", "network") == "unix" or \ +#@ getattr_safe(data.values.endpoints, "https", "network") == "unix" +#@ end diff --git a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml new file mode 100644 index 00000000..7bb486de --- /dev/null +++ b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml @@ -0,0 +1,318 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev +spec: + group: idp.supervisor.pinniped.dev + names: + categories: + - pinniped + - pinniped-idp + - pinniped-idps + kind: ActiveDirectoryIdentityProvider + listKind: ActiveDirectoryIdentityProviderList + plural: activedirectoryidentityproviders + singular: activedirectoryidentityprovider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.host + name: Host + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ActiveDirectoryIdentityProvider describes the configuration of + an upstream Microsoft Active Directory identity provider. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec for configuring the identity provider. + properties: + bind: + description: Bind contains the configuration for how to provide access + credentials during an initial bind to the ActiveDirectory server + to be allowed to perform searches and binds to validate a user's + credentials during a user's authentication attempt. + properties: + secretName: + description: SecretName contains the name of a namespace-local + Secret object that provides the username and password for an + Active Directory bind user. This account will be used to perform + LDAP searches. The Secret should be of type "kubernetes.io/basic-auth" + which includes "username" and "password" keys. The username + value should be the full dn (distinguished name) of your bind + account, e.g. "cn=bind-account,ou=users,dc=example,dc=com". + The password must be non-empty. + minLength: 1 + type: string + required: + - secretName + type: object + groupSearch: + description: GroupSearch contains the configuration for searching + for a user's group membership in ActiveDirectory. + properties: + attributes: + description: Attributes specifies how the group's information + should be read from each ActiveDirectory entry which was found + as the result of the group search. + properties: + groupName: + description: GroupName specifies the name of the attribute + in the Active Directory entries whose value shall become + a group name in the user's list of groups after a successful + authentication. The value of this field is case-sensitive + and must match the case of the attribute name returned by + the ActiveDirectory server in the user's entry. E.g. "cn" + for common name. Distinguished names can be used by specifying + lower-case "dn". Optional. When not specified, this defaults + to a custom field that looks like "sAMAccountName@domain", + where domain is constructed from the domain components of + the group DN. + type: string + type: object + base: + description: Base is the dn (distinguished name) that should be + used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". + Optional, when not specified it will be based on the result + of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). + The default behavior searches your entire domain for groups. + It may make sense to specify a subtree as a search base if you + wish to exclude some groups for security reasons or to make + searches faster. + type: string + filter: + description: Filter is the ActiveDirectory search filter which + should be applied when searching for groups for a user. The + pattern "{}" must occur in the filter at least once and will + be dynamically replaced by the value of an attribute of the + user entry found as a result of the user search. Which attribute's + value is used to replace the placeholder(s) depends on the value + of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". + For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. + Note that the dn (distinguished name) is not an attribute of + an entry, so "dn={}" cannot be used. Optional. When not specified, + the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". + This searches nested groups by default. Note that nested group + search can be slow for some Active Directory servers. To disable + it, you can set the filter to "(&(objectClass=group)(member={})" + type: string + skipGroupRefresh: + description: "The user's group membership is refreshed as they + interact with the supervisor to obtain new credentials (as their + old credentials expire). This allows group membership changes + to be quickly reflected into Kubernetes clusters. Since group + membership is often used to bind authorization policies, it + is important to keep the groups observed in Kubernetes clusters + in-sync with the identity provider. \n In some environments, + frequent group membership queries may result in a significant + performance impact on the identity provider and/or the supervisor. + The best approach to handle performance impacts is to tweak + the group query to be more performant, for example by disabling + nested group search or by using a more targeted group search + base. \n If the group search query cannot be made performant + and you are willing to have group memberships remain static + for approximately a day, then set skipGroupRefresh to true. + \ This is an insecure configuration as authorization policies + that are bound to group membership will not notice if a user + has been removed from a particular group until their next login. + \n This is an experimental feature that may be removed or significantly + altered in the future. Consumers of this configuration should + carefully read all release notes before upgrading to ensure + that the meaning of this field has not changed." + type: boolean + userAttributeForFilter: + description: UserAttributeForFilter specifies which attribute's + value from the user entry found as a result of the user search + will be used to replace the "{}" placeholder(s) in the group + search Filter. For example, specifying "uid" as the UserAttributeForFilter + while specifying "&(objectClass=posixGroup)(memberUid={})" as + the Filter would search for groups by replacing the "{}" placeholder + in the Filter with the value of the user's "uid" attribute. + Optional. When not specified, the default will act as if "dn" + were specified. For example, leaving UserAttributeForFilter + unspecified while specifying "&(objectClass=groupOfNames)(member={})" + as the Filter would search for groups by replacing the "{}" + placeholder(s) with the dn (distinguished name) of the user. + type: string + type: object + host: + description: 'Host is the hostname of this Active Directory identity + provider, i.e., where to connect. For example: ldap.example.com:636.' + minLength: 1 + type: string + tls: + description: TLS contains the connection settings for how to establish + the connection to the Host. + properties: + certificateAuthorityData: + description: X.509 Certificate Authority (base64-encoded PEM bundle). + If omitted, a default set of system roots will be trusted. + type: string + type: object + userSearch: + description: UserSearch contains the configuration for searching for + a user by name in Active Directory. + properties: + attributes: + description: Attributes specifies how the user's information should + be read from the ActiveDirectory entry which was found as the + result of the user search. + properties: + uid: + description: UID specifies the name of the attribute in the + ActiveDirectory entry which whose value shall be used to + uniquely identify the user within this ActiveDirectory provider + after a successful authentication. Optional, when empty + this defaults to "objectGUID". + type: string + username: + description: Username specifies the name of the attribute + in Active Directory entry whose value shall become the username + of the user after a successful authentication. Optional, + when empty this defaults to "userPrincipalName". + type: string + type: object + base: + description: Base is the dn (distinguished name) that should be + used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com". + Optional, when not specified it will be based on the result + of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). + The default behavior searches your entire domain for users. + It may make sense to specify a subtree as a search base if you + wish to exclude some users or to make searches faster. + type: string + filter: + description: Filter is the search filter which should be applied + when searching for users. The pattern "{}" must occur in the + filter at least once and will be dynamically replaced by the + username for which the search is being run. E.g. "mail={}" or + "&(objectClass=person)(uid={})". For more information about + LDAP filters, see https://ldap.com/ldap-filters. Note that the + dn (distinguished name) is not an attribute of an entry, so + "dn={}" cannot be used. Optional. When not specified, the default + will be '(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))' + This means that the user is a person, is not a computer, the + sAMAccountType is for a normal user account, and is not shown + in advanced view only (which would likely mean its a system + created service account with advanced permissions). Also, either + the sAMAccountName, the userPrincipalName, or the mail attribute + matches the input username. + type: string + type: object + required: + - host + type: object + status: + description: Status of the identity provider. + properties: + conditions: + description: Represents the observations of an identity provider's + current state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + phase: + default: Pending + description: Phase summarizes the overall status of the ActiveDirectoryIdentityProvider. + enum: + - Pending + - Ready + - Error + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml new file mode 100644 index 00000000..85106cb8 --- /dev/null +++ b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml @@ -0,0 +1,315 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: ldapidentityproviders.idp.supervisor.pinniped.dev +spec: + group: idp.supervisor.pinniped.dev + names: + categories: + - pinniped + - pinniped-idp + - pinniped-idps + kind: LDAPIdentityProvider + listKind: LDAPIdentityProviderList + plural: ldapidentityproviders + singular: ldapidentityprovider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.host + name: Host + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: LDAPIdentityProvider describes the configuration of an upstream + Lightweight Directory Access Protocol (LDAP) identity provider. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec for configuring the identity provider. + properties: + bind: + description: Bind contains the configuration for how to provide access + credentials during an initial bind to the LDAP server to be allowed + to perform searches and binds to validate a user's credentials during + a user's authentication attempt. + properties: + secretName: + description: SecretName contains the name of a namespace-local + Secret object that provides the username and password for an + LDAP bind user. This account will be used to perform LDAP searches. + The Secret should be of type "kubernetes.io/basic-auth" which + includes "username" and "password" keys. The username value + should be the full dn (distinguished name) of your bind account, + e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password + must be non-empty. + minLength: 1 + type: string + required: + - secretName + type: object + groupSearch: + description: GroupSearch contains the configuration for searching + for a user's group membership in the LDAP provider. + properties: + attributes: + description: Attributes specifies how the group's information + should be read from each LDAP entry which was found as the result + of the group search. + properties: + groupName: + description: GroupName specifies the name of the attribute + in the LDAP entries whose value shall become a group name + in the user's list of groups after a successful authentication. + The value of this field is case-sensitive and must match + the case of the attribute name returned by the LDAP server + in the user's entry. E.g. "cn" for common name. Distinguished + names can be used by specifying lower-case "dn". Optional. + When not specified, the default will act as if the GroupName + were specified as "dn" (distinguished name). + type: string + type: object + base: + description: Base is the dn (distinguished name) that should be + used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". + When not specified, no group search will be performed and authenticated + users will not belong to any groups from the LDAP provider. + Also, when not specified, the values of Filter, UserAttributeForFilter, + Attributes, and SkipGroupRefresh are ignored. + type: string + filter: + description: Filter is the LDAP search filter which should be + applied when searching for groups for a user. The pattern "{}" + must occur in the filter at least once and will be dynamically + replaced by the value of an attribute of the user entry found + as a result of the user search. Which attribute's value is used + to replace the placeholder(s) depends on the value of UserAttributeForFilter. + For more information about LDAP filters, see https://ldap.com/ldap-filters. + Note that the dn (distinguished name) is not an attribute of + an entry, so "dn={}" cannot be used. Optional. When not specified, + the default will act as if the Filter were specified as "member={}". + type: string + skipGroupRefresh: + description: "The user's group membership is refreshed as they + interact with the supervisor to obtain new credentials (as their + old credentials expire). This allows group membership changes + to be quickly reflected into Kubernetes clusters. Since group + membership is often used to bind authorization policies, it + is important to keep the groups observed in Kubernetes clusters + in-sync with the identity provider. \n In some environments, + frequent group membership queries may result in a significant + performance impact on the identity provider and/or the supervisor. + The best approach to handle performance impacts is to tweak + the group query to be more performant, for example by disabling + nested group search or by using a more targeted group search + base. \n If the group search query cannot be made performant + and you are willing to have group memberships remain static + for approximately a day, then set skipGroupRefresh to true. + \ This is an insecure configuration as authorization policies + that are bound to group membership will not notice if a user + has been removed from a particular group until their next login. + \n This is an experimental feature that may be removed or significantly + altered in the future. Consumers of this configuration should + carefully read all release notes before upgrading to ensure + that the meaning of this field has not changed." + type: boolean + userAttributeForFilter: + description: UserAttributeForFilter specifies which attribute's + value from the user entry found as a result of the user search + will be used to replace the "{}" placeholder(s) in the group + search Filter. For example, specifying "uid" as the UserAttributeForFilter + while specifying "&(objectClass=posixGroup)(memberUid={})" as + the Filter would search for groups by replacing the "{}" placeholder + in the Filter with the value of the user's "uid" attribute. + Optional. When not specified, the default will act as if "dn" + were specified. For example, leaving UserAttributeForFilter + unspecified while specifying "&(objectClass=groupOfNames)(member={})" + as the Filter would search for groups by replacing the "{}" + placeholder(s) with the dn (distinguished name) of the user. + type: string + type: object + host: + description: 'Host is the hostname of this LDAP identity provider, + i.e., where to connect. For example: ldap.example.com:636.' + minLength: 1 + type: string + tls: + description: TLS contains the connection settings for how to establish + the connection to the Host. + properties: + certificateAuthorityData: + description: X.509 Certificate Authority (base64-encoded PEM bundle). + If omitted, a default set of system roots will be trusted. + type: string + type: object + userSearch: + description: UserSearch contains the configuration for searching for + a user by name in the LDAP provider. + properties: + attributes: + description: Attributes specifies how the user's information should + be read from the LDAP entry which was found as the result of + the user search. + properties: + uid: + description: UID specifies the name of the attribute in the + LDAP entry which whose value shall be used to uniquely identify + the user within this LDAP provider after a successful authentication. + E.g. "uidNumber" or "objectGUID". The value of this field + is case-sensitive and must match the case of the attribute + name returned by the LDAP server in the user's entry. Distinguished + names can be used by specifying lower-case "dn". + minLength: 1 + type: string + username: + description: Username specifies the name of the attribute + in the LDAP entry whose value shall become the username + of the user after a successful authentication. This would + typically be the same attribute name used in the user search + filter, although it can be different. E.g. "mail" or "uid" + or "userPrincipalName". The value of this field is case-sensitive + and must match the case of the attribute name returned by + the LDAP server in the user's entry. Distinguished names + can be used by specifying lower-case "dn". When this field + is set to "dn" then the LDAPIdentityProviderUserSearch's + Filter field cannot be blank, since the default value of + "dn={}" would not work. + minLength: 1 + type: string + type: object + base: + description: Base is the dn (distinguished name) that should be + used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com". + minLength: 1 + type: string + filter: + description: Filter is the LDAP search filter which should be + applied when searching for users. The pattern "{}" must occur + in the filter at least once and will be dynamically replaced + by the username for which the search is being run. E.g. "mail={}" + or "&(objectClass=person)(uid={})". For more information about + LDAP filters, see https://ldap.com/ldap-filters. Note that the + dn (distinguished name) is not an attribute of an entry, so + "dn={}" cannot be used. Optional. When not specified, the default + will act as if the Filter were specified as the value from Attributes.Username + appended by "={}". When the Attributes.Username is set to "dn" + then the Filter must be explicitly specified, since the default + value of "dn={}" would not work. + type: string + type: object + required: + - host + type: object + status: + description: Status of the identity provider. + properties: + conditions: + description: Represents the observations of an identity provider's + current state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + phase: + default: Pending + description: Phase summarizes the overall status of the LDAPIdentityProvider. + enum: + - Pending + - Ready + - Error + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml new file mode 100644 index 00000000..7bea863d --- /dev/null +++ b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml @@ -0,0 +1,345 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: oidcidentityproviders.idp.supervisor.pinniped.dev +spec: + group: idp.supervisor.pinniped.dev + names: + categories: + - pinniped + - pinniped-idp + - pinniped-idps + kind: OIDCIdentityProvider + listKind: OIDCIdentityProviderList + plural: oidcidentityproviders + singular: oidcidentityprovider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.issuer + name: Issuer + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: OIDCIdentityProvider describes the configuration of an upstream + OpenID Connect identity provider. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec for configuring the identity provider. + properties: + authorizationConfig: + description: AuthorizationConfig holds information about how to form + the OAuth2 authorization request parameters to be used with this + OIDC identity provider. + properties: + additionalAuthorizeParameters: + description: additionalAuthorizeParameters are extra query parameters + that should be included in the authorize request to your OIDC + provider in the authorization request during an OIDC Authorization + Code Flow. By default, no extra parameters are sent. The standard + parameters that will be sent are "response_type", "scope", "client_id", + "state", "nonce", "code_challenge", "code_challenge_method", + and "redirect_uri". These parameters cannot be included in this + setting. Additionally, the "hd" parameter cannot be included + in this setting at this time. The "hd" parameter is used by + Google's OIDC provider to provide a hint as to which "hosted + domain" the user should use during login. However, Pinniped + does not yet support validating the hosted domain in the resulting + ID token, so it is not yet safe to use this feature of Google's + OIDC provider with Pinniped. This setting does not influence + the parameters sent to the token endpoint in the Resource Owner + Password Credentials Grant. The Pinniped Supervisor requires + that your OIDC provider returns refresh tokens to the Supervisor + from the authorization flows. Some OIDC providers may require + a certain value for the "prompt" parameter in order to properly + request refresh tokens. See the documentation of your OIDC provider's + authorization endpoint for its requirements for what to include + in the request in order to receive a refresh token in the response, + if anything. If your provider requires the prompt parameter + to request a refresh token, then include it here. Also note + that most providers also require a certain scope to be requested + in order to receive refresh tokens. See the additionalScopes + setting for more information about using scopes to request refresh + tokens. + items: + description: Parameter is a key/value pair which represents + a parameter in an HTTP request. + properties: + name: + description: The name of the parameter. Required. + minLength: 1 + type: string + value: + description: The value of the parameter. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + additionalScopes: + description: 'additionalScopes are the additional scopes that + will be requested from your OIDC provider in the authorization + request during an OIDC Authorization Code Flow and in the token + request during a Resource Owner Password Credentials Grant. + Note that the "openid" scope will always be requested regardless + of the value in this setting, since it is always required according + to the OIDC spec. By default, when this field is not set, the + Supervisor will request the following scopes: "openid", "offline_access", + "email", and "profile". See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims + for a description of the "profile" and "email" scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess + for a description of the "offline_access" scope. This default + value may change in future versions of Pinniped as the standard + evolves, or as common patterns used by providers who implement + the standard in the ecosystem evolve. By setting this list to + anything other than an empty list, you are overriding the default + value, so you may wish to include some of "offline_access", + "email", and "profile" in your override list. If you do not + want any of these scopes to be requested, you may set this list + to contain only "openid". Some OIDC providers may also require + a scope to get access to the user''s group membership, in which + case you may wish to include it in this list. Sometimes the + scope to request the user''s group membership is called "groups", + but unfortunately this is not specified in the OIDC standard. + Generally speaking, you should include any scopes required to + cause the appropriate claims to be the returned by your OIDC + provider in the ID token or userinfo endpoint results for those + claims which you would like to use in the oidcClaims settings + to determine the usernames and group memberships of your Kubernetes + users. See your OIDC provider''s documentation for more information + about what scopes are available to request claims. Additionally, + the Pinniped Supervisor requires that your OIDC provider returns + refresh tokens to the Supervisor from these authorization flows. + For most OIDC providers, the scope required to receive refresh + tokens will be "offline_access". See the documentation of your + OIDC provider''s authorization and token endpoints for its requirements + for what to include in the request in order to receive a refresh + token in the response, if anything. Note that it may be safe + to send "offline_access" even to providers which do not require + it, since the provider may ignore scopes that it does not understand + or require (see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3). + In the unusual case that you must avoid sending the "offline_access" + scope, then you must override the default value of this setting. + This is required if your OIDC provider will reject the request + when it includes "offline_access" (e.g. GitLab''s OIDC provider).' + items: + type: string + type: array + allowPasswordGrant: + description: allowPasswordGrant, when true, will allow the use + of OAuth 2.0's Resource Owner Password Credentials Grant (see + https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to + authenticate to the OIDC provider using a username and password + without a web browser, in addition to the usual browser-based + OIDC Authorization Code Flow. The Resource Owner Password Credentials + Grant is not officially part of the OIDC specification, so it + may not be supported by your OIDC provider. If your OIDC provider + supports returning ID tokens from a Resource Owner Password + Credentials Grant token request, then you can choose to set + this field to true. This will allow end users to choose to present + their username and password to the kubectl CLI (using the Pinniped + plugin) to authenticate to the cluster, without using a web + browser to log in as is customary in OIDC Authorization Code + Flow. This may be convenient for users, especially for identities + from your OIDC provider which are not intended to represent + a human actor, such as service accounts performing actions in + a CI/CD environment. Even if your OIDC provider supports it, + you may wish to disable this behavior by setting this field + to false when you prefer to only allow users of this OIDCIdentityProvider + to log in via the browser-based OIDC Authorization Code Flow. + Using the Resource Owner Password Credentials Grant means that + the Pinniped CLI and Pinniped Supervisor will directly handle + your end users' passwords (similar to LDAPIdentityProvider), + and you will not be able to require multi-factor authentication + or use the other web-based login features of your OIDC provider + during Resource Owner Password Credentials Grant logins. allowPasswordGrant + defaults to false. + type: boolean + type: object + claims: + description: Claims provides the names of token claims that will be + used when inspecting an identity from this OIDC identity provider. + properties: + additionalClaimMappings: + additionalProperties: + type: string + description: AdditionalClaimMappings allows for additional arbitrary + upstream claim values to be mapped into the "additionalClaims" + claim of the ID tokens generated by the Supervisor. This should + be specified as a map of new claim names as the keys, and upstream + claim names as the values. These new claim names will be nested + under the top-level "additionalClaims" claim in ID tokens generated + by the Supervisor when this OIDCIdentityProvider was used for + user authentication. These claims will be made available to + all clients. This feature is not required to use the Supervisor + to provide authentication for Kubernetes clusters, but can be + used when using the Supervisor for other authentication purposes. + When this map is empty or the upstream claims are not available, + the "additionalClaims" claim will be excluded from the ID tokens + generated by the Supervisor. + type: object + groups: + description: Groups provides the name of the ID token claim or + userinfo endpoint response claim that will be used to ascertain + the groups to which an identity belongs. By default, the identities + will not include any group memberships when this setting is + not configured. + type: string + username: + description: Username provides the name of the ID token claim + or userinfo endpoint response claim that will be used to ascertain + an identity's username. When not set, the username will be an + automatically constructed unique string which will include the + issuer URL of your OIDC provider along with the value of the + "sub" (subject) claim from the ID token. + type: string + type: object + client: + description: OIDCClient contains OIDC client information to be used + used with this OIDC identity provider. + properties: + secretName: + description: SecretName contains the name of a namespace-local + Secret object that provides the clientID and clientSecret for + an OIDC client. If only the SecretName is specified in an OIDCClient + struct, then it is expected that the Secret is of type "secrets.pinniped.dev/oidc-client" + with keys "clientID" and "clientSecret". + type: string + required: + - secretName + type: object + issuer: + description: Issuer is the issuer URL of this OIDC identity provider, + i.e., where to fetch /.well-known/openid-configuration. + minLength: 1 + pattern: ^https:// + type: string + tls: + description: TLS configuration for discovery/JWKS requests to the + issuer. + properties: + certificateAuthorityData: + description: X.509 Certificate Authority (base64-encoded PEM bundle). + If omitted, a default set of system roots will be trusted. + type: string + type: object + required: + - client + - issuer + type: object + status: + description: Status of the identity provider. + properties: + conditions: + description: Represents the observations of an identity provider's + current state. + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + phase: + default: Pending + description: Phase summarizes the overall status of the OIDCIdentityProvider. + enum: + - Pending + - Ready + - Error + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy_carvel/supervisor/config/rbac.yaml b/deploy_carvel/supervisor/config/rbac.yaml new file mode 100644 index 00000000..97b542fe --- /dev/null +++ b/deploy_carvel/supervisor/config/rbac.yaml @@ -0,0 +1,152 @@ +#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") +#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "pinnipedDevAPIGroupWithPrefix") + +#! Give permission to various objects within the app's own namespace +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() +rules: + - apiGroups: [""] + resources: [secrets] + verbs: [create, get, list, patch, update, watch, delete] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") + resources: [federationdomains] + verbs: [get, list, watch] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") + resources: [federationdomains/status] + verbs: [get, patch, update] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") + resources: [oidcclients] + verbs: [get, list, watch] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") + resources: [oidcclients/status] + verbs: [get, patch, update] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + resources: [oidcidentityproviders] + verbs: [get, list, watch] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + resources: [oidcidentityproviders/status] + verbs: [get, patch, update] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + resources: [ldapidentityproviders] + verbs: [get, list, watch] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + resources: [ldapidentityproviders/status] + verbs: [get, patch, update] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + resources: [activedirectoryidentityproviders] + verbs: [get, list, watch] + - apiGroups: + - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + resources: [activedirectoryidentityproviders/status] + verbs: [get, patch, update] + #! We want to be able to read pods/replicasets/deployment so we can learn who our deployment is to set + #! as an owner reference. + - apiGroups: [""] + resources: [pods] + verbs: [get] + - apiGroups: [apps] + resources: [replicasets,deployments] + verbs: [get] + - apiGroups: [ coordination.k8s.io ] + resources: [ leases ] + verbs: [ create, get, update ] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceName() + namespace: #@ namespace() + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: Role + name: #@ defaultResourceName() + apiGroup: rbac.authorization.k8s.io + +#! Give permissions for a special configmap of CA bundles that is needed by aggregated api servers +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("extension-apiserver-authentication-reader") + namespace: kube-system + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: Role + name: extension-apiserver-authentication-reader + apiGroup: rbac.authorization.k8s.io + +#! Give permissions for subjectaccessreviews, tokenreview that is needed by aggregated api servers +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceName() + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: ClusterRole + name: system:auth-delegator + apiGroup: rbac.authorization.k8s.io + +#! Give permission to various cluster-scoped objects +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + labels: #@ labels() +rules: + - apiGroups: [ "" ] + resources: [ namespaces ] + verbs: [ get, list, watch ] + - apiGroups: [ apiregistration.k8s.io ] + resources: [ apiservices ] + verbs: [ get, list, patch, update, watch ] + - apiGroups: [ admissionregistration.k8s.io ] + resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ] + verbs: [ get, list, watch ] + - apiGroups: [ flowcontrol.apiserver.k8s.io ] + resources: [ flowschemas, prioritylevelconfigurations ] + verbs: [ get, list, watch ] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + labels: #@ labels() +subjects: + - kind: ServiceAccount + name: #@ defaultResourceName() + namespace: #@ namespace() +roleRef: + kind: ClusterRole + name: #@ defaultResourceNameWithSuffix("aggregated-api-server") + apiGroup: rbac.authorization.k8s.io diff --git a/deploy_carvel/supervisor/config/service.yaml b/deploy_carvel/supervisor/config/service.yaml new file mode 100644 index 00000000..fd6b9623 --- /dev/null +++ b/deploy_carvel/supervisor/config/service.yaml @@ -0,0 +1,115 @@ +#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:data", "data") +#@ load("@ytt:assert", "assert") +#@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") + +#@ if hasattr(data.values, "service_http_nodeport_port"): +#@ assert.fail('value "service_http_nodeport_port" has been renamed to "deprecated_service_http_nodeport_port" and will be removed in a future release') +#@ end +#@ if hasattr(data.values, "service_http_nodeport_nodeport"): +#@ assert.fail('value "service_http_nodeport_nodeport" has been renamed to "deprecated_service_http_nodeport_nodeport" and will be removed in a future release') +#@ end +#@ if hasattr(data.values, "service_http_loadbalancer_port"): +#@ assert.fail('value "service_http_loadbalancer_port" has been renamed to "deprecated_service_http_loadbalancer_port" and will be removed in a future release') +#@ end +#@ if hasattr(data.values, "service_http_clusterip_port"): +#@ assert.fail('value "service_http_clusterip_port" has been renamed to "deprecated_service_http_clusterip_port" and will be removed in a future release') +#@ end + +#@ if data.values.deprecated_service_http_nodeport_port or data.values.service_https_nodeport_port: +--- +apiVersion: v1 +kind: Service +metadata: + name: #@ defaultResourceNameWithSuffix("nodeport") + namespace: #@ namespace() + labels: #@ labels() + #! prevent kapp from altering the selector of our services to match kubectl behavior + annotations: + kapp.k14s.io/disable-default-label-scoping-rules: "" +spec: + type: NodePort + selector: #@ deploymentPodLabel() + ports: + #@ if data.values.deprecated_service_http_nodeport_port: + - name: http + protocol: TCP + port: #@ data.values.deprecated_service_http_nodeport_port + targetPort: 8080 + #@ if data.values.deprecated_service_http_nodeport_nodeport: + nodePort: #@ data.values.deprecated_service_http_nodeport_nodeport + #@ end + #@ end + #@ if data.values.service_https_nodeport_port: + - name: https + protocol: TCP + port: #@ data.values.service_https_nodeport_port + targetPort: 8443 + #@ if data.values.service_https_nodeport_nodeport: + nodePort: #@ data.values.service_https_nodeport_nodeport + #@ end + #@ end +#@ end + +#@ if data.values.deprecated_service_http_clusterip_port or data.values.service_https_clusterip_port: +--- +apiVersion: v1 +kind: Service +metadata: + name: #@ defaultResourceNameWithSuffix("clusterip") + namespace: #@ namespace() + labels: #@ labels() + #! prevent kapp from altering the selector of our services to match kubectl behavior + annotations: + kapp.k14s.io/disable-default-label-scoping-rules: "" +spec: + type: ClusterIP + selector: #@ deploymentPodLabel() + ports: + #@ if data.values.deprecated_service_http_clusterip_port: + - name: http + protocol: TCP + port: #@ data.values.deprecated_service_http_clusterip_port + targetPort: 8080 + #@ end + #@ if data.values.service_https_clusterip_port: + - name: https + protocol: TCP + port: #@ data.values.service_https_clusterip_port + targetPort: 8443 + #@ end +#@ end + +#@ if data.values.deprecated_service_http_loadbalancer_port or data.values.service_https_loadbalancer_port: +--- +apiVersion: v1 +kind: Service +metadata: + name: #@ defaultResourceNameWithSuffix("loadbalancer") + namespace: #@ namespace() + labels: #@ labels() + #! prevent kapp from altering the selector of our services to match kubectl behavior + annotations: + kapp.k14s.io/disable-default-label-scoping-rules: "" +spec: + type: LoadBalancer + selector: #@ deploymentPodLabel() + #@ if data.values.service_loadbalancer_ip: + loadBalancerIP: #@ data.values.service_loadbalancer_ip + #@ end + ports: + #@ if data.values.deprecated_service_http_loadbalancer_port: + - name: http + protocol: TCP + port: #@ data.values.deprecated_service_http_loadbalancer_port + targetPort: 8080 + #@ end + #@ if data.values.service_https_loadbalancer_port: + - name: https + protocol: TCP + port: #@ data.values.service_https_loadbalancer_port + targetPort: 8443 + #@ end +#@ end diff --git a/deploy_carvel/supervisor/config/values.yaml b/deploy_carvel/supervisor/config/values.yaml new file mode 100644 index 00000000..04606edb --- /dev/null +++ b/deploy_carvel/supervisor/config/values.yaml @@ -0,0 +1,175 @@ +#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@data/values-schema +--- +#@schema/desc "Name of pinniped-supervisor." +app_name: pinniped-supervisor + +#@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." +namespace: pinniped-supervisor +#@ into_namespace_desc = "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." +#@schema/desc into_namespace_desc +#@schema/nullable +into_namespace: my-preexisting-namespace + +#@ custom_labels_desc = "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 value of `custom_labels` must be a map of string keys to string values. \ +#@ 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." +#@schema/desc custom_labels_desc +#@schema/type any=True +custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} + +#@schema/desc "Specify how many replicas of the Pinniped server to run." +replicas: 2 + +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +image_repo: projects.registry.vmware.com/pinniped/pinniped-server +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +#@schema/nullable +image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 +#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +image_tag: latest + +#@ image_pull_dockerconfigjson_desc = "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." +#@schema/desc image_pull_dockerconfigjson_desc +#@schema/nullable +image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} + +#! Specify how to expose the Supervisor app's HTTPS port as a Service. +#! Typically, you would set a value for only one of the following service types. +#! Setting any of these values means that a Service of that type will be created. They are all optional. +#! Note that all port numbers should be numbers (not strings), i.e. use ytt's `--data-value-yaml` instead of `--data-value`. +#! Several of these values have been deprecated and will be removed in a future release. Their names have been changed to +#! mark them as deprecated and to make it obvious upon upgrade to anyone who was using them that they have been deprecated. +#@schema/desc "will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/nullable +deprecated_service_http_nodeport_port: 31234 +#@schema/desc "will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified" +#@schema/nullable +deprecated_service_http_nodeport_nodeport: 31234 +#@schema/desc "will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/nullable +deprecated_service_http_loadbalancer_port: 8443 +#@schema/desc "#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/nullable +deprecated_service_http_clusterip_port: 8443 +#@schema/desc "#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/nullable +service_https_nodeport_port: 31243 +#@schema/desc "#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified" +#@schema/nullable +service_https_nodeport_nodeport: 31243 +#@schema/desc "#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/nullable +service_https_loadbalancer_port: 8443 +#@schema/desc "#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/nullable +service_https_clusterip_port: 8443 +#@ service_loadbalancer_ip_desc="The `loadBalancerIP` value of the LoadBalancer Service. \ +#@ Ignored unless service_https_loadbalancer_port is provided." +#@schema/desc service_loadbalancer_ip_desc +#@schema/nullable +service_loadbalancer_ip: 1.2.3.4 + +#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information), +#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged. +#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." +#@schema/nullable +log_level: info +#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ +#@ By default, when this value is left unset, logs are formatted in json. \ +#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." +#@schema/desc deprecated_log_format_desc +#@schema/nullable +deprecated_log_format: json + +#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_user: 65532 +#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" +run_as_group: 65532 + +#@ api_group_suffix_desc = "Specify the API group suffix for all Pinniped API groups. By default, this is set to \ +#@ pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, \ +#@ authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then \ +#@ Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc." +#@schema/desc api_group_suffix_desc +api_group_suffix: pinniped.dev + +#@ https_proxy_desc = "Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. \ +#@ These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, \ +#@ e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. \ +#@ The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. \ +#@ Optional." +#@schema/desc https_proxy_desc +#@schema/nullable +https_proxy: http://proxy.example.com +#@schema/desc "do not proxy Kubernetes endpoints" +no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" + +#! Control the HTTP and HTTPS listeners of the Supervisor. +#! +#! The schema of this config is as follows: +#! +#! endpoints: +#! https: +#! network: tcp | unix | disabled +#! address: host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix +#! http: +#! network: same as above +#! address: same as above, except that when network=tcp then the address is only allowed to bind to loopback interfaces +#! +#! Setting network to disabled turns off that particular listener. +#! See https://pkg.go.dev/net#Listen and https://pkg.go.dev/net#Dial for a description of what can be +#! specified in the address parameter based on the given network parameter. To aid in the use of unix +#! domain sockets, a writable empty dir volume is mounted at /pinniped_socket when network is set to "unix." +#! +#! The current defaults are: +#! +#! endpoints: +#! https: +#! network: tcp +#! address: :8443 +#! http: +#! network: disabled +#! +#! These defaults mean: For HTTPS listening, bind to all interfaces using TCP on port 8443. +#! Disable HTTP listening by default. +#! +#! The HTTP listener can only be bound to loopback interfaces. This allows the listener to accept +#! traffic from within the pod, e.g. from a service mesh sidecar. The HTTP listener should not be +#! used to accept traffic from outside the pod, since that would mean that the network traffic could be +#! transmitted unencrypted. The HTTPS listener should be used instead to accept traffic from outside the pod. +#! Ingresses and load balancers that terminate TLS connections should re-encrypt the data and route traffic +#! to the HTTPS listener. Unix domain sockets may also be used for integrations with service meshes. +#! +#! Changing the HTTPS port number must be accompanied by matching changes to the service and deployment +#! manifests. Changes to the HTTPS listener must be coordinated with the deployment health checks. +#! +#@schema/desc "Control the HTTP and HTTPS listeners of the Supervisor." +#@schema/nullable +endpoints: + https: + network: tcp + address: 1.2.3.4:5678 + +#! deprecated_insecure_accept_external_unencrypted_http_requests_desc = "Optionally override the validation on the endpoints. \ +#! http value which checks that only loopback interfaces are used. \ +#! When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any \ +#! interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced \ +#! to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time \ +#! to change their ingress strategy to avoid using plain HTTP into the Supervisor pods. \ +#! This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time \ +#! traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available. \ +#! Allowed values are true (boolean), "true" (string), false (boolean), and "false" (string). The default is false. \ +#! Optional." +#@schema/desc https_proxy_desc +deprecated_insecure_accept_external_unencrypted_http_requests: false diff --git a/deploy_carvel/supervisor/config/z0_crd_overlay.yaml b/deploy_carvel/supervisor/config/z0_crd_overlay.yaml new file mode 100644 index 00000000..f7a50a88 --- /dev/null +++ b/deploy_carvel/supervisor/config/z0_crd_overlay.yaml @@ -0,0 +1,63 @@ +#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:overlay", "overlay") +#@ load("helpers.lib.yaml", "labels", "pinnipedDevAPIGroupWithPrefix") +#@ load("@ytt:data", "data") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"federationdomains.config.supervisor.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("federationdomains.config.supervisor") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("oidcidentityproviders.idp.supervisor") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"ldapidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("ldapidentityproviders.idp.supervisor") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"activedirectoryidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("activedirectoryidentityproviders.idp.supervisor") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") + +#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcclients.config.supervisor.pinniped.dev"}}), expects=1 +--- +metadata: + #@overlay/match missing_ok=True + labels: #@ labels() + name: #@ pinnipedDevAPIGroupWithPrefix("oidcclients.config.supervisor") +spec: + group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") + versions: + #@overlay/match by=overlay.all, expects="1+" + - schema: + openAPIV3Schema: + #@overlay/match by=overlay.subset({"metadata":{"type":"object"}}), expects=1 + properties: + metadata: + #@overlay/match missing_ok=True + properties: + name: + pattern: ^client\.oauth\.pinniped\.dev- + type: string diff --git a/deploy_carvel/supervisor/package-template.yml b/deploy_carvel/supervisor/package-template.yml index 82e1cfe4..6b74d5ee 100644 --- a/deploy_carvel/supervisor/package-template.yml +++ b/deploy_carvel/supervisor/package-template.yml @@ -16,7 +16,7 @@ spec: spec: fetch: - imgpkgBundle: - image: #@ "${REPO_HOST}/packages/pinniped-supervisor:" + data.values.version + image: #@ data.values.repo_host + ":" + data.values.version template: - ytt: paths: diff --git a/deploy_carvel/supervisor/schema-openapi.yaml b/deploy_carvel/supervisor/schema-openapi.yaml deleted file mode 100644 index 0e0903fa..00000000 --- a/deploy_carvel/supervisor/schema-openapi.yaml +++ /dev/null @@ -1,164 +0,0 @@ -openapi: 3.0.0 -info: - version: 0.1.0 - title: Schema for data values, generated by ytt -paths: {} -components: - schemas: - dataValues: - type: object - additionalProperties: false - properties: - app_name: - type: string - description: Name of pinniped-supervisor. - default: pinniped-supervisor - namespace: - type: string - description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. - default: pinniped-supervisor - into_namespace: - type: string - nullable: true - description: 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. - default: null - custom_labels: - nullable: true - description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' - default: {} - replicas: - type: integer - description: Specify how many replicas of the Pinniped server to run. - default: 2 - image_repo: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: projects.registry.vmware.com/pinniped/pinniped-server - image_digest: - type: string - nullable: true - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: null - image_tag: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: latest - image_pull_dockerconfigjson: - type: object - additionalProperties: false - nullable: true - description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD - deprecated_service_http_nodeport_port: - type: integer - nullable: true - description: will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort` - default: null - deprecated_service_http_nodeport_nodeport: - type: integer - nullable: true - description: will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified - default: null - deprecated_service_http_loadbalancer_port: - type: integer - nullable: true - description: will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort` - default: null - deprecated_service_http_clusterip_port: - type: integer - nullable: true - description: '#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`' - default: null - service_https_nodeport_port: - type: integer - nullable: true - description: '#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`' - default: null - service_https_nodeport_nodeport: - type: integer - nullable: true - description: '#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified' - default: null - service_https_loadbalancer_port: - type: integer - nullable: true - description: '#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`' - default: null - service_https_clusterip_port: - type: integer - nullable: true - description: '#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`' - default: null - service_loadbalancer_ip: - type: string - nullable: true - description: The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided. - default: null - log_level: - type: string - nullable: true - description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. - default: null - deprecated_log_format: - type: string - nullable: true - description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' - default: null - run_as_user: - type: integer - description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - run_as_group: - type: integer - description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - api_group_suffix: - type: string - description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. - default: pinniped.dev - https_proxy: - type: string - nullable: true - description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. - default: null - no_proxy: - type: string - description: do not proxy Kubernetes endpoints - default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local - endpoints: - type: object - additionalProperties: false - nullable: true - description: Control the HTTP and HTTPS listeners of the Supervisor. - properties: - https: - type: object - additionalProperties: false - properties: - network: - type: string - default: tcp - address: - type: string - default: 1.2.3.4:5678 - deprecated_insecure_accept_external_unencrypted_http_requests: - type: boolean - description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. - default: false diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index e785d4d8..edbd920c 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -42,30 +42,366 @@ function check_dependency() { fi } -# registry="pinniped.local" + +pinniped_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$pinniped_path" || exit 1 + +# arguments provided to scripts called by hack/prepare-for-integration-tests.sh +# - app: unimportant, but always first +# - tag: uuidgen in hack/prepare-for-integration-tests.sh +# if this script is run standalone, then auto-fill with a unique value +app=${1:-"undefined"} +tag=${2:-$(uuidgen)} + +# TODO: automate the version by release somehow. +# the tag is the version in our build scripts, but we will want real versions for releases +pinniped_package_version="${tag}" # ie, "0.25.0" + +# core pinniped binaries (concierge, supervisor, local-user-authenticator) registry="kind-registry.local:5000" repo="test/build" registry_repo="$registry/$repo" -tag=$(uuidgen) # always a new tag to force K8s to reload the image on redeploy registry_repo_tag="${registry_repo}:${tag}" -# Generate the OpenAPI v3 Schema files +api_group_suffix="pinniped.dev" + +# Package prefix for concierge, supervisor, local-user-authenticator +package_prefix="test/build-package" # + $resource_name + ":" + $tag +package_repo_prefix="${registry_repo}/${package_prefix}" # + $resource_name + ":" + $tag + +# Pinniped Package repository +package_repository_repo="test/build-package-repository-pinniped" +package_repository_repo_tag="${registry_repo}/${package_repository_repo}:${tag}" + +# carvel +log_note "Installing kapp-controller on cluster..." +KAPP_CONTROLLER_GLOBAL_NAMESPACE="kapp-controller-packaging-global" +kapp deploy --app kapp-controller --file "https://github.com/vmware-tanzu/carvel-kapp-controller/releases/latest/download/release.yml" -y +kubectl get customresourcedefinitions + +# Generate the OpenAPI v3 Schema files, imgpkg images.yml files declare -a arr=("supervisor" "concierge" "local-user-authenticator") for resource_name in "${arr[@]}" do + resource_qualified_name="${resource_name}.${api_group_suffix}" + package_repo_tag="${package_repo_prefix}-${resource_name}:${tag}" + + resource_dir="deploy_carvel/${resource_name}" + resource_config_source_dir="deploy/${resource_name}" + resource_config_destination_dir="deploy_carvel/${resource_name}/config" + + # this must be real files, not symlinks + log_note "Copy deploy directory for ${resource_name} to package bundle..." + echo "cp -aRf ${resource_config_source_dir} ${resource_config_destination_dir}" + rm -rf "${resource_config_destination_dir}" # clean + cp -r "${resource_config_source_dir}" "${resource_config_destination_dir}" + log_note "Generating OpenAPI v3 schema for ${resource_name}..." ytt \ - --file "deploy/${resource_name}" \ + --file "${resource_config_destination_dir}" \ --data-values-schema-inspect \ --output openapi-v3 > \ - "deploy_carvel/${resource_name}/schema-openapi.yaml" + "${resource_dir}/schema-openapi.yaml" log_note "Generating .imgpkg/images.yml for ${resource_name}..." + mkdir -p "${resource_dir}/.imgpkg" ytt \ - --file "deploy/${resource_name}/" | \ - kbld -f- --imgpkg-lock-output "deploy_carvel/${resource_name}/.imgpkg/images.yml" + --file "${resource_config_destination_dir}" | \ + kbld -f- --imgpkg-lock-output "${resource_dir}/.imgpkg/images.yml" + + + log_note "Pushing Pinniped ${resource_name} Package bundle..." + imgpkg push --bundle "${package_repo_tag}" --file "${resource_dir}" + # validation flag? + log_note "Validating ${resource_name} Package bundle not empty (/tmp/${package_repo_tag})..." + imgpkg pull --bundle "${package_repo_tag}" --output "/tmp/${package_repo_tag}" + + + log_note "Generating PackageRepository Package entry for ${resource_name}" + # publish package versions to package repository + # TODO: what is package_image_repo? + # TODO: package_version should just become version, no need for it to not match. + package_repository_dir="deploy_carvel/package_repository/packages/${resource_qualified_name}" + ytt \ + --file "${resource_dir}/package-template.yml" \ + --data-value-file openapi="${resource_dir}/schema-openapi.yml" \ + --data-value repo_host="${package_repo_prefix}-${resource_name}" \ + --data-value version="${pinniped_package_version}" > "${package_repository_dir}/${pinniped_package_version}.yml" + cp "deploy_carvel/${resource_name}/metadata.yml" "${package_repository_dir}/metadata.yml" +done + +log_note "Generating .imgpkg/images.yml for Pinniped PackageRepository bundle..." +mkdir -p "deploy_carvel/package_repository/.imgpkg" +kbld --file "deploy_carvel/package_repository/packages/" --imgpkg-lock-output "deploy_carvel/package_repository/.imgpkg/images.yml" + +log_note "Pushing Pinniped PackageRepository bundle.... " +imgpkg push --bundle "${package_repository_repo_tag}" --file "deploy_carvel/package_repository" + +# validation flag? +log_note "Validating Pinniped PackageRepository bundle not empty /tmp/${package_repo_tag}..." +imgpkg pull --bundle "${package_repository_repo_tag}" --output "/tmp/${package_repository_repo_tag}" + + +log_note "deploying PackageRepository..." +pinniped_package_repository_name="pinniped-package-repository" +pinniped_package_repository_file="packagerepository.${pinniped_package_version}.yml" +echo -n "" > "${pinniped_package_repository_file}" +cat <> "${pinniped_package_repository_file}" +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageRepository +metadata: + name: "${pinniped_package_repository_name}" + namespace: "${KAPP_CONTROLLER_GLOBAL_NAMESPACE}" +spec: + fetch: + imgpkgBundle: + image: "${package_repository_repo_tag}" +EOT + +kapp deploy --app "${pinniped_package_repository_name}" --file "${pinniped_package_repository_file}" -y +kapp inspect --app "${pinniped_package_repository_name}" --tree + + + +for resource_name in "${arr[@]}" +do + log_note "creating PackageInstall and RBAC for ${resource_name}..." + + namespace="${resource_name}-install-ns" + pinniped_package_rbac_prefix="pinniped-package-rbac-${resource_name}" + pinniped_package_rbac_file="deploy_carvel/${pinniped_package_rbac_prefix}-${resource_name}-rbac.yml" + echo -n "" > "${pinniped_package_rbac_file}" +cat <> "${pinniped_package_rbac_file}" +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "${namespace}" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "${pinniped_package_rbac_prefix}-sa-superadmin-dangerous" + namespace: "${namespace}" +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "${pinniped_package_rbac_prefix}-role-superadmin-dangerous" + namespace: "${namespace}" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "${pinniped_package_rbac_prefix}-role-binding-superadmin-dangerous" +subjects: +- kind: ServiceAccount + name: "${pinniped_package_rbac_prefix}-sa-superadmin-dangerous" + namespace: "${namespace}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "${pinniped_package_rbac_prefix}-role-superadmin-dangerous" + +EOF + + kapp deploy --app "${pinniped_package_rbac_prefix}" --file "${pinniped_package_rbac_file}" -y done -log_note "Finished." -log_note "Now run hack/prepare-for-integration-tests.sh to create a kind cluster!" + +log_note "deploying supervisor PackageInstall resources..." +resource_name="supervisor" +NAMESPACE="${resource_name}-install-ns" +PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" +RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +SECRET_NAME="${resource_name}-package-install-secret" + +# from prepare-for-integration-test.sh +supervisor_app_name="pinniped-supervisor" +supervisor_namespace="supervisor" +supervisor_custom_labels="{mySupervisorCustomLabelName: mySupervisorCustomLabelValue}" +log_level="debug" +service_https_nodeport_port="443" +service_https_nodeport_nodeport="31243" +service_https_clusterip_port="443" +cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "${resource_name}-package-install" + namespace: "${NAMESPACE}" +spec: + serviceAccountName: "${PINNIPED_PACKAGE_RBAC_PREFIX}-sa-superadmin-dangerous" + packageRef: + refName: "${RESOURCE_PACKAGE_VERSION}" + versionSelection: + constraints: "${pinniped_package_version}" + values: + - secretRef: + name: "${SECRET_NAME}" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "${SECRET_NAME}" + namespace: "${NAMESPACE}" +stringData: + values.yml: | + --- + app_name: $supervisor_app_name + namespace: $supervisor_namespace + api_group_suffix: $api_group_suffix + image_repo: $registry_repo + image_tag: $tag + log_level: $log_level + + service_https_nodeport_port: $service_https_nodeport_port + service_https_nodeport_nodeport: $service_https_nodeport_nodeport + service_https_clusterip_port: $service_https_clusterip_port +EOF + +KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" +log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." +kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y +# end supervisor + + + +# concierge +log_note "deploying concierge PackageInstall resources..." +resource_name="concierge" +NAMESPACE="${resource_name}-install-ns" +PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" +RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +SECRET_NAME="${resource_name}-package-install-secret" + +# from prepare-for-integration-tests.sh +concierge_app_name="pinniped-concierge" +concierge_namespace="concierge" +webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" +webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" +discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" +concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" +log_level="debug" +cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "${resource_name}-package-install" + namespace: "${NAMESPACE}" +spec: + serviceAccountName: "${PINNIPED_PACKAGE_RBAC_PREFIX}-sa-superadmin-dangerous" + packageRef: + refName: "${RESOURCE_PACKAGE_VERSION}" + versionSelection: + constraints: "${pinniped_package_version}" + values: + - secretRef: + name: "${SECRET_NAME}" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "${SECRET_NAME}" + namespace: "${NAMESPACE}" +stringData: + values.yml: | + --- + app_name: $concierge_app_name + namespace: $concierge_namespace + api_group_suffix: $api_group_suffix + log_level: $log_level + + image_repo: $registry_repo + image_tag: $tag +EOF + +KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" +log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." +kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y +# end concierge + + + + +# local-user-authenticator +log_note "deploying local-user-authenticator PackageInstall resources..." +resource_name="local-user-authenticator" +NAMESPACE="${resource_name}-install-ns" +PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" +RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +SECRET_NAME="${resource_name}-package-install-secret" + +# from prepare-for-integration-tests.sh +concierge_app_name="pinniped-concierge" +concierge_namespace="concierge" +webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" +webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" +discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" +concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" +log_level="debug" +cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "${resource_name}-package-install" + namespace: "${NAMESPACE}" +spec: + serviceAccountName: "${PINNIPED_PACKAGE_RBAC_PREFIX}-sa-superadmin-dangerous" + packageRef: + refName: "${RESOURCE_PACKAGE_VERSION}" + versionSelection: + constraints: "${pinniped_package_version}" + values: + - secretRef: + name: "${SECRET_NAME}" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "${SECRET_NAME}" + namespace: "${NAMESPACE}" +stringData: + values.yml: | + --- + app_name: $concierge_app_name + namespace: $concierge_namespace + api_group_suffix: $api_group_suffix + log_level: $log_level + + image_repo: $registry_repo + image_tag: $tag +EOF + +KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" +log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." +kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y +# end concierge + +log_note "verifying PackageInstall resources..." +kubectl get PackageInstall -A | grep pinniped +kubectl get secret -A | grep pinniped + +log_note "listing all package resources (PackageRepository, Package, PackageInstall)..." +kubectl get pkgi && kubectl get pkgr && kubectl get pkg + +log_note "listing all kapp cli apps..." +kapp ls --all-namespaces + +log_note "listing all kapp-controller apps..." +kubectl get app --all-namespaces diff --git a/hack/noop.sh b/hack/noop.sh new file mode 100755 index 00000000..99511277 --- /dev/null +++ b/hack/noop.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# +# This script is intended to be used with: +# - $repo_root/hack/prepare-for-integration-test.sh --alternate-deploy $(pwd)/deploy_carvel/hack/log-args.sh +# and originated with the following: +# - https://github.com/jvanzyl/pinniped-charts/blob/main/alternate-deploy-helm +# along with this PR to pinniped: +# - https://github.com/vmware-tanzu/pinniped/pull/1028 +set -euo pipefail + +# +# Helper functions +# +function log_note() { + GREEN='\033[0;32m' + NC='\033[0m' + if [[ ${COLORTERM:-unknown} =~ ^(truecolor|24bit)$ ]]; then + echo -e "${GREEN}$*${NC}" + else + echo "$*" + fi +} + +function log_error() { + RED='\033[0;31m' + NC='\033[0m' + if [[ ${COLORTERM:-unknown} =~ ^(truecolor|24bit)$ ]]; then + echo -e "🙁${RED} Error: $* ${NC}" + else + echo ":( Error: $*" + fi +} + +function check_dependency() { + if ! command -v "$1" >/dev/null; then + log_error "Missing dependency..." + log_error "$2" + exit 1 + fi +} + +## two vars will be received by this script: +## Received: local-user-authenticator +## Received: D00A4537-80F1-4AF2-A3B3-5F20BDBB9AEB +app=${1} +## tag is fed in from the prepare-for-integration-tests.sh script, just uuidgen to identify a +## specific docker build of the pinniped-server image. +tag=${2} +#SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +#log_note "noop.sh >>> script dir: ${SCRIPT_DIR}" +log_note "noop.sh >>> app: ${app} tag: ${tag}" +## nothing else, this is a test. +# +#log_note "temporarily creating ns:local-user-authenticator as workaround..." +# +#local_user_authenticator_file="/tmp/install-local-user-authenticator-namespace.yaml" +#cat < "${local_user_authenticator_file}" +#--- +#apiVersion: v1 +#kind: Namespace +#metadata: +# name: local-user-authenticator +# labels: +# name: local-user-authenticator +#EOF +# +#kubectl apply -f "${local_user_authenticator_file}" diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 37487fef..5c959c52 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -235,7 +235,7 @@ fi registry="kind-registry.local:5000" repo="test/build" registry_repo="$registry/$repo" -tag=$(uuidgen) # always a new tag to force K8s to reload the image on redeploy +tag="0.0.0-$(uuidgen)" # always a new tag to force K8s to reload the image on redeploy if [[ "$skip_build" == "yes" ]]; then most_recent_tag=$(docker images "$registry/$repo" --format "{{.Tag}}" | head -1) @@ -292,6 +292,20 @@ else kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. + + # TODO: will have to create this in our package install script.... + test_username="test-username" + test_groups="test-group-0,test-group-1" + test_password="$(openssl rand -hex 16)" + log_note "Creating test user '$test_username'..." + kubectl create secret generic "$test_username" \ + --namespace local-user-authenticator \ + --from-literal=groups="$test_groups" \ + --from-literal=passwordHash="$(htpasswd -nbBC 10 x "$test_password" | sed -e "s/^x://")" \ + --dry-run=client \ + --output yaml | + kubectl apply -f - + popd >/dev/null fi @@ -315,18 +329,6 @@ kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. popd >/dev/null -test_username="test-username" -test_groups="test-group-0,test-group-1" -test_password="$(openssl rand -hex 16)" -log_note "Creating test user '$test_username'..." -kubectl create secret generic "$test_username" \ - --namespace local-user-authenticator \ - --from-literal=groups="$test_groups" \ - --from-literal=passwordHash="$(htpasswd -nbBC 10 x "$test_password" | sed -e "s/^x://")" \ - --dry-run=client \ - --output yaml | - kubectl apply -f - - # # Deploy the Pinniped Supervisor # From de1bbde2cc1c3bc6a42468f28904f76d631b7675 Mon Sep 17 00:00:00 2001 From: Joshua Casey Date: Tue, 3 Oct 2023 09:15:17 -0500 Subject: [PATCH 14/40] Use vendir sync instead of cp to sync the deploy manifests --- deploy_carvel/concierge/.gitignore | 1 + deploy_carvel/concierge/config/README.md | 3 - ...cierge.pinniped.dev_jwtauthenticators.yaml | 175 ------- ...ge.pinniped.dev_webhookauthenticators.yaml | 148 ------ ...cierge.pinniped.dev_credentialissuers.yaml | 257 --------- .../concierge/config/deployment.yaml | 355 ------------- .../concierge/config/helpers.lib.yaml | 47 -- deploy_carvel/concierge/config/rbac.yaml | 296 ----------- deploy_carvel/concierge/config/values.yaml | 137 ----- .../concierge/config/z0_crd_overlay.yaml | 33 -- deploy_carvel/concierge/vendir.lock.yml | 7 + deploy_carvel/concierge/vendir.yml | 8 + .../local-user-authenticator/.gitignore | 1 + .../local-user-authenticator/config/README.md | 163 ------ .../config/deployment.yaml | 97 ---- .../local-user-authenticator/config/rbac.yaml | 30 -- .../config/values.yaml | 26 - .../local-user-authenticator/vendir.lock.yml | 7 + .../local-user-authenticator/vendir.yml | 8 + deploy_carvel/supervisor/.gitignore | 1 + deploy_carvel/supervisor/config/README.md | 3 - ...rvisor.pinniped.dev_federationdomains.yaml | 488 ------------------ ...g.supervisor.pinniped.dev_oidcclients.yaml | 220 -------- .../supervisor/config/deployment.yaml | 236 --------- .../supervisor/config/helpers.lib.yaml | 88 ---- ....dev_activedirectoryidentityproviders.yaml | 318 ------------ ...or.pinniped.dev_ldapidentityproviders.yaml | 315 ----------- ...or.pinniped.dev_oidcidentityproviders.yaml | 345 ------------- deploy_carvel/supervisor/config/rbac.yaml | 152 ------ deploy_carvel/supervisor/config/service.yaml | 115 ----- deploy_carvel/supervisor/config/values.yaml | 175 ------- .../supervisor/config/z0_crd_overlay.yaml | 63 --- deploy_carvel/supervisor/vendir.lock.yml | 7 + deploy_carvel/supervisor/vendir.yml | 8 + hack/build-carvel-packages.sh | 10 +- 35 files changed, 53 insertions(+), 4290 deletions(-) create mode 100644 deploy_carvel/concierge/.gitignore delete mode 100644 deploy_carvel/concierge/config/README.md delete mode 100644 deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml delete mode 100644 deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml delete mode 100644 deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml delete mode 100644 deploy_carvel/concierge/config/deployment.yaml delete mode 100644 deploy_carvel/concierge/config/helpers.lib.yaml delete mode 100644 deploy_carvel/concierge/config/rbac.yaml delete mode 100644 deploy_carvel/concierge/config/values.yaml delete mode 100644 deploy_carvel/concierge/config/z0_crd_overlay.yaml create mode 100644 deploy_carvel/concierge/vendir.lock.yml create mode 100644 deploy_carvel/concierge/vendir.yml create mode 100644 deploy_carvel/local-user-authenticator/.gitignore delete mode 100644 deploy_carvel/local-user-authenticator/config/README.md delete mode 100644 deploy_carvel/local-user-authenticator/config/deployment.yaml delete mode 100644 deploy_carvel/local-user-authenticator/config/rbac.yaml delete mode 100644 deploy_carvel/local-user-authenticator/config/values.yaml create mode 100644 deploy_carvel/local-user-authenticator/vendir.lock.yml create mode 100644 deploy_carvel/local-user-authenticator/vendir.yml create mode 100644 deploy_carvel/supervisor/.gitignore delete mode 100644 deploy_carvel/supervisor/config/README.md delete mode 100644 deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml delete mode 100644 deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml delete mode 100644 deploy_carvel/supervisor/config/deployment.yaml delete mode 100644 deploy_carvel/supervisor/config/helpers.lib.yaml delete mode 100644 deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml delete mode 100644 deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml delete mode 100644 deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml delete mode 100644 deploy_carvel/supervisor/config/rbac.yaml delete mode 100644 deploy_carvel/supervisor/config/service.yaml delete mode 100644 deploy_carvel/supervisor/config/values.yaml delete mode 100644 deploy_carvel/supervisor/config/z0_crd_overlay.yaml create mode 100644 deploy_carvel/supervisor/vendir.lock.yml create mode 100644 deploy_carvel/supervisor/vendir.yml diff --git a/deploy_carvel/concierge/.gitignore b/deploy_carvel/concierge/.gitignore new file mode 100644 index 00000000..f733c4b5 --- /dev/null +++ b/deploy_carvel/concierge/.gitignore @@ -0,0 +1 @@ +config/ diff --git a/deploy_carvel/concierge/config/README.md b/deploy_carvel/concierge/config/README.md deleted file mode 100644 index 39ce06b2..00000000 --- a/deploy_carvel/concierge/config/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Pinniped Concierge Deployment - -See [the how-to guide for details](https://pinniped.dev/docs/howto/install-concierge/). diff --git a/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml b/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml deleted file mode 100644 index 0520898f..00000000 --- a/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_jwtauthenticators.yaml +++ /dev/null @@ -1,175 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: jwtauthenticators.authentication.concierge.pinniped.dev -spec: - group: authentication.concierge.pinniped.dev - names: - categories: - - pinniped - - pinniped-authenticator - - pinniped-authenticators - kind: JWTAuthenticator - listKind: JWTAuthenticatorList - plural: jwtauthenticators - singular: jwtauthenticator - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .spec.issuer - name: Issuer - type: string - - jsonPath: .spec.audience - name: Audience - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: "JWTAuthenticator describes the configuration of a JWT authenticator. - \n Upon receiving a signed JWT, a JWTAuthenticator will performs some validation - on it (e.g., valid signature, existence of claims, etc.) and extract the - username and groups from the token." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec for configuring the authenticator. - properties: - audience: - description: Audience is the required value of the "aud" JWT claim. - minLength: 1 - type: string - claims: - description: Claims allows customization of the claims that will be - mapped to user identity for Kubernetes access. - properties: - groups: - description: Groups is the name of the claim which should be read - to extract the user's group membership from the JWT token. When - not specified, it will default to "groups". - type: string - username: - description: Username is the name of the claim which should be - read to extract the username from the JWT token. When not specified, - it will default to "username". - type: string - type: object - issuer: - description: Issuer is the OIDC issuer URL that will be used to discover - public signing keys. Issuer is also used to validate the "iss" JWT - claim. - minLength: 1 - pattern: ^https:// - type: string - tls: - description: TLS configuration for communicating with the OIDC provider. - properties: - certificateAuthorityData: - description: X.509 Certificate Authority (base64-encoded PEM bundle). - If omitted, a default set of system roots will be trusted. - type: string - type: object - required: - - audience - - issuer - type: object - status: - description: Status of the authenticator. - properties: - conditions: - description: Represents the observations of the authenticator's current - state. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml b/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml deleted file mode 100644 index 5924c6f6..00000000 --- a/deploy_carvel/concierge/config/authentication.concierge.pinniped.dev_webhookauthenticators.yaml +++ /dev/null @@ -1,148 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: webhookauthenticators.authentication.concierge.pinniped.dev -spec: - group: authentication.concierge.pinniped.dev - names: - categories: - - pinniped - - pinniped-authenticator - - pinniped-authenticators - kind: WebhookAuthenticator - listKind: WebhookAuthenticatorList - plural: webhookauthenticators - singular: webhookauthenticator - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .spec.endpoint - name: Endpoint - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: WebhookAuthenticator describes the configuration of a webhook - authenticator. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec for configuring the authenticator. - properties: - endpoint: - description: Webhook server endpoint URL. - minLength: 1 - pattern: ^https:// - type: string - tls: - description: TLS configuration. - properties: - certificateAuthorityData: - description: X.509 Certificate Authority (base64-encoded PEM bundle). - If omitted, a default set of system roots will be trusted. - type: string - type: object - required: - - endpoint - type: object - status: - description: Status of the authenticator. - properties: - conditions: - description: Represents the observations of the authenticator's current - state. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml b/deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml deleted file mode 100644 index 23bb032c..00000000 --- a/deploy_carvel/concierge/config/config.concierge.pinniped.dev_credentialissuers.yaml +++ /dev/null @@ -1,257 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: credentialissuers.config.concierge.pinniped.dev -spec: - group: config.concierge.pinniped.dev - names: - categories: - - pinniped - kind: CredentialIssuer - listKind: CredentialIssuerList - plural: credentialissuers - singular: credentialissuer - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .spec.impersonationProxy.mode - name: ProxyMode - type: string - - jsonPath: .status.strategies[?(@.status == "Success")].type - name: DefaultStrategy - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: CredentialIssuer describes the configuration and status of the - Pinniped Concierge credential issuer. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec describes the intended configuration of the Concierge. - properties: - impersonationProxy: - description: ImpersonationProxy describes the intended configuration - of the Concierge impersonation proxy. - properties: - externalEndpoint: - description: "ExternalEndpoint describes the HTTPS endpoint where - the proxy will be exposed. If not set, the proxy will be served - using the external name of the LoadBalancer service or the cluster - service DNS name. \n This field must be non-empty when spec.impersonationProxy.service.type - is \"None\"." - type: string - mode: - description: 'Mode configures whether the impersonation proxy - should be started: - "disabled" explicitly disables the impersonation - proxy. This is the default. - "enabled" explicitly enables the - impersonation proxy. - "auto" enables or disables the impersonation - proxy based upon the cluster in which it is running.' - enum: - - auto - - enabled - - disabled - type: string - service: - default: - type: LoadBalancer - description: Service describes the configuration of the Service - provisioned to expose the impersonation proxy to clients. - properties: - annotations: - additionalProperties: - type: string - description: Annotations specifies zero or more key/value - pairs to set as annotations on the provisioned Service. - type: object - loadBalancerIP: - description: LoadBalancerIP specifies the IP address to set - in the spec.loadBalancerIP field of the provisioned Service. - This is not supported on all cloud providers. - maxLength: 255 - minLength: 1 - type: string - type: - default: LoadBalancer - description: "Type specifies the type of Service to provision - for the impersonation proxy. \n If the type is \"None\", - then the \"spec.impersonationProxy.externalEndpoint\" field - must be set to a non-empty value so that the Concierge can - properly advertise the endpoint in the CredentialIssuer's - status." - enum: - - LoadBalancer - - ClusterIP - - None - type: string - type: object - tls: - description: "TLS contains information about how the Concierge - impersonation proxy should serve TLS. \n If this field is empty, - the impersonation proxy will generate its own TLS certificate." - properties: - certificateAuthorityData: - description: X.509 Certificate Authority (base64-encoded PEM - bundle). Used to advertise the CA bundle for the impersonation - proxy endpoint. - type: string - secretName: - description: SecretName is the name of a Secret in the same - namespace, of type `kubernetes.io/tls`, which contains the - TLS serving certificate for the Concierge impersonation - proxy endpoint. - minLength: 1 - type: string - type: object - required: - - mode - - service - type: object - required: - - impersonationProxy - type: object - status: - description: CredentialIssuerStatus describes the status of the Concierge. - properties: - kubeConfigInfo: - description: Information needed to form a valid Pinniped-based kubeconfig - using this credential issuer. This field is deprecated and will - be removed in a future version. - properties: - certificateAuthorityData: - description: The K8s API server CA bundle. - minLength: 1 - type: string - server: - description: The K8s API server URL. - minLength: 1 - pattern: ^https://|^http:// - type: string - required: - - certificateAuthorityData - - server - type: object - strategies: - description: List of integration strategies that were attempted by - Pinniped. - items: - description: CredentialIssuerStrategy describes the status of an - integration strategy that was attempted by Pinniped. - properties: - frontend: - description: Frontend describes how clients can connect using - this strategy. - properties: - impersonationProxyInfo: - description: ImpersonationProxyInfo describes the parameters - for the impersonation proxy on this Concierge. This field - is only set when Type is "ImpersonationProxy". - properties: - certificateAuthorityData: - description: CertificateAuthorityData is the base64-encoded - PEM CA bundle of the impersonation proxy. - minLength: 1 - type: string - endpoint: - description: Endpoint is the HTTPS endpoint of the impersonation - proxy. - minLength: 1 - pattern: ^https:// - type: string - required: - - certificateAuthorityData - - endpoint - type: object - tokenCredentialRequestInfo: - description: TokenCredentialRequestAPIInfo describes the - parameters for the TokenCredentialRequest API on this - Concierge. This field is only set when Type is "TokenCredentialRequestAPI". - properties: - certificateAuthorityData: - description: CertificateAuthorityData is the base64-encoded - Kubernetes API server CA bundle. - minLength: 1 - type: string - server: - description: Server is the Kubernetes API server URL. - minLength: 1 - pattern: ^https://|^http:// - type: string - required: - - certificateAuthorityData - - server - type: object - type: - description: Type describes which frontend mechanism clients - can use with a strategy. - enum: - - TokenCredentialRequestAPI - - ImpersonationProxy - type: string - required: - - type - type: object - lastUpdateTime: - description: When the status was last checked. - format: date-time - type: string - message: - description: Human-readable description of the current status. - minLength: 1 - type: string - reason: - description: Reason for the current status. - enum: - - Listening - - Pending - - Disabled - - ErrorDuringSetup - - CouldNotFetchKey - - CouldNotGetClusterInfo - - FetchedKey - type: string - status: - description: Status of the attempted integration strategy. - enum: - - Success - - Error - type: string - type: - description: Type of integration attempted. - enum: - - KubeClusterSigningCertificate - - ImpersonationProxy - type: string - required: - - lastUpdateTime - - message - - reason - - status - - type - type: object - type: array - required: - - strategies - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/concierge/config/deployment.yaml b/deploy_carvel/concierge/config/deployment.yaml deleted file mode 100644 index bd1c690f..00000000 --- a/deploy_carvel/concierge/config/deployment.yaml +++ /dev/null @@ -1,355 +0,0 @@ -#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:data", "data") -#@ load("@ytt:json", "json") -#@ load("helpers.lib.yaml", "defaultLabel", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "getAndValidateLogLevel", "pinnipedDevAPIGroupWithPrefix") -#@ load("@ytt:template", "template") - -#@ if not data.values.into_namespace: ---- -apiVersion: v1 -kind: Namespace -metadata: - name: #@ data.values.namespace - labels: - _: #@ template.replace(labels()) - #! When deploying onto a cluster which has PSAs enabled by default for namespaces, - #! effectively disable them for this namespace. The kube-cert-agent Deployment's pod - #! created by the Concierge in this namespace needs to be able to perform privileged - #! actions. The regular Concierge pod containers created by the Deployment below do - #! not need special privileges and are marked as such in their securityContext settings. - pod-security.kubernetes.io/enforce: privileged -#@ end ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: #@ defaultResourceName() - namespace: #@ namespace() - labels: #@ labels() ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: #@ defaultResourceNameWithSuffix("kube-cert-agent") - namespace: #@ namespace() - labels: #@ labels() ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: #@ defaultResourceNameWithSuffix("impersonation-proxy") - namespace: #@ namespace() - labels: #@ labels() - annotations: - #! we need to create this service account before we create the secret - kapp.k14s.io/change-group: "impersonation-proxy.concierge.pinniped.dev/serviceaccount" -secrets: #! make sure the token controller does not create any other secrets -- name: #@ defaultResourceNameWithSuffix("impersonation-proxy") ---- -apiVersion: v1 -kind: ConfigMap -metadata: - 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 - pinniped.yaml: | - discovery: - url: (@= data.values.discovery_url or "null" @) - api: - servingCertificate: - durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @) - renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @) - apiGroupSuffix: (@= data.values.api_group_suffix @) - # aggregatedAPIServerPort may be set here, although other YAML references to the default port (10250) may also need to be updated - # impersonationProxyServerPort may be set here, although other YAML references to the default port (8444) may also need to be updated - names: - servingCertificateSecret: (@= defaultResourceNameWithSuffix("api-tls-serving-certificate") @) - credentialIssuer: (@= defaultResourceNameWithSuffix("config") @) - apiService: (@= defaultResourceNameWithSuffix("api") @) - impersonationLoadBalancerService: (@= defaultResourceNameWithSuffix("impersonation-proxy-load-balancer") @) - impersonationClusterIPService: (@= defaultResourceNameWithSuffix("impersonation-proxy-cluster-ip") @) - impersonationTLSCertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-tls-serving-certificate") @) - impersonationCACertificateSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-ca-certificate") @) - impersonationSignerSecret: (@= defaultResourceNameWithSuffix("impersonation-proxy-signer-ca-certificate") @) - agentServiceAccount: (@= defaultResourceNameWithSuffix("kube-cert-agent") @) - labels: (@= json.encode(labels()).rstrip() @) - kubeCertAgent: - namePrefix: (@= defaultResourceNameWithSuffix("kube-cert-agent-") @) - (@ if data.values.kube_cert_agent_image: @) - image: (@= data.values.kube_cert_agent_image @) - (@ else: @) - (@ if data.values.image_digest: @) - image: (@= data.values.image_repo + "@" + data.values.image_digest @) - (@ else: @) - image: (@= data.values.image_repo + ":" + data.values.image_tag @) - (@ end @) - (@ end @) - (@ if data.values.image_pull_dockerconfigjson: @) - imagePullSecrets: - - image-pull-secret - (@ end @) - (@ if data.values.log_level or data.values.deprecated_log_format: @) - log: - (@ if data.values.log_level: @) - level: (@= getAndValidateLogLevel() @) - (@ end @) - (@ if data.values.deprecated_log_format: @) - format: (@= data.values.deprecated_log_format @) - (@ end @) - (@ end @) ---- -#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": -apiVersion: v1 -kind: Secret -metadata: - name: image-pull-secret - namespace: #@ namespace() - labels: #@ labels() -type: kubernetes.io/dockerconfigjson -data: - .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson -#@ end ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: #@ defaultResourceName() - namespace: #@ namespace() - labels: #@ labels() -spec: - replicas: #@ data.values.replicas - selector: - #! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades. - matchLabels: #@ defaultLabel() - template: - metadata: - labels: - #! This has always included defaultLabel(), which is used by this Deployment's selector. - _: #@ template.replace(defaultLabel()) - #! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically - #! without accidentally selecting any other Deployment's Pods, especially the kube cert agent Deployment's Pods. - _: #@ template.replace(deploymentPodLabel()) - spec: - securityContext: - runAsUser: #@ data.values.run_as_user - runAsGroup: #@ data.values.run_as_group - serviceAccountName: #@ defaultResourceName() - #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": - imagePullSecrets: - - name: image-pull-secret - #@ end - containers: - - name: #@ defaultResourceName() - #@ if data.values.image_digest: - image: #@ data.values.image_repo + "@" + data.values.image_digest - #@ else: - image: #@ data.values.image_repo + ":" + data.values.image_tag - #@ end - imagePullPolicy: IfNotPresent - securityContext: - readOnlyRootFilesystem: true - runAsNonRoot: true - allowPrivilegeEscalation: false - capabilities: - drop: [ "ALL" ] - #! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a - #! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's - #! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error. - seccompProfile: - type: "RuntimeDefault" - resources: - requests: - cpu: "100m" - memory: "128Mi" - limits: - cpu: "100m" - memory: "128Mi" - command: - - pinniped-concierge - - --config=/etc/config/pinniped.yaml - - --downward-api-path=/etc/podinfo - volumeMounts: - - name: tmp - mountPath: /tmp - - name: config-volume - mountPath: /etc/config - readOnly: true - - name: podinfo - mountPath: /etc/podinfo - readOnly: true - - name: impersonation-proxy - mountPath: /var/run/secrets/impersonation-proxy.concierge.pinniped.dev/serviceaccount - readOnly: true - env: - #@ if data.values.https_proxy: - - name: HTTPS_PROXY - value: #@ data.values.https_proxy - #@ end - #@ if data.values.https_proxy and data.values.no_proxy: - - name: NO_PROXY - value: #@ data.values.no_proxy - #@ end - livenessProbe: - httpGet: - path: /healthz - port: 10250 - scheme: HTTPS - initialDelaySeconds: 2 - timeoutSeconds: 15 - periodSeconds: 10 - failureThreshold: 5 - readinessProbe: - httpGet: - path: /healthz - port: 10250 - scheme: HTTPS - initialDelaySeconds: 2 - timeoutSeconds: 3 - periodSeconds: 10 - failureThreshold: 3 - volumes: - - name: tmp - emptyDir: - medium: Memory - sizeLimit: 100Mi - - name: config-volume - configMap: - name: #@ defaultResourceNameWithSuffix("config") - - name: impersonation-proxy - secret: - secretName: #@ defaultResourceNameWithSuffix("impersonation-proxy") - items: #! make sure our pod does not start until the token controller has a chance to populate the secret - - key: token - path: token - - name: podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "name" - fieldRef: - fieldPath: metadata.name - - path: "namespace" - fieldRef: - fieldPath: metadata.namespace - tolerations: - - key: CriticalAddonsOnly - operator: Exists - - key: node-role.kubernetes.io/master #! Allow running on master nodes too (name deprecated by kubernetes 1.20). - effect: NoSchedule - - key: node-role.kubernetes.io/control-plane #! The new name for these nodes as of Kubernetes 1.24. - effect: NoSchedule - #! This will help make sure our multiple pods run on different nodes, making - #! our deployment "more" "HA". - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 50 - podAffinityTerm: - labelSelector: - matchLabels: #@ deploymentPodLabel() - 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: #@ defaultResourceNameWithSuffix("api") - namespace: #@ namespace() - labels: #@ labels() - #! prevent kapp from altering the selector of our services to match kubectl behavior - annotations: - kapp.k14s.io/disable-default-label-scoping-rules: "" -spec: - type: ClusterIP - selector: #@ deploymentPodLabel() - ports: - - protocol: TCP - port: 443 - targetPort: 10250 ---- -apiVersion: v1 -kind: Service -metadata: - name: #@ defaultResourceNameWithSuffix("proxy") - namespace: #@ namespace() - labels: #@ labels() - #! prevent kapp from altering the selector of our services to match kubectl behavior - annotations: - kapp.k14s.io/disable-default-label-scoping-rules: "" -spec: - type: ClusterIP - selector: #@ deploymentPodLabel() - ports: - - protocol: TCP - port: 443 - targetPort: 8444 ---- -apiVersion: apiregistration.k8s.io/v1 -kind: APIService -metadata: - name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.login.concierge") - labels: #@ labels() -spec: - version: v1alpha1 - group: #@ pinnipedDevAPIGroupWithPrefix("login.concierge") - groupPriorityMinimum: 9900 - versionPriority: 15 - #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code. - service: - name: #@ defaultResourceNameWithSuffix("api") - namespace: #@ namespace() - port: 443 ---- -apiVersion: apiregistration.k8s.io/v1 -kind: APIService -metadata: - name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.identity.concierge") - labels: #@ labels() -spec: - version: v1alpha1 - group: #@ pinnipedDevAPIGroupWithPrefix("identity.concierge") - groupPriorityMinimum: 9900 - versionPriority: 15 - #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code. - service: - name: #@ defaultResourceNameWithSuffix("api") - namespace: #@ namespace() - port: 443 ---- -apiVersion: #@ pinnipedDevAPIGroupWithPrefix("config.concierge") + "/v1alpha1" -kind: CredentialIssuer -metadata: - name: #@ defaultResourceNameWithSuffix("config") - labels: #@ labels() -spec: - impersonationProxy: - mode: #@ data.values.impersonation_proxy_spec.mode - #@ if data.values.impersonation_proxy_spec.external_endpoint: - externalEndpoint: #@ data.values.impersonation_proxy_spec.external_endpoint - #@ end - service: - type: #@ data.values.impersonation_proxy_spec.service.type - #@ if data.values.impersonation_proxy_spec.service.load_balancer_ip: - loadBalancerIP: #@ data.values.impersonation_proxy_spec.service.load_balancer_ip - #@ end - annotations: #@ data.values.impersonation_proxy_spec.service.annotations ---- -apiVersion: v1 -kind: Secret -metadata: - name: #@ defaultResourceNameWithSuffix("impersonation-proxy") - namespace: #@ namespace() - labels: #@ labels() - annotations: - #! wait until the SA exists to create this secret so that the token controller does not delete it - #! we have this secret at the end so that kubectl will create the service account first - kapp.k14s.io/change-rule: "upsert after upserting impersonation-proxy.concierge.pinniped.dev/serviceaccount" - kubernetes.io/service-account.name: #@ defaultResourceNameWithSuffix("impersonation-proxy") -type: kubernetes.io/service-account-token diff --git a/deploy_carvel/concierge/config/helpers.lib.yaml b/deploy_carvel/concierge/config/helpers.lib.yaml deleted file mode 100644 index 542fe069..00000000 --- a/deploy_carvel/concierge/config/helpers.lib.yaml +++ /dev/null @@ -1,47 +0,0 @@ -#! Copyright 2020-2021 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 pinnipedDevAPIGroupWithPrefix(prefix): -#@ return prefix + "." + data.values.api_group_suffix -#@ end - -#@ def namespace(): -#@ if data.values.into_namespace: -#@ return data.values.into_namespace -#@ else: -#@ return data.values.namespace -#@ end -#@ end - -#@ def defaultLabel(): -#! Note that the name of this label's key is also assumed by kubecertagent.go and impersonator_config.go -app: #@ data.values.app_name -#@ end - -#@ def deploymentPodLabel(): -deployment.pinniped.dev: concierge -#@ end - -#@ def labels(): -_: #@ template.replace(defaultLabel()) -_: #@ template.replace(data.values.custom_labels) -#@ end - -#@ def getAndValidateLogLevel(): -#@ log_level = data.values.log_level -#@ if log_level != "info" and log_level != "debug" and log_level != "trace" and log_level != "all": -#@ fail("log_level '" + log_level + "' is invalid") -#@ end -#@ return log_level -#@ end diff --git a/deploy_carvel/concierge/config/rbac.yaml b/deploy_carvel/concierge/config/rbac.yaml deleted file mode 100644 index 61ffa57b..00000000 --- a/deploy_carvel/concierge/config/rbac.yaml +++ /dev/null @@ -1,296 +0,0 @@ -#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:data", "data") -#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "pinnipedDevAPIGroupWithPrefix") - -#! Give permission to various cluster-scoped objects ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - labels: #@ labels() -rules: - - apiGroups: [ "" ] - resources: [ namespaces ] - verbs: [ get, list, watch ] - - apiGroups: [ apiregistration.k8s.io ] - resources: [ apiservices ] - verbs: [ get, list, patch, update, watch ] - - apiGroups: [ admissionregistration.k8s.io ] - resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ] - verbs: [ get, list, watch ] - - apiGroups: [ flowcontrol.apiserver.k8s.io ] - resources: [ flowschemas, prioritylevelconfigurations ] - verbs: [ get, list, watch ] - - apiGroups: [ security.openshift.io ] - resources: [ securitycontextconstraints ] - verbs: [ use ] - resourceNames: [ nonroot ] - - apiGroups: [ "" ] - resources: [ nodes ] - verbs: [ list ] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("config.concierge") - resources: [ credentialissuers ] - verbs: [ get, list, watch, create ] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("config.concierge") - resources: [ credentialissuers/status ] - verbs: [ get, patch, update ] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge") - resources: [ jwtauthenticators, webhookauthenticators ] - verbs: [ get, list, watch ] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: ClusterRole - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - apiGroup: rbac.authorization.k8s.io - -#! Give minimal permissions to impersonation proxy service account ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: #@ defaultResourceNameWithSuffix("impersonation-proxy") - labels: #@ labels() -rules: - - apiGroups: [ "" ] - resources: [ "users", "groups", "serviceaccounts" ] - verbs: [ "impersonate" ] - - apiGroups: [ "authentication.k8s.io" ] - resources: [ "*" ] #! What we really want is userextras/* but the RBAC authorizer only supports */subresource, not resource/* - verbs: [ "impersonate" ] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("impersonation-proxy") - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceNameWithSuffix("impersonation-proxy") - namespace: #@ namespace() -roleRef: - kind: ClusterRole - name: #@ defaultResourceNameWithSuffix("impersonation-proxy") - apiGroup: rbac.authorization.k8s.io - -#! Give permission to the kube-cert-agent Pod to run privileged. ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: #@ defaultResourceNameWithSuffix("kube-cert-agent") - namespace: #@ namespace() - labels: #@ labels() -rules: - - apiGroups: [ policy ] - resources: [ podsecuritypolicies ] - verbs: [ use ] ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("kube-cert-agent") - namespace: #@ namespace() - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceNameWithSuffix("kube-cert-agent") - namespace: #@ namespace() -roleRef: - kind: Role - name: #@ defaultResourceNameWithSuffix("kube-cert-agent") - apiGroup: rbac.authorization.k8s.io - -#! Give permission to various objects within the app's own namespace ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - namespace: #@ namespace() - labels: #@ labels() -rules: - - apiGroups: [ "" ] - resources: [ services ] - verbs: [ create, get, list, patch, update, watch, delete ] - - apiGroups: [ "" ] - resources: [ secrets ] - verbs: [ create, get, list, patch, update, watch, delete ] - #! We need to be able to watch pods in our namespace so we can find the kube-cert-agent pods. - - apiGroups: [ "" ] - resources: [ pods ] - verbs: [ get, list, watch ] - #! 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 ] - #! We need to be able to delete pods in our namespace so we can clean up legacy kube-cert-agent pods. - - apiGroups: [ "" ] - resources: [ pods ] - verbs: [ delete ] - #! We need to be able to create and update deployments in our namespace so we can manage the kube-cert-agent Deployment. - - apiGroups: [ apps ] - resources: [ deployments ] - verbs: [ create, get, list, patch, update, watch, delete ] - #! We need to be able to get replicasets so we can form the correct owner references on our generated objects. - - apiGroups: [ apps ] - resources: [ replicasets ] - verbs: [ get ] - - apiGroups: [ "" ] - resources: [ configmaps ] - verbs: [ list, get, watch ] - - apiGroups: [ coordination.k8s.io ] - resources: [ leases ] - verbs: [ create, get, update ] ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - namespace: #@ namespace() - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: Role - 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 ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") - namespace: kube-system - labels: #@ labels() -rules: - - apiGroups: [ "" ] - resources: [ pods ] - verbs: [ get, list, watch ] ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") - namespace: kube-system - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: Role - name: #@ defaultResourceNameWithSuffix("kube-system-pod-read") - apiGroup: rbac.authorization.k8s.io - -#! Allow both authenticated and unauthenticated TokenCredentialRequests (i.e. allow all requests) ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: #@ defaultResourceNameWithSuffix("pre-authn-apis") - labels: #@ labels() -rules: - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("login.concierge") - resources: [ tokencredentialrequests ] - verbs: [ create, list ] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("identity.concierge") - resources: [ whoamirequests ] - verbs: [ create, list ] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("pre-authn-apis") - labels: #@ labels() -subjects: - - kind: Group - name: system:authenticated - apiGroup: rbac.authorization.k8s.io - - kind: Group - name: system:unauthenticated - apiGroup: rbac.authorization.k8s.io -roleRef: - kind: ClusterRole - name: #@ defaultResourceNameWithSuffix("pre-authn-apis") - apiGroup: rbac.authorization.k8s.io - -#! Give permissions for subjectaccessreviews, tokenreview that is needed by aggregated api servers ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceName() - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: ClusterRole - name: system:auth-delegator - apiGroup: rbac.authorization.k8s.io - -#! Give permissions for a special configmap of CA bundles that is needed by aggregated api servers ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("extension-apiserver-authentication-reader") - namespace: kube-system - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: Role - name: extension-apiserver-authentication-reader - apiGroup: rbac.authorization.k8s.io - -#! Give permission to list and watch ConfigMaps in kube-public ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") - namespace: kube-public - labels: #@ labels() -rules: - - apiGroups: [ "" ] - resources: [ configmaps ] - verbs: [ list, watch ] ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") - namespace: kube-public - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: Role - name: #@ defaultResourceNameWithSuffix("cluster-info-lister-watcher") - apiGroup: rbac.authorization.k8s.io diff --git a/deploy_carvel/concierge/config/values.yaml b/deploy_carvel/concierge/config/values.yaml deleted file mode 100644 index 32306740..00000000 --- a/deploy_carvel/concierge/config/values.yaml +++ /dev/null @@ -1,137 +0,0 @@ -#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@data/values-schema ---- -#@schema/desc "Name of pinniped-concierge." -app_name: pinniped-concierge - -#@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." -namespace: pinniped-concierge -#@ into_namespace_desc = "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." -#@schema/desc into_namespace_desc -#@schema/nullable -into_namespace: my-preexisting-namespace - -#@ custom_labels_desc = "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 value of `custom_labels` must be a map of string keys to string values. \ -#@ 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." -#@schema/desc custom_labels_desc -#@schema/type any=True -custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} - -#@schema/desc "Specify how many replicas of the Pinniped server to run." -replicas: 2 - -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -image_repo: projects.registry.vmware.com/pinniped/pinniped-server -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -#@schema/nullable -image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -image_tag: latest - -#@ kube_cert_agent_image = "Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled \ -#@ on the control plane. This image needs only to include `sleep` and `cat` binaries. \ -#@ By default, the same image specified for image_repo/image_digest/image_tag will be re-used." -#@schema/desc kube_cert_agent_image -#@schema/nullable -kube_cert_agent_image: projects.registry.vmware.com/pinniped/pinniped-server - -#@ image_pull_dockerconfigjson_desc = "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." -#@schema/desc image_pull_dockerconfigjson_desc -#@schema/nullable -image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} - -#@schema/desc "Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden." -#@schema/nullable -discovery_url: https://example.com - - -#@ api_serving_certificate_desc = "Specify the duration and renewal interval for the API serving certificate. \ -#@ The defaults are set to expire the cert about every 30 days, and to rotate it \ -#@ about every 25 days." -#@schema/desc api_serving_certificate_desc -api_serving_certificate_duration_seconds: 2592000 -#@schema/desc api_serving_certificate_desc -api_serving_certificate_renew_before_seconds: 2160000 - -#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information), -#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged. -#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." -#@schema/nullable -log_level: info -#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ -#@ By default, when this value is left unset, logs are formatted in json. \ -#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." -#@schema/desc deprecated_log_format_desc -#@schema/nullable -deprecated_log_format: json - -#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" -run_as_user: 65532 -#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" -run_as_group: 65532 - -#@ api_group_suffix_desc = "Specify the API group suffix for all Pinniped API groups. By default, this is set to \ -#@ pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, \ -#@ authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then \ -#@ Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc." -#@schema/desc api_group_suffix_desc -api_group_suffix: pinniped.dev - - -#@schema/desc "Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation." -impersonation_proxy_spec: - #! options are "auto", "disabled" or "enabled". - #! If auto, the impersonation proxy will run only if the cluster signing key is not available - #! and the other strategy does not work. - #! If disabled, the impersonation proxy will never run, which could mean that the concierge - #! doesn't work at all. - #! If enabled, the impersonation proxy will always run regardless of other strategies available. - #@schema/desc "If enabled, the impersonation proxy will always run regardless of other strategies available." - mode: auto - #@ external_endpoint_desc = "The endpoint which the client should use to connect to the impersonation proxy. \ - #@ If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint." - #@schema/desc external_endpoint_desc - #@schema/nullable - external_endpoint: 1.2.3.4:5678 - #@schema/desc "The impersonation proxy service configuration" - service: - #! Options are "LoadBalancer", "ClusterIP" and "None". - #! LoadBalancer automatically provisions a Service of type LoadBalancer pointing at - #! the impersonation proxy. Some cloud providers will allocate - #! a public IP address by default even on private clusters. - #! ClusterIP automatically provisions a Service of type ClusterIP pointing at the - #! impersonation proxy. - #! None does not provision either and assumes that you have set the external_endpoint - #! and set up your own ingress to connect to the impersonation proxy. - #@schema/desc "Options are 'LoadBalancer', 'ClusterIP' and 'None'." - #@schema/nullable - type: LoadBalancer - #@schema/desc "The annotations that should be set on the ClusterIP or LoadBalancer Service." - #@schema/nullable - annotations: - {service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"} - #@schema/desc "When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP." - #@schema/nullable - load_balancer_ip: 1.2.3.4:5678 - -#@ https_proxy_desc = "Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. \ -#@ These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, \ -#@ e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. \ -#@ The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. \ -#@ Optional." -#@schema/desc https_proxy_desc -#@schema/nullable -https_proxy: http://proxy.example.com -#@schema/desc "do not proxy Kubernetes endpoints" -no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints diff --git a/deploy_carvel/concierge/config/z0_crd_overlay.yaml b/deploy_carvel/concierge/config/z0_crd_overlay.yaml deleted file mode 100644 index 935d5f8c..00000000 --- a/deploy_carvel/concierge/config/z0_crd_overlay.yaml +++ /dev/null @@ -1,33 +0,0 @@ -#! Copyright 2020-2021 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:overlay", "overlay") -#@ load("helpers.lib.yaml", "labels", "pinnipedDevAPIGroupWithPrefix") -#@ load("@ytt:data", "data") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"credentialissuers.config.concierge.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("credentialissuers.config.concierge") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("config.concierge") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"webhookauthenticators.authentication.concierge.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("webhookauthenticators.authentication.concierge") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"jwtauthenticators.authentication.concierge.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("jwtauthenticators.authentication.concierge") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("authentication.concierge") diff --git a/deploy_carvel/concierge/vendir.lock.yml b/deploy_carvel/concierge/vendir.lock.yml new file mode 100644 index 00000000..34a854bb --- /dev/null +++ b/deploy_carvel/concierge/vendir.lock.yml @@ -0,0 +1,7 @@ +apiVersion: vendir.k14s.io/v1alpha1 +directories: +- contents: + - directory: {} + path: . + path: config +kind: LockConfig diff --git a/deploy_carvel/concierge/vendir.yml b/deploy_carvel/concierge/vendir.yml new file mode 100644 index 00000000..0408ed49 --- /dev/null +++ b/deploy_carvel/concierge/vendir.yml @@ -0,0 +1,8 @@ +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: config + contents: + - path: . + directory: + path: ../../deploy/concierge diff --git a/deploy_carvel/local-user-authenticator/.gitignore b/deploy_carvel/local-user-authenticator/.gitignore new file mode 100644 index 00000000..f733c4b5 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/.gitignore @@ -0,0 +1 @@ +config/ diff --git a/deploy_carvel/local-user-authenticator/config/README.md b/deploy_carvel/local-user-authenticator/config/README.md deleted file mode 100644 index dd54de39..00000000 --- a/deploy_carvel/local-user-authenticator/config/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# Deploying local-user-authenticator - -## What is local-user-authenticator? - -The local-user-authenticator app is an identity provider used for integration testing and demos. -If you would like to demo Pinniped, but you don't have a compatible identity provider handy, -you can use Pinniped's local-user-authenticator identity provider. Note that this is not recommended for -production use. - -The local-user-authenticator is a Kubernetes Deployment which runs a webhook server that implements the Kubernetes -[Webhook Token Authentication interface](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#webhook-token-authentication). - -User accounts can be created and edited dynamically using `kubectl` commands (see below). - -## Installing the Latest Version with Default Options - -```bash -kubectl apply -f https://get.pinniped.dev/latest/install-local-user-authenticator.yaml -``` - -## Installing a Specific Version with Default Options - -Choose your preferred [release](https://github.com/vmware-tanzu/pinniped/releases) version number -and use it to replace the version number in the URL below. - -```bash -# Replace v0.4.1 with your preferred version in the URL below -kubectl apply -f https://get.pinniped.dev/v0.4.1/install-local-user-authenticator.yaml -``` - -## Installing with Custom Options - -Creating your own deployment YAML file requires `ytt` from [Carvel](https://carvel.dev/) to template the YAML files -in the `deploy/local-user-authenticator` directory. -Either [install `ytt`](https://get-ytt.io/) or use the [container image from Dockerhub](https://hub.docker.com/r/k14s/image/tags). - -1. `git clone` this repo and `git checkout` the release version tag of the release that you would like to deploy. -1. The configuration options are in [deploy/local-user-authenticator/values.yml](values.yaml). - Fill in the values in that file, or override those values using additional `ytt` command-line options in - the command below. Use the release version tag as the `image_tag` value. -2. In a terminal, cd to this `deploy/local-user-authenticator` directory -3. To generate the final YAML files, run `ytt --file .` -4. Deploy the generated YAML using your preferred deployment tool, such as `kubectl` or [`kapp`](https://get-kapp.io/). - For example: `ytt --file . | kapp deploy --yes --app local-user-authenticator --diff-changes --file -` - -## Configuring After Installing - -### Create Users - -Use `kubectl` to create, edit, and delete user accounts by creating a `Secret` for each user account in the same -namespace where local-user-authenticator is deployed. The name of the `Secret` resource is the username. -Store the user's group membership and `bcrypt` encrypted password as the contents of the `Secret`. -For example, to create a user named `pinny-the-seal` with the password `password123` -who belongs to the groups `group1` and `group2`, use: - -```bash -kubectl create secret generic pinny-the-seal \ - --namespace local-user-authenticator \ - --from-literal=groups=group1,group2 \ - --from-literal=passwordHash=$(htpasswd -nbBC 10 x password123 | sed -e "s/^x://") -``` - -Note that the above command requires a tool capable of generating a `bcrypt` hash. It uses `htpasswd`, -which is installed on most macOS systems, and can be -installed on some Linux systems via the `apache2-utils` package (e.g., `apt-get install apache2-utils`). - -### Get the local-user-authenticator App's Auto-Generated Certificate Authority Bundle - -Fetch the auto-generated CA bundle for the local-user-authenticator's HTTP TLS endpoint. - -```bash -kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \ - -o jsonpath={.data.caCertificate} \ - | base64 -d \ - | tee /tmp/local-user-authenticator-ca -``` - -### Configuring Pinniped to Use local-user-authenticator as an Identity Provider - -When installing Pinniped on the same cluster, configure local-user-authenticator as an Identity Provider for Pinniped -using the webhook URL `https://local-user-authenticator.local-user-authenticator.svc/authenticate` -along with the CA bundle fetched by the above command. See [demo](https://pinniped.dev/docs/demo/) for an example. - -## Optional: Manually Testing the Webhook Endpoint After Installing - -The following steps demonstrate the API of the local-user-authenticator app. Typically, a user would not need to -interact with this API directly. Pinniped will automatically integrate with this API if the local-user-authenticator -is configured as an identity provider for Pinniped. - - 1. Start a pod from which you can curl the endpoint from inside the cluster. - - ```bash - kubectl run curlpod --image=curlimages/curl --command -- /bin/sh -c "while true; do echo hi; sleep 120; done" - ``` - - 1. Copy the CA bundle that was fetched above onto the new pod. - - ```bash - kubectl cp /tmp/local-user-authenticator-ca curlpod:/tmp/local-user-authenticator-ca - ``` - - 1. Run a `curl` command to try to authenticate as the user created above. - - ```bash - kubectl -it exec curlpod -- curl https://local-user-authenticator.local-user-authenticator.svc/authenticate \ - --cacert /tmp/local-user-authenticator-ca \ - -H 'Content-Type: application/json' -H 'Accept: application/json' -d ' - { - "apiVersion": "authentication.k8s.io/v1beta1", - "kind": "TokenReview", - "spec": { - "token": "pinny-the-seal:password123" - } - }' - ``` - - When authentication is successful the above command should return some JSON similar to the following. - Note that the value of `authenticated` is `true` to indicate a successful authentication. - - ```json - { - "kind": "TokenReview", - "apiVersion": "authentication.k8s.io/v1beta1", - "metadata": { - "creationTimestamp": null - }, - "spec": {}, - "status": { - "authenticated": true, - "user": { - "username": "pinny-the-seal", - "uid": "19c433ec-8f58-44ca-9ef0-2d1081ccb876", - "groups": [ - "group1", - "group2" - ] - } - } - } - ``` - - Trying the above `curl` command again with the wrong username or password in the body of the request - should result in a JSON response which indicates that the authentication failed. - - ```json - { - "kind": "TokenReview", - "apiVersion": "authentication.k8s.io/v1beta1", - "metadata": { - "creationTimestamp": null - }, - "spec": {}, - "status": { - "user": {} - } - } - ``` - - 1. Remove the curl pod. - - ```bash - kubectl delete pod curlpod - ``` diff --git a/deploy_carvel/local-user-authenticator/config/deployment.yaml b/deploy_carvel/local-user-authenticator/config/deployment.yaml deleted file mode 100644 index 5098422a..00000000 --- a/deploy_carvel/local-user-authenticator/config/deployment.yaml +++ /dev/null @@ -1,97 +0,0 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:data", "data") - ---- -apiVersion: v1 -kind: Namespace -metadata: - name: local-user-authenticator - labels: - name: local-user-authenticator ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: local-user-authenticator - namespace: local-user-authenticator ---- -#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": -apiVersion: v1 -kind: Secret -metadata: - name: image-pull-secret - namespace: local-user-authenticator - labels: - app: local-user-authenticator -type: kubernetes.io/dockerconfigjson -data: - .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson -#@ end ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: local-user-authenticator - namespace: local-user-authenticator - labels: - app: local-user-authenticator -spec: - replicas: 1 - selector: - matchLabels: - app: local-user-authenticator - template: - metadata: - labels: - app: local-user-authenticator - spec: - securityContext: - runAsUser: #@ data.values.run_as_user - runAsGroup: #@ data.values.run_as_group - serviceAccountName: local-user-authenticator - #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": - imagePullSecrets: - - name: image-pull-secret - #@ end - containers: - - name: local-user-authenticator - #@ if data.values.image_digest: - image: #@ data.values.image_repo + "@" + data.values.image_digest - #@ else: - image: #@ data.values.image_repo + ":" + data.values.image_tag - #@ end - imagePullPolicy: IfNotPresent - command: - - local-user-authenticator - securityContext: - readOnlyRootFilesystem: true - runAsNonRoot: true - allowPrivilegeEscalation: false - capabilities: - drop: [ "ALL" ] - #! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a - #! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's - #! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error. - seccompProfile: - type: "RuntimeDefault" ---- -apiVersion: v1 -kind: Service -metadata: - name: local-user-authenticator - namespace: local-user-authenticator - labels: - app: local-user-authenticator - #! prevent kapp from altering the selector of our services to match kubectl behavior - annotations: - kapp.k14s.io/disable-default-label-scoping-rules: "" -spec: - type: ClusterIP - selector: - app: local-user-authenticator - ports: - - protocol: TCP - port: 443 - targetPort: 8443 diff --git a/deploy_carvel/local-user-authenticator/config/rbac.yaml b/deploy_carvel/local-user-authenticator/config/rbac.yaml deleted file mode 100644 index a32d757d..00000000 --- a/deploy_carvel/local-user-authenticator/config/rbac.yaml +++ /dev/null @@ -1,30 +0,0 @@ -#! Copyright 2020 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:data", "data") - -#! Give permission to various objects within the app's own namespace ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: local-user-authenticator - namespace: local-user-authenticator -rules: - - apiGroups: [""] - resources: [secrets] - verbs: [create, get, list, patch, update, watch] ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: local-user-authenticator - namespace: local-user-authenticator -subjects: - - kind: ServiceAccount - name: local-user-authenticator - namespace: local-user-authenticator -roleRef: - kind: Role - name: local-user-authenticator - apiGroup: rbac.authorization.k8s.io diff --git a/deploy_carvel/local-user-authenticator/config/values.yaml b/deploy_carvel/local-user-authenticator/config/values.yaml deleted file mode 100644 index c0591304..00000000 --- a/deploy_carvel/local-user-authenticator/config/values.yaml +++ /dev/null @@ -1,26 +0,0 @@ -#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@data/values-schema ---- - -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -image_repo: projects.registry.vmware.com/pinniped/pinniped-server -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -#@schema/nullable -image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -image_tag: latest - -#@ image_pull_dockerconfigjson_desc = "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." -#@schema/desc image_pull_dockerconfigjson_desc -#@schema/nullable -image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} - -#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" -run_as_user: 65532 -#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" -run_as_group: 65532 diff --git a/deploy_carvel/local-user-authenticator/vendir.lock.yml b/deploy_carvel/local-user-authenticator/vendir.lock.yml new file mode 100644 index 00000000..34a854bb --- /dev/null +++ b/deploy_carvel/local-user-authenticator/vendir.lock.yml @@ -0,0 +1,7 @@ +apiVersion: vendir.k14s.io/v1alpha1 +directories: +- contents: + - directory: {} + path: . + path: config +kind: LockConfig diff --git a/deploy_carvel/local-user-authenticator/vendir.yml b/deploy_carvel/local-user-authenticator/vendir.yml new file mode 100644 index 00000000..e264b518 --- /dev/null +++ b/deploy_carvel/local-user-authenticator/vendir.yml @@ -0,0 +1,8 @@ +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: config + contents: + - path: . + directory: + path: ../../deploy/local-user-authenticator diff --git a/deploy_carvel/supervisor/.gitignore b/deploy_carvel/supervisor/.gitignore new file mode 100644 index 00000000..f733c4b5 --- /dev/null +++ b/deploy_carvel/supervisor/.gitignore @@ -0,0 +1 @@ +config/ diff --git a/deploy_carvel/supervisor/config/README.md b/deploy_carvel/supervisor/config/README.md deleted file mode 100644 index 04d84b81..00000000 --- a/deploy_carvel/supervisor/config/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Pinniped Supervisor Deployment - -See [the how-to guide for details](https://pinniped.dev/docs/howto/install-supervisor/). diff --git a/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml b/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml deleted file mode 100644 index 6f50730c..00000000 --- a/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_federationdomains.yaml +++ /dev/null @@ -1,488 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: federationdomains.config.supervisor.pinniped.dev -spec: - group: config.supervisor.pinniped.dev - names: - categories: - - pinniped - kind: FederationDomain - listKind: FederationDomainList - plural: federationdomains - singular: federationdomain - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.issuer - name: Issuer - type: string - - jsonPath: .status.phase - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: FederationDomain describes the configuration of an OIDC provider. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec of the OIDC provider. - properties: - identityProviders: - description: "IdentityProviders is the list of identity providers - available for use by this FederationDomain. \n An identity provider - CR (e.g. OIDCIdentityProvider or LDAPIdentityProvider) describes - how to connect to a server, how to talk in a specific protocol for - authentication, and how to use the schema of that server/protocol - to extract a normalized user identity. Normalized user identities - include a username and a list of group names. In contrast, IdentityProviders - describes how to use that normalized identity in those Kubernetes - clusters which belong to this FederationDomain. Each entry in IdentityProviders - can be configured with arbitrary transformations on that normalized - identity. For example, a transformation can add a prefix to all - usernames to help avoid accidental conflicts when multiple identity - providers have different users with the same username (e.g. \"idp1:ryan\" - versus \"idp2:ryan\"). Each entry in IdentityProviders can also - implement arbitrary authentication rejection policies. Even though - a user was able to authenticate with the identity provider, a policy - can disallow the authentication to the Kubernetes clusters that - belong to this FederationDomain. For example, a policy could disallow - the authentication unless the user belongs to a specific group in - the identity provider. \n For backwards compatibility with versions - of Pinniped which predate support for multiple identity providers, - an empty IdentityProviders list will cause the FederationDomain - to use all available identity providers which exist in the same - namespace, but also to reject all authentication requests when there - is more than one identity provider currently defined. In this backwards - compatibility mode, the name of the identity provider resource (e.g. - the Name of an OIDCIdentityProvider resource) will be used as the - name of the identity provider in this FederationDomain. This mode - is provided to make upgrading from older versions easier. However, - instead of relying on this backwards compatibility mode, please - consider this mode to be deprecated and please instead explicitly - list the identity provider using this IdentityProviders field." - items: - description: FederationDomainIdentityProvider describes how an identity - provider is made available in this FederationDomain. - properties: - displayName: - description: DisplayName is the name of this identity provider - as it will appear to clients. This name ends up in the kubeconfig - of end users, so changing the name of an identity provider - that is in use by end users will be a disruptive change for - those users. - minLength: 1 - type: string - objectRef: - description: ObjectRef is a reference to a Pinniped identity - provider resource. A valid reference is required. If the reference - cannot be resolved then the identity provider will not be - made available. Must refer to a resource of one of the Pinniped - identity provider types, e.g. OIDCIdentityProvider, LDAPIdentityProvider, - ActiveDirectoryIdentityProvider. - properties: - apiGroup: - description: APIGroup is the group for the resource being - referenced. If APIGroup is not specified, the specified - Kind must be in the core API group. For any other third-party - types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - transforms: - description: Transforms is an optional way to specify transformations - to be applied during user authentication and session refresh. - properties: - constants: - description: Constants defines constant variables and their - values which will be made available to the transform expressions. - items: - description: FederationDomainTransformsConstant defines - a constant variable and its value which will be made - available to the transform expressions. This is a union - type, and Type is the discriminator field. - properties: - name: - description: Name determines the name of the constant. - It must be a valid identifier name. - maxLength: 64 - minLength: 1 - pattern: ^[a-zA-Z][_a-zA-Z0-9]*$ - type: string - stringListValue: - description: StringListValue should hold the value - when Type is "stringList", and is otherwise ignored. - items: - type: string - type: array - stringValue: - description: StringValue should hold the value when - Type is "string", and is otherwise ignored. - type: string - type: - description: Type determines the type of the constant, - and indicates which other field should be non-empty. - enum: - - string - - stringList - type: string - required: - - name - - type - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - examples: - description: Examples can optionally be used to ensure that - the sequence of transformation expressions are working - as expected. Examples define sample input identities which - are then run through the expression list, and the results - are compared to the expected results. If any example in - this list fails, then this identity provider will not - be available for use within this FederationDomain, and - the error(s) will be added to the FederationDomain status. - This can be used to help guard against programming mistakes - in the expressions, and also act as living documentation - for other administrators to better understand the expressions. - items: - description: FederationDomainTransformsExample defines - a transform example. - properties: - expects: - description: Expects is the expected output of the - entire sequence of transforms when they are run - against the input Username and Groups. - properties: - groups: - description: Groups is the expected list of group - names after the transformations have been applied. - items: - type: string - type: array - message: - description: Message is the expected error message - of the transforms. When Rejected is true, then - Message is the expected message for the policy - which rejected the authentication attempt. When - Rejected is true and Message is blank, then - Message will be treated as the default error - message for authentication attempts which are - rejected by a policy. When Rejected is false, - then Message is the expected error message for - some other non-policy transformation error, - such as a runtime error. When Rejected is false, - there is no default expected Message. - type: string - rejected: - description: Rejected is a boolean that indicates - whether authentication is expected to be rejected - by a policy expression after the transformations - have been applied. True means that it is expected - that the authentication would be rejected. The - default value of false means that it is expected - that the authentication would not be rejected - by any policy expression. - type: boolean - username: - description: Username is the expected username - after the transformations have been applied. - type: string - type: object - groups: - description: Groups is the input list of group names. - items: - type: string - type: array - username: - description: Username is the input username. - minLength: 1 - type: string - required: - - expects - - username - type: object - type: array - expressions: - description: "Expressions are an optional list of transforms - and policies to be executed in the order given during - every authentication attempt, including during every session - refresh. Each is a CEL expression. It may use the basic - CEL language as defined in https://github.com/google/cel-spec/blob/master/doc/langdef.md - plus the CEL string extensions defined in https://github.com/google/cel-go/tree/master/ext#strings. - \n The username and groups extracted from the identity - provider, and the constants defined in this CR, are available - as variables in all expressions. The username is provided - via a variable called `username` and the list of group - names is provided via a variable called `groups` (which - may be an empty list). Each user-provided constants is - provided via a variable named `strConst.varName` for string - constants and `strListConst.varName` for string list constants. - \n The only allowed types for expressions are currently - policy/v1, username/v1, and groups/v1. Each policy/v1 - must return a boolean, and when it returns false, no more - expressions from the list are evaluated and the authentication - attempt is rejected. Transformations of type policy/v1 - do not return usernames or group names, and therefore - cannot change the username or group names. Each username/v1 - transform must return the new username (a string), which - can be the same as the old username. Transformations of - type username/v1 do not return group names, and therefore - cannot change the group names. Each groups/v1 transform - must return the new groups list (list of strings), which - can be the same as the old groups list. Transformations - of type groups/v1 do not return usernames, and therefore - cannot change the usernames. After each expression, the - new (potentially changed) username or groups get passed - to the following expression. \n Any compilation or static - type-checking failure of any expression will cause an - error status on the FederationDomain. During an authentication - attempt, any unexpected runtime evaluation errors (e.g. - division by zero) cause the authentication attempt to - fail. When all expressions evaluate successfully, then - the (potentially changed) username and group names have - been decided for that authentication attempt." - items: - description: FederationDomainTransformsExpression defines - a transform expression. - properties: - expression: - description: Expression is a CEL expression that will - be evaluated based on the Type during an authentication. - minLength: 1 - type: string - message: - description: Message is only used when Type is policy/v1. - It defines an error message to be used when the - policy rejects an authentication attempt. When empty, - a default message will be used. - type: string - type: - description: Type determines the type of the expression. - It must be one of the supported types. - enum: - - policy/v1 - - username/v1 - - groups/v1 - type: string - required: - - expression - - type - type: object - type: array - type: object - required: - - displayName - - objectRef - type: object - type: array - issuer: - description: "Issuer is the OIDC Provider's issuer, per the OIDC Discovery - Metadata document, as well as the identifier that it will use for - the iss claim in issued JWTs. This field will also be used as the - base URL for any endpoints used by the OIDC Provider (e.g., if your - issuer is https://example.com/foo, then your authorization endpoint - will look like https://example.com/foo/some/path/to/auth/endpoint). - \n See https://openid.net/specs/openid-connect-discovery-1_0.html#rfc.section.3 - for more information." - minLength: 1 - type: string - tls: - description: TLS specifies a secret which will contain Transport Layer - Security (TLS) configuration for the FederationDomain. - properties: - secretName: - description: "SecretName is an optional name of a Secret in the - same namespace, of type `kubernetes.io/tls`, which contains - the TLS serving certificate for the HTTPS endpoints served by - this FederationDomain. When provided, the TLS Secret named here - must contain keys named `tls.crt` and `tls.key` that contain - the certificate and private key to use for TLS. \n Server Name - Indication (SNI) is an extension to the Transport Layer Security - (TLS) supported by all major browsers. \n SecretName is required - if you would like to use different TLS certificates for issuers - of different hostnames. SNI requests do not include port numbers, - so all issuers with the same DNS hostname must use the same - SecretName value even if they have different port numbers. \n - SecretName is not required when you would like to use only the - HTTP endpoints (e.g. when the HTTP listener is configured to - listen on loopback interfaces or UNIX domain sockets for traffic - from a service mesh sidecar). It is also not required when you - would like all requests to this OIDC Provider's HTTPS endpoints - to use the default TLS certificate, which is configured elsewhere. - \n When your Issuer URL's host is an IP address, then this field - is ignored. SNI does not work for IP addresses." - type: string - type: object - required: - - issuer - type: object - status: - description: Status of the OIDC provider. - properties: - conditions: - description: Conditions represent the observations of an FederationDomain's - current state. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - phase: - default: Pending - description: Phase summarizes the overall status of the FederationDomain. - enum: - - Pending - - Ready - - Error - type: string - secrets: - description: Secrets contains information about this OIDC Provider's - secrets. - properties: - jwks: - description: JWKS holds the name of the corev1.Secret in which - this OIDC Provider's signing/verification keys are stored. If - it is empty, then the signing/verification keys are either unknown - or they don't exist. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - stateEncryptionKey: - description: StateSigningKey holds the name of the corev1.Secret - in which this OIDC Provider's key for encrypting state parameters - is stored. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - stateSigningKey: - description: StateSigningKey holds the name of the corev1.Secret - in which this OIDC Provider's key for signing state parameters - is stored. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - tokenSigningKey: - description: TokenSigningKey holds the name of the corev1.Secret - in which this OIDC Provider's key for signing tokens is stored. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - type: object - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml b/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml deleted file mode 100644 index c61c4b15..00000000 --- a/deploy_carvel/supervisor/config/config.supervisor.pinniped.dev_oidcclients.yaml +++ /dev/null @@ -1,220 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: oidcclients.config.supervisor.pinniped.dev -spec: - group: config.supervisor.pinniped.dev - names: - categories: - - pinniped - kind: OIDCClient - listKind: OIDCClientList - plural: oidcclients - singular: oidcclient - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.allowedScopes[?(@ == "pinniped:request-audience")] - name: Privileged Scopes - type: string - - jsonPath: .status.totalClientSecrets - name: Client Secrets - type: integer - - jsonPath: .status.phase - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: OIDCClient describes the configuration of an OIDC client. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec of the OIDC client. - properties: - allowedGrantTypes: - description: "allowedGrantTypes is a list of the allowed grant_type - param values that should be accepted during OIDC flows with this - client. \n Must only contain the following values: - authorization_code: - allows the client to perform the authorization code grant flow, - i.e. allows the webapp to authenticate users. This grant must always - be listed. - refresh_token: allows the client to perform refresh - grants for the user to extend the user's session. This grant must - be listed if allowedScopes lists offline_access. - urn:ietf:params:oauth:grant-type:token-exchange: - allows the client to perform RFC8693 token exchange, which is a - step in the process to be able to get a cluster credential for the - user. This grant must be listed if allowedScopes lists pinniped:request-audience." - items: - enum: - - authorization_code - - refresh_token - - urn:ietf:params:oauth:grant-type:token-exchange - type: string - minItems: 1 - type: array - x-kubernetes-list-type: set - allowedRedirectURIs: - description: allowedRedirectURIs is a list of the allowed redirect_uri - param values that should be accepted during OIDC flows with this - client. Any other uris will be rejected. Must be a URI with the - https scheme, unless the hostname is 127.0.0.1 or ::1 which may - use the http scheme. Port numbers are not required for 127.0.0.1 - or ::1 and are ignored when checking for a matching redirect_uri. - items: - pattern: ^https://.+|^http://(127\.0\.0\.1|\[::1\])(:\d+)?/ - type: string - minItems: 1 - type: array - x-kubernetes-list-type: set - allowedScopes: - description: "allowedScopes is a list of the allowed scopes param - values that should be accepted during OIDC flows with this client. - \n Must only contain the following values: - openid: The client - is allowed to request ID tokens. ID tokens only include the required - claims by default (iss, sub, aud, exp, iat). This scope must always - be listed. - offline_access: The client is allowed to request an - initial refresh token during the authorization code grant flow. - This scope must be listed if allowedGrantTypes lists refresh_token. - - pinniped:request-audience: The client is allowed to request a - new audience value during a RFC8693 token exchange, which is a step - in the process to be able to get a cluster credential for the user. - openid, username and groups scopes must be listed when this scope - is present. This scope must be listed if allowedGrantTypes lists - urn:ietf:params:oauth:grant-type:token-exchange. - username: The - client is allowed to request that ID tokens contain the user's username. - Without the username scope being requested and allowed, the ID token - will not contain the user's username. - groups: The client is allowed - to request that ID tokens contain the user's group membership, if - their group membership is discoverable by the Supervisor. Without - the groups scope being requested and allowed, the ID token will - not contain groups." - items: - enum: - - openid - - offline_access - - username - - groups - - pinniped:request-audience - type: string - minItems: 1 - type: array - x-kubernetes-list-type: set - required: - - allowedGrantTypes - - allowedRedirectURIs - - allowedScopes - type: object - status: - description: Status of the OIDC client. - properties: - conditions: - description: conditions represent the observations of an OIDCClient's - current state. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - phase: - default: Pending - description: phase summarizes the overall status of the OIDCClient. - enum: - - Pending - - Ready - - Error - type: string - totalClientSecrets: - description: totalClientSecrets is the current number of client secrets - that are detected for this OIDCClient. - format: int32 - type: integer - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/supervisor/config/deployment.yaml b/deploy_carvel/supervisor/config/deployment.yaml deleted file mode 100644 index 30791a1b..00000000 --- a/deploy_carvel/supervisor/config/deployment.yaml +++ /dev/null @@ -1,236 +0,0 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:data", "data") -#@ load("@ytt:yaml", "yaml") -#@ load("helpers.lib.yaml", -#@ "defaultLabel", -#@ "labels", -#@ "deploymentPodLabel", -#@ "namespace", -#@ "defaultResourceName", -#@ "defaultResourceNameWithSuffix", -#@ "pinnipedDevAPIGroupWithPrefix", -#@ "getPinnipedConfigMapData", -#@ "hasUnixNetworkEndpoint", -#@ ) -#@ load("@ytt:template", "template") - -#@ if not data.values.into_namespace: ---- -apiVersion: v1 -kind: Namespace -metadata: - name: #@ data.values.namespace - labels: #@ labels() -#@ end ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: #@ defaultResourceName() - namespace: #@ namespace() - labels: #@ labels() ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: #@ defaultResourceNameWithSuffix("static-config") - namespace: #@ namespace() - labels: #@ labels() -data: - #@yaml/text-templated-strings - pinniped.yaml: #@ yaml.encode(getPinnipedConfigMapData()) ---- -#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": -apiVersion: v1 -kind: Secret -metadata: - name: image-pull-secret - namespace: #@ namespace() - labels: #@ labels() -type: kubernetes.io/dockerconfigjson -data: - .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson -#@ end ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: #@ defaultResourceName() - namespace: #@ namespace() - labels: #@ labels() -spec: - replicas: #@ data.values.replicas - selector: - #! In hindsight, this should have been deploymentPodLabel(), but this field is immutable so changing it would break upgrades. - matchLabels: #@ defaultLabel() - template: - metadata: - labels: - #! This has always included defaultLabel(), which is used by this Deployment's selector. - _: #@ template.replace(defaultLabel()) - #! More recently added the more unique deploymentPodLabel() so Services can select these Pods more specifically - #! without accidentally selecting pods from any future Deployments which might also want to use the defaultLabel(). - _: #@ template.replace(deploymentPodLabel()) - spec: - securityContext: - runAsUser: #@ data.values.run_as_user - runAsGroup: #@ data.values.run_as_group - serviceAccountName: #@ defaultResourceName() - #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": - imagePullSecrets: - - name: image-pull-secret - #@ end - containers: - - name: #@ defaultResourceName() - #@ if data.values.image_digest: - image: #@ data.values.image_repo + "@" + data.values.image_digest - #@ else: - image: #@ data.values.image_repo + ":" + data.values.image_tag - #@ end - imagePullPolicy: IfNotPresent - command: - - pinniped-supervisor - - /etc/podinfo - - /etc/config/pinniped.yaml - securityContext: - readOnlyRootFilesystem: true - runAsNonRoot: true - allowPrivilegeEscalation: false - capabilities: - drop: [ "ALL" ] - #! seccompProfile was introduced in Kube v1.19. Using it on an older Kube version will result in a - #! kubectl validation error when installing via `kubectl apply`, which can be ignored using kubectl's - #! `--validate=false` flag. Note that installing via `kapp` does not complain about this validation error. - seccompProfile: - type: "RuntimeDefault" - resources: - requests: - #! If OIDCClient CRs are being used, then the Supervisor needs enough CPU to run expensive bcrypt - #! operations inside the implementation of the token endpoint for any authcode flows performed by those - #! clients, so for that use case administrators may wish to increase the requests.cpu value to more - #! closely align with their anticipated needs. Increasing this value will cause Kubernetes to give more - #! available CPU to this process during times of high CPU contention. By default, don't ask for too much - #! because that would make it impossible to install the Pinniped Supervisor on small clusters. - #! Aside from performing bcrypts at the token endpoint for those clients, the Supervisor is not a - #! particularly CPU-intensive process. - cpu: "100m" #! by default, request one-tenth of a CPU - memory: "128Mi" - limits: - #! By declaring a CPU limit that is not equal to the CPU request value, the Supervisor will be classified - #! by Kubernetes to have "burstable" quality of service. - #! See https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-burstable - #! If OIDCClient CRs are being used, and lots of simultaneous users have active sessions, then it is hard - #! pre-determine what the CPU limit should be for that use case. Guessing too low would cause the - #! pod's CPU usage to be throttled, resulting in poor performance. Guessing too high would allow clients - #! to cause the usage of lots of CPU resources. Administrators who have a good sense of anticipated usage - #! patterns may choose to set the requests.cpu and limits.cpu differently from these defaults. - cpu: "1000m" #! by default, throttle each pod's usage at 1 CPU - memory: "128Mi" - volumeMounts: - - name: config-volume - mountPath: /etc/config - readOnly: true - - name: podinfo - mountPath: /etc/podinfo - readOnly: true - #@ if hasUnixNetworkEndpoint(): - - name: socket - mountPath: /pinniped_socket - readOnly: false #! writable to allow for socket use - #@ end - ports: - - containerPort: 8443 - protocol: TCP - env: - #@ if data.values.https_proxy: - - name: HTTPS_PROXY - value: #@ data.values.https_proxy - #@ end - #@ if data.values.https_proxy and data.values.no_proxy: - - name: NO_PROXY - value: #@ data.values.no_proxy - #@ end - livenessProbe: - httpGet: - path: /healthz - port: 8443 - scheme: HTTPS - initialDelaySeconds: 2 - timeoutSeconds: 15 - periodSeconds: 10 - failureThreshold: 5 - readinessProbe: - httpGet: - path: /healthz - port: 8443 - scheme: HTTPS - initialDelaySeconds: 2 - timeoutSeconds: 3 - periodSeconds: 10 - failureThreshold: 3 - volumes: - - name: config-volume - configMap: - name: #@ defaultResourceNameWithSuffix("static-config") - - name: podinfo - downwardAPI: - items: - - path: "labels" - fieldRef: - fieldPath: metadata.labels - - path: "namespace" - fieldRef: - fieldPath: metadata.namespace - - path: "name" - fieldRef: - fieldPath: metadata.name - #@ if hasUnixNetworkEndpoint(): - - name: socket - emptyDir: {} - #@ end - #! This will help make sure our multiple pods run on different nodes, making - #! our deployment "more" "HA". - affinity: - podAntiAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 50 - podAffinityTerm: - labelSelector: - matchLabels: #@ deploymentPodLabel() - 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: #@ defaultResourceNameWithSuffix("api") - namespace: #@ namespace() - labels: #@ labels() - #! prevent kapp from altering the selector of our services to match kubectl behavior - annotations: - kapp.k14s.io/disable-default-label-scoping-rules: "" -spec: - type: ClusterIP - selector: #@ deploymentPodLabel() - ports: - - protocol: TCP - port: 443 - targetPort: 10250 ---- -apiVersion: apiregistration.k8s.io/v1 -kind: APIService -metadata: - name: #@ pinnipedDevAPIGroupWithPrefix("v1alpha1.clientsecret.supervisor") - labels: #@ labels() -spec: - version: v1alpha1 - group: #@ pinnipedDevAPIGroupWithPrefix("clientsecret.supervisor") - groupPriorityMinimum: 9900 - versionPriority: 15 - #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code. - service: - name: #@ defaultResourceNameWithSuffix("api") - namespace: #@ namespace() - port: 443 diff --git a/deploy_carvel/supervisor/config/helpers.lib.yaml b/deploy_carvel/supervisor/config/helpers.lib.yaml deleted file mode 100644 index fbb60a2d..00000000 --- a/deploy_carvel/supervisor/config/helpers.lib.yaml +++ /dev/null @@ -1,88 +0,0 @@ -#! Copyright 2020-2022 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 pinnipedDevAPIGroupWithPrefix(prefix): -#@ return prefix + "." + data.values.api_group_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 deploymentPodLabel(): -deployment.pinniped.dev: supervisor -#@ end - -#@ def labels(): -_: #@ template.replace(defaultLabel()) -_: #@ template.replace(data.values.custom_labels) -#@ end - -#@ def getAndValidateLogLevel(): -#@ log_level = data.values.log_level -#@ if log_level != "info" and log_level != "debug" and log_level != "trace" and log_level != "all": -#@ fail("log_level '" + log_level + "' is invalid") -#@ end -#@ return log_level -#@ end - -#@ def getPinnipedConfigMapData(): -#@ config = { -#@ "apiGroupSuffix": data.values.api_group_suffix, -#@ "names": { -#@ "defaultTLSCertificateSecret": defaultResourceNameWithSuffix("default-tls-certificate"), -#@ "apiService": defaultResourceNameWithSuffix("api"), -#@ }, -#@ "labels": labels(), -#@ "insecureAcceptExternalUnencryptedHttpRequests": data.values.deprecated_insecure_accept_external_unencrypted_http_requests -#@ } -#@ if data.values.log_level or data.values.deprecated_log_format: -#@ config["log"] = {} -#@ end -#@ if data.values.log_level: -#@ config["log"]["level"] = getAndValidateLogLevel() -#@ end -#@ if data.values.deprecated_log_format: -#@ config["log"]["format"] = data.values.deprecated_log_format -#@ end -#@ if data.values.endpoints: -#@ config["endpoints"] = data.values.endpoints -#@ end -#@ return config -#@ end - -#@ def getattr_safe(val, *args): -#@ out = None -#@ for arg in args: -#@ if not hasattr(val, arg): -#@ return None -#@ end -#@ out = getattr(val, arg) -#@ val = out -#@ end -#@ return out -#@ end - -#@ def hasUnixNetworkEndpoint(): -#@ return getattr_safe(data.values.endpoints, "http", "network") == "unix" or \ -#@ getattr_safe(data.values.endpoints, "https", "network") == "unix" -#@ end diff --git a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml deleted file mode 100644 index 7bb486de..00000000 --- a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_activedirectoryidentityproviders.yaml +++ /dev/null @@ -1,318 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: activedirectoryidentityproviders.idp.supervisor.pinniped.dev -spec: - group: idp.supervisor.pinniped.dev - names: - categories: - - pinniped - - pinniped-idp - - pinniped-idps - kind: ActiveDirectoryIdentityProvider - listKind: ActiveDirectoryIdentityProviderList - plural: activedirectoryidentityproviders - singular: activedirectoryidentityprovider - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.host - name: Host - type: string - - jsonPath: .status.phase - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: ActiveDirectoryIdentityProvider describes the configuration of - an upstream Microsoft Active Directory identity provider. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec for configuring the identity provider. - properties: - bind: - description: Bind contains the configuration for how to provide access - credentials during an initial bind to the ActiveDirectory server - to be allowed to perform searches and binds to validate a user's - credentials during a user's authentication attempt. - properties: - secretName: - description: SecretName contains the name of a namespace-local - Secret object that provides the username and password for an - Active Directory bind user. This account will be used to perform - LDAP searches. The Secret should be of type "kubernetes.io/basic-auth" - which includes "username" and "password" keys. The username - value should be the full dn (distinguished name) of your bind - account, e.g. "cn=bind-account,ou=users,dc=example,dc=com". - The password must be non-empty. - minLength: 1 - type: string - required: - - secretName - type: object - groupSearch: - description: GroupSearch contains the configuration for searching - for a user's group membership in ActiveDirectory. - properties: - attributes: - description: Attributes specifies how the group's information - should be read from each ActiveDirectory entry which was found - as the result of the group search. - properties: - groupName: - description: GroupName specifies the name of the attribute - in the Active Directory entries whose value shall become - a group name in the user's list of groups after a successful - authentication. The value of this field is case-sensitive - and must match the case of the attribute name returned by - the ActiveDirectory server in the user's entry. E.g. "cn" - for common name. Distinguished names can be used by specifying - lower-case "dn". Optional. When not specified, this defaults - to a custom field that looks like "sAMAccountName@domain", - where domain is constructed from the domain components of - the group DN. - type: string - type: object - base: - description: Base is the dn (distinguished name) that should be - used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". - Optional, when not specified it will be based on the result - of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). - The default behavior searches your entire domain for groups. - It may make sense to specify a subtree as a search base if you - wish to exclude some groups for security reasons or to make - searches faster. - type: string - filter: - description: Filter is the ActiveDirectory search filter which - should be applied when searching for groups for a user. The - pattern "{}" must occur in the filter at least once and will - be dynamically replaced by the value of an attribute of the - user entry found as a result of the user search. Which attribute's - value is used to replace the placeholder(s) depends on the value - of UserAttributeForFilter. E.g. "member={}" or "&(objectClass=groupOfNames)(member={})". - For more information about ActiveDirectory filters, see https://ldap.com/ldap-filters. - Note that the dn (distinguished name) is not an attribute of - an entry, so "dn={}" cannot be used. Optional. When not specified, - the default will act as if the filter were specified as "(&(objectClass=group)(member:1.2.840.113556.1.4.1941:={})". - This searches nested groups by default. Note that nested group - search can be slow for some Active Directory servers. To disable - it, you can set the filter to "(&(objectClass=group)(member={})" - type: string - skipGroupRefresh: - description: "The user's group membership is refreshed as they - interact with the supervisor to obtain new credentials (as their - old credentials expire). This allows group membership changes - to be quickly reflected into Kubernetes clusters. Since group - membership is often used to bind authorization policies, it - is important to keep the groups observed in Kubernetes clusters - in-sync with the identity provider. \n In some environments, - frequent group membership queries may result in a significant - performance impact on the identity provider and/or the supervisor. - The best approach to handle performance impacts is to tweak - the group query to be more performant, for example by disabling - nested group search or by using a more targeted group search - base. \n If the group search query cannot be made performant - and you are willing to have group memberships remain static - for approximately a day, then set skipGroupRefresh to true. - \ This is an insecure configuration as authorization policies - that are bound to group membership will not notice if a user - has been removed from a particular group until their next login. - \n This is an experimental feature that may be removed or significantly - altered in the future. Consumers of this configuration should - carefully read all release notes before upgrading to ensure - that the meaning of this field has not changed." - type: boolean - userAttributeForFilter: - description: UserAttributeForFilter specifies which attribute's - value from the user entry found as a result of the user search - will be used to replace the "{}" placeholder(s) in the group - search Filter. For example, specifying "uid" as the UserAttributeForFilter - while specifying "&(objectClass=posixGroup)(memberUid={})" as - the Filter would search for groups by replacing the "{}" placeholder - in the Filter with the value of the user's "uid" attribute. - Optional. When not specified, the default will act as if "dn" - were specified. For example, leaving UserAttributeForFilter - unspecified while specifying "&(objectClass=groupOfNames)(member={})" - as the Filter would search for groups by replacing the "{}" - placeholder(s) with the dn (distinguished name) of the user. - type: string - type: object - host: - description: 'Host is the hostname of this Active Directory identity - provider, i.e., where to connect. For example: ldap.example.com:636.' - minLength: 1 - type: string - tls: - description: TLS contains the connection settings for how to establish - the connection to the Host. - properties: - certificateAuthorityData: - description: X.509 Certificate Authority (base64-encoded PEM bundle). - If omitted, a default set of system roots will be trusted. - type: string - type: object - userSearch: - description: UserSearch contains the configuration for searching for - a user by name in Active Directory. - properties: - attributes: - description: Attributes specifies how the user's information should - be read from the ActiveDirectory entry which was found as the - result of the user search. - properties: - uid: - description: UID specifies the name of the attribute in the - ActiveDirectory entry which whose value shall be used to - uniquely identify the user within this ActiveDirectory provider - after a successful authentication. Optional, when empty - this defaults to "objectGUID". - type: string - username: - description: Username specifies the name of the attribute - in Active Directory entry whose value shall become the username - of the user after a successful authentication. Optional, - when empty this defaults to "userPrincipalName". - type: string - type: object - base: - description: Base is the dn (distinguished name) that should be - used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com". - Optional, when not specified it will be based on the result - of a query for the defaultNamingContext (see https://docs.microsoft.com/en-us/windows/win32/adschema/rootdse). - The default behavior searches your entire domain for users. - It may make sense to specify a subtree as a search base if you - wish to exclude some users or to make searches faster. - type: string - filter: - description: Filter is the search filter which should be applied - when searching for users. The pattern "{}" must occur in the - filter at least once and will be dynamically replaced by the - username for which the search is being run. E.g. "mail={}" or - "&(objectClass=person)(uid={})". For more information about - LDAP filters, see https://ldap.com/ldap-filters. Note that the - dn (distinguished name) is not an attribute of an entry, so - "dn={}" cannot be used. Optional. When not specified, the default - will be '(&(objectClass=person)(!(objectClass=computer))(!(showInAdvancedViewOnly=TRUE))(|(sAMAccountName={}")(mail={})(userPrincipalName={})(sAMAccountType=805306368))' - This means that the user is a person, is not a computer, the - sAMAccountType is for a normal user account, and is not shown - in advanced view only (which would likely mean its a system - created service account with advanced permissions). Also, either - the sAMAccountName, the userPrincipalName, or the mail attribute - matches the input username. - type: string - type: object - required: - - host - type: object - status: - description: Status of the identity provider. - properties: - conditions: - description: Represents the observations of an identity provider's - current state. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - phase: - default: Pending - description: Phase summarizes the overall status of the ActiveDirectoryIdentityProvider. - enum: - - Pending - - Ready - - Error - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml deleted file mode 100644 index 85106cb8..00000000 --- a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_ldapidentityproviders.yaml +++ /dev/null @@ -1,315 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: ldapidentityproviders.idp.supervisor.pinniped.dev -spec: - group: idp.supervisor.pinniped.dev - names: - categories: - - pinniped - - pinniped-idp - - pinniped-idps - kind: LDAPIdentityProvider - listKind: LDAPIdentityProviderList - plural: ldapidentityproviders - singular: ldapidentityprovider - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.host - name: Host - type: string - - jsonPath: .status.phase - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: LDAPIdentityProvider describes the configuration of an upstream - Lightweight Directory Access Protocol (LDAP) identity provider. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec for configuring the identity provider. - properties: - bind: - description: Bind contains the configuration for how to provide access - credentials during an initial bind to the LDAP server to be allowed - to perform searches and binds to validate a user's credentials during - a user's authentication attempt. - properties: - secretName: - description: SecretName contains the name of a namespace-local - Secret object that provides the username and password for an - LDAP bind user. This account will be used to perform LDAP searches. - The Secret should be of type "kubernetes.io/basic-auth" which - includes "username" and "password" keys. The username value - should be the full dn (distinguished name) of your bind account, - e.g. "cn=bind-account,ou=users,dc=example,dc=com". The password - must be non-empty. - minLength: 1 - type: string - required: - - secretName - type: object - groupSearch: - description: GroupSearch contains the configuration for searching - for a user's group membership in the LDAP provider. - properties: - attributes: - description: Attributes specifies how the group's information - should be read from each LDAP entry which was found as the result - of the group search. - properties: - groupName: - description: GroupName specifies the name of the attribute - in the LDAP entries whose value shall become a group name - in the user's list of groups after a successful authentication. - The value of this field is case-sensitive and must match - the case of the attribute name returned by the LDAP server - in the user's entry. E.g. "cn" for common name. Distinguished - names can be used by specifying lower-case "dn". Optional. - When not specified, the default will act as if the GroupName - were specified as "dn" (distinguished name). - type: string - type: object - base: - description: Base is the dn (distinguished name) that should be - used as the search base when searching for groups. E.g. "ou=groups,dc=example,dc=com". - When not specified, no group search will be performed and authenticated - users will not belong to any groups from the LDAP provider. - Also, when not specified, the values of Filter, UserAttributeForFilter, - Attributes, and SkipGroupRefresh are ignored. - type: string - filter: - description: Filter is the LDAP search filter which should be - applied when searching for groups for a user. The pattern "{}" - must occur in the filter at least once and will be dynamically - replaced by the value of an attribute of the user entry found - as a result of the user search. Which attribute's value is used - to replace the placeholder(s) depends on the value of UserAttributeForFilter. - For more information about LDAP filters, see https://ldap.com/ldap-filters. - Note that the dn (distinguished name) is not an attribute of - an entry, so "dn={}" cannot be used. Optional. When not specified, - the default will act as if the Filter were specified as "member={}". - type: string - skipGroupRefresh: - description: "The user's group membership is refreshed as they - interact with the supervisor to obtain new credentials (as their - old credentials expire). This allows group membership changes - to be quickly reflected into Kubernetes clusters. Since group - membership is often used to bind authorization policies, it - is important to keep the groups observed in Kubernetes clusters - in-sync with the identity provider. \n In some environments, - frequent group membership queries may result in a significant - performance impact on the identity provider and/or the supervisor. - The best approach to handle performance impacts is to tweak - the group query to be more performant, for example by disabling - nested group search or by using a more targeted group search - base. \n If the group search query cannot be made performant - and you are willing to have group memberships remain static - for approximately a day, then set skipGroupRefresh to true. - \ This is an insecure configuration as authorization policies - that are bound to group membership will not notice if a user - has been removed from a particular group until their next login. - \n This is an experimental feature that may be removed or significantly - altered in the future. Consumers of this configuration should - carefully read all release notes before upgrading to ensure - that the meaning of this field has not changed." - type: boolean - userAttributeForFilter: - description: UserAttributeForFilter specifies which attribute's - value from the user entry found as a result of the user search - will be used to replace the "{}" placeholder(s) in the group - search Filter. For example, specifying "uid" as the UserAttributeForFilter - while specifying "&(objectClass=posixGroup)(memberUid={})" as - the Filter would search for groups by replacing the "{}" placeholder - in the Filter with the value of the user's "uid" attribute. - Optional. When not specified, the default will act as if "dn" - were specified. For example, leaving UserAttributeForFilter - unspecified while specifying "&(objectClass=groupOfNames)(member={})" - as the Filter would search for groups by replacing the "{}" - placeholder(s) with the dn (distinguished name) of the user. - type: string - type: object - host: - description: 'Host is the hostname of this LDAP identity provider, - i.e., where to connect. For example: ldap.example.com:636.' - minLength: 1 - type: string - tls: - description: TLS contains the connection settings for how to establish - the connection to the Host. - properties: - certificateAuthorityData: - description: X.509 Certificate Authority (base64-encoded PEM bundle). - If omitted, a default set of system roots will be trusted. - type: string - type: object - userSearch: - description: UserSearch contains the configuration for searching for - a user by name in the LDAP provider. - properties: - attributes: - description: Attributes specifies how the user's information should - be read from the LDAP entry which was found as the result of - the user search. - properties: - uid: - description: UID specifies the name of the attribute in the - LDAP entry which whose value shall be used to uniquely identify - the user within this LDAP provider after a successful authentication. - E.g. "uidNumber" or "objectGUID". The value of this field - is case-sensitive and must match the case of the attribute - name returned by the LDAP server in the user's entry. Distinguished - names can be used by specifying lower-case "dn". - minLength: 1 - type: string - username: - description: Username specifies the name of the attribute - in the LDAP entry whose value shall become the username - of the user after a successful authentication. This would - typically be the same attribute name used in the user search - filter, although it can be different. E.g. "mail" or "uid" - or "userPrincipalName". The value of this field is case-sensitive - and must match the case of the attribute name returned by - the LDAP server in the user's entry. Distinguished names - can be used by specifying lower-case "dn". When this field - is set to "dn" then the LDAPIdentityProviderUserSearch's - Filter field cannot be blank, since the default value of - "dn={}" would not work. - minLength: 1 - type: string - type: object - base: - description: Base is the dn (distinguished name) that should be - used as the search base when searching for users. E.g. "ou=users,dc=example,dc=com". - minLength: 1 - type: string - filter: - description: Filter is the LDAP search filter which should be - applied when searching for users. The pattern "{}" must occur - in the filter at least once and will be dynamically replaced - by the username for which the search is being run. E.g. "mail={}" - or "&(objectClass=person)(uid={})". For more information about - LDAP filters, see https://ldap.com/ldap-filters. Note that the - dn (distinguished name) is not an attribute of an entry, so - "dn={}" cannot be used. Optional. When not specified, the default - will act as if the Filter were specified as the value from Attributes.Username - appended by "={}". When the Attributes.Username is set to "dn" - then the Filter must be explicitly specified, since the default - value of "dn={}" would not work. - type: string - type: object - required: - - host - type: object - status: - description: Status of the identity provider. - properties: - conditions: - description: Represents the observations of an identity provider's - current state. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - phase: - default: Pending - description: Phase summarizes the overall status of the LDAPIdentityProvider. - enum: - - Pending - - Ready - - Error - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml b/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml deleted file mode 100644 index 7bea863d..00000000 --- a/deploy_carvel/supervisor/config/idp.supervisor.pinniped.dev_oidcidentityproviders.yaml +++ /dev/null @@ -1,345 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: oidcidentityproviders.idp.supervisor.pinniped.dev -spec: - group: idp.supervisor.pinniped.dev - names: - categories: - - pinniped - - pinniped-idp - - pinniped-idps - kind: OIDCIdentityProvider - listKind: OIDCIdentityProviderList - plural: oidcidentityproviders - singular: oidcidentityprovider - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.issuer - name: Issuer - type: string - - jsonPath: .status.phase - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: OIDCIdentityProvider describes the configuration of an upstream - OpenID Connect identity provider. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec for configuring the identity provider. - properties: - authorizationConfig: - description: AuthorizationConfig holds information about how to form - the OAuth2 authorization request parameters to be used with this - OIDC identity provider. - properties: - additionalAuthorizeParameters: - description: additionalAuthorizeParameters are extra query parameters - that should be included in the authorize request to your OIDC - provider in the authorization request during an OIDC Authorization - Code Flow. By default, no extra parameters are sent. The standard - parameters that will be sent are "response_type", "scope", "client_id", - "state", "nonce", "code_challenge", "code_challenge_method", - and "redirect_uri". These parameters cannot be included in this - setting. Additionally, the "hd" parameter cannot be included - in this setting at this time. The "hd" parameter is used by - Google's OIDC provider to provide a hint as to which "hosted - domain" the user should use during login. However, Pinniped - does not yet support validating the hosted domain in the resulting - ID token, so it is not yet safe to use this feature of Google's - OIDC provider with Pinniped. This setting does not influence - the parameters sent to the token endpoint in the Resource Owner - Password Credentials Grant. The Pinniped Supervisor requires - that your OIDC provider returns refresh tokens to the Supervisor - from the authorization flows. Some OIDC providers may require - a certain value for the "prompt" parameter in order to properly - request refresh tokens. See the documentation of your OIDC provider's - authorization endpoint for its requirements for what to include - in the request in order to receive a refresh token in the response, - if anything. If your provider requires the prompt parameter - to request a refresh token, then include it here. Also note - that most providers also require a certain scope to be requested - in order to receive refresh tokens. See the additionalScopes - setting for more information about using scopes to request refresh - tokens. - items: - description: Parameter is a key/value pair which represents - a parameter in an HTTP request. - properties: - name: - description: The name of the parameter. Required. - minLength: 1 - type: string - value: - description: The value of the parameter. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - additionalScopes: - description: 'additionalScopes are the additional scopes that - will be requested from your OIDC provider in the authorization - request during an OIDC Authorization Code Flow and in the token - request during a Resource Owner Password Credentials Grant. - Note that the "openid" scope will always be requested regardless - of the value in this setting, since it is always required according - to the OIDC spec. By default, when this field is not set, the - Supervisor will request the following scopes: "openid", "offline_access", - "email", and "profile". See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims - for a description of the "profile" and "email" scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess - for a description of the "offline_access" scope. This default - value may change in future versions of Pinniped as the standard - evolves, or as common patterns used by providers who implement - the standard in the ecosystem evolve. By setting this list to - anything other than an empty list, you are overriding the default - value, so you may wish to include some of "offline_access", - "email", and "profile" in your override list. If you do not - want any of these scopes to be requested, you may set this list - to contain only "openid". Some OIDC providers may also require - a scope to get access to the user''s group membership, in which - case you may wish to include it in this list. Sometimes the - scope to request the user''s group membership is called "groups", - but unfortunately this is not specified in the OIDC standard. - Generally speaking, you should include any scopes required to - cause the appropriate claims to be the returned by your OIDC - provider in the ID token or userinfo endpoint results for those - claims which you would like to use in the oidcClaims settings - to determine the usernames and group memberships of your Kubernetes - users. See your OIDC provider''s documentation for more information - about what scopes are available to request claims. Additionally, - the Pinniped Supervisor requires that your OIDC provider returns - refresh tokens to the Supervisor from these authorization flows. - For most OIDC providers, the scope required to receive refresh - tokens will be "offline_access". See the documentation of your - OIDC provider''s authorization and token endpoints for its requirements - for what to include in the request in order to receive a refresh - token in the response, if anything. Note that it may be safe - to send "offline_access" even to providers which do not require - it, since the provider may ignore scopes that it does not understand - or require (see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3). - In the unusual case that you must avoid sending the "offline_access" - scope, then you must override the default value of this setting. - This is required if your OIDC provider will reject the request - when it includes "offline_access" (e.g. GitLab''s OIDC provider).' - items: - type: string - type: array - allowPasswordGrant: - description: allowPasswordGrant, when true, will allow the use - of OAuth 2.0's Resource Owner Password Credentials Grant (see - https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to - authenticate to the OIDC provider using a username and password - without a web browser, in addition to the usual browser-based - OIDC Authorization Code Flow. The Resource Owner Password Credentials - Grant is not officially part of the OIDC specification, so it - may not be supported by your OIDC provider. If your OIDC provider - supports returning ID tokens from a Resource Owner Password - Credentials Grant token request, then you can choose to set - this field to true. This will allow end users to choose to present - their username and password to the kubectl CLI (using the Pinniped - plugin) to authenticate to the cluster, without using a web - browser to log in as is customary in OIDC Authorization Code - Flow. This may be convenient for users, especially for identities - from your OIDC provider which are not intended to represent - a human actor, such as service accounts performing actions in - a CI/CD environment. Even if your OIDC provider supports it, - you may wish to disable this behavior by setting this field - to false when you prefer to only allow users of this OIDCIdentityProvider - to log in via the browser-based OIDC Authorization Code Flow. - Using the Resource Owner Password Credentials Grant means that - the Pinniped CLI and Pinniped Supervisor will directly handle - your end users' passwords (similar to LDAPIdentityProvider), - and you will not be able to require multi-factor authentication - or use the other web-based login features of your OIDC provider - during Resource Owner Password Credentials Grant logins. allowPasswordGrant - defaults to false. - type: boolean - type: object - claims: - description: Claims provides the names of token claims that will be - used when inspecting an identity from this OIDC identity provider. - properties: - additionalClaimMappings: - additionalProperties: - type: string - description: AdditionalClaimMappings allows for additional arbitrary - upstream claim values to be mapped into the "additionalClaims" - claim of the ID tokens generated by the Supervisor. This should - be specified as a map of new claim names as the keys, and upstream - claim names as the values. These new claim names will be nested - under the top-level "additionalClaims" claim in ID tokens generated - by the Supervisor when this OIDCIdentityProvider was used for - user authentication. These claims will be made available to - all clients. This feature is not required to use the Supervisor - to provide authentication for Kubernetes clusters, but can be - used when using the Supervisor for other authentication purposes. - When this map is empty or the upstream claims are not available, - the "additionalClaims" claim will be excluded from the ID tokens - generated by the Supervisor. - type: object - groups: - description: Groups provides the name of the ID token claim or - userinfo endpoint response claim that will be used to ascertain - the groups to which an identity belongs. By default, the identities - will not include any group memberships when this setting is - not configured. - type: string - username: - description: Username provides the name of the ID token claim - or userinfo endpoint response claim that will be used to ascertain - an identity's username. When not set, the username will be an - automatically constructed unique string which will include the - issuer URL of your OIDC provider along with the value of the - "sub" (subject) claim from the ID token. - type: string - type: object - client: - description: OIDCClient contains OIDC client information to be used - used with this OIDC identity provider. - properties: - secretName: - description: SecretName contains the name of a namespace-local - Secret object that provides the clientID and clientSecret for - an OIDC client. If only the SecretName is specified in an OIDCClient - struct, then it is expected that the Secret is of type "secrets.pinniped.dev/oidc-client" - with keys "clientID" and "clientSecret". - type: string - required: - - secretName - type: object - issuer: - description: Issuer is the issuer URL of this OIDC identity provider, - i.e., where to fetch /.well-known/openid-configuration. - minLength: 1 - pattern: ^https:// - type: string - tls: - description: TLS configuration for discovery/JWKS requests to the - issuer. - properties: - certificateAuthorityData: - description: X.509 Certificate Authority (base64-encoded PEM bundle). - If omitted, a default set of system roots will be trusted. - type: string - type: object - required: - - client - - issuer - type: object - status: - description: Status of the identity provider. - properties: - conditions: - description: Represents the observations of an identity provider's - current state. - items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - \n type FooStatus struct{ // Represents the observations of a - foo's current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - phase: - default: Pending - description: Phase summarizes the overall status of the OIDCIdentityProvider. - enum: - - Pending - - Ready - - Error - type: string - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} diff --git a/deploy_carvel/supervisor/config/rbac.yaml b/deploy_carvel/supervisor/config/rbac.yaml deleted file mode 100644 index 97b542fe..00000000 --- a/deploy_carvel/supervisor/config/rbac.yaml +++ /dev/null @@ -1,152 +0,0 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:data", "data") -#@ load("helpers.lib.yaml", "labels", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix", "pinnipedDevAPIGroupWithPrefix") - -#! Give permission to various objects within the app's own namespace ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: #@ defaultResourceName() - namespace: #@ namespace() - labels: #@ labels() -rules: - - apiGroups: [""] - resources: [secrets] - verbs: [create, get, list, patch, update, watch, delete] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") - resources: [federationdomains] - verbs: [get, list, watch] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") - resources: [federationdomains/status] - verbs: [get, patch, update] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") - resources: [oidcclients] - verbs: [get, list, watch] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") - resources: [oidcclients/status] - verbs: [get, patch, update] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - resources: [oidcidentityproviders] - verbs: [get, list, watch] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - resources: [oidcidentityproviders/status] - verbs: [get, patch, update] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - resources: [ldapidentityproviders] - verbs: [get, list, watch] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - resources: [ldapidentityproviders/status] - verbs: [get, patch, update] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - resources: [activedirectoryidentityproviders] - verbs: [get, list, watch] - - apiGroups: - - #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - resources: [activedirectoryidentityproviders/status] - verbs: [get, patch, update] - #! We want to be able to read pods/replicasets/deployment so we can learn who our deployment is to set - #! as an owner reference. - - apiGroups: [""] - resources: [pods] - verbs: [get] - - apiGroups: [apps] - resources: [replicasets,deployments] - verbs: [get] - - apiGroups: [ coordination.k8s.io ] - resources: [ leases ] - verbs: [ create, get, update ] ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceName() - namespace: #@ namespace() - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: Role - name: #@ defaultResourceName() - apiGroup: rbac.authorization.k8s.io - -#! Give permissions for a special configmap of CA bundles that is needed by aggregated api servers ---- -kind: RoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("extension-apiserver-authentication-reader") - namespace: kube-system - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: Role - name: extension-apiserver-authentication-reader - apiGroup: rbac.authorization.k8s.io - -#! Give permissions for subjectaccessreviews, tokenreview that is needed by aggregated api servers ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceName() - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: ClusterRole - name: system:auth-delegator - apiGroup: rbac.authorization.k8s.io - -#! Give permission to various cluster-scoped objects ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - labels: #@ labels() -rules: - - apiGroups: [ "" ] - resources: [ namespaces ] - verbs: [ get, list, watch ] - - apiGroups: [ apiregistration.k8s.io ] - resources: [ apiservices ] - verbs: [ get, list, patch, update, watch ] - - apiGroups: [ admissionregistration.k8s.io ] - resources: [ validatingwebhookconfigurations, mutatingwebhookconfigurations ] - verbs: [ get, list, watch ] - - apiGroups: [ flowcontrol.apiserver.k8s.io ] - resources: [ flowschemas, prioritylevelconfigurations ] - verbs: [ get, list, watch ] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - labels: #@ labels() -subjects: - - kind: ServiceAccount - name: #@ defaultResourceName() - namespace: #@ namespace() -roleRef: - kind: ClusterRole - name: #@ defaultResourceNameWithSuffix("aggregated-api-server") - apiGroup: rbac.authorization.k8s.io diff --git a/deploy_carvel/supervisor/config/service.yaml b/deploy_carvel/supervisor/config/service.yaml deleted file mode 100644 index fd6b9623..00000000 --- a/deploy_carvel/supervisor/config/service.yaml +++ /dev/null @@ -1,115 +0,0 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:data", "data") -#@ load("@ytt:assert", "assert") -#@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") - -#@ if hasattr(data.values, "service_http_nodeport_port"): -#@ assert.fail('value "service_http_nodeport_port" has been renamed to "deprecated_service_http_nodeport_port" and will be removed in a future release') -#@ end -#@ if hasattr(data.values, "service_http_nodeport_nodeport"): -#@ assert.fail('value "service_http_nodeport_nodeport" has been renamed to "deprecated_service_http_nodeport_nodeport" and will be removed in a future release') -#@ end -#@ if hasattr(data.values, "service_http_loadbalancer_port"): -#@ assert.fail('value "service_http_loadbalancer_port" has been renamed to "deprecated_service_http_loadbalancer_port" and will be removed in a future release') -#@ end -#@ if hasattr(data.values, "service_http_clusterip_port"): -#@ assert.fail('value "service_http_clusterip_port" has been renamed to "deprecated_service_http_clusterip_port" and will be removed in a future release') -#@ end - -#@ if data.values.deprecated_service_http_nodeport_port or data.values.service_https_nodeport_port: ---- -apiVersion: v1 -kind: Service -metadata: - name: #@ defaultResourceNameWithSuffix("nodeport") - namespace: #@ namespace() - labels: #@ labels() - #! prevent kapp from altering the selector of our services to match kubectl behavior - annotations: - kapp.k14s.io/disable-default-label-scoping-rules: "" -spec: - type: NodePort - selector: #@ deploymentPodLabel() - ports: - #@ if data.values.deprecated_service_http_nodeport_port: - - name: http - protocol: TCP - port: #@ data.values.deprecated_service_http_nodeport_port - targetPort: 8080 - #@ if data.values.deprecated_service_http_nodeport_nodeport: - nodePort: #@ data.values.deprecated_service_http_nodeport_nodeport - #@ end - #@ end - #@ if data.values.service_https_nodeport_port: - - name: https - protocol: TCP - port: #@ data.values.service_https_nodeport_port - targetPort: 8443 - #@ if data.values.service_https_nodeport_nodeport: - nodePort: #@ data.values.service_https_nodeport_nodeport - #@ end - #@ end -#@ end - -#@ if data.values.deprecated_service_http_clusterip_port or data.values.service_https_clusterip_port: ---- -apiVersion: v1 -kind: Service -metadata: - name: #@ defaultResourceNameWithSuffix("clusterip") - namespace: #@ namespace() - labels: #@ labels() - #! prevent kapp from altering the selector of our services to match kubectl behavior - annotations: - kapp.k14s.io/disable-default-label-scoping-rules: "" -spec: - type: ClusterIP - selector: #@ deploymentPodLabel() - ports: - #@ if data.values.deprecated_service_http_clusterip_port: - - name: http - protocol: TCP - port: #@ data.values.deprecated_service_http_clusterip_port - targetPort: 8080 - #@ end - #@ if data.values.service_https_clusterip_port: - - name: https - protocol: TCP - port: #@ data.values.service_https_clusterip_port - targetPort: 8443 - #@ end -#@ end - -#@ if data.values.deprecated_service_http_loadbalancer_port or data.values.service_https_loadbalancer_port: ---- -apiVersion: v1 -kind: Service -metadata: - name: #@ defaultResourceNameWithSuffix("loadbalancer") - namespace: #@ namespace() - labels: #@ labels() - #! prevent kapp from altering the selector of our services to match kubectl behavior - annotations: - kapp.k14s.io/disable-default-label-scoping-rules: "" -spec: - type: LoadBalancer - selector: #@ deploymentPodLabel() - #@ if data.values.service_loadbalancer_ip: - loadBalancerIP: #@ data.values.service_loadbalancer_ip - #@ end - ports: - #@ if data.values.deprecated_service_http_loadbalancer_port: - - name: http - protocol: TCP - port: #@ data.values.deprecated_service_http_loadbalancer_port - targetPort: 8080 - #@ end - #@ if data.values.service_https_loadbalancer_port: - - name: https - protocol: TCP - port: #@ data.values.service_https_loadbalancer_port - targetPort: 8443 - #@ end -#@ end diff --git a/deploy_carvel/supervisor/config/values.yaml b/deploy_carvel/supervisor/config/values.yaml deleted file mode 100644 index 04606edb..00000000 --- a/deploy_carvel/supervisor/config/values.yaml +++ /dev/null @@ -1,175 +0,0 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@data/values-schema ---- -#@schema/desc "Name of pinniped-supervisor." -app_name: pinniped-supervisor - -#@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." -namespace: pinniped-supervisor -#@ into_namespace_desc = "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." -#@schema/desc into_namespace_desc -#@schema/nullable -into_namespace: my-preexisting-namespace - -#@ custom_labels_desc = "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 value of `custom_labels` must be a map of string keys to string values. \ -#@ 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." -#@schema/desc custom_labels_desc -#@schema/type any=True -custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} - -#@schema/desc "Specify how many replicas of the Pinniped server to run." -replicas: 2 - -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -image_repo: projects.registry.vmware.com/pinniped/pinniped-server -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -#@schema/nullable -image_digest: sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8 -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." -image_tag: latest - -#@ image_pull_dockerconfigjson_desc = "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." -#@schema/desc image_pull_dockerconfigjson_desc -#@schema/nullable -image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} - -#! Specify how to expose the Supervisor app's HTTPS port as a Service. -#! Typically, you would set a value for only one of the following service types. -#! Setting any of these values means that a Service of that type will be created. They are all optional. -#! Note that all port numbers should be numbers (not strings), i.e. use ytt's `--data-value-yaml` instead of `--data-value`. -#! Several of these values have been deprecated and will be removed in a future release. Their names have been changed to -#! mark them as deprecated and to make it obvious upon upgrade to anyone who was using them that they have been deprecated. -#@schema/desc "will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/nullable -deprecated_service_http_nodeport_port: 31234 -#@schema/desc "will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified" -#@schema/nullable -deprecated_service_http_nodeport_nodeport: 31234 -#@schema/desc "will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/nullable -deprecated_service_http_loadbalancer_port: 8443 -#@schema/desc "#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/nullable -deprecated_service_http_clusterip_port: 8443 -#@schema/desc "#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`" -#@schema/nullable -service_https_nodeport_port: 31243 -#@schema/desc "#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified" -#@schema/nullable -service_https_nodeport_nodeport: 31243 -#@schema/desc "#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`" -#@schema/nullable -service_https_loadbalancer_port: 8443 -#@schema/desc "#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`" -#@schema/nullable -service_https_clusterip_port: 8443 -#@ service_loadbalancer_ip_desc="The `loadBalancerIP` value of the LoadBalancer Service. \ -#@ Ignored unless service_https_loadbalancer_port is provided." -#@schema/desc service_loadbalancer_ip_desc -#@schema/nullable -service_loadbalancer_ip: 1.2.3.4 - -#! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information), -#! or all (kitchen sink). Do not use trace or all on production systems, as credentials may get logged. -#@schema/desc "default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." -#@schema/nullable -log_level: info -#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ -#@ By default, when this value is left unset, logs are formatted in json. \ -#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." -#@schema/desc deprecated_log_format_desc -#@schema/nullable -deprecated_log_format: json - -#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" -run_as_user: 65532 -#@schema/desc "run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" -run_as_group: 65532 - -#@ api_group_suffix_desc = "Specify the API group suffix for all Pinniped API groups. By default, this is set to \ -#@ pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, \ -#@ authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then \ -#@ Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc." -#@schema/desc api_group_suffix_desc -api_group_suffix: pinniped.dev - -#@ https_proxy_desc = "Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. \ -#@ These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, \ -#@ e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. \ -#@ The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. \ -#@ Optional." -#@schema/desc https_proxy_desc -#@schema/nullable -https_proxy: http://proxy.example.com -#@schema/desc "do not proxy Kubernetes endpoints" -no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" - -#! Control the HTTP and HTTPS listeners of the Supervisor. -#! -#! The schema of this config is as follows: -#! -#! endpoints: -#! https: -#! network: tcp | unix | disabled -#! address: host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix -#! http: -#! network: same as above -#! address: same as above, except that when network=tcp then the address is only allowed to bind to loopback interfaces -#! -#! Setting network to disabled turns off that particular listener. -#! See https://pkg.go.dev/net#Listen and https://pkg.go.dev/net#Dial for a description of what can be -#! specified in the address parameter based on the given network parameter. To aid in the use of unix -#! domain sockets, a writable empty dir volume is mounted at /pinniped_socket when network is set to "unix." -#! -#! The current defaults are: -#! -#! endpoints: -#! https: -#! network: tcp -#! address: :8443 -#! http: -#! network: disabled -#! -#! These defaults mean: For HTTPS listening, bind to all interfaces using TCP on port 8443. -#! Disable HTTP listening by default. -#! -#! The HTTP listener can only be bound to loopback interfaces. This allows the listener to accept -#! traffic from within the pod, e.g. from a service mesh sidecar. The HTTP listener should not be -#! used to accept traffic from outside the pod, since that would mean that the network traffic could be -#! transmitted unencrypted. The HTTPS listener should be used instead to accept traffic from outside the pod. -#! Ingresses and load balancers that terminate TLS connections should re-encrypt the data and route traffic -#! to the HTTPS listener. Unix domain sockets may also be used for integrations with service meshes. -#! -#! Changing the HTTPS port number must be accompanied by matching changes to the service and deployment -#! manifests. Changes to the HTTPS listener must be coordinated with the deployment health checks. -#! -#@schema/desc "Control the HTTP and HTTPS listeners of the Supervisor." -#@schema/nullable -endpoints: - https: - network: tcp - address: 1.2.3.4:5678 - -#! deprecated_insecure_accept_external_unencrypted_http_requests_desc = "Optionally override the validation on the endpoints. \ -#! http value which checks that only loopback interfaces are used. \ -#! When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any \ -#! interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced \ -#! to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time \ -#! to change their ingress strategy to avoid using plain HTTP into the Supervisor pods. \ -#! This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time \ -#! traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available. \ -#! Allowed values are true (boolean), "true" (string), false (boolean), and "false" (string). The default is false. \ -#! Optional." -#@schema/desc https_proxy_desc -deprecated_insecure_accept_external_unencrypted_http_requests: false diff --git a/deploy_carvel/supervisor/config/z0_crd_overlay.yaml b/deploy_carvel/supervisor/config/z0_crd_overlay.yaml deleted file mode 100644 index f7a50a88..00000000 --- a/deploy_carvel/supervisor/config/z0_crd_overlay.yaml +++ /dev/null @@ -1,63 +0,0 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. -#! SPDX-License-Identifier: Apache-2.0 - -#@ load("@ytt:overlay", "overlay") -#@ load("helpers.lib.yaml", "labels", "pinnipedDevAPIGroupWithPrefix") -#@ load("@ytt:data", "data") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"federationdomains.config.supervisor.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("federationdomains.config.supervisor") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("oidcidentityproviders.idp.supervisor") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"ldapidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("ldapidentityproviders.idp.supervisor") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"activedirectoryidentityproviders.idp.supervisor.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("activedirectoryidentityproviders.idp.supervisor") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("idp.supervisor") - -#@overlay/match by=overlay.subset({"kind": "CustomResourceDefinition", "metadata":{"name":"oidcclients.config.supervisor.pinniped.dev"}}), expects=1 ---- -metadata: - #@overlay/match missing_ok=True - labels: #@ labels() - name: #@ pinnipedDevAPIGroupWithPrefix("oidcclients.config.supervisor") -spec: - group: #@ pinnipedDevAPIGroupWithPrefix("config.supervisor") - versions: - #@overlay/match by=overlay.all, expects="1+" - - schema: - openAPIV3Schema: - #@overlay/match by=overlay.subset({"metadata":{"type":"object"}}), expects=1 - properties: - metadata: - #@overlay/match missing_ok=True - properties: - name: - pattern: ^client\.oauth\.pinniped\.dev- - type: string diff --git a/deploy_carvel/supervisor/vendir.lock.yml b/deploy_carvel/supervisor/vendir.lock.yml new file mode 100644 index 00000000..34a854bb --- /dev/null +++ b/deploy_carvel/supervisor/vendir.lock.yml @@ -0,0 +1,7 @@ +apiVersion: vendir.k14s.io/v1alpha1 +directories: +- contents: + - directory: {} + path: . + path: config +kind: LockConfig diff --git a/deploy_carvel/supervisor/vendir.yml b/deploy_carvel/supervisor/vendir.yml new file mode 100644 index 00000000..30c187ea --- /dev/null +++ b/deploy_carvel/supervisor/vendir.yml @@ -0,0 +1,8 @@ +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: +- path: config + contents: + - path: . + directory: + path: ../../deploy/supervisor diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index edbd920c..acda6b24 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -90,11 +90,11 @@ do resource_config_source_dir="deploy/${resource_name}" resource_config_destination_dir="deploy_carvel/${resource_name}/config" - # this must be real files, not symlinks - log_note "Copy deploy directory for ${resource_name} to package bundle..." - echo "cp -aRf ${resource_config_source_dir} ${resource_config_destination_dir}" - rm -rf "${resource_config_destination_dir}" # clean - cp -r "${resource_config_source_dir}" "${resource_config_destination_dir}" + # these must be real files, not symlinks + log_note "Vendir sync deploy directory for ${resource_name} to package bundle..." + pushd "${resource_config_destination_dir}" > /dev/null + vendir sync + popd > /dev/null log_note "Generating OpenAPI v3 schema for ${resource_name}..." ytt \ From cb6d29915635290c051fbbc39ca4ed89bbe7409f Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 3 Oct 2023 12:28:00 -0400 Subject: [PATCH 15/40] Fix prepare-for-integration-tests.sh with carvel packages --- deploy_carvel/concierge-pkginstall.yml | 4 +- deploy_carvel/concierge/schema-openapi.yaml | 155 +++++++++++ .../local-user-authenticator-pkginstall.yml | 9 +- .../schema-openapi.yaml | 55 ++++ .../package_repository/.imgpkg/images.yml | 45 +-- ...0-F3326187-009A-4313-B188-1B454D1A7E04.yml | 173 ++++++++++++ ...0-F3326187-009A-4313-B188-1B454D1A7E04.yml | 73 +++++ ...0-F3326187-009A-4313-B188-1B454D1A7E04.yml | 182 ++++++++++++ deploy_carvel/supervisor-pkginstall.yml | 4 +- deploy_carvel/supervisor/schema-openapi.yaml | 164 +++++++++++ hack/build-carvel-packages.sh | 260 ++++++++++-------- hack/prepare-for-integration-tests.sh | 33 ++- 12 files changed, 981 insertions(+), 176 deletions(-) create mode 100644 deploy_carvel/concierge/schema-openapi.yaml create mode 100644 deploy_carvel/local-user-authenticator/schema-openapi.yaml create mode 100644 deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml create mode 100644 deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml create mode 100644 deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml create mode 100644 deploy_carvel/supervisor/schema-openapi.yaml diff --git a/deploy_carvel/concierge-pkginstall.yml b/deploy_carvel/concierge-pkginstall.yml index c1d876c2..007f1f8f 100644 --- a/deploy_carvel/concierge-pkginstall.yml +++ b/deploy_carvel/concierge-pkginstall.yml @@ -10,7 +10,7 @@ spec: packageRef: refName: "concierge.pinniped.dev" versionSelection: - constraints: "0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7" + constraints: "0.0.0-F3326187-009A-4313-B188-1B454D1A7E04" values: - secretRef: name: "concierge-package-install-secret" @@ -29,4 +29,4 @@ stringData: log_level: debug image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + image_tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 diff --git a/deploy_carvel/concierge/schema-openapi.yaml b/deploy_carvel/concierge/schema-openapi.yaml new file mode 100644 index 00000000..9f18a393 --- /dev/null +++ b/deploy_carvel/concierge/schema-openapi.yaml @@ -0,0 +1,155 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-concierge. + default: pinniped-concierge + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-concierge + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: {} + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + kube_cert_agent_image: + type: string + nullable: true + description: Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled on the control plane. This image needs only to include `sleep` and `cat` binaries. By default, the same image specified for image_repo/image_digest/image_tag will be re-used. + default: null + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + discovery_url: + type: string + nullable: true + description: Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden. + default: null + api_serving_certificate_duration_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2592000 + api_serving_certificate_renew_before_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2160000 + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + impersonation_proxy_spec: + type: object + additionalProperties: false + description: Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation. + properties: + mode: + type: string + description: If enabled, the impersonation proxy will always run regardless of other strategies available. + default: auto + external_endpoint: + type: string + nullable: true + description: The endpoint which the client should use to connect to the impersonation proxy. If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint. + default: null + service: + type: object + additionalProperties: false + description: The impersonation proxy service configuration + properties: + type: + type: string + nullable: true + description: Options are 'LoadBalancer', 'ClusterIP' and 'None'. + default: null + annotations: + type: object + additionalProperties: false + nullable: true + description: The annotations that should be set on the ClusterIP or LoadBalancer Service. + properties: + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: + type: string + default: "4000" + load_balancer_ip: + type: string + nullable: true + description: When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP. + default: null + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local diff --git a/deploy_carvel/local-user-authenticator-pkginstall.yml b/deploy_carvel/local-user-authenticator-pkginstall.yml index 1c53a360..bc950c0a 100644 --- a/deploy_carvel/local-user-authenticator-pkginstall.yml +++ b/deploy_carvel/local-user-authenticator-pkginstall.yml @@ -10,7 +10,7 @@ spec: packageRef: refName: "local-user-authenticator.pinniped.dev" versionSelection: - constraints: "0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7" + constraints: "0.0.0-F3326187-009A-4313-B188-1B454D1A7E04" values: - secretRef: name: "local-user-authenticator-package-install-secret" @@ -23,10 +23,5 @@ metadata: stringData: values.yml: | --- - app_name: pinniped-concierge - namespace: concierge - api_group_suffix: pinniped.dev - log_level: debug - image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + image_tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 diff --git a/deploy_carvel/local-user-authenticator/schema-openapi.yaml b/deploy_carvel/local-user-authenticator/schema-openapi.yaml new file mode 100644 index 00000000..6dfcff7f --- /dev/null +++ b/deploy_carvel/local-user-authenticator/schema-openapi.yaml @@ -0,0 +1,55 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 diff --git a/deploy_carvel/package_repository/.imgpkg/images.yml b/deploy_carvel/package_repository/.imgpkg/images.yml index ada38a60..17bc6c5e 100644 --- a/deploy_carvel/package_repository/.imgpkg/images.yml +++ b/deploy_carvel/package_repository/.imgpkg/images.yml @@ -2,45 +2,24 @@ apiVersion: imgpkg.carvel.dev/v1alpha1 images: - annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 kbld.carvel.dev/origins: | - resolved: - tag: 0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 - url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 - image: kind-registry.local:5000/test/build/test/build-package-concierge@sha256:666682c02d09cef2d116152d4762e8af52c03bc133d06c91f8ea1ff2db605a90 + tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image: kind-registry.local:5000/test/build/test/build-package-concierge@sha256:ffc8371ff94e939233af0643476a597c025adb5609cc35c5ded6bd67ce13fdec - annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 kbld.carvel.dev/origins: | - resolved: - tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - image: kind-registry.local:5000/test/build/test/build-package-concierge@sha256:666682c02d09cef2d116152d4762e8af52c03bc133d06c91f8ea1ff2db605a90 + tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator@sha256:4f111f27ecf38622e4cbb29ce1d88589b488d8eb57d9b29cb577d64a417a2c4c - annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 kbld.carvel.dev/origins: | - resolved: - tag: 0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 - url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 - image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator@sha256:a094c2971a8a24c3ab34e0146cbb540d6277e853bbc8fd3efb6691b174bb5709 -- annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - kbld.carvel.dev/origins: | - - resolved: - tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator@sha256:a094c2971a8a24c3ab34e0146cbb540d6277e853bbc8fd3efb6691b174bb5709 -- annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 - kbld.carvel.dev/origins: | - - resolved: - tag: 0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 - url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-84D55AC3-B367-41A3-B17B-E11B10443CC8 - image: kind-registry.local:5000/test/build/test/build-package-supervisor@sha256:28488e1c9bbf8988c9a9f70ae6478188b6ebe01522fe45029940ed21a2cf221f -- annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - kbld.carvel.dev/origins: | - - resolved: - tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 - image: kind-registry.local:5000/test/build/test/build-package-supervisor@sha256:28488e1c9bbf8988c9a9f70ae6478188b6ebe01522fe45029940ed21a2cf221f + tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image: kind-registry.local:5000/test/build/test/build-package-supervisor@sha256:f3ceb23f0202c83955f4ad1a7836325340da25ebb6d2e14f02a66e915b4e09f5 kind: ImagesLock diff --git a/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml b/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml new file mode 100644 index 00000000..05f9351b --- /dev/null +++ b/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml @@ -0,0 +1,173 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: Package +metadata: + name: concierge.pinniped.dev.0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 +spec: + refName: concierge.pinniped.dev + version: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + releaseNotes: | + Initial release of the pinniped concierge package, TODO: AUTOMATE THIS?? + valuesSchema: + openAPIv3: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-concierge. + default: pinniped-concierge + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-concierge + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: null + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + kube_cert_agent_image: + type: string + nullable: true + description: Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled on the control plane. This image needs only to include `sleep` and `cat` binaries. By default, the same image specified for image_repo/image_digest/image_tag will be re-used. + default: null + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + discovery_url: + type: string + nullable: true + description: Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden. + default: null + api_serving_certificate_duration_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2592000 + api_serving_certificate_renew_before_seconds: + type: integer + description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. + default: 2160000 + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + impersonation_proxy_spec: + type: object + additionalProperties: false + description: Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation. + properties: + mode: + type: string + description: If enabled, the impersonation proxy will always run regardless of other strategies available. + default: auto + external_endpoint: + type: string + nullable: true + description: The endpoint which the client should use to connect to the impersonation proxy. If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint. + default: null + service: + type: object + additionalProperties: false + description: The impersonation proxy service configuration + properties: + type: + type: string + nullable: true + description: Options are 'LoadBalancer', 'ClusterIP' and 'None'. + default: null + annotations: + type: object + additionalProperties: false + nullable: true + description: The annotations that should be set on the ClusterIP or LoadBalancer Service. + properties: + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: + type: string + default: "4000" + load_balancer_ip: + type: string + nullable: true + description: When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP. + default: null + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local + template: + spec: + fetch: + - imgpkgBundle: + image: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + template: + - ytt: + paths: + - config/ + - kbld: + paths: + - .imgpkg/images.yml + - '-' + deploy: + - kapp: {} diff --git a/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml b/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml new file mode 100644 index 00000000..e00acc0f --- /dev/null +++ b/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml @@ -0,0 +1,73 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: Package +metadata: + name: local-user-authenticator.pinniped.dev.0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 +spec: + refName: local-user-authenticator.pinniped.dev + version: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + releaseNotes: | + Initial release of the local-user-authenticator package, TODO: AUTOMATE THIS?? + valuesSchema: + openAPIv3: + type: object + additionalProperties: false + properties: + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + template: + spec: + fetch: + - imgpkgBundle: + image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + template: + - ytt: + paths: + - config/ + - kbld: + paths: + - .imgpkg/images.yml + - '-' + deploy: + - kapp: {} diff --git a/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml b/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml new file mode 100644 index 00000000..6ae8c717 --- /dev/null +++ b/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml @@ -0,0 +1,182 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: Package +metadata: + name: supervisor.pinniped.dev.0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 +spec: + refName: supervisor.pinniped.dev + version: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + releaseNotes: | + Initial release of the pinniped supervisor package, TODO: AUTOMATE THIS?? + valuesSchema: + openAPIv3: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-supervisor. + default: pinniped-supervisor + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-supervisor + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: null + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + deprecated_service_http_nodeport_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_nodeport_nodeport: + type: integer + nullable: true + description: will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified + default: null + deprecated_service_http_loadbalancer_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_clusterip_port: + type: integer + nullable: true + description: '#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`' + default: null + service_https_nodeport_port: + type: integer + nullable: true + description: '#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_nodeport_nodeport: + type: integer + nullable: true + description: '#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified' + default: null + service_https_loadbalancer_port: + type: integer + nullable: true + description: '#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_clusterip_port: + type: integer + nullable: true + description: '#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_loadbalancer_ip: + type: string + nullable: true + description: The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided. + default: null + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local + endpoints: + type: object + additionalProperties: false + nullable: true + description: Control the HTTP and HTTPS listeners of the Supervisor. + properties: + https: + type: object + additionalProperties: false + properties: + network: + type: string + default: tcp + address: + type: string + default: 1.2.3.4:5678 + deprecated_insecure_accept_external_unencrypted_http_requests: + type: boolean + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: false + template: + spec: + fetch: + - imgpkgBundle: + image: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + template: + - ytt: + paths: + - config/ + - kbld: + paths: + - .imgpkg/images.yml + - '-' + deploy: + - kapp: {} diff --git a/deploy_carvel/supervisor-pkginstall.yml b/deploy_carvel/supervisor-pkginstall.yml index b166fce3..86caeebe 100644 --- a/deploy_carvel/supervisor-pkginstall.yml +++ b/deploy_carvel/supervisor-pkginstall.yml @@ -10,7 +10,7 @@ spec: packageRef: refName: "supervisor.pinniped.dev" versionSelection: - constraints: "0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7" + constraints: "0.0.0-F3326187-009A-4313-B188-1B454D1A7E04" values: - secretRef: name: "supervisor-package-install-secret" @@ -27,7 +27,7 @@ stringData: namespace: supervisor api_group_suffix: pinniped.dev image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-EEE84AC0-DE44-425C-8785-4C6DD92307F7 + image_tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 log_level: debug service_https_nodeport_port: 443 diff --git a/deploy_carvel/supervisor/schema-openapi.yaml b/deploy_carvel/supervisor/schema-openapi.yaml new file mode 100644 index 00000000..0e0903fa --- /dev/null +++ b/deploy_carvel/supervisor/schema-openapi.yaml @@ -0,0 +1,164 @@ +openapi: 3.0.0 +info: + version: 0.1.0 + title: Schema for data values, generated by ytt +paths: {} +components: + schemas: + dataValues: + type: object + additionalProperties: false + properties: + app_name: + type: string + description: Name of pinniped-supervisor. + default: pinniped-supervisor + namespace: + type: string + description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. + default: pinniped-supervisor + into_namespace: + type: string + nullable: true + description: 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. + default: null + custom_labels: + nullable: true + description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' + default: {} + replicas: + type: integer + description: Specify how many replicas of the Pinniped server to run. + default: 2 + image_repo: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: projects.registry.vmware.com/pinniped/pinniped-server + image_digest: + type: string + nullable: true + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: null + image_tag: + type: string + description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. + default: latest + image_pull_dockerconfigjson: + type: object + additionalProperties: false + nullable: true + description: '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.' + properties: + auths: + type: object + additionalProperties: false + properties: + https://registry.example.com: + type: object + additionalProperties: false + properties: + username: + type: string + default: USERNAME + password: + type: string + default: PASSWORD + auth: + type: string + default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + deprecated_service_http_nodeport_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_nodeport_nodeport: + type: integer + nullable: true + description: will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified + default: null + deprecated_service_http_loadbalancer_port: + type: integer + nullable: true + description: will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort` + default: null + deprecated_service_http_clusterip_port: + type: integer + nullable: true + description: '#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`' + default: null + service_https_nodeport_port: + type: integer + nullable: true + description: '#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_nodeport_nodeport: + type: integer + nullable: true + description: '#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified' + default: null + service_https_loadbalancer_port: + type: integer + nullable: true + description: '#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_https_clusterip_port: + type: integer + nullable: true + description: '#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`' + default: null + service_loadbalancer_ip: + type: string + nullable: true + description: The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided. + default: null + log_level: + type: string + nullable: true + description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. + default: null + deprecated_log_format: + type: string + nullable: true + description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' + default: null + run_as_user: + type: integer + description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + run_as_group: + type: integer + description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice + default: 65532 + api_group_suffix: + type: string + description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. + default: pinniped.dev + https_proxy: + type: string + nullable: true + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: null + no_proxy: + type: string + description: do not proxy Kubernetes endpoints + default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local + endpoints: + type: object + additionalProperties: false + nullable: true + description: Control the HTTP and HTTPS listeners of the Supervisor. + properties: + https: + type: object + additionalProperties: false + properties: + network: + type: string + default: tcp + address: + type: string + default: 1.2.3.4:5678 + deprecated_insecure_accept_external_unencrypted_http_requests: + type: boolean + description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. + default: false diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index acda6b24..da493580 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -80,7 +80,7 @@ kapp deploy --app kapp-controller --file "https://github.com/vmware-tanzu/carvel kubectl get customresourcedefinitions # Generate the OpenAPI v3 Schema files, imgpkg images.yml files -declare -a arr=("supervisor" "concierge" "local-user-authenticator") +declare -a arr=("local-user-authenticator" "concierge" "supervisor") for resource_name in "${arr[@]}" do resource_qualified_name="${resource_name}.${api_group_suffix}" @@ -88,11 +88,12 @@ do resource_dir="deploy_carvel/${resource_name}" resource_config_source_dir="deploy/${resource_name}" - resource_config_destination_dir="deploy_carvel/${resource_name}/config" + resource_destination_dir="deploy_carvel/${resource_name}" + resource_config_destination_dir="${resource_destination_dir}/config" # these must be real files, not symlinks log_note "Vendir sync deploy directory for ${resource_name} to package bundle..." - pushd "${resource_config_destination_dir}" > /dev/null + pushd "${resource_destination_dir}" > /dev/null vendir sync popd > /dev/null @@ -122,6 +123,9 @@ do # TODO: what is package_image_repo? # TODO: package_version should just become version, no need for it to not match. package_repository_dir="deploy_carvel/package_repository/packages/${resource_qualified_name}" + rm -rf "${package_repository_dir}" + mkdir "${package_repository_dir}" + ytt \ --file "${resource_dir}/package-template.yml" \ --data-value-file openapi="${resource_dir}/schema-openapi.yml" \ @@ -130,6 +134,7 @@ do cp "deploy_carvel/${resource_name}/metadata.yml" "${package_repository_dir}/metadata.yml" done + log_note "Generating .imgpkg/images.yml for Pinniped PackageRepository bundle..." mkdir -p "deploy_carvel/package_repository/.imgpkg" kbld --file "deploy_carvel/package_repository/packages/" --imgpkg-lock-output "deploy_carvel/package_repository/.imgpkg/images.yml" @@ -142,9 +147,13 @@ log_note "Validating Pinniped PackageRepository bundle not empty /tmp/${package_ imgpkg pull --bundle "${package_repository_repo_tag}" --output "/tmp/${package_repository_repo_tag}" + +## NOTE: could break apart here at a build and a deploy script. + + log_note "deploying PackageRepository..." pinniped_package_repository_name="pinniped-package-repository" -pinniped_package_repository_file="packagerepository.${pinniped_package_version}.yml" +pinniped_package_repository_file="packagerepository.${pinniped_package_version}.yml" # TODO: deploy_carvel/ dir... echo -n "" > "${pinniped_package_repository_file}" cat <> "${pinniped_package_repository_file}" --- @@ -163,7 +172,6 @@ kapp deploy --app "${pinniped_package_repository_name}" --file "${pinniped_packa kapp inspect --app "${pinniped_package_repository_name}" --tree - for resource_name in "${arr[@]}" do log_note "creating PackageInstall and RBAC for ${resource_name}..." @@ -213,8 +221,123 @@ EOF kapp deploy --app "${pinniped_package_rbac_prefix}" --file "${pinniped_package_rbac_file}" -y done +# start local-user-authenticator +# local-user-authenticator +log_note "deploying local-user-authenticator PackageInstall resources..." +resource_name="local-user-authenticator" +NAMESPACE="${resource_name}-install-ns" +PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" +RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +SECRET_NAME="${resource_name}-package-install-secret" + +cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "${resource_name}-package-install" + namespace: "${NAMESPACE}" +spec: + serviceAccountName: "${PINNIPED_PACKAGE_RBAC_PREFIX}-sa-superadmin-dangerous" + packageRef: + refName: "${RESOURCE_PACKAGE_VERSION}" + versionSelection: + constraints: "${pinniped_package_version}" + values: + - secretRef: + name: "${SECRET_NAME}" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "${SECRET_NAME}" + namespace: "${NAMESPACE}" +stringData: + values.yml: | + --- + image_repo: $registry_repo + image_tag: $tag +EOF + +KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" +log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." +kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y + +test_username="test-username" +test_groups="test-group-0,test-group-1" +test_password="$(openssl rand -hex 16)" +log_note "Creating test user '$test_username'..." +kubectl create secret generic "$test_username" \ + --namespace local-user-authenticator \ + --from-literal=groups="$test_groups" \ + --from-literal=passwordHash="$(htpasswd -nbBC 10 x "$test_password" | sed -e "s/^x://")" \ + --dry-run=client \ + --output yaml | + kubectl apply -f - +# end local-user-authenticator +# start concierge +log_note "deploying concierge PackageInstall resources..." +resource_name="concierge" +NAMESPACE="${resource_name}-install-ns" +PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" +RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +SECRET_NAME="${resource_name}-package-install-secret" + +# from prepare-for-integration-tests.sh +concierge_app_name="pinniped-concierge" +concierge_namespace="concierge" +webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" +webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" +discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" +concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" +log_level="debug" +cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "${resource_name}-package-install" + namespace: "${NAMESPACE}" +spec: + serviceAccountName: "${PINNIPED_PACKAGE_RBAC_PREFIX}-sa-superadmin-dangerous" + packageRef: + refName: "${RESOURCE_PACKAGE_VERSION}" + versionSelection: + constraints: "${pinniped_package_version}" + values: + - secretRef: + name: "${SECRET_NAME}" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "${SECRET_NAME}" + namespace: "${NAMESPACE}" +stringData: + values.yml: | + --- + app_name: $concierge_app_name + namespace: $concierge_namespace + api_group_suffix: $api_group_suffix + log_level: $log_level + + image_repo: $registry_repo + image_tag: $tag +EOF + +KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" +log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." +kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y +# end concierge + + +# start supervisor log_note "deploying supervisor PackageInstall resources..." resource_name="supervisor" NAMESPACE="${resource_name}-install-ns" @@ -275,124 +398,23 @@ kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_N # end supervisor +log_note "appending environment variables to /tmp/integration-test-env" +# TODO: since I pulled these out of the main script, I'll have to put them back as well. +# To be "finished" the scripts need to work for both the ytt deploy and the carvel package, +# regardless of which branch the user takes. +integration_env_file="/tmp/integration-test-env" +integration_env_file_text=$(cat "${integration_env_file}") -# concierge -log_note "deploying concierge PackageInstall resources..." -resource_name="concierge" -NAMESPACE="${resource_name}-install-ns" -PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" -RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" -PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" -SECRET_NAME="${resource_name}-package-install-secret" - -# from prepare-for-integration-tests.sh -concierge_app_name="pinniped-concierge" -concierge_namespace="concierge" -webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" -webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" -discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" -concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" -log_level="debug" -cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF ---- -apiVersion: packaging.carvel.dev/v1alpha1 -kind: PackageInstall -metadata: - # name, does not have to be versioned, versionSelection.constraints below will handle - name: "${resource_name}-package-install" - namespace: "${NAMESPACE}" -spec: - serviceAccountName: "${PINNIPED_PACKAGE_RBAC_PREFIX}-sa-superadmin-dangerous" - packageRef: - refName: "${RESOURCE_PACKAGE_VERSION}" - versionSelection: - constraints: "${pinniped_package_version}" - values: - - secretRef: - name: "${SECRET_NAME}" ---- -apiVersion: v1 -kind: Secret -metadata: - name: "${SECRET_NAME}" - namespace: "${NAMESPACE}" -stringData: - values.yml: | - --- - app_name: $concierge_app_name - namespace: $concierge_namespace - api_group_suffix: $api_group_suffix - log_level: $log_level - - image_repo: $registry_repo - image_tag: $tag -EOF - -KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" -log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." -kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y -# end concierge +cat <"${integration_env_file}" +export PINNIPED_TEST_USER_USERNAME=${test_username} +export PINNIPED_TEST_USER_GROUPS=${test_groups} +export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} +export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle} +EOT +echo "${integration_env_file_text}" >> "${integration_env_file}" - -# local-user-authenticator -log_note "deploying local-user-authenticator PackageInstall resources..." -resource_name="local-user-authenticator" -NAMESPACE="${resource_name}-install-ns" -PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" -RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" -PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" -SECRET_NAME="${resource_name}-package-install-secret" - -# from prepare-for-integration-tests.sh -concierge_app_name="pinniped-concierge" -concierge_namespace="concierge" -webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" -webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" -discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" -concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" -log_level="debug" -cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF ---- -apiVersion: packaging.carvel.dev/v1alpha1 -kind: PackageInstall -metadata: - # name, does not have to be versioned, versionSelection.constraints below will handle - name: "${resource_name}-package-install" - namespace: "${NAMESPACE}" -spec: - serviceAccountName: "${PINNIPED_PACKAGE_RBAC_PREFIX}-sa-superadmin-dangerous" - packageRef: - refName: "${RESOURCE_PACKAGE_VERSION}" - versionSelection: - constraints: "${pinniped_package_version}" - values: - - secretRef: - name: "${SECRET_NAME}" ---- -apiVersion: v1 -kind: Secret -metadata: - name: "${SECRET_NAME}" - namespace: "${NAMESPACE}" -stringData: - values.yml: | - --- - app_name: $concierge_app_name - namespace: $concierge_namespace - api_group_suffix: $api_group_suffix - log_level: $log_level - - image_repo: $registry_repo - image_tag: $tag -EOF - -KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" -log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." -kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y -# end concierge - log_note "verifying PackageInstall resources..." kubectl get PackageInstall -A | grep pinniped kubectl get secret -A | grep pinniped diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 5c959c52..15cef6f6 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -378,12 +378,15 @@ manifest=/tmp/pinniped-concierge.yaml concierge_app_name="pinniped-concierge" concierge_namespace="concierge" webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" -webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" +webhook_ca_bundle="undefined" # TODO: need to fix this later discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" log_level="debug" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_concierge" != "undefined" ] ; then + # TODO: this is typically needed to export below.... + # our deploy_carvel script may need to append this to the same file. + webhook_ca_bundle="(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag..." $alternate_deploy pinniped-concierge $tag @@ -410,15 +413,6 @@ else popd >/dev/null fi -# -# Call a post-install script -# simplifies passing the $tag which may be necessary if the current local build is to be -# referenced, for example, deploying via a Carvel package rather than our ytt mechanism -if [ "$post_install" != "undefined" ] ; then - log_note "The post-install script will be called with $tag..." - $post_install post-install-script $tag -fi - # # Download the test CA bundle that was generated in the Dex pod. # Note that this returns a base64 encoded value. @@ -435,15 +429,16 @@ test_ca_bundle_pem="$(kubectl get secrets -n tools certs -o go-template='{{index kind_capabilities_file="$pinniped_path/test/cluster_capabilities/kind.yaml" pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file") +# TODO: fix this later +# export PINNIPED_TEST_USER_USERNAME=${test_username} +# export PINNIPED_TEST_USER_GROUPS=${test_groups} +# export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} cat </tmp/integration-test-env # The following env vars should be set before running 'go test -v -count 1 -timeout 0 ./test/integration' export PINNIPED_TEST_TOOLS_NAMESPACE="tools" export PINNIPED_TEST_CONCIERGE_NAMESPACE=${concierge_namespace} export PINNIPED_TEST_CONCIERGE_APP_NAME=${concierge_app_name} export PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS='${concierge_custom_labels}' -export PINNIPED_TEST_USER_USERNAME=${test_username} -export PINNIPED_TEST_USER_GROUPS=${test_groups} -export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} export PINNIPED_TEST_WEBHOOK_ENDPOINT=${webhook_url} export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle} export PINNIPED_TEST_SUPERVISOR_NAMESPACE=${supervisor_namespace} @@ -507,6 +502,18 @@ PINNIPED_TEST_CLUSTER_CAPABILITY_YAML_EOF export PINNIPED_TEST_CLUSTER_CAPABILITY_YAML EOF + +# +# Call a post-install script +# simplifies passing the $tag which may be necessary if the current local build is to be +# referenced, for example, deploying via a Carvel package rather than our ytt mechanism +# running it after the above also allows appending to the environment variable file +if [ "$post_install" != "undefined" ] ; then + log_note "The post-install script will be called with $tag..." + $post_install post-install-script $tag +fi + + # # Print instructions for next steps. # From e6707ca448856c424d60a9625b6c61defae77c59 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 3 Oct 2023 14:01:23 -0400 Subject: [PATCH 16/40] Adjust outputs from build-carvel-package, remove old files --- deploy_carvel/concierge-pkginstall.yml | 4 ++-- .../local-user-authenticator-pkginstall.yml | 4 ++-- .../package_repository/.imgpkg/images.yml | 18 +++++++++--------- ...0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml} | 6 +++--- ...0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml} | 6 +++--- ...0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml} | 6 +++--- ....0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml | 10 ++++++++++ deploy_carvel/supervisor-pkginstall.yml | 4 ++-- hack/build-carvel-packages.sh | 5 +++-- 9 files changed, 37 insertions(+), 26 deletions(-) rename deploy_carvel/package_repository/packages/concierge.pinniped.dev/{0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml => 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml} (98%) rename deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/{0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml => 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml} (92%) rename deploy_carvel/package_repository/packages/supervisor.pinniped.dev/{0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml => 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml} (98%) create mode 100644 deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml diff --git a/deploy_carvel/concierge-pkginstall.yml b/deploy_carvel/concierge-pkginstall.yml index 007f1f8f..1da4bf1c 100644 --- a/deploy_carvel/concierge-pkginstall.yml +++ b/deploy_carvel/concierge-pkginstall.yml @@ -10,7 +10,7 @@ spec: packageRef: refName: "concierge.pinniped.dev" versionSelection: - constraints: "0.0.0-F3326187-009A-4313-B188-1B454D1A7E04" + constraints: "0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" values: - secretRef: name: "concierge-package-install-secret" @@ -29,4 +29,4 @@ stringData: log_level: debug image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image_tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D diff --git a/deploy_carvel/local-user-authenticator-pkginstall.yml b/deploy_carvel/local-user-authenticator-pkginstall.yml index bc950c0a..2de09a06 100644 --- a/deploy_carvel/local-user-authenticator-pkginstall.yml +++ b/deploy_carvel/local-user-authenticator-pkginstall.yml @@ -10,7 +10,7 @@ spec: packageRef: refName: "local-user-authenticator.pinniped.dev" versionSelection: - constraints: "0.0.0-F3326187-009A-4313-B188-1B454D1A7E04" + constraints: "0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" values: - secretRef: name: "local-user-authenticator-package-install-secret" @@ -24,4 +24,4 @@ stringData: values.yml: | --- image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image_tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D diff --git a/deploy_carvel/package_repository/.imgpkg/images.yml b/deploy_carvel/package_repository/.imgpkg/images.yml index 17bc6c5e..bc04629b 100644 --- a/deploy_carvel/package_repository/.imgpkg/images.yml +++ b/deploy_carvel/package_repository/.imgpkg/images.yml @@ -2,24 +2,24 @@ apiVersion: imgpkg.carvel.dev/v1alpha1 images: - annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D kbld.carvel.dev/origins: | - resolved: - tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 - url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D + url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D image: kind-registry.local:5000/test/build/test/build-package-concierge@sha256:ffc8371ff94e939233af0643476a597c025adb5609cc35c5ded6bd67ce13fdec - annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D kbld.carvel.dev/origins: | - resolved: - tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 - url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D + url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator@sha256:4f111f27ecf38622e4cbb29ce1d88589b488d8eb57d9b29cb577d64a417a2c4c - annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D kbld.carvel.dev/origins: | - resolved: - tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 - url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D + url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D image: kind-registry.local:5000/test/build/test/build-package-supervisor@sha256:f3ceb23f0202c83955f4ad1a7836325340da25ebb6d2e14f02a66e915b4e09f5 kind: ImagesLock diff --git a/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml b/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml similarity index 98% rename from deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml rename to deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml index 05f9351b..7c65e2c6 100644 --- a/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml +++ b/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml @@ -1,10 +1,10 @@ apiVersion: data.packaging.carvel.dev/v1alpha1 kind: Package metadata: - name: concierge.pinniped.dev.0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + name: concierge.pinniped.dev.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D spec: refName: concierge.pinniped.dev - version: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + version: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D releaseNotes: | Initial release of the pinniped concierge package, TODO: AUTOMATE THIS?? valuesSchema: @@ -160,7 +160,7 @@ spec: spec: fetch: - imgpkgBundle: - image: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D template: - ytt: paths: diff --git a/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml b/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml similarity index 92% rename from deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml rename to deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml index e00acc0f..e1603132 100644 --- a/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml +++ b/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml @@ -1,10 +1,10 @@ apiVersion: data.packaging.carvel.dev/v1alpha1 kind: Package metadata: - name: local-user-authenticator.pinniped.dev.0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + name: local-user-authenticator.pinniped.dev.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D spec: refName: local-user-authenticator.pinniped.dev - version: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + version: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D releaseNotes: | Initial release of the local-user-authenticator package, TODO: AUTOMATE THIS?? valuesSchema: @@ -60,7 +60,7 @@ spec: spec: fetch: - imgpkgBundle: - image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D template: - ytt: paths: diff --git a/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml b/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml similarity index 98% rename from deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml rename to deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml index 6ae8c717..d64f6591 100644 --- a/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-F3326187-009A-4313-B188-1B454D1A7E04.yml +++ b/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml @@ -1,10 +1,10 @@ apiVersion: data.packaging.carvel.dev/v1alpha1 kind: Package metadata: - name: supervisor.pinniped.dev.0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + name: supervisor.pinniped.dev.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D spec: refName: supervisor.pinniped.dev - version: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + version: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D releaseNotes: | Initial release of the pinniped supervisor package, TODO: AUTOMATE THIS?? valuesSchema: @@ -169,7 +169,7 @@ spec: spec: fetch: - imgpkgBundle: - image: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D template: - ytt: paths: diff --git a/deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml b/deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml new file mode 100644 index 00000000..6032738d --- /dev/null +++ b/deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml @@ -0,0 +1,10 @@ +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageRepository +metadata: + name: "pinniped-package-repository" + namespace: "kapp-controller-packaging-global" +spec: + fetch: + imgpkgBundle: + image: "kind-registry.local:5000/test/build/test/build-package-repository-pinniped:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" diff --git a/deploy_carvel/supervisor-pkginstall.yml b/deploy_carvel/supervisor-pkginstall.yml index 86caeebe..9de43f13 100644 --- a/deploy_carvel/supervisor-pkginstall.yml +++ b/deploy_carvel/supervisor-pkginstall.yml @@ -10,7 +10,7 @@ spec: packageRef: refName: "supervisor.pinniped.dev" versionSelection: - constraints: "0.0.0-F3326187-009A-4313-B188-1B454D1A7E04" + constraints: "0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" values: - secretRef: name: "supervisor-package-install-secret" @@ -27,7 +27,7 @@ stringData: namespace: supervisor api_group_suffix: pinniped.dev image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-F3326187-009A-4313-B188-1B454D1A7E04 + image_tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D log_level: debug service_https_nodeport_port: 443 diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index da493580..edd7fc03 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -134,7 +134,6 @@ do cp "deploy_carvel/${resource_name}/metadata.yml" "${package_repository_dir}/metadata.yml" done - log_note "Generating .imgpkg/images.yml for Pinniped PackageRepository bundle..." mkdir -p "deploy_carvel/package_repository/.imgpkg" kbld --file "deploy_carvel/package_repository/packages/" --imgpkg-lock-output "deploy_carvel/package_repository/.imgpkg/images.yml" @@ -153,7 +152,9 @@ imgpkg pull --bundle "${package_repository_repo_tag}" --output "/tmp/${package_r log_note "deploying PackageRepository..." pinniped_package_repository_name="pinniped-package-repository" -pinniped_package_repository_file="packagerepository.${pinniped_package_version}.yml" # TODO: deploy_carvel/ dir... +# TODO: deploy_carvel/ dir... +# TODO: delete the "extras", so perhaps put this in a "deploy_carvel/tmp/" dir that can be cleaned. +pinniped_package_repository_file="deploy_carvel/packagerepository.${pinniped_package_version}.yml" echo -n "" > "${pinniped_package_repository_file}" cat <> "${pinniped_package_repository_file}" --- From eeb08d52b703b2f0de474c3bef3ed26ffe5330dd Mon Sep 17 00:00:00 2001 From: Joshua Casey Date: Tue, 3 Oct 2023 14:14:31 -0500 Subject: [PATCH 17/40] Don't add 0.0.0 files to the git repository --- deploy_carvel/.gitignore | 1 + ...0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml | 173 ----------------- ...0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml | 73 ------- ...0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml | 182 ------------------ ...0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml | 10 - 5 files changed, 1 insertion(+), 438 deletions(-) create mode 100644 deploy_carvel/.gitignore delete mode 100644 deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml delete mode 100644 deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml delete mode 100644 deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml delete mode 100644 deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml diff --git a/deploy_carvel/.gitignore b/deploy_carvel/.gitignore new file mode 100644 index 00000000..6e5e67eb --- /dev/null +++ b/deploy_carvel/.gitignore @@ -0,0 +1 @@ +*0.0.0* diff --git a/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml b/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml deleted file mode 100644 index 7c65e2c6..00000000 --- a/deploy_carvel/package_repository/packages/concierge.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml +++ /dev/null @@ -1,173 +0,0 @@ -apiVersion: data.packaging.carvel.dev/v1alpha1 -kind: Package -metadata: - name: concierge.pinniped.dev.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D -spec: - refName: concierge.pinniped.dev - version: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - releaseNotes: | - Initial release of the pinniped concierge package, TODO: AUTOMATE THIS?? - valuesSchema: - openAPIv3: - type: object - additionalProperties: false - properties: - app_name: - type: string - description: Name of pinniped-concierge. - default: pinniped-concierge - namespace: - type: string - description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. - default: pinniped-concierge - into_namespace: - type: string - nullable: true - description: 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. - default: null - custom_labels: - nullable: true - description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' - default: null - replicas: - type: integer - description: Specify how many replicas of the Pinniped server to run. - default: 2 - image_repo: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: projects.registry.vmware.com/pinniped/pinniped-server - image_digest: - type: string - nullable: true - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: null - image_tag: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: latest - kube_cert_agent_image: - type: string - nullable: true - description: Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled on the control plane. This image needs only to include `sleep` and `cat` binaries. By default, the same image specified for image_repo/image_digest/image_tag will be re-used. - default: null - image_pull_dockerconfigjson: - type: object - additionalProperties: false - nullable: true - description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD - discovery_url: - type: string - nullable: true - description: Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden. - default: null - api_serving_certificate_duration_seconds: - type: integer - description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. - default: 2592000 - api_serving_certificate_renew_before_seconds: - type: integer - description: Specify the duration and renewal interval for the API serving certificate. The defaults are set to expire the cert about every 30 days, and to rotate it about every 25 days. - default: 2160000 - log_level: - type: string - nullable: true - description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. - default: null - deprecated_log_format: - type: string - nullable: true - description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' - default: null - run_as_user: - type: integer - description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - run_as_group: - type: integer - description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - api_group_suffix: - type: string - description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. - default: pinniped.dev - impersonation_proxy_spec: - type: object - additionalProperties: false - description: Customize CredentialIssuer.spec.impersonationProxy to change how the concierge handles impersonation. - properties: - mode: - type: string - description: If enabled, the impersonation proxy will always run regardless of other strategies available. - default: auto - external_endpoint: - type: string - nullable: true - description: The endpoint which the client should use to connect to the impersonation proxy. If left unset, the client will default to connecting based on the ClusterIP or LoadBalancer endpoint. - default: null - service: - type: object - additionalProperties: false - description: The impersonation proxy service configuration - properties: - type: - type: string - nullable: true - description: Options are 'LoadBalancer', 'ClusterIP' and 'None'. - default: null - annotations: - type: object - additionalProperties: false - nullable: true - description: The annotations that should be set on the ClusterIP or LoadBalancer Service. - properties: - service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: - type: string - default: "4000" - load_balancer_ip: - type: string - nullable: true - description: When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP. - default: null - https_proxy: - type: string - nullable: true - description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. - default: null - no_proxy: - type: string - description: do not proxy Kubernetes endpoints - default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local - template: - spec: - fetch: - - imgpkgBundle: - image: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - template: - - ytt: - paths: - - config/ - - kbld: - paths: - - .imgpkg/images.yml - - '-' - deploy: - - kapp: {} diff --git a/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml b/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml deleted file mode 100644 index e1603132..00000000 --- a/deploy_carvel/package_repository/packages/local-user-authenticator.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml +++ /dev/null @@ -1,73 +0,0 @@ -apiVersion: data.packaging.carvel.dev/v1alpha1 -kind: Package -metadata: - name: local-user-authenticator.pinniped.dev.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D -spec: - refName: local-user-authenticator.pinniped.dev - version: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - releaseNotes: | - Initial release of the local-user-authenticator package, TODO: AUTOMATE THIS?? - valuesSchema: - openAPIv3: - type: object - additionalProperties: false - properties: - image_repo: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: projects.registry.vmware.com/pinniped/pinniped-server - image_digest: - type: string - nullable: true - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: null - image_tag: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: latest - image_pull_dockerconfigjson: - type: object - additionalProperties: false - nullable: true - description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD - run_as_user: - type: integer - description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - run_as_group: - type: integer - description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - template: - spec: - fetch: - - imgpkgBundle: - image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - template: - - ytt: - paths: - - config/ - - kbld: - paths: - - .imgpkg/images.yml - - '-' - deploy: - - kapp: {} diff --git a/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml b/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml deleted file mode 100644 index d64f6591..00000000 --- a/deploy_carvel/package_repository/packages/supervisor.pinniped.dev/0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml +++ /dev/null @@ -1,182 +0,0 @@ -apiVersion: data.packaging.carvel.dev/v1alpha1 -kind: Package -metadata: - name: supervisor.pinniped.dev.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D -spec: - refName: supervisor.pinniped.dev - version: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - releaseNotes: | - Initial release of the pinniped supervisor package, TODO: AUTOMATE THIS?? - valuesSchema: - openAPIv3: - type: object - additionalProperties: false - properties: - app_name: - type: string - description: Name of pinniped-supervisor. - default: pinniped-supervisor - namespace: - type: string - description: Creates a new namespace statically in yaml with the given name and installs the app into that namespace. - default: pinniped-supervisor - into_namespace: - type: string - nullable: true - description: 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. - default: null - custom_labels: - nullable: true - description: '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 value of `custom_labels` must be a map of string keys to string values. 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.' - default: null - replicas: - type: integer - description: Specify how many replicas of the Pinniped server to run. - default: 2 - image_repo: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: projects.registry.vmware.com/pinniped/pinniped-server - image_digest: - type: string - nullable: true - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: null - image_tag: - type: string - description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. - default: latest - image_pull_dockerconfigjson: - type: object - additionalProperties: false - nullable: true - description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD - deprecated_service_http_nodeport_port: - type: integer - nullable: true - description: will be removed in a future release; when specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort` - default: null - deprecated_service_http_nodeport_nodeport: - type: integer - nullable: true - description: will be removed in a future release; the `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified - default: null - deprecated_service_http_loadbalancer_port: - type: integer - nullable: true - description: will be removed in a future release; when specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort` - default: null - deprecated_service_http_clusterip_port: - type: integer - nullable: true - description: '#! will be removed in a future release; when specified, creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`' - default: null - service_https_nodeport_port: - type: integer - nullable: true - description: '#! when specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`' - default: null - service_https_nodeport_nodeport: - type: integer - nullable: true - description: '#! the `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified' - default: null - service_https_loadbalancer_port: - type: integer - nullable: true - description: '#! when specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`' - default: null - service_https_clusterip_port: - type: integer - nullable: true - description: '#! when specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`' - default: null - service_loadbalancer_ip: - type: string - nullable: true - description: The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided. - default: null - log_level: - type: string - nullable: true - description: default, when this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs. - default: null - deprecated_log_format: - type: string - nullable: true - description: 'Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). By default, when this value is left unset, logs are formatted in json. This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json.' - default: null - run_as_user: - type: integer - description: run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - run_as_group: - type: integer - description: run_as_group specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice - default: 65532 - api_group_suffix: - type: string - description: Specify the API group suffix for all Pinniped API groups. By default, this is set to pinniped.dev, so Pinniped API groups will look like foo.pinniped.dev, authentication.concierge.pinniped.dev, etc. As an example, if this is set to tuna.io, then Pinniped API groups will look like foo.tuna.io. authentication.concierge.tuna.io, etc. - default: pinniped.dev - https_proxy: - type: string - nullable: true - description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. - default: null - no_proxy: - type: string - description: do not proxy Kubernetes endpoints - default: $(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local - endpoints: - type: object - additionalProperties: false - nullable: true - description: Control the HTTP and HTTPS listeners of the Supervisor. - properties: - https: - type: object - additionalProperties: false - properties: - network: - type: string - default: tcp - address: - type: string - default: 1.2.3.4:5678 - deprecated_insecure_accept_external_unencrypted_http_requests: - type: boolean - description: Set the standard golang HTTPS_PROXY and NO_PROXY environment variables on the Supervisor containers. These will be used when the Supervisor makes backend-to-backend calls to upstream identity providers using HTTPS, e.g. when the Supervisor fetches discovery documents, JWKS keys, and tokens from an upstream OIDC Provider. The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY. Optional. - default: false - template: - spec: - fetch: - - imgpkgBundle: - image: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - template: - - ytt: - paths: - - config/ - - kbld: - paths: - - .imgpkg/images.yml - - '-' - deploy: - - kapp: {} diff --git a/deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml b/deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml deleted file mode 100644 index 6032738d..00000000 --- a/deploy_carvel/packagerepository.0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -apiVersion: packaging.carvel.dev/v1alpha1 -kind: PackageRepository -metadata: - name: "pinniped-package-repository" - namespace: "kapp-controller-packaging-global" -spec: - fetch: - imgpkgBundle: - image: "kind-registry.local:5000/test/build/test/build-package-repository-pinniped:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" From 740463bba7f6b5cdd07b243c0fdc5d1347e28130 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 10 Oct 2023 12:54:13 -0400 Subject: [PATCH 18/40] add vars back to prepare-for-integration-tests script --- hack/prepare-for-integration-tests.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 15cef6f6..d906808e 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -273,7 +273,9 @@ docker push "$registry_repo_tag" # Deploy local-user-authenticator # manifest=/tmp/pinniped-local-user-authenticator.yaml - +test_username="" +test_groups="" +test_password="" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_local_user_authenticator" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag..." @@ -293,7 +295,6 @@ else kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. - # TODO: will have to create this in our package install script.... test_username="test-username" test_groups="test-group-0,test-group-1" test_password="$(openssl rand -hex 16)" @@ -378,14 +379,12 @@ manifest=/tmp/pinniped-concierge.yaml concierge_app_name="pinniped-concierge" concierge_namespace="concierge" webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" -webhook_ca_bundle="undefined" # TODO: need to fix this later +webhook_ca_bundle="undefined" discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" log_level="debug" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_concierge" != "undefined" ] ; then - # TODO: this is typically needed to export below.... - # our deploy_carvel script may need to append this to the same file. webhook_ca_bundle="(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag..." @@ -429,16 +428,16 @@ test_ca_bundle_pem="$(kubectl get secrets -n tools certs -o go-template='{{index kind_capabilities_file="$pinniped_path/test/cluster_capabilities/kind.yaml" pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file") -# TODO: fix this later -# export PINNIPED_TEST_USER_USERNAME=${test_username} -# export PINNIPED_TEST_USER_GROUPS=${test_groups} -# export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} + cat </tmp/integration-test-env # The following env vars should be set before running 'go test -v -count 1 -timeout 0 ./test/integration' export PINNIPED_TEST_TOOLS_NAMESPACE="tools" export PINNIPED_TEST_CONCIERGE_NAMESPACE=${concierge_namespace} export PINNIPED_TEST_CONCIERGE_APP_NAME=${concierge_app_name} export PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS='${concierge_custom_labels}' +export PINNIPED_TEST_USER_USERNAME=${test_username} +export PINNIPED_TEST_USER_GROUPS=${test_groups} +export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} export PINNIPED_TEST_WEBHOOK_ENDPOINT=${webhook_url} export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle} export PINNIPED_TEST_SUPERVISOR_NAMESPACE=${supervisor_namespace} From 231870582ebcddd72c6165b1a79c5c848bac0426 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 10 Oct 2023 13:03:20 -0400 Subject: [PATCH 19/40] cleanup local registry in kind-down.sh --- hack/kind-down.sh | 5 +++++ hack/prepare-for-integration-tests.sh | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hack/kind-down.sh b/hack/kind-down.sh index d90ccef2..be359cb4 100755 --- a/hack/kind-down.sh +++ b/hack/kind-down.sh @@ -8,4 +8,9 @@ set -euo pipefail ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" cd "${ROOT}" +reg_name='kind-registry.local' +docker network disconnect "kind" "${reg_name}" || true +docker stop "${reg_name}" || true +docker rm "${reg_name}" || true + kind delete cluster --name pinniped diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index d906808e..450d7e5f 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -385,7 +385,7 @@ concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValu log_level="debug" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_concierge" != "undefined" ] ; then - webhook_ca_bundle="(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" + webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag..." $alternate_deploy pinniped-concierge $tag From 761e3237777b6750ca48449ac30de8dd2e6675ca Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 10 Oct 2023 13:44:22 -0400 Subject: [PATCH 20/40] ignore images.yml and pkginstall.yml files (specific SHAs) --- deploy_carvel/.gitignore | 13 +++++++ deploy_carvel/concierge-pkginstall.yml | 32 ----------------- .../local-user-authenticator-pkginstall.yml | 27 -------------- .../package_repository/.imgpkg/images.yml | 25 ------------- deploy_carvel/supervisor-pkginstall.yml | 35 ------------------- 5 files changed, 13 insertions(+), 119 deletions(-) delete mode 100644 deploy_carvel/concierge-pkginstall.yml delete mode 100644 deploy_carvel/local-user-authenticator-pkginstall.yml delete mode 100644 deploy_carvel/package_repository/.imgpkg/images.yml delete mode 100644 deploy_carvel/supervisor-pkginstall.yml diff --git a/deploy_carvel/.gitignore b/deploy_carvel/.gitignore index 6e5e67eb..393a4d4c 100644 --- a/deploy_carvel/.gitignore +++ b/deploy_carvel/.gitignore @@ -1 +1,14 @@ +# package_repository/packages/{pkg}/ contains specific SHAs of images +# we are using 0.0.0- to indicate dev versions of images *0.0.0* + +# pkginstall.yml files contain specific SHAs of images +concierge-pkginstall.yml +local-user-authenticator-pkginstall.yml +supervisor-pkginstall.yml + +# images.yml files contain specific SHAs of images +concierge/.imgpkg/images.yml +supervisor/.imgpkg/images.yml +local-user-authenticator/.imgpkg/images.yml +package_repository/.imgpkg/images.yml diff --git a/deploy_carvel/concierge-pkginstall.yml b/deploy_carvel/concierge-pkginstall.yml deleted file mode 100644 index 1da4bf1c..00000000 --- a/deploy_carvel/concierge-pkginstall.yml +++ /dev/null @@ -1,32 +0,0 @@ ---- -apiVersion: packaging.carvel.dev/v1alpha1 -kind: PackageInstall -metadata: - # name, does not have to be versioned, versionSelection.constraints below will handle - name: "concierge-package-install" - namespace: "concierge-install-ns" -spec: - serviceAccountName: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" - packageRef: - refName: "concierge.pinniped.dev" - versionSelection: - constraints: "0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" - values: - - secretRef: - name: "concierge-package-install-secret" ---- -apiVersion: v1 -kind: Secret -metadata: - name: "concierge-package-install-secret" - namespace: "concierge-install-ns" -stringData: - values.yml: | - --- - app_name: pinniped-concierge - namespace: concierge - api_group_suffix: pinniped.dev - log_level: debug - - image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D diff --git a/deploy_carvel/local-user-authenticator-pkginstall.yml b/deploy_carvel/local-user-authenticator-pkginstall.yml deleted file mode 100644 index 2de09a06..00000000 --- a/deploy_carvel/local-user-authenticator-pkginstall.yml +++ /dev/null @@ -1,27 +0,0 @@ ---- -apiVersion: packaging.carvel.dev/v1alpha1 -kind: PackageInstall -metadata: - # name, does not have to be versioned, versionSelection.constraints below will handle - name: "local-user-authenticator-package-install" - namespace: "local-user-authenticator-install-ns" -spec: - serviceAccountName: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" - packageRef: - refName: "local-user-authenticator.pinniped.dev" - versionSelection: - constraints: "0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" - values: - - secretRef: - name: "local-user-authenticator-package-install-secret" ---- -apiVersion: v1 -kind: Secret -metadata: - name: "local-user-authenticator-package-install-secret" - namespace: "local-user-authenticator-install-ns" -stringData: - values.yml: | - --- - image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D diff --git a/deploy_carvel/package_repository/.imgpkg/images.yml b/deploy_carvel/package_repository/.imgpkg/images.yml deleted file mode 100644 index bc04629b..00000000 --- a/deploy_carvel/package_repository/.imgpkg/images.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -apiVersion: imgpkg.carvel.dev/v1alpha1 -images: -- annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - kbld.carvel.dev/origins: | - - resolved: - tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - url: kind-registry.local:5000/test/build/test/build-package-concierge:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - image: kind-registry.local:5000/test/build/test/build-package-concierge@sha256:ffc8371ff94e939233af0643476a597c025adb5609cc35c5ded6bd67ce13fdec -- annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - kbld.carvel.dev/origins: | - - resolved: - tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - url: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - image: kind-registry.local:5000/test/build/test/build-package-local-user-authenticator@sha256:4f111f27ecf38622e4cbb29ce1d88589b488d8eb57d9b29cb577d64a417a2c4c -- annotations: - kbld.carvel.dev/id: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - kbld.carvel.dev/origins: | - - resolved: - tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - url: kind-registry.local:5000/test/build/test/build-package-supervisor:0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - image: kind-registry.local:5000/test/build/test/build-package-supervisor@sha256:f3ceb23f0202c83955f4ad1a7836325340da25ebb6d2e14f02a66e915b4e09f5 -kind: ImagesLock diff --git a/deploy_carvel/supervisor-pkginstall.yml b/deploy_carvel/supervisor-pkginstall.yml deleted file mode 100644 index 9de43f13..00000000 --- a/deploy_carvel/supervisor-pkginstall.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -apiVersion: packaging.carvel.dev/v1alpha1 -kind: PackageInstall -metadata: - # name, does not have to be versioned, versionSelection.constraints below will handle - name: "supervisor-package-install" - namespace: "supervisor-install-ns" -spec: - serviceAccountName: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" - packageRef: - refName: "supervisor.pinniped.dev" - versionSelection: - constraints: "0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D" - values: - - secretRef: - name: "supervisor-package-install-secret" ---- -apiVersion: v1 -kind: Secret -metadata: - name: "supervisor-package-install-secret" - namespace: "supervisor-install-ns" -stringData: - values.yml: | - --- - app_name: pinniped-supervisor - namespace: supervisor - api_group_suffix: pinniped.dev - image_repo: kind-registry.local:5000/test/build - image_tag: 0.0.0-B0EC99E6-F598-42A9-8976-DFCE049C768D - log_level: debug - - service_https_nodeport_port: 443 - service_https_nodeport_nodeport: 31243 - service_https_clusterip_port: 443 From 4b5e869a5e87e3eb6b48db3d6e9f501182cc9142 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 10 Oct 2023 16:20:58 -0400 Subject: [PATCH 21/40] webhook_ca_bundle moved in hack script --- hack/prepare-for-integration-tests.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 450d7e5f..19c45b03 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -276,6 +276,7 @@ manifest=/tmp/pinniped-local-user-authenticator.yaml test_username="" test_groups="" test_password="" +webhook_ca_bundle="undefined" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_local_user_authenticator" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag..." @@ -294,6 +295,7 @@ else kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. + webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" test_username="test-username" test_groups="test-group-0,test-group-1" @@ -379,13 +381,11 @@ manifest=/tmp/pinniped-concierge.yaml concierge_app_name="pinniped-concierge" concierge_namespace="concierge" webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" -webhook_ca_bundle="undefined" discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" log_level="debug" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_concierge" != "undefined" ] ; then - webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag..." $alternate_deploy pinniped-concierge $tag From f521917b5e75de8605d58dafc01bb56da49db7c0 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 10 Oct 2023 17:22:37 -0400 Subject: [PATCH 22/40] adjust were to call post-install script --- hack/build-carvel-packages.sh | 5 ----- hack/prepare-for-integration-tests.sh | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index edd7fc03..3ab9a557 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -120,8 +120,6 @@ do log_note "Generating PackageRepository Package entry for ${resource_name}" # publish package versions to package repository - # TODO: what is package_image_repo? - # TODO: package_version should just become version, no need for it to not match. package_repository_dir="deploy_carvel/package_repository/packages/${resource_qualified_name}" rm -rf "${package_repository_dir}" mkdir "${package_repository_dir}" @@ -293,7 +291,6 @@ SECRET_NAME="${resource_name}-package-install-secret" concierge_app_name="pinniped-concierge" concierge_namespace="concierge" webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" -webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" log_level="debug" @@ -400,7 +397,6 @@ kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_N log_note "appending environment variables to /tmp/integration-test-env" -# TODO: since I pulled these out of the main script, I'll have to put them back as well. # To be "finished" the scripts need to work for both the ytt deploy and the carvel package, # regardless of which branch the user takes. integration_env_file="/tmp/integration-test-env" @@ -410,7 +406,6 @@ cat <"${integration_env_file}" export PINNIPED_TEST_USER_USERNAME=${test_username} export PINNIPED_TEST_USER_GROUPS=${test_groups} export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} -export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle} EOT echo "${integration_env_file_text}" >> "${integration_env_file}" diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 19c45b03..203d93b1 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -276,7 +276,7 @@ manifest=/tmp/pinniped-local-user-authenticator.yaml test_username="" test_groups="" test_password="" -webhook_ca_bundle="undefined" +webhook_ca_bundle="" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_local_user_authenticator" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag..." @@ -295,7 +295,6 @@ else kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. - webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" test_username="test-username" test_groups="test-group-0,test-group-1" @@ -412,6 +411,16 @@ else popd >/dev/null fi +# +# Call a post-install script +# simplifies passing the $tag which may be necessary if the current local build is to be +# referenced, for example, deploying via a Carvel package rather than our ytt mechanism +# running it after the above also allows appending to the environment variable file +if [ "$post_install" != "undefined" ] ; then + log_note "The post-install script will be called with $tag..." + $post_install post-install-script $tag +fi + # # Download the test CA bundle that was generated in the Dex pod. # Note that this returns a base64 encoded value. @@ -428,6 +437,8 @@ test_ca_bundle_pem="$(kubectl get secrets -n tools certs -o go-template='{{index kind_capabilities_file="$pinniped_path/test/cluster_capabilities/kind.yaml" pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file") +# however it was installed, we need the CA bundle now +webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" cat </tmp/integration-test-env # The following env vars should be set before running 'go test -v -count 1 -timeout 0 ./test/integration' @@ -502,17 +513,6 @@ export PINNIPED_TEST_CLUSTER_CAPABILITY_YAML EOF -# -# Call a post-install script -# simplifies passing the $tag which may be necessary if the current local build is to be -# referenced, for example, deploying via a Carvel package rather than our ytt mechanism -# running it after the above also allows appending to the environment variable file -if [ "$post_install" != "undefined" ] ; then - log_note "The post-install script will be called with $tag..." - $post_install post-install-script $tag -fi - - # # Print instructions for next steps. # From f2b5d568d9fa9907179bdaf24ff99eb9b2d0c0ce Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 12:09:04 -0400 Subject: [PATCH 23/40] improve cleanup of carvel package artifacts --- deploy_carvel/.gitignore | 12 ++---------- hack/build-carvel-packages.sh | 16 +++++++++------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/deploy_carvel/.gitignore b/deploy_carvel/.gitignore index 393a4d4c..94b9a4bc 100644 --- a/deploy_carvel/.gitignore +++ b/deploy_carvel/.gitignore @@ -2,13 +2,5 @@ # we are using 0.0.0- to indicate dev versions of images *0.0.0* -# pkginstall.yml files contain specific SHAs of images -concierge-pkginstall.yml -local-user-authenticator-pkginstall.yml -supervisor-pkginstall.yml - -# images.yml files contain specific SHAs of images -concierge/.imgpkg/images.yml -supervisor/.imgpkg/images.yml -local-user-authenticator/.imgpkg/images.yml -package_repository/.imgpkg/images.yml +# installation artifacts will be generated here +deploy_carvel/deploy/ diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index 3ab9a557..89d14669 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -147,12 +147,13 @@ imgpkg pull --bundle "${package_repository_repo_tag}" --output "/tmp/${package_r ## NOTE: could break apart here at a build and a deploy script. +log_note "cleaning deploy artifacts..." +rm -rf "deploy_carvel/deploy" +mkdir "deploy_carvel/deploy" log_note "deploying PackageRepository..." pinniped_package_repository_name="pinniped-package-repository" -# TODO: deploy_carvel/ dir... -# TODO: delete the "extras", so perhaps put this in a "deploy_carvel/tmp/" dir that can be cleaned. -pinniped_package_repository_file="deploy_carvel/packagerepository.${pinniped_package_version}.yml" +pinniped_package_repository_file="deploy_carvel/deploy/packagerepository.${pinniped_package_version}.yml" echo -n "" > "${pinniped_package_repository_file}" cat <> "${pinniped_package_repository_file}" --- @@ -177,7 +178,7 @@ do namespace="${resource_name}-install-ns" pinniped_package_rbac_prefix="pinniped-package-rbac-${resource_name}" - pinniped_package_rbac_file="deploy_carvel/${pinniped_package_rbac_prefix}-${resource_name}-rbac.yml" + pinniped_package_rbac_file="deploy_carvel/deploy/${pinniped_package_rbac_prefix}-${resource_name}-rbac.yml" echo -n "" > "${pinniped_package_rbac_file}" cat <> "${pinniped_package_rbac_file}" --- @@ -227,7 +228,7 @@ resource_name="local-user-authenticator" NAMESPACE="${resource_name}-install-ns" PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" -PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/deploy/${resource_name}-pkginstall.yml" SECRET_NAME="${resource_name}-package-install-secret" cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF @@ -397,6 +398,9 @@ kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_N log_note "appending environment variables to /tmp/integration-test-env" +echo "PINNIPED_TEST_USER_USERNAME=${test_username}" +echo "PINNIPED_TEST_USER_GROUPS=${test_groups}" +echo "PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password}" # To be "finished" the scripts need to work for both the ytt deploy and the carvel package, # regardless of which branch the user takes. integration_env_file="/tmp/integration-test-env" @@ -409,8 +413,6 @@ export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} EOT echo "${integration_env_file_text}" >> "${integration_env_file}" - - log_note "verifying PackageInstall resources..." kubectl get PackageInstall -A | grep pinniped kubectl get secret -A | grep pinniped From 9ec2cf6bcd2a8efc41f34401d177892d277e2a49 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 12:28:41 -0400 Subject: [PATCH 24/40] improve cleanup of carvel package artifacts --- deploy_carvel/.gitignore | 6 ++++ deploy_carvel/concierge/.imgpkg/images.yml | 11 ------ .../.imgpkg/images.yml | 11 ------ ...-package-rbac-concierge-concierge-rbac.yml | 35 ------------------- ...nticator-local-user-authenticator-rbac.yml | 35 ------------------- ...ackage-rbac-supervisor-supervisor-rbac.yml | 35 ------------------- deploy_carvel/supervisor/.imgpkg/images.yml | 11 ------ 7 files changed, 6 insertions(+), 138 deletions(-) delete mode 100644 deploy_carvel/concierge/.imgpkg/images.yml delete mode 100644 deploy_carvel/local-user-authenticator/.imgpkg/images.yml delete mode 100644 deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml delete mode 100644 deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml delete mode 100644 deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml delete mode 100644 deploy_carvel/supervisor/.imgpkg/images.yml diff --git a/deploy_carvel/.gitignore b/deploy_carvel/.gitignore index 94b9a4bc..fb55f463 100644 --- a/deploy_carvel/.gitignore +++ b/deploy_carvel/.gitignore @@ -4,3 +4,9 @@ # installation artifacts will be generated here deploy_carvel/deploy/ + +# images.yml files contain specific SHAs of images +concierge/.imgpkg/images.yml +supervisor/.imgpkg/images.yml +local-user-authenticator/.imgpkg/images.yml +package_repository/.imgpkg/images.yml diff --git a/deploy_carvel/concierge/.imgpkg/images.yml b/deploy_carvel/concierge/.imgpkg/images.yml deleted file mode 100644 index adc53f2c..00000000 --- a/deploy_carvel/concierge/.imgpkg/images.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -apiVersion: imgpkg.carvel.dev/v1alpha1 -images: -- annotations: - kbld.carvel.dev/id: projects.registry.vmware.com/pinniped/pinniped-server:latest - kbld.carvel.dev/origins: | - - resolved: - tag: latest - url: projects.registry.vmware.com/pinniped/pinniped-server:latest - image: projects.registry.vmware.com/pinniped/pinniped-server@sha256:a92183de893eb0b1850cc3a1d33306b96ba2cdb72a8a49c6493a58c01b4fa9cd -kind: ImagesLock diff --git a/deploy_carvel/local-user-authenticator/.imgpkg/images.yml b/deploy_carvel/local-user-authenticator/.imgpkg/images.yml deleted file mode 100644 index adc53f2c..00000000 --- a/deploy_carvel/local-user-authenticator/.imgpkg/images.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -apiVersion: imgpkg.carvel.dev/v1alpha1 -images: -- annotations: - kbld.carvel.dev/id: projects.registry.vmware.com/pinniped/pinniped-server:latest - kbld.carvel.dev/origins: | - - resolved: - tag: latest - url: projects.registry.vmware.com/pinniped/pinniped-server:latest - image: projects.registry.vmware.com/pinniped/pinniped-server@sha256:a92183de893eb0b1850cc3a1d33306b96ba2cdb72a8a49c6493a58c01b4fa9cd -kind: ImagesLock diff --git a/deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml b/deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml deleted file mode 100644 index bd79c4cd..00000000 --- a/deploy_carvel/pinniped-package-rbac-concierge-concierge-rbac.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: "concierge-install-ns" ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" - namespace: "concierge-install-ns" ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: "pinniped-package-rbac-concierge-role-superadmin-dangerous" - namespace: "concierge-install-ns" -rules: -- apiGroups: ["*"] - resources: ["*"] - verbs: ["*"] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: "pinniped-package-rbac-concierge-role-binding-superadmin-dangerous" -subjects: -- kind: ServiceAccount - name: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" - namespace: "concierge-install-ns" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: "pinniped-package-rbac-concierge-role-superadmin-dangerous" - diff --git a/deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml b/deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml deleted file mode 100644 index b04a37c6..00000000 --- a/deploy_carvel/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: "local-user-authenticator-install-ns" ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" - namespace: "local-user-authenticator-install-ns" ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: "pinniped-package-rbac-local-user-authenticator-role-superadmin-dangerous" - namespace: "local-user-authenticator-install-ns" -rules: -- apiGroups: ["*"] - resources: ["*"] - verbs: ["*"] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: "pinniped-package-rbac-local-user-authenticator-role-binding-superadmin-dangerous" -subjects: -- kind: ServiceAccount - name: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" - namespace: "local-user-authenticator-install-ns" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: "pinniped-package-rbac-local-user-authenticator-role-superadmin-dangerous" - diff --git a/deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml b/deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml deleted file mode 100644 index d3ea042a..00000000 --- a/deploy_carvel/pinniped-package-rbac-supervisor-supervisor-rbac.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: "supervisor-install-ns" ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" - namespace: "supervisor-install-ns" ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: "pinniped-package-rbac-supervisor-role-superadmin-dangerous" - namespace: "supervisor-install-ns" -rules: -- apiGroups: ["*"] - resources: ["*"] - verbs: ["*"] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: "pinniped-package-rbac-supervisor-role-binding-superadmin-dangerous" -subjects: -- kind: ServiceAccount - name: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" - namespace: "supervisor-install-ns" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: "pinniped-package-rbac-supervisor-role-superadmin-dangerous" - diff --git a/deploy_carvel/supervisor/.imgpkg/images.yml b/deploy_carvel/supervisor/.imgpkg/images.yml deleted file mode 100644 index adc53f2c..00000000 --- a/deploy_carvel/supervisor/.imgpkg/images.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -apiVersion: imgpkg.carvel.dev/v1alpha1 -images: -- annotations: - kbld.carvel.dev/id: projects.registry.vmware.com/pinniped/pinniped-server:latest - kbld.carvel.dev/origins: | - - resolved: - tag: latest - url: projects.registry.vmware.com/pinniped/pinniped-server:latest - image: projects.registry.vmware.com/pinniped/pinniped-server@sha256:a92183de893eb0b1850cc3a1d33306b96ba2cdb72a8a49c6493a58c01b4fa9cd -kind: ImagesLock From b6afd567162f5437421a285c017e75c2950ad270 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 12:49:18 -0400 Subject: [PATCH 25/40] remove old install artifacts --- .../local-user-authenticator-pkginstall.yml | 27 ++++++++++++++ ...-package-rbac-concierge-concierge-rbac.yml | 35 +++++++++++++++++++ ...nticator-local-user-authenticator-rbac.yml | 35 +++++++++++++++++++ ...ackage-rbac-supervisor-supervisor-rbac.yml | 35 +++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 deploy_carvel/deploy/local-user-authenticator-pkginstall.yml create mode 100644 deploy_carvel/deploy/pinniped-package-rbac-concierge-concierge-rbac.yml create mode 100644 deploy_carvel/deploy/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml create mode 100644 deploy_carvel/deploy/pinniped-package-rbac-supervisor-supervisor-rbac.yml diff --git a/deploy_carvel/deploy/local-user-authenticator-pkginstall.yml b/deploy_carvel/deploy/local-user-authenticator-pkginstall.yml new file mode 100644 index 00000000..c1dbfedc --- /dev/null +++ b/deploy_carvel/deploy/local-user-authenticator-pkginstall.yml @@ -0,0 +1,27 @@ +--- +apiVersion: packaging.carvel.dev/v1alpha1 +kind: PackageInstall +metadata: + # name, does not have to be versioned, versionSelection.constraints below will handle + name: "local-user-authenticator-package-install" + namespace: "local-user-authenticator-install-ns" +spec: + serviceAccountName: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" + packageRef: + refName: "local-user-authenticator.pinniped.dev" + versionSelection: + constraints: "0.0.0-7E26B8EF-A4D6-4020-83E8-EAF8F3D1533F" + values: + - secretRef: + name: "local-user-authenticator-package-install-secret" +--- +apiVersion: v1 +kind: Secret +metadata: + name: "local-user-authenticator-package-install-secret" + namespace: "local-user-authenticator-install-ns" +stringData: + values.yml: | + --- + image_repo: kind-registry.local:5000/test/build + image_tag: 0.0.0-7E26B8EF-A4D6-4020-83E8-EAF8F3D1533F diff --git a/deploy_carvel/deploy/pinniped-package-rbac-concierge-concierge-rbac.yml b/deploy_carvel/deploy/pinniped-package-rbac-concierge-concierge-rbac.yml new file mode 100644 index 00000000..bd79c4cd --- /dev/null +++ b/deploy_carvel/deploy/pinniped-package-rbac-concierge-concierge-rbac.yml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "concierge-install-ns" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" + namespace: "concierge-install-ns" +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-concierge-role-superadmin-dangerous" + namespace: "concierge-install-ns" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-concierge-role-binding-superadmin-dangerous" +subjects: +- kind: ServiceAccount + name: "pinniped-package-rbac-concierge-sa-superadmin-dangerous" + namespace: "concierge-install-ns" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "pinniped-package-rbac-concierge-role-superadmin-dangerous" + diff --git a/deploy_carvel/deploy/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml b/deploy_carvel/deploy/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml new file mode 100644 index 00000000..b04a37c6 --- /dev/null +++ b/deploy_carvel/deploy/pinniped-package-rbac-local-user-authenticator-local-user-authenticator-rbac.yml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "local-user-authenticator-install-ns" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" + namespace: "local-user-authenticator-install-ns" +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-local-user-authenticator-role-superadmin-dangerous" + namespace: "local-user-authenticator-install-ns" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-local-user-authenticator-role-binding-superadmin-dangerous" +subjects: +- kind: ServiceAccount + name: "pinniped-package-rbac-local-user-authenticator-sa-superadmin-dangerous" + namespace: "local-user-authenticator-install-ns" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "pinniped-package-rbac-local-user-authenticator-role-superadmin-dangerous" + diff --git a/deploy_carvel/deploy/pinniped-package-rbac-supervisor-supervisor-rbac.yml b/deploy_carvel/deploy/pinniped-package-rbac-supervisor-supervisor-rbac.yml new file mode 100644 index 00000000..d3ea042a --- /dev/null +++ b/deploy_carvel/deploy/pinniped-package-rbac-supervisor-supervisor-rbac.yml @@ -0,0 +1,35 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: "supervisor-install-ns" +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" + namespace: "supervisor-install-ns" +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-supervisor-role-superadmin-dangerous" + namespace: "supervisor-install-ns" +rules: +- apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: "pinniped-package-rbac-supervisor-role-binding-superadmin-dangerous" +subjects: +- kind: ServiceAccount + name: "pinniped-package-rbac-supervisor-sa-superadmin-dangerous" + namespace: "supervisor-install-ns" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: "pinniped-package-rbac-supervisor-role-superadmin-dangerous" + From 1a143f9720cb43441edf33831f4e7d5f84c123e0 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 12:49:47 -0400 Subject: [PATCH 26/40] adjust variables in hack/prepare-for-integration-tests.sh --- hack/prepare-for-integration-tests.sh | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 203d93b1..cec57f6e 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -273,10 +273,11 @@ docker push "$registry_repo_tag" # Deploy local-user-authenticator # manifest=/tmp/pinniped-local-user-authenticator.yaml -test_username="" -test_groups="" -test_password="" -webhook_ca_bundle="" +# TODO: these are duplicated into the build-carvel-packages.sh script +# since the script can't write to the same env file (it would be overwritten) +test_username="test-username" +test_groups="test-group-0,test-group-1" +test_password="$(openssl rand -hex 16)" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_local_user_authenticator" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag..." @@ -296,9 +297,7 @@ else kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. - test_username="test-username" - test_groups="test-group-0,test-group-1" - test_password="$(openssl rand -hex 16)" + log_note "Creating test user '$test_username'..." kubectl create secret generic "$test_username" \ --namespace local-user-authenticator \ @@ -437,7 +436,10 @@ test_ca_bundle_pem="$(kubectl get secrets -n tools certs -o go-template='{{index kind_capabilities_file="$pinniped_path/test/cluster_capabilities/kind.yaml" pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file") -# however it was installed, we need the CA bundle now +# whether installed by the carvel package or the default method, we need to get this +# entered into the environment variable file now. +# TODO: this is a bit of a bleeding of concerns... ideally if the carvel package method installs the +# local-user-authenticator, it would write this env var to the env file. webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" cat </tmp/integration-test-env From 8fda51850bf4ca118842241d2fab73a32b6a8d70 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 16:05:53 -0400 Subject: [PATCH 27/40] deploy/{}/values.yml image_pull_dockerconfigjson type change to base64 string --- deploy/concierge/values.yaml | 4 +++- deploy/supervisor/values.yaml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 32306740..7ecdc9d0 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -47,9 +47,11 @@ kube_cert_agent_image: projects.registry.vmware.com/pinniped/pinniped-server #@ 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." +#! base64 encoded: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +#! result: eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ== #@schema/desc image_pull_dockerconfigjson_desc #@schema/nullable -image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +image_pull_dockerconfigjson: "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" #@schema/desc "Pinniped will try to guess the right K8s API URL for sharing that information with potential clients. This setting allows the guess to be overridden." #@schema/nullable diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 04606edb..29352e3e 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -40,9 +40,11 @@ image_tag: latest #@ 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." +#! base64 encoded: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +#! result: eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ== #@schema/desc image_pull_dockerconfigjson_desc #@schema/nullable -image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +image_pull_dockerconfigjson: "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" #! Specify how to expose the Supervisor app's HTTPS port as a Service. #! Typically, you would set a value for only one of the following service types. From 5bcff5a6518afbbe88ac44d299c0a8a121d1ac7a Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 16:06:59 -0400 Subject: [PATCH 28/40] update schema from values.yml schema change --- deploy_carvel/concierge/schema-openapi.yaml | 22 ++------------------ deploy_carvel/supervisor/schema-openapi.yaml | 22 ++------------------ 2 files changed, 4 insertions(+), 40 deletions(-) diff --git a/deploy_carvel/concierge/schema-openapi.yaml b/deploy_carvel/concierge/schema-openapi.yaml index 9f18a393..881eee99 100644 --- a/deploy_carvel/concierge/schema-openapi.yaml +++ b/deploy_carvel/concierge/schema-openapi.yaml @@ -49,28 +49,10 @@ components: description: Optionally specify a different image for the 'kube-cert-agent' pod which is scheduled on the control plane. This image needs only to include `sleep` and `cat` binaries. By default, the same image specified for image_repo/image_digest/image_tag will be re-used. default: null image_pull_dockerconfigjson: - type: object - additionalProperties: false + type: string nullable: true description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + default: null discovery_url: type: string nullable: true diff --git a/deploy_carvel/supervisor/schema-openapi.yaml b/deploy_carvel/supervisor/schema-openapi.yaml index 0e0903fa..77aa80ba 100644 --- a/deploy_carvel/supervisor/schema-openapi.yaml +++ b/deploy_carvel/supervisor/schema-openapi.yaml @@ -44,28 +44,10 @@ components: description: Specify either an image_digest or an image_tag. If both are given, only image_digest will be used. default: latest image_pull_dockerconfigjson: - type: object - additionalProperties: false + type: string nullable: true description: '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.' - properties: - auths: - type: object - additionalProperties: false - properties: - https://registry.example.com: - type: object - additionalProperties: false - properties: - username: - type: string - default: USERNAME - password: - type: string - default: PASSWORD - auth: - type: string - default: BASE64_ENCODED_USERNAME_COLON_PASSWORD + default: null deprecated_service_http_nodeport_port: type: integer nullable: true From b091b41b8dd2343b830efe7c250c246a7f5da27e Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 16:07:25 -0400 Subject: [PATCH 29/40] todo: test user changes need to be addressed --- hack/build-carvel-packages.sh | 6 +++--- hack/prepare-for-integration-tests.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index 89d14669..9bb5b168 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -267,7 +267,7 @@ kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_N test_username="test-username" test_groups="test-group-0,test-group-1" -test_password="$(openssl rand -hex 16)" +test_password="$(openssl rand -hex 16)" # TODO: this will be different than in the prepare-for-integration-tests.sh file. log_note "Creating test user '$test_username'..." kubectl create secret generic "$test_username" \ --namespace local-user-authenticator \ @@ -325,7 +325,7 @@ stringData: namespace: $concierge_namespace api_group_suffix: $api_group_suffix log_level: $log_level - + custom_labels: $concierge_custom_labels image_repo: $registry_repo image_tag: $tag EOF @@ -385,7 +385,7 @@ stringData: image_repo: $registry_repo image_tag: $tag log_level: $log_level - + custom_labels: $supervisor_custom_labels service_https_nodeport_port: $service_https_nodeport_port service_https_nodeport_nodeport: $service_https_nodeport_nodeport service_https_clusterip_port: $service_https_clusterip_port diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index cec57f6e..ac3de263 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -277,7 +277,7 @@ manifest=/tmp/pinniped-local-user-authenticator.yaml # since the script can't write to the same env file (it would be overwritten) test_username="test-username" test_groups="test-group-0,test-group-1" -test_password="$(openssl rand -hex 16)" +test_password="$(openssl rand -hex 16)" # TODO: this will be different than in the build-carvel-packages.sh file if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_local_user_authenticator" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag..." From dc4948f5709ed7f4c3185f7e9af4818b1b916c71 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 17:09:18 -0400 Subject: [PATCH 30/40] values.yaml: make consistent comment between supervisor & concierge --- deploy/supervisor/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 29352e3e..546f05b5 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -38,7 +38,7 @@ image_tag: latest #@ image_pull_dockerconfigjson_desc = "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']' \ +#@ 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." #! base64 encoded: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} #! result: eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ== From 8e430c8e77b855e9ca7b7cf5e4180b3f89a271b4 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Wed, 11 Oct 2023 17:09:46 -0400 Subject: [PATCH 31/40] remove dead code --- hack/build-carvel-packages.sh | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index 9bb5b168..295d5d71 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -285,7 +285,7 @@ resource_name="concierge" NAMESPACE="${resource_name}-install-ns" PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" -PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/deploy/${resource_name}-pkginstall.yml" SECRET_NAME="${resource_name}-package-install-secret" # from prepare-for-integration-tests.sh @@ -342,7 +342,7 @@ resource_name="supervisor" NAMESPACE="${resource_name}-install-ns" PINNIPED_PACKAGE_RBAC_PREFIX="pinniped-package-rbac-${resource_name}" RESOURCE_PACKAGE_VERSION="${resource_name}.pinniped.dev" -PACKAGE_INSTALL_FILE_NAME="deploy_carvel/${resource_name}-pkginstall.yml" +PACKAGE_INSTALL_FILE_NAME="deploy_carvel/deploy/${resource_name}-pkginstall.yml" SECRET_NAME="${resource_name}-package-install-secret" # from prepare-for-integration-test.sh @@ -397,22 +397,6 @@ kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_N # end supervisor -log_note "appending environment variables to /tmp/integration-test-env" -echo "PINNIPED_TEST_USER_USERNAME=${test_username}" -echo "PINNIPED_TEST_USER_GROUPS=${test_groups}" -echo "PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password}" -# To be "finished" the scripts need to work for both the ytt deploy and the carvel package, -# regardless of which branch the user takes. -integration_env_file="/tmp/integration-test-env" -integration_env_file_text=$(cat "${integration_env_file}") - -cat <"${integration_env_file}" -export PINNIPED_TEST_USER_USERNAME=${test_username} -export PINNIPED_TEST_USER_GROUPS=${test_groups} -export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} -EOT -echo "${integration_env_file_text}" >> "${integration_env_file}" - log_note "verifying PackageInstall resources..." kubectl get PackageInstall -A | grep pinniped kubectl get secret -A | grep pinniped From ac42b725fbe3edb9480e4e64dda73e8fe8f0e190 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 12 Oct 2023 11:21:06 -0400 Subject: [PATCH 32/40] escapes in values.yaml for complex examples --- deploy/concierge/values.yaml | 2 +- deploy/supervisor/values.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 7ecdc9d0..4807cfc0 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -45,7 +45,7 @@ kube_cert_agent_image: projects.registry.vmware.com/pinniped/pinniped-server #@ image_pull_dockerconfigjson_desc = "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']' \ +#@ 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." #! base64 encoded: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} #! result: eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ== diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 546f05b5..1af80921 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -38,7 +38,7 @@ image_tag: latest #@ image_pull_dockerconfigjson_desc = "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"]' \ +#@ 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." #! base64 encoded: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} #! result: eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ== From 4bbd6312c521e650b8ba9e3c8a8d3199d8ec4cd5 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 12 Oct 2023 11:23:47 -0400 Subject: [PATCH 33/40] Update hack scripts to support fresh /tmp/pinniped-XXX env files on every run --- hack/integration-test-env-goland.sh | 10 +++++- hack/prepare-for-integration-tests.sh | 46 +++++++++++++++------------ hack/prepare-supervisor-on-kind.sh | 15 ++++++++- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/hack/integration-test-env-goland.sh b/hack/integration-test-env-goland.sh index c4991627..86fd1b90 100755 --- a/hack/integration-test-env-goland.sh +++ b/hack/integration-test-env-goland.sh @@ -11,7 +11,15 @@ set -euo pipefail ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" -source /tmp/integration-test-env +env_file_name=${1:-"undefined"} +if [ "${env_file_name}" == "undefined" ] +then + echo "environment variable file name must be specified." + echo "hint: this is typically in the output of running hack/prepare-for-integration-tests.sh" + exit 1 +fi + +source "${env_file_name}" echo -n "PINNIPED_TEST_GOLAND_RUNNER=true;" diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index ac3de263..192025e7 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -231,6 +231,11 @@ else fi fi + +# since we allow other scripts to write to the environment file, we need to create a new one every time +env_file_name="$(mktemp /tmp/pinniped.integration.XXXXXXXX)" +log_note "creating environment variable file: $env_file_name" + # registry="pinniped.local" registry="kind-registry.local:5000" repo="test/build" @@ -273,19 +278,18 @@ docker push "$registry_repo_tag" # Deploy local-user-authenticator # manifest=/tmp/pinniped-local-user-authenticator.yaml -# TODO: these are duplicated into the build-carvel-packages.sh script -# since the script can't write to the same env file (it would be overwritten) -test_username="test-username" -test_groups="test-group-0,test-group-1" -test_password="$(openssl rand -hex 16)" # TODO: this will be different than in the build-carvel-packages.sh file +test_username="" +test_groups="" +test_password="" +webhook_ca_bundle="" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_local_user_authenticator" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag..." - $alternate_deploy local-user-authenticator $tag + $alternate_deploy local-user-authenticator $tag $env_file_name fi if [ "$alternate_deploy_local_user_authenticator" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy_local_user_authenticator local-user-authenticator $tag..." - $alternate_deploy_local_user_authenticator local-user-authenticator $tag + $alternate_deploy_local_user_authenticator local-user-authenticator $tag $env_file_name fi else log_note "Deploying the local-user-authenticator app to the cluster using kapp..." @@ -299,6 +303,13 @@ else log_note "Creating test user '$test_username'..." + test_username="test-username" + test_groups="test-group-0,test-group-1" + test_password="$(openssl rand -hex 16)" + echo "export PINNIPED_TEST_USER_USERNAME=${test_username}" >> "${env_file_name}" + echo "export PINNIPED_TEST_USER_GROUPS=${test_groups}" >> "${env_file_name}" + echo "export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password}" >> "${env_file_name}" + kubectl create secret generic "$test_username" \ --namespace local-user-authenticator \ --from-literal=groups="$test_groups" \ @@ -307,6 +318,7 @@ else --output yaml | kubectl apply -f - + webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" popd >/dev/null fi @@ -345,11 +357,11 @@ service_https_clusterip_port="443" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_supervisor" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Supervisor will be deployed with $alternate_deploy pinniped-supervisor $tag..." - $alternate_deploy pinniped-supervisor $tag + $alternate_deploy pinniped-supervisor $tag $env_file_name fi if [ "$alternate_deploy_supervisor" != "undefined" ]; then log_note "The Pinniped Supervisor will be deployed with $alternate_deploy_supervisor pinniped-supervisor $tag..." - $alternate_deploy_supervisor pinniped-supervisor $tag + $alternate_deploy_supervisor pinniped-supervisor $tag $env_file_name fi else log_note "Deploying the Pinniped Supervisor app to the cluster using kapp..." @@ -386,11 +398,11 @@ log_level="debug" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_concierge" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag..." - $alternate_deploy pinniped-concierge $tag + $alternate_deploy pinniped-concierge $tag $env_file_name fi if [ "$alternate_deploy_concierge" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy_concierge pinniped-concierge $tag..." - $alternate_deploy_concierge pinniped-concierge $tag + $alternate_deploy_concierge pinniped-concierge $tag $env_file_name fi else log_note "Deploying the Pinniped Concierge app to the cluster using kapp..." @@ -436,21 +448,13 @@ test_ca_bundle_pem="$(kubectl get secrets -n tools certs -o go-template='{{index kind_capabilities_file="$pinniped_path/test/cluster_capabilities/kind.yaml" pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file") -# whether installed by the carvel package or the default method, we need to get this -# entered into the environment variable file now. -# TODO: this is a bit of a bleeding of concerns... ideally if the carvel package method installs the -# local-user-authenticator, it would write this env var to the env file. -webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" -cat </tmp/integration-test-env +cat <>"$env_file_name" # The following env vars should be set before running 'go test -v -count 1 -timeout 0 ./test/integration' export PINNIPED_TEST_TOOLS_NAMESPACE="tools" export PINNIPED_TEST_CONCIERGE_NAMESPACE=${concierge_namespace} export PINNIPED_TEST_CONCIERGE_APP_NAME=${concierge_app_name} export PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS='${concierge_custom_labels}' -export PINNIPED_TEST_USER_USERNAME=${test_username} -export PINNIPED_TEST_USER_GROUPS=${test_groups} -export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} export PINNIPED_TEST_WEBHOOK_ENDPOINT=${webhook_url} export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle} export PINNIPED_TEST_SUPERVISOR_NAMESPACE=${supervisor_namespace} @@ -522,7 +526,7 @@ log_note log_note "🚀 Ready to run integration tests! For example..." log_note " cd $pinniped_path" log_note " ulimit -n 512" -log_note ' source /tmp/integration-test-env && go test -v -race -count 1 -timeout 0 ./test/integration' +log_note " source $env_file_name && go test -v -race -count 1 -timeout 0 ./test/integration" log_note log_note "Using GoLand? Paste the result of this command into GoLand's run configuration \"Environment\"." log_note " hack/integration-test-env-goland.sh | pbcopy" diff --git a/hack/prepare-supervisor-on-kind.sh b/hack/prepare-supervisor-on-kind.sh index ba644388..9425b50b 100755 --- a/hack/prepare-supervisor-on-kind.sh +++ b/hack/prepare-supervisor-on-kind.sh @@ -51,6 +51,7 @@ use_oidc_upstream=no use_ldap_upstream=no use_ad_upstream=no use_flow="" +env_file_name="" while (("$#")); do case "$1" in --flow) @@ -81,6 +82,13 @@ while (("$#")); do use_ad_upstream=yes shift ;; + --env) + shift + # Use an ActiveDirectoryIdentityProvider. + # This assumes that you used the --get-active-directory-vars flag with hack/prepare-for-integration-tests.sh. + env_file_name=$1 + shift + ;; -*) log_error "Unsupported flag $1" >&2 exit 1 @@ -97,8 +105,13 @@ if [[ "$use_oidc_upstream" == "no" && "$use_ldap_upstream" == "no" && "$use_ad_u exit 1 fi +if [[ "$env_file_name" == "" ]]; then + log_error "Error: Please provide --env file, typically printed in the output of ./hack/prepare-for-integration-tests.sh" + exit 1 +fi + # Read the env vars output by hack/prepare-for-integration-tests.sh -source /tmp/integration-test-env +source $env_file_name # Choose some filenames. root_ca_crt_path=root_ca.crt From 86a25246ddfa88280e2df4150b3ef56db961a305 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 12 Oct 2023 13:31:50 -0400 Subject: [PATCH 34/40] Tweak hack scripts for carvel package usage --- hack/build-carvel-packages.sh | 20 ++++++++++++++++++++ hack/prepare-for-integration-tests.sh | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index 295d5d71..77e214a4 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -50,8 +50,19 @@ cd "$pinniped_path" || exit 1 # - app: unimportant, but always first # - tag: uuidgen in hack/prepare-for-integration-tests.sh # if this script is run standalone, then auto-fill with a unique value +# - env_file_name: the text file to write environment variables for integration tests, IDEs, etc. app=${1:-"undefined"} tag=${2:-$(uuidgen)} +# best if this is passed in by calling code to share the same file +env_file_name=${3:-"undefined"} + + +if [ "${env_file_name}" == "undefined" ]; then + env_file_name="$(mktemp /tmp/pinniped.integration.XXXXXXXX)" + log_note "env file name not passed, generating new environment file: ${env_file_name}" +else + log_note "appending to shared env file: ${env_file_name}" +fi # TODO: automate the version by release somehow. # the tag is the version in our build scripts, but we will want real versions for releases @@ -276,6 +287,8 @@ kubectl create secret generic "$test_username" \ --dry-run=client \ --output yaml | kubectl apply -f - + +webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" # end local-user-authenticator @@ -396,6 +409,13 @@ log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y # end supervisor +log_note "writing to environment file: ${env_file_name}..." +echo "# carvel package script additions........." +echo "export PINNIPED_TEST_USER_USERNAME=${test_username}" >> "${env_file_name}" +echo "export PINNIPED_TEST_USER_GROUPS=${test_groups}" >> "${env_file_name}" +echo "export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password}" >> "${env_file_name}" +echo "export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle}" >> "${env_file_name}" +echo "# carvel package script additions end....." log_note "verifying PackageInstall resources..." kubectl get PackageInstall -A | grep pinniped diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 192025e7..02d9629f 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -319,6 +319,7 @@ else kubectl apply -f - webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" + echo "export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle}" >> "${env_file_name}" popd >/dev/null fi @@ -429,7 +430,7 @@ fi # running it after the above also allows appending to the environment variable file if [ "$post_install" != "undefined" ] ; then log_note "The post-install script will be called with $tag..." - $post_install post-install-script $tag + $post_install post-install-script $tag $env_file_name fi # @@ -456,7 +457,6 @@ export PINNIPED_TEST_CONCIERGE_NAMESPACE=${concierge_namespace} export PINNIPED_TEST_CONCIERGE_APP_NAME=${concierge_app_name} export PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS='${concierge_custom_labels}' export PINNIPED_TEST_WEBHOOK_ENDPOINT=${webhook_url} -export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle} export PINNIPED_TEST_SUPERVISOR_NAMESPACE=${supervisor_namespace} export PINNIPED_TEST_SUPERVISOR_APP_NAME=${supervisor_app_name} export PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS='${supervisor_custom_labels}' From 106edd48684c3d6b2d8868cb6b41d585decc7350 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 12 Oct 2023 16:58:43 -0400 Subject: [PATCH 35/40] Add comments to build files --- hack/build-carvel-packages.sh | 11 +++++++++-- hack/noop.sh | 2 ++ hack/prepare-for-integration-tests.sh | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index 77e214a4..cd6a50e8 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -69,6 +69,8 @@ fi pinniped_package_version="${tag}" # ie, "0.25.0" # core pinniped binaries (concierge, supervisor, local-user-authenticator) +# TODO: we can likely just pass in the whole registry_repo_tag from the parent script and be done. +# the duplication is unnecessary. This script doesn't ever need to run standalone again. registry="kind-registry.local:5000" repo="test/build" registry_repo="$registry/$repo" @@ -191,6 +193,10 @@ do pinniped_package_rbac_prefix="pinniped-package-rbac-${resource_name}" pinniped_package_rbac_file="deploy_carvel/deploy/${pinniped_package_rbac_prefix}-${resource_name}-rbac.yml" echo -n "" > "${pinniped_package_rbac_file}" +# TODO: will just a Role and RoleBinding work? Just for the target namespace. +# - limit this to the LEAST privilege for each of the resources +# - and document this for each of the resources. +# - and we may need to TEMPLATE the namespace, if pinniped is installed in alt namespaces? cat <> "${pinniped_package_rbac_file}" --- apiVersion: v1 @@ -208,7 +214,6 @@ kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: "${pinniped_package_rbac_prefix}-role-superadmin-dangerous" - namespace: "${namespace}" rules: - apiGroups: ["*"] resources: ["*"] @@ -278,7 +283,7 @@ kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_N test_username="test-username" test_groups="test-group-0,test-group-1" -test_password="$(openssl rand -hex 16)" # TODO: this will be different than in the prepare-for-integration-tests.sh file. +test_password="$(openssl rand -hex 16)" log_note "Creating test user '$test_username'..." kubectl create secret generic "$test_username" \ --namespace local-user-authenticator \ @@ -288,6 +293,7 @@ kubectl create secret generic "$test_username" \ --output yaml | kubectl apply -f - +# TODO: this is a race, we need to wait for this secret to exist, should we --wait? webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" # end local-user-authenticator @@ -406,6 +412,7 @@ EOF KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." +# TODO: does this wait not only for the PackageInstall, but the Package, and its deployments and pods, to be successful? Because we need that. kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y # end supervisor diff --git a/hack/noop.sh b/hack/noop.sh index 99511277..ff76a90f 100755 --- a/hack/noop.sh +++ b/hack/noop.sh @@ -47,6 +47,8 @@ app=${1} ## tag is fed in from the prepare-for-integration-tests.sh script, just uuidgen to identify a ## specific docker build of the pinniped-server image. tag=${2} +# env_file_name is where to write env vars, if necessary to contribute to the environment +env_file_name=${3} #SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) #log_note "noop.sh >>> script dir: ${SCRIPT_DIR}" log_note "noop.sh >>> app: ${app} tag: ${tag}" diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 02d9629f..4f806a71 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -318,6 +318,7 @@ else --output yaml | kubectl apply -f - + # TODO: this is a race, we need to wait for this secret to exist, should we --wait? webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" echo "export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle}" >> "${env_file_name}" popd >/dev/null From 050750d682ef29bb13faad85848154a0f8b37b32 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Mon, 16 Oct 2023 14:12:10 -0400 Subject: [PATCH 36/40] Add TODO for /etc/hosts --- hack/prepare-for-integration-tests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 4f806a71..7981be2e 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -238,6 +238,8 @@ log_note "creating environment variable file: $env_file_name" # registry="pinniped.local" registry="kind-registry.local:5000" +# TODO: need to prompt the user to edit their /etc/hosts here, because otherwise +# we can't push images to the registry! maybe check /etc/hosts for this change else error? repo="test/build" registry_repo="$registry/$repo" tag="0.0.0-$(uuidgen)" # always a new tag to force K8s to reload the image on redeploy From d803b7c3d4dd561b328cdcd94e6eed705f135c8e Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 19 Oct 2023 14:44:56 -0400 Subject: [PATCH 37/40] simplify env vars again, create one well known /tmp/integration-test-env file again --- hack/build-carvel-packages.sh | 23 +-------- hack/integration-test-env-goland.sh | 9 +--- hack/noop.sh | 25 ---------- hack/prepare-for-integration-tests.sh | 71 +++++++++++++-------------- hack/prepare-supervisor-on-kind.sh | 15 +----- 5 files changed, 38 insertions(+), 105 deletions(-) diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index cd6a50e8..7c07db22 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -50,19 +50,8 @@ cd "$pinniped_path" || exit 1 # - app: unimportant, but always first # - tag: uuidgen in hack/prepare-for-integration-tests.sh # if this script is run standalone, then auto-fill with a unique value -# - env_file_name: the text file to write environment variables for integration tests, IDEs, etc. app=${1:-"undefined"} tag=${2:-$(uuidgen)} -# best if this is passed in by calling code to share the same file -env_file_name=${3:-"undefined"} - - -if [ "${env_file_name}" == "undefined" ]; then - env_file_name="$(mktemp /tmp/pinniped.integration.XXXXXXXX)" - log_note "env file name not passed, generating new environment file: ${env_file_name}" -else - log_note "appending to shared env file: ${env_file_name}" -fi # TODO: automate the version by release somehow. # the tag is the version in our build scripts, but we will want real versions for releases @@ -293,9 +282,6 @@ kubectl create secret generic "$test_username" \ --output yaml | kubectl apply -f - -# TODO: this is a race, we need to wait for this secret to exist, should we --wait? -webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" -# end local-user-authenticator # start concierge @@ -347,6 +333,7 @@ stringData: custom_labels: $concierge_custom_labels image_repo: $registry_repo image_tag: $tag + discovery_url: $discovery_url EOF KAPP_CONTROLLER_APP_NAME="${resource_name}-pkginstall" @@ -416,14 +403,6 @@ log_note "deploying ${KAPP_CONTROLLER_APP_NAME}..." kapp deploy --app "${KAPP_CONTROLLER_APP_NAME}" --file "${PACKAGE_INSTALL_FILE_NAME}" -y # end supervisor -log_note "writing to environment file: ${env_file_name}..." -echo "# carvel package script additions........." -echo "export PINNIPED_TEST_USER_USERNAME=${test_username}" >> "${env_file_name}" -echo "export PINNIPED_TEST_USER_GROUPS=${test_groups}" >> "${env_file_name}" -echo "export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password}" >> "${env_file_name}" -echo "export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle}" >> "${env_file_name}" -echo "# carvel package script additions end....." - log_note "verifying PackageInstall resources..." kubectl get PackageInstall -A | grep pinniped kubectl get secret -A | grep pinniped diff --git a/hack/integration-test-env-goland.sh b/hack/integration-test-env-goland.sh index 86fd1b90..cf06b612 100755 --- a/hack/integration-test-env-goland.sh +++ b/hack/integration-test-env-goland.sh @@ -11,15 +11,8 @@ set -euo pipefail ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" -env_file_name=${1:-"undefined"} -if [ "${env_file_name}" == "undefined" ] -then - echo "environment variable file name must be specified." - echo "hint: this is typically in the output of running hack/prepare-for-integration-tests.sh" - exit 1 -fi -source "${env_file_name}" +source "/tmp/integration-test-env" echo -n "PINNIPED_TEST_GOLAND_RUNNER=true;" diff --git a/hack/noop.sh b/hack/noop.sh index ff76a90f..19903763 100755 --- a/hack/noop.sh +++ b/hack/noop.sh @@ -40,31 +40,6 @@ function check_dependency() { fi } -## two vars will be received by this script: -## Received: local-user-authenticator -## Received: D00A4537-80F1-4AF2-A3B3-5F20BDBB9AEB app=${1} -## tag is fed in from the prepare-for-integration-tests.sh script, just uuidgen to identify a -## specific docker build of the pinniped-server image. tag=${2} -# env_file_name is where to write env vars, if necessary to contribute to the environment -env_file_name=${3} -#SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) -#log_note "noop.sh >>> script dir: ${SCRIPT_DIR}" log_note "noop.sh >>> app: ${app} tag: ${tag}" -## nothing else, this is a test. -# -#log_note "temporarily creating ns:local-user-authenticator as workaround..." -# -#local_user_authenticator_file="/tmp/install-local-user-authenticator-namespace.yaml" -#cat < "${local_user_authenticator_file}" -#--- -#apiVersion: v1 -#kind: Namespace -#metadata: -# name: local-user-authenticator -# labels: -# name: local-user-authenticator -#EOF -# -#kubectl apply -f "${local_user_authenticator_file}" diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 7981be2e..c6f4cb72 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -232,10 +232,6 @@ else fi -# since we allow other scripts to write to the environment file, we need to create a new one every time -env_file_name="$(mktemp /tmp/pinniped.integration.XXXXXXXX)" -log_note "creating environment variable file: $env_file_name" - # registry="pinniped.local" registry="kind-registry.local:5000" # TODO: need to prompt the user to edit their /etc/hosts here, because otherwise @@ -280,18 +276,14 @@ docker push "$registry_repo_tag" # Deploy local-user-authenticator # manifest=/tmp/pinniped-local-user-authenticator.yaml -test_username="" -test_groups="" -test_password="" -webhook_ca_bundle="" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_local_user_authenticator" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag..." - $alternate_deploy local-user-authenticator $tag $env_file_name + $alternate_deploy local-user-authenticator $tag fi if [ "$alternate_deploy_local_user_authenticator" != "undefined" ]; then log_note "The Pinniped local-user-authenticator will be deployed with $alternate_deploy_local_user_authenticator local-user-authenticator $tag..." - $alternate_deploy_local_user_authenticator local-user-authenticator $tag $env_file_name + $alternate_deploy_local_user_authenticator local-user-authenticator $tag fi else log_note "Deploying the local-user-authenticator app to the cluster using kapp..." @@ -303,26 +295,6 @@ else kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. - - log_note "Creating test user '$test_username'..." - test_username="test-username" - test_groups="test-group-0,test-group-1" - test_password="$(openssl rand -hex 16)" - echo "export PINNIPED_TEST_USER_USERNAME=${test_username}" >> "${env_file_name}" - echo "export PINNIPED_TEST_USER_GROUPS=${test_groups}" >> "${env_file_name}" - echo "export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password}" >> "${env_file_name}" - - kubectl create secret generic "$test_username" \ - --namespace local-user-authenticator \ - --from-literal=groups="$test_groups" \ - --from-literal=passwordHash="$(htpasswd -nbBC 10 x "$test_password" | sed -e "s/^x://")" \ - --dry-run=client \ - --output yaml | - kubectl apply -f - - - # TODO: this is a race, we need to wait for this secret to exist, should we --wait? - webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" - echo "export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle}" >> "${env_file_name}" popd >/dev/null fi @@ -361,11 +333,11 @@ service_https_clusterip_port="443" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_supervisor" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Supervisor will be deployed with $alternate_deploy pinniped-supervisor $tag..." - $alternate_deploy pinniped-supervisor $tag $env_file_name + $alternate_deploy pinniped-supervisor $tag fi if [ "$alternate_deploy_supervisor" != "undefined" ]; then log_note "The Pinniped Supervisor will be deployed with $alternate_deploy_supervisor pinniped-supervisor $tag..." - $alternate_deploy_supervisor pinniped-supervisor $tag $env_file_name + $alternate_deploy_supervisor pinniped-supervisor $tag fi else log_note "Deploying the Pinniped Supervisor app to the cluster using kapp..." @@ -402,11 +374,11 @@ log_level="debug" if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_concierge" != "undefined" ] ; then if [ "$alternate_deploy" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag..." - $alternate_deploy pinniped-concierge $tag $env_file_name + $alternate_deploy pinniped-concierge $tag fi if [ "$alternate_deploy_concierge" != "undefined" ]; then log_note "The Pinniped Concierge will be deployed with $alternate_deploy_concierge pinniped-concierge $tag..." - $alternate_deploy_concierge pinniped-concierge $tag $env_file_name + $alternate_deploy_concierge pinniped-concierge $tag fi else log_note "Deploying the Pinniped Concierge app to the cluster using kapp..." @@ -433,9 +405,31 @@ fi # running it after the above also allows appending to the environment variable file if [ "$post_install" != "undefined" ] ; then log_note "The post-install script will be called with $tag..." - $post_install post-install-script $tag $env_file_name + $post_install post-install-script $tag fi +# +# Test user for the authenticator +# the authenticator may be deployed in alternative ways (ex. carvel package) but regardless we need a test user. +# +log_note "Creating test user for local-user-authenticator..." +test_username="test-username" +test_groups="test-group-0,test-group-1" +test_password="$(openssl rand -hex 16)" + +kubectl create secret generic "$test_username" \ + --namespace local-user-authenticator \ + --from-literal=groups="$test_groups" \ + --from-literal=passwordHash="$(htpasswd -nbBC 10 x "$test_password" | sed -e "s/^x://")" \ + --dry-run=client \ + --output yaml | + kubectl apply -f - + +# +# Regardless of how the local-user-authenticator is installed, we need the webhook bundle in the environment file. +# +webhook_ca_bundle="$(kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator -o 'jsonpath={.data.caCertificate}')" + # # Download the test CA bundle that was generated in the Dex pod. # Note that this returns a base64 encoded value. @@ -452,14 +446,19 @@ test_ca_bundle_pem="$(kubectl get secrets -n tools certs -o go-template='{{index kind_capabilities_file="$pinniped_path/test/cluster_capabilities/kind.yaml" pinniped_cluster_capability_file_content=$(cat "$kind_capabilities_file") +env_file_name="/tmp/integration-test-env" -cat <>"$env_file_name" +cat <"$env_file_name" # The following env vars should be set before running 'go test -v -count 1 -timeout 0 ./test/integration' export PINNIPED_TEST_TOOLS_NAMESPACE="tools" export PINNIPED_TEST_CONCIERGE_NAMESPACE=${concierge_namespace} export PINNIPED_TEST_CONCIERGE_APP_NAME=${concierge_app_name} export PINNIPED_TEST_CONCIERGE_CUSTOM_LABELS='${concierge_custom_labels}' +export PINNIPED_TEST_USER_USERNAME=${test_username} +export PINNIPED_TEST_USER_GROUPS=${test_groups} +export PINNIPED_TEST_USER_TOKEN=${test_username}:${test_password} export PINNIPED_TEST_WEBHOOK_ENDPOINT=${webhook_url} +export PINNIPED_TEST_WEBHOOK_CA_BUNDLE=${webhook_ca_bundle} export PINNIPED_TEST_SUPERVISOR_NAMESPACE=${supervisor_namespace} export PINNIPED_TEST_SUPERVISOR_APP_NAME=${supervisor_app_name} export PINNIPED_TEST_SUPERVISOR_CUSTOM_LABELS='${supervisor_custom_labels}' diff --git a/hack/prepare-supervisor-on-kind.sh b/hack/prepare-supervisor-on-kind.sh index 9425b50b..ea474eee 100755 --- a/hack/prepare-supervisor-on-kind.sh +++ b/hack/prepare-supervisor-on-kind.sh @@ -51,7 +51,6 @@ use_oidc_upstream=no use_ldap_upstream=no use_ad_upstream=no use_flow="" -env_file_name="" while (("$#")); do case "$1" in --flow) @@ -82,13 +81,6 @@ while (("$#")); do use_ad_upstream=yes shift ;; - --env) - shift - # Use an ActiveDirectoryIdentityProvider. - # This assumes that you used the --get-active-directory-vars flag with hack/prepare-for-integration-tests.sh. - env_file_name=$1 - shift - ;; -*) log_error "Unsupported flag $1" >&2 exit 1 @@ -105,13 +97,8 @@ if [[ "$use_oidc_upstream" == "no" && "$use_ldap_upstream" == "no" && "$use_ad_u exit 1 fi -if [[ "$env_file_name" == "" ]]; then - log_error "Error: Please provide --env file, typically printed in the output of ./hack/prepare-for-integration-tests.sh" - exit 1 -fi - # Read the env vars output by hack/prepare-for-integration-tests.sh -source $env_file_name +source "/tmp/integration-test-env" # Choose some filenames. root_ca_crt_path=root_ca.crt From 03527171531631e8e6de1e67a3df7a699a5777e6 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 19 Oct 2023 15:18:56 -0400 Subject: [PATCH 38/40] Adjust /etc/hosts message for local registry (if line not found) --- hack/prepare-for-integration-tests.sh | 31 +++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index c6f4cb72..349ddbfb 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -233,15 +233,29 @@ fi # registry="pinniped.local" -registry="kind-registry.local:5000" -# TODO: need to prompt the user to edit their /etc/hosts here, because otherwise -# we can't push images to the registry! maybe check /etc/hosts for this change else error? +registry="kind-registry.local" +registry_with_port="$registry:5000" repo="test/build" -registry_repo="$registry/$repo" +registry_repo="$registry_with_port/$repo" tag="0.0.0-$(uuidgen)" # always a new tag to force K8s to reload the image on redeploy + +etc_hosts_local_registry_missing=no +if ! grep -q "$registry" /etc/hosts; then + etc_hosts_local_registry_missing=yes +fi + +if [[ "$etc_hosts_local_registry_missing" == "yes" ]]; then + echo + log_error "In order to configure the kind cluster to use the local registry properly," + log_error "please run this command to edit /etc/hosts, and then run this script again with the same options." + echo "sudo bash -c \"echo '127.0.0.1 $registry' >> /etc/hosts\"" + log_error "When you are finished with your Kind cluster, you can remove this line from /etc/hosts." + exit 1 +fi + if [[ "$skip_build" == "yes" ]]; then - most_recent_tag=$(docker images "$registry/$repo" --format "{{.Tag}}" | head -1) + most_recent_tag=$(docker images "$registry_repo" --format "{{.Tag}}" | head -1) if [[ -n "$most_recent_tag" ]]; then tag="$most_recent_tag" do_build=no @@ -269,7 +283,7 @@ if [[ "$do_build" == "yes" ]]; then fi # Load it into the cluster -log_note "Loading the app's container image into the local registry ($registry)..." +log_note "Loading the app's container image into the local registry ($registry_with_port)..." docker push "$registry_repo_tag" # @@ -539,8 +553,3 @@ log_note "To delete the deployments, run:" log_note " kapp delete -a local-user-authenticator -y && kapp delete -a $concierge_app_name -y && kapp delete -a $supervisor_app_name -y" log_note "When you're finished, use './hack/kind-down.sh' to tear down the cluster." log_note -# TODO: come back and check the /etc/hosts file for the existence of -# the correct lines, just like is done in prepare-supervisor-on-kind.sh -log_note "Please run these commands to edit /etc/hosts, and then run this script again with the same options." -log_note " sudo bash -c \"echo '127.0.0.1 kind-registry.local' >> /etc/hosts\"" -log_note "When you are finished with your Kind cluster, you can remove these lines from /etc/hosts." From 8dfac21eb807e02dff94917586b95e3ea584a9fe Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 20 Oct 2023 12:36:26 -0400 Subject: [PATCH 39/40] Add PINNIPED_USE_LOCAL_KIND_REGISTRY env var - ensures regular use of hack/prepare-for-integration-tests.sh - PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh --clean --alternate-deploy ./hack/noop.sh --post-install ./hack/build-carvel-packages.sh - ./hack/prepare-for-integration-tests.sh --clean --- hack/build-carvel-packages.sh | 32 ++++++++--- hack/delete-carvel-packages.sh | 22 +++++++ hack/kind-down.sh | 10 ++-- hack/kind-up.sh | 48 +++++++++++----- .../kind-config/kind-registry-overlay.yaml | 11 ++++ hack/lib/kind-config/single-node.yaml | 8 --- hack/prepare-for-integration-tests.sh | 57 ++++++++++++------- 7 files changed, 134 insertions(+), 54 deletions(-) create mode 100644 hack/delete-carvel-packages.sh create mode 100644 hack/lib/kind-config/kind-registry-overlay.yaml diff --git a/hack/build-carvel-packages.sh b/hack/build-carvel-packages.sh index 7c07db22..a2496ffa 100755 --- a/hack/build-carvel-packages.sh +++ b/hack/build-carvel-packages.sh @@ -4,11 +4,22 @@ # SPDX-License-Identifier: Apache-2.0 # -# This script can be used to prepare a kind cluster and deploy the app. -# You can call this script again to redeploy the app. -# It will also output instructions on how to run the integration. +# This script can be used in conjunction with prepare-for-integration-tests.sh. +# When invoked with the PINNIPED_USE_LOCAL_KIND_REGISTRY environment variable set to a non-empty value, +# the integration tests script will create a local docker registry and configure kind to use the registry +# and will build the Pinniped binary and container image. +# This script will then create Carvel Packages for supervisor,concierge and local-user-authenticator. +# It will also create a Carvel PackageRepository. +# The PackageRepository will be installed on the kind cluster, then PackageInstall resources +# will be created to deploy an instance of each of the packages on the cluster. +# Once this script has completed, Pinniped can be interacted with as if it had been deployed in the usual way, +# for example by running tests or by preparing supervisor for manual interactions: +# source /tmp/integration-test-env && go test -v -race -count 1 -timeout 0 ./test/integration -run /TestE2EFullIntegration_Browser +# hack/prepare-supervisor-on-kind.sh --oidc +# +# Example usage: +# PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh --clean --alternate-deploy ./hack/noop.sh --post-install ./hack/build-carvel-packages.sh # - set -euo pipefail # @@ -53,6 +64,14 @@ cd "$pinniped_path" || exit 1 app=${1:-"undefined"} tag=${2:-$(uuidgen)} +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" == "" ]]; then + log_error "Building the Carvel package requires configuring kind with a local registry." + log_error "please set the environment variable PINNIPED_USE_LOCAL_KIND_REGISTRY" + log_error "for example:" + log_error " PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh --clean --alternate-deploy ./hack/noop.sh --post-install ./hack/build-carvel-packages.sh" +fi + + # TODO: automate the version by release somehow. # the tag is the version in our build scripts, but we will want real versions for releases pinniped_package_version="${tag}" # ie, "0.25.0" @@ -68,11 +87,10 @@ registry_repo_tag="${registry_repo}:${tag}" api_group_suffix="pinniped.dev" # Package prefix for concierge, supervisor, local-user-authenticator -package_prefix="test/build-package" # + $resource_name + ":" + $tag -package_repo_prefix="${registry_repo}/${package_prefix}" # + $resource_name + ":" + $tag +package_repo_prefix="${registry_repo}/package" # + $resource_name + ":" + $tag # Pinniped Package repository -package_repository_repo="test/build-package-repository-pinniped" +package_repository_repo="pinniped-package-repository" package_repository_repo_tag="${registry_repo}/${package_repository_repo}:${tag}" # carvel diff --git a/hack/delete-carvel-packages.sh b/hack/delete-carvel-packages.sh new file mode 100644 index 00000000..03b99fb8 --- /dev/null +++ b/hack/delete-carvel-packages.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +# +# This script can be used to prepare a kind cluster and deploy the app. +# You can call this script again to redeploy the app. +# It will also output instructions on how to run the integration. +# + +set -euo pipefail + +# whats all installed +kubectl get pkgr -A && kubectl get pkg -A && kubectl get pkgi -A + +# delete the package installs +kubectl delete pkgi concierge-package-install -n concierge-install-ns +kubectl delete pkgi supervisor-package-install -n supervisor-install-ns +kubectl delete pkgi local-user-authenticator-package-install -n local-user-authenticator-install-ns + +# TODO: clean up the rest also diff --git a/hack/kind-down.sh b/hack/kind-down.sh index be359cb4..59ea0d0a 100755 --- a/hack/kind-down.sh +++ b/hack/kind-down.sh @@ -8,9 +8,11 @@ set -euo pipefail ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" cd "${ROOT}" -reg_name='kind-registry.local' -docker network disconnect "kind" "${reg_name}" || true -docker stop "${reg_name}" || true -docker rm "${reg_name}" || true +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + reg_name='kind-registry.local' + docker network disconnect "kind" "${reg_name}" || true + docker stop "${reg_name}" || true + docker rm "${reg_name}" || true +fi kind delete cluster --name pinniped diff --git a/hack/kind-up.sh b/hack/kind-up.sh index 035eeab2..e9723c96 100755 --- a/hack/kind-up.sh +++ b/hack/kind-up.sh @@ -8,20 +8,35 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" -# create registry container unless it already exists -reg_name='kind-registry.local' -reg_port='5000' -if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then - docker run \ - -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \ - registry:2 + +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + # create registry container unless it already exists + reg_name='kind-registry.local' + reg_port='5000' + if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then + docker run \ + -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \ + registry:2 + fi fi -if [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then + +if [[ "${PINNIPED_USE_CONTOUR:-}" != "" && "$PINNIPED_USE_LOCAL_KIND_REGISTRY" != "" ]]; then + echo "Adding Contour port mapping and local registry to Kind config." + ytt -f "${ROOT}/hack/lib/kind-config/single-node.yaml" \ + -f "${ROOT}/hack/lib/kind-config/contour-overlay.yaml" \ + -f "${ROOT}/hack/lib/kind-config/kind-registry-overlay.yaml" >/tmp/kind-config.yaml + kind create cluster --config /tmp/kind-config.yaml --name pinniped +elif [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then echo "Adding Contour port mapping to Kind config." ytt -f "${ROOT}/hack/lib/kind-config/single-node.yaml" \ -f "${ROOT}/hack/lib/kind-config/contour-overlay.yaml" >/tmp/kind-config.yaml kind create cluster --config /tmp/kind-config.yaml --name pinniped +elif [[ "$PINNIPED_USE_LOCAL_KIND_REGISTRY" != "" ]]; then + echo "Adding local registry to Kind config." + ytt -f "${ROOT}/hack/lib/kind-config/single-node.yaml" \ + -f "${ROOT}/hack/lib/kind-config/kind-registry-overlay.yaml" >/tmp/kind-config.yaml + kind create cluster --config /tmp/kind-config.yaml --name pinniped else # To choose a specific version of kube, add this option to the command below: `--image kindest/node:v1.28.0`. # To debug the kind config, add this option to the command below: `-v 10` @@ -29,14 +44,15 @@ else fi -# connect the registry to the cluster network if not already connected -if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then - docker network connect "kind" "${reg_name}" -fi +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + # connect the registry to the cluster network if not already connected + if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then + docker network connect "kind" "${reg_name}" + fi -# Document the local registry -# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry -cat <> /etc/hosts\"" - log_error "When you are finished with your Kind cluster, you can remove this line from /etc/hosts." - exit 1 +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + etc_hosts_local_registry_missing=no + if ! grep -q "$registry" /etc/hosts; then + etc_hosts_local_registry_missing=yes + fi + if [[ "$etc_hosts_local_registry_missing" == "yes" ]]; then + echo + log_error "In order to configure the kind cluster to use the local registry properly," + log_error "please run this command to edit /etc/hosts, and then run this script again with the same options." + echo "sudo bash -c \"echo '127.0.0.1 $registry' >> /etc/hosts\"" + log_error "When you are finished with your Kind cluster, you can remove this line from /etc/hosts." + exit 1 + fi fi if [[ "$skip_build" == "yes" ]]; then @@ -282,10 +294,15 @@ if [[ "$do_build" == "yes" ]]; then fi fi -# Load it into the cluster -log_note "Loading the app's container image into the local registry ($registry_with_port)..." -docker push "$registry_repo_tag" - +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + # if registry used, push to the registry + log_note "Loading the app's container image into the local registry ($registry_with_port)..." + docker push "$registry_repo_tag" +else + # otherwise side-load directly + log_note "Loading the app's container image into the kind cluster..." + kind load docker-image "$registry_repo_tag" --name pinniped +fi # # Deploy local-user-authenticator # From d5565af1d3523b280b1d4b42a2782c9543e4aac9 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 20 Oct 2023 14:49:16 -0400 Subject: [PATCH 40/40] Carvel package readme updates --- deploy_carvel/README.md | 10 ++++++++++ deploy_carvel/concierge/README.md | 11 ++++++++++- deploy_carvel/local-user-authenticator/README.md | 14 +++++++++++++- deploy_carvel/supervisor/README.md | 11 ++++++++++- 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 deploy_carvel/README.md diff --git a/deploy_carvel/README.md b/deploy_carvel/README.md new file mode 100644 index 00000000..aaa61f05 --- /dev/null +++ b/deploy_carvel/README.md @@ -0,0 +1,10 @@ +# Deployment via Carvel Packages + +The Carvel Package deployment method can be exercised via the following invocation: + +```bash +PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh \ + --clean \ + --alternate-deploy ./hack/noop.sh \ + --post-install ./hack/build-carvel-packages.sh +``` diff --git a/deploy_carvel/concierge/README.md b/deploy_carvel/concierge/README.md index fcca81c3..3a6fc4b8 100644 --- a/deploy_carvel/concierge/README.md +++ b/deploy_carvel/concierge/README.md @@ -2,6 +2,15 @@ See [the how-to guide for details](https://pinniped.dev/docs/howto/concierge/). +The Carvel Package deployment method can be exercised via the following invocation: + +```bash +PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh \ + --clean \ + --alternate-deploy ./hack/noop.sh \ + --post-install ./hack/build-carvel-packages.sh +``` + ## In this directory: -- the ./config symlink points to /deploy/concierge +- `vendir` is used to copy the /deploy/concierge ytt files to /deploy_carvel/concierge/config. diff --git a/deploy_carvel/local-user-authenticator/README.md b/deploy_carvel/local-user-authenticator/README.md index ff77ea57..d9787894 100644 --- a/deploy_carvel/local-user-authenticator/README.md +++ b/deploy_carvel/local-user-authenticator/README.md @@ -1,5 +1,17 @@ # local-user-authenticator +The local-user-authenticator is a component used for testing Pinniped and is not a production component. +See [Application main functions](https://pinniped.dev/docs/reference/code-walkthrough/#application-main-functions) for a brief description. + +The Carvel Package deployment method can be exercised via the following invocation: + +```bash +PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh \ + --clean \ + --alternate-deploy ./hack/noop.sh \ + --post-install ./hack/build-carvel-packages.sh +``` + ## In this directory: -- the ./config symlink points to /deploy/local-user-authenticator +- `vendir` is used to copy the /deploy/local-user-authenticator ytt files to /deploy_carvel/local-user-authenticator/config. diff --git a/deploy_carvel/supervisor/README.md b/deploy_carvel/supervisor/README.md index bfd5cf46..d7449f46 100644 --- a/deploy_carvel/supervisor/README.md +++ b/deploy_carvel/supervisor/README.md @@ -2,6 +2,15 @@ See [the how-to guide for details](https://pinniped.dev/docs/howto/install-supervisor/). +The Carvel Package deployment method can be exercised via the following invocation: + +```bash +PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh \ + --clean \ + --alternate-deploy ./hack/noop.sh \ + --post-install ./hack/build-carvel-packages.sh +``` + ## In this directory: -- the ./config symlink points to /deploy/supervisor +- `vendir` is used to copy the /deploy/supervisor ytt files to /deploy_carvel/supervisor/config.