From e10d21d6785d512ff01810ddc37bc31ff08cdb20 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 28 Sep 2023 14:48:06 -0400 Subject: [PATCH 01/15] Support Carvel Package as alternate deployment mechanism - 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 - Update values.yaml for supervisor,concierge to schema files - Update values.yaml for local-user-authenticator to schema file - Add ytt openapi-v3 generation to build carvel package script - Add supervisor carvel package files - Add concierge carvel package files - Add local-user-authenticator carvel package files - Add hack script to build openapi-v3 files - add --post-install to hack/prepare-for-integration-tests.sh - cleanup local registry in kind-down.sh - webhook_ca_bundle moved in hack script - adjust were to call post-install script - deploy/{}/values.yml image_pull_dockerconfigjson type change to base64 string - 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 - if PINNIPED_USE_LOCAL_KIND_REGISTRY for kind-down.sh in hack/prepare-for-integration-tests.sh - Split carvel build & deploy scripts, add --pre-install flag - add pre-install flag to hack/prepare-for-integration-tests.sh - split /hack/build-carvel-packages.sh and /hack/deploy-carvel-packages.sh - Remove --alternate-deploy-* flags from hack script - Move scripts to hack/lib/carvel_packages - Split build.sh deploy.sh - Separate template files from install artifacts - Generate all install artifacts in $root/deploy_carvel - remove $root/deploy_carvel from git - Extract ytt values to file in hack/prepare-for-integration-tests.sh - pass registry/repo to carvel build scripts --- .gitignore | 5 + deploy/concierge/values.yaml | 154 ++++++----- deploy/local-user-authenticator/values.yaml | 29 ++- deploy/supervisor/values.yaml | 168 +++++++----- hack/kind-down.sh | 7 + hack/kind-up.sh | 61 ++++- hack/lib/carvel_packages/README.md | 10 + hack/lib/carvel_packages/build.sh | 172 ++++++++++++ hack/lib/carvel_packages/deploy.sh | 228 ++++++++++++++++ hack/lib/carvel_packages/tpl/.gitignore | 12 + .../tpl/local-user-authenticator/build.yml | 4 + .../tpl/local-user-authenticator/metadata.yml | 11 + .../package-template.yml | 28 ++ .../release_notes.txt | 4 + .../tpl/local-user-authenticator/vendir.yml | 8 + .../tpl/pinniped-concierge/build.yml | 4 + .../tpl/pinniped-concierge/metadata.yml | 10 + .../pinniped-concierge/package-template.yml | 28 ++ .../tpl/pinniped-concierge/release_notes.txt | 4 + .../tpl/pinniped-concierge/vendir.yml | 8 + .../tpl/pinniped-supervisor/build.yml | 4 + .../tpl/pinniped-supervisor/metadata.yml | 10 + .../pinniped-supervisor/package-template.yml | 28 ++ .../tpl/pinniped-supervisor/release_notes.txt | 4 + .../tpl/pinniped-supervisor/vendir.yml | 8 + .../kind-config/kind-registry-overlay.yaml | 11 + hack/prepare-for-integration-tests.sh | 244 +++++++++++------- 27 files changed, 1022 insertions(+), 242 deletions(-) create mode 100644 hack/lib/carvel_packages/README.md create mode 100755 hack/lib/carvel_packages/build.sh create mode 100755 hack/lib/carvel_packages/deploy.sh create mode 100644 hack/lib/carvel_packages/tpl/.gitignore create mode 100644 hack/lib/carvel_packages/tpl/local-user-authenticator/build.yml create mode 100644 hack/lib/carvel_packages/tpl/local-user-authenticator/metadata.yml create mode 100644 hack/lib/carvel_packages/tpl/local-user-authenticator/package-template.yml create mode 100644 hack/lib/carvel_packages/tpl/local-user-authenticator/release_notes.txt create mode 100644 hack/lib/carvel_packages/tpl/local-user-authenticator/vendir.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-concierge/build.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-concierge/metadata.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-concierge/package-template.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-concierge/release_notes.txt create mode 100644 hack/lib/carvel_packages/tpl/pinniped-concierge/vendir.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-supervisor/build.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-supervisor/metadata.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-supervisor/package-template.yml create mode 100644 hack/lib/carvel_packages/tpl/pinniped-supervisor/release_notes.txt create mode 100644 hack/lib/carvel_packages/tpl/pinniped-supervisor/vendir.yml create mode 100644 hack/lib/kind-config/kind-registry-overlay.yaml diff --git a/.gitignore b/.gitignore index 4d1df9312..ab430bda6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,8 @@ # Hugo temp file .hugo_build.lock + +# deploy_carvel is an ephemeral directory generated when certain scripts are executed. +# this directory will be created and populated with files that can be applied to a +# kubernetes cluster (specifically kind) in order to deploy Pinniped in an alternative way. +deploy_carvel diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 9267b0fc3..4807cfc02 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -1,75 +1,97 @@ #! 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 +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." +#! 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: "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" -#! 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 +99,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 +116,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/local-user-authenticator/values.yaml b/deploy/local-user-authenticator/values.yaml index 1f65baa4f..c05913049 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 diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 888d50381..1af809217 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -1,39 +1,50 @@ #! 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 +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." +#! 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: "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. @@ -41,43 +52,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 +156,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 diff --git a/hack/kind-down.sh b/hack/kind-down.sh index d90ccef24..59ea0d0a0 100755 --- a/hack/kind-down.sh +++ b/hack/kind-down.sh @@ -8,4 +8,11 @@ set -euo pipefail ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" cd "${ROOT}" +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 1bf702165..d92524a2b 100755 --- a/hack/kind-up.sh +++ b/hack/kind-up.sh @@ -8,13 +8,56 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" -if [[ "${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 -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` - kind create cluster --config "hack/lib/kind-config/single-node.yaml" --name pinniped + +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 + + +use_contour_registry="" +if [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then + echo "Adding Contour port mapping to Kind config." + use_contour_registry="--file=${ROOT}/hack/lib/kind-config/contour-overlay.yaml" +fi + + +use_kind_registry="" +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + echo "Adding local registry to Kind config." + use_kind_registry="--file=${ROOT}/hack/lib/kind-config/kind-registry-overlay.yaml" +fi + +$(ytt ${use_kind_registry} ${use_contour_registry} --file=${ROOT}/hack/lib/kind-config/single-node.yaml >/tmp/kind-config.yaml) +# 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` +kind create cluster --config /tmp/kind-config.yaml --name pinniped + + +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 </dev/null; then + log_error "Missing dependency..." + log_error "$2" + exit 1 + fi +} + +# this script is best invoked from the root directory +# it is designed to be passed as --pre-install flag to hack/prepare-for-integration-tests.sh +hack_lib_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "${hack_lib_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:-"app-argument-not-provided"} +tag=${2:-"tag-argument-not-provided"} +registry=${3:-"registry-argument-not-provided"} +repo=${4:-"repo-argument-not-provided"} + +log_note "build.sh called with app: ${app} tag: ${tag} registry: ${registry} repo: ${repo}" + +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 --pre-install ./hack/lib/carvel_packages/build.sh --alternate-deploy ./hack/lib/carvel_packages/deploy.sh" + exit 1 +fi + + +pinniped_package_version="${tag}" # ie, "0.25.0" +registry_repo="$registry/$repo" +registry_repo_tag="${registry_repo}:${tag}" + +api_group_suffix="pinniped.dev" + +# Package prefix for pinniped-concierge, pinniped-supervisor, local-user-authenticator +package_repo_prefix="${registry_repo}/package" # + $resource_name + ":" + $tag + +# Pinniped Package repository +package_repository_repo="pinniped-package-repository" +package_repository_repo_tag="${registry_repo}/${package_repository_repo}:${tag}" + + +dest_dir="deploy_carvel" +carvel_package_src="hack/lib/carvel_packages" +template_src_dir="${carvel_package_src}/tpl" + + +# clean the root carvel package directory +rm -rf "${dest_dir}" +mkdir "${dest_dir}" + +# Generate the OpenAPI v3 Schema files, imgpkg images.yml files +declare -a packages_to_build=("local-user-authenticator" "pinniped-concierge" "pinniped-supervisor") +for resource_name in "${packages_to_build[@]}" +do + resource_qualified_name="${resource_name}.${api_group_suffix}" + package_repo_tag="${package_repo_prefix}-${resource_name}:${tag}" + + # sources + resource_package_template_source_dir="${template_src_dir}/${resource_name}" + resource_ytt_config_file_source_dir="deploy/${resource_name}" # copy from original ytt templates + # destinations + resource_destination_dir="${dest_dir}/${resource_name}" + resource_config_destination_dir="${resource_destination_dir}/config" + + log_note "Copying static template files for ${resource_name}..." + mkdir "${resource_destination_dir}" + cp "${resource_package_template_source_dir}/metadata.yml" "${resource_destination_dir}/metadata.yml" + cp "${resource_package_template_source_dir}/build.yml" "${resource_destination_dir}/build.yml" + cp "${resource_package_template_source_dir}/vendir.yml" "${resource_destination_dir}/vendir.yml" + cp "${resource_package_template_source_dir}/release_notes.txt" "${resource_destination_dir}/release_notes.txt" # dummy + log_note "Vendir sync deploy directory for ${resource_name} to package bundle..." + pushd "${resource_destination_dir}" > /dev/null + vendir sync + popd > /dev/null + + log_note "Generating OpenAPI v3 schema for ${resource_name}..." + ytt \ + --file "${resource_config_destination_dir}" \ + --data-values-schema-inspect \ + --output openapi-v3 > \ + "${resource_destination_dir}/schema-openapi.yml" + + log_note "Generating .imgpkg/images.yml for ${resource_name}..." + mkdir -p "${resource_destination_dir}/.imgpkg" + ytt \ + --file "${resource_config_destination_dir}" | \ + kbld -f- --imgpkg-lock-output "${resource_destination_dir}/.imgpkg/images.yml" + + log_note "Pushing Pinniped ${resource_name} Package bundle..." + imgpkg push --bundle "${package_repo_tag}" --file "${resource_destination_dir}" + + log_note "Generating PackageRepository Package entry for ${resource_name}" + # publish package versions to package repository + packages_dir="deploy_carvel/package_repository/packages/" + package_repository_dir="${packages_dir}/${resource_qualified_name}" + mkdir -p "${packages_dir}" + rm -rf "${package_repository_dir}" + mkdir "${package_repository_dir}" + + ytt \ + --file "${resource_package_template_source_dir}/package-template.yml" \ + --data-value-file openapi="${resource_destination_dir}/schema-openapi.yml" \ + --data-value-file releaseNotes="${resource_destination_dir}/release_notes.txt" \ + --data-value repo_host="${package_repo_prefix}-${resource_name}" \ + --data-value version="${pinniped_package_version}" > "${package_repository_dir}/${pinniped_package_version}.yml" + cp "${resource_package_template_source_dir}/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" + +# manually validate the package bundle by pulling it from the registry and examining its contents: +# imgpkg pull --bundle "${package_repository_repo_tag}" --output "/tmp/${package_repository_repo_tag}" + +log_note "Building Carvel Packages for Supervisor, Concierge & local-user-authenticator complete." diff --git a/hack/lib/carvel_packages/deploy.sh b/hack/lib/carvel_packages/deploy.sh new file mode 100755 index 000000000..9282671c1 --- /dev/null +++ b/hack/lib/carvel_packages/deploy.sh @@ -0,0 +1,228 @@ +#!/usr/bin/env bash + +# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +# +# 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 --pre-install ./hack/lib/carvel_packages/build.sh --alternate-deploy ./hack/lib/carvel_packages/deploy.sh +# +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 +} + +# this script is best invoked from the root directory +# it is designed to be passed as --pre-install flag to hack/prepare-for-integration-tests.sh +hack_lib_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$hack_lib_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:-"app-argument-not-provided"} +tag=${2:-"tag-argument-not-provided"} +registry=${3:-"registry-argument-not-provided"} +repo=${4:-"repo-argument-not-provided"} +data_values_file=${5:-"ytt-data-values-file-argument-not-provided"} + +log_note "deploy.sh called with app: ${app} tag: ${tag} registry: ${registry} repo: ${repo} data_values_file: ${data_values_file}" + +log_note "Begin deploy of carvel package for ${app}..." + +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 --pre-install ./hack/lib/carvel_packages/build.sh --alternate-deploy ./hack/lib/carvel_packages/deploy.sh" + exit 1 +fi + + +pinniped_package_version="${tag}" # ie, "0.25.0" + +registry_repo="$registry/$repo" +registry_repo_tag="${registry_repo}:${tag}" + +api_group_suffix="pinniped.dev" + +# Package prefix for concierge, supervisor, local-user-authenticator +package_repo_prefix="${registry_repo}/package" # + $resource_name + ":" + $tag + +# Pinniped Package repository +package_repository_repo="pinniped-package-repository" +package_repository_repo_tag="${registry_repo}/${package_repository_repo}:${tag}" + + +# deploy kapp-controller onto kind cluster +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 + +# ensure this directory exists though this script will run several times +mkdir -p "deploy_carvel/install" + +log_note "Deploying Pinniped PackageRepository..." +pinniped_package_repository_name="pinniped-package-repository" +pinniped_package_repository_file="deploy_carvel/install/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 + + +resource_name="${app}" + +log_note "Creating RBAC for ${resource_name} PackageInstall..." + +namespace="${resource_name}-install-ns" +pinniped_package_rbac_prefix="pinniped-package-rbac-${resource_name}" +pinniped_package_rbac_file="deploy_carvel/install/${pinniped_package_rbac_prefix}-${resource_name}-rbac.yml" +echo -n "" > "${pinniped_package_rbac_file}" +# NOTE: this script is for development purposes running on a local kind cluster. +# For any other use case, the generated artifacts should be properly reviewed. +# For example, the RBAC generated here should be adjusted to conform to the +# principle of LEAST privilege. +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" +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 + + +log_note "Creating ${resource_name} PackageInstall..." +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/install/${resource_name}-pkginstall.yml" +SECRET_NAME="${resource_name}-package-install-secret" + +log_note "Generating ${PACKAGE_INSTALL_FILE_NAME}..." +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}" +EOF + +log_note "Creating secret ${SECRET_NAME} with ${data_values_file}..." +kubectl create secret generic "${SECRET_NAME}" --namespace "${NAMESPACE}" --from-file "${data_values_file}" --dry-run=client -o yaml | kubectl apply -f- + +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 + + +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 + +log_note "Complete deploy of carvel package for ${app}..." diff --git a/hack/lib/carvel_packages/tpl/.gitignore b/hack/lib/carvel_packages/tpl/.gitignore new file mode 100644 index 000000000..d6ba8ff17 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/.gitignore @@ -0,0 +1,12 @@ +# package_repository/packages/{pkg}/ contains specific SHAs of images +# we are using 0.0.0- to indicate dev versions of images +*0.0.0* + +# installation artifacts will be generated here +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/hack/lib/carvel_packages/tpl/local-user-authenticator/build.yml b/hack/lib/carvel_packages/tpl/local-user-authenticator/build.yml new file mode 100644 index 000000000..dfff29741 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/local-user-authenticator/build.yml @@ -0,0 +1,4 @@ +apiVersion: kbld.k14s.io/v1alpha1 +kind: Config +minimumRequiredVersion: 0.31.0 +overrides: diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/metadata.yml b/hack/lib/carvel_packages/tpl/local-user-authenticator/metadata.yml new file mode 100644 index 000000000..1ad53d442 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/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/hack/lib/carvel_packages/tpl/local-user-authenticator/package-template.yml b/hack/lib/carvel_packages/tpl/local-user-authenticator/package-template.yml new file mode 100644 index 000000000..5a0f6a5a0 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/local-user-authenticator/package-template.yml @@ -0,0 +1,28 @@ +#@ 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: #@ yaml.decode(data.values.releaseNotes) + valuesSchema: + openAPIv3: #@ yaml.decode(data.values.openapi)["components"]["schemas"]["dataValues"] + template: + spec: + fetch: + - imgpkgBundle: + image: #@ data.values.repo_host + ":" + data.values.version + template: + - ytt: + paths: + - "config/" + - kbld: + paths: + - ".imgpkg/images.yml" + - "-" + deploy: + - kapp: {} diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/release_notes.txt b/hack/lib/carvel_packages/tpl/local-user-authenticator/release_notes.txt new file mode 100644 index 000000000..6bf385a4b --- /dev/null +++ b/hack/lib/carvel_packages/tpl/local-user-authenticator/release_notes.txt @@ -0,0 +1,4 @@ +Dummy Release Notes for local-user-authenticator +- foo +- bar +- baz diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/vendir.yml b/hack/lib/carvel_packages/tpl/local-user-authenticator/vendir.yml new file mode 100644 index 000000000..e264b5187 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/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/hack/lib/carvel_packages/tpl/pinniped-concierge/build.yml b/hack/lib/carvel_packages/tpl/pinniped-concierge/build.yml new file mode 100644 index 000000000..dfff29741 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-concierge/build.yml @@ -0,0 +1,4 @@ +apiVersion: kbld.k14s.io/v1alpha1 +kind: Config +minimumRequiredVersion: 0.31.0 +overrides: diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/metadata.yml b/hack/lib/carvel_packages/tpl/pinniped-concierge/metadata.yml new file mode 100644 index 000000000..7fb142363 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-concierge/metadata.yml @@ -0,0 +1,10 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: pinniped-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/hack/lib/carvel_packages/tpl/pinniped-concierge/package-template.yml b/hack/lib/carvel_packages/tpl/pinniped-concierge/package-template.yml new file mode 100644 index 000000000..a5df8bd63 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-concierge/package-template.yml @@ -0,0 +1,28 @@ +#@ 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: #@ "pinniped-concierge.pinniped.dev." + data.values.version +spec: + refName: pinniped-concierge.pinniped.dev + version: #@ data.values.version + releaseNotes: #@ yaml.decode(data.values.releaseNotes) + valuesSchema: + openAPIv3: #@ yaml.decode(data.values.openapi)["components"]["schemas"]["dataValues"] + template: + spec: + fetch: + - imgpkgBundle: + image: #@ data.values.repo_host + ":" + data.values.version + template: + - ytt: + paths: + - "config/" + - kbld: + paths: + - ".imgpkg/images.yml" + - "-" + deploy: + - kapp: {} diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/release_notes.txt b/hack/lib/carvel_packages/tpl/pinniped-concierge/release_notes.txt new file mode 100644 index 000000000..f978bbf0f --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-concierge/release_notes.txt @@ -0,0 +1,4 @@ +Dummy Release Notes for Concierge +- foo +- bar +- baz diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/vendir.yml b/hack/lib/carvel_packages/tpl/pinniped-concierge/vendir.yml new file mode 100644 index 000000000..0408ed493 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-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/hack/lib/carvel_packages/tpl/pinniped-supervisor/build.yml b/hack/lib/carvel_packages/tpl/pinniped-supervisor/build.yml new file mode 100644 index 000000000..dfff29741 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-supervisor/build.yml @@ -0,0 +1,4 @@ +apiVersion: kbld.k14s.io/v1alpha1 +kind: Config +minimumRequiredVersion: 0.31.0 +overrides: diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/metadata.yml b/hack/lib/carvel_packages/tpl/pinniped-supervisor/metadata.yml new file mode 100644 index 000000000..a775c9fa3 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-supervisor/metadata.yml @@ -0,0 +1,10 @@ +apiVersion: data.packaging.carvel.dev/v1alpha1 +kind: PackageMetadata +metadata: + name: pinniped-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/hack/lib/carvel_packages/tpl/pinniped-supervisor/package-template.yml b/hack/lib/carvel_packages/tpl/pinniped-supervisor/package-template.yml new file mode 100644 index 000000000..0cd4c5bae --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-supervisor/package-template.yml @@ -0,0 +1,28 @@ +#@ 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: #@ "pinniped-supervisor.pinniped.dev." + data.values.version +spec: + refName: pinniped-supervisor.pinniped.dev + version: #@ data.values.version + releaseNotes: #@ yaml.decode(data.values.releaseNotes) + valuesSchema: + openAPIv3: #@ yaml.decode(data.values.openapi)["components"]["schemas"]["dataValues"] + template: + spec: + fetch: + - imgpkgBundle: + image: #@ data.values.repo_host + ":" + data.values.version + template: + - ytt: + paths: + - "config/" + - kbld: + paths: + - ".imgpkg/images.yml" + - "-" + deploy: + - kapp: {} diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/release_notes.txt b/hack/lib/carvel_packages/tpl/pinniped-supervisor/release_notes.txt new file mode 100644 index 000000000..446a7b76a --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-supervisor/release_notes.txt @@ -0,0 +1,4 @@ +Dummy Release Notes for Supervisor +- foo +- bar +- baz diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/vendir.yml b/hack/lib/carvel_packages/tpl/pinniped-supervisor/vendir.yml new file mode 100644 index 000000000..30c187ea9 --- /dev/null +++ b/hack/lib/carvel_packages/tpl/pinniped-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/lib/kind-config/kind-registry-overlay.yaml b/hack/lib/kind-config/kind-registry-overlay.yaml new file mode 100644 index 000000000..e4901dec0 --- /dev/null +++ b/hack/lib/kind-config/kind-registry-overlay.yaml @@ -0,0 +1,11 @@ +#! Copyright 2023 the Pinniped contributors. All Rights Reserved. +#! SPDX-License-Identifier: Apache-2.0 + +#@ load("@ytt:overlay", "overlay") +#@overlay/match by=overlay.all +--- +#@overlay/match missing_ok=True +containerdConfigPatches: +- |- + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."kind-registry.local:5000"] + endpoint = ["http://kind-registry.local:5000"] diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 18032d429..034f0611c 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -8,7 +8,15 @@ # You can call this script again to redeploy the app. # It will also output instructions on how to run the integration. # - +# When invoked with the PINNIPED_USE_LOCAL_KIND_REGISTRY environment variable set to a non-empty value, +# the script will create a local docker registry and configure kind to use the registry. When building +# and installing Pinniped normally this is unnecessary. However, if an alternative build and install approach +# is taken, such as via a Carvel packaging mechanism, a local registry might be needed (for example, the +# kbld tool requires a registry to resolve images to shas). +# +# Example usage: +# PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh --clean --pre-install ./hack/lib/carvel_packages/build.sh --alternate-deploy ./hack/lib/carvel_packages/deploy.sh +# set -euo pipefail # @@ -52,9 +60,7 @@ api_group_suffix="pinniped.dev" # same default as in the values.yaml ytt file dockerfile_path="" get_active_directory_vars="" # specify a filename for a script to get AD related env variables alternate_deploy="undefined" -alternate_deploy_supervisor="undefined" -alternate_deploy_concierge="undefined" -alternate_deploy_local_user_authenticator="undefined" +pre_install="undefined" # supported variable style: # --dockerfile-path ./foo.sh @@ -113,31 +119,13 @@ while (("$#")); do alternate_deploy=$1 shift ;; - --alternate-deploy-supervisor) + --pre-install) shift if [[ "$#" == "0" || "$1" == -* ]]; then - log_error "--alternate-deploy-supervisor requires a script path to be specified" + log_error "--pre-install requires a script path to be specified" exit 1 fi - alternate_deploy_supervisor=$1 - shift - ;; - --alternate-deploy-concierge) - shift - if [[ "$#" == "0" || "$1" == -* ]]; then - log_error "--alternate-deploy-concierge requires a script path to be specified" - exit 1 - fi - alternate_deploy_concierge=$1 - shift - ;; - --alternate-deploy-local-user-authenticator) - shift - if [[ "$#" == "0" || "$1" == -* ]]; then - log_error "--alternate-deploy-local-user-authenticator requires a script path to be specified" - exit 1 - fi - alternate_deploy_local_user_authenticator=$1 + pre_install=$1 shift ;; -*) @@ -166,9 +154,7 @@ if [[ "$help" == "yes" ]]; then log_note " -s, --skip-build: reuse the most recently built image of the app instead of building" log_note " -a, --get-active-directory-vars: specify a script that exports active directory environment variables" log_note " --alternate-deploy: specify an alternate deploy script to install all components of Pinniped" - 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 " --pre-install: specify an pre-install script such as a build script" exit 1 fi @@ -221,12 +207,34 @@ else fi registry="pinniped.local" +registry_with_port="$registry" +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + registry="kind-registry.local" + registry_with_port="$registry:5000" +fi + repo="test/build" -registry_repo="$registry/$repo" -tag=$(uuidgen) # always a new tag to force K8s to reload the image on redeploy +registry_repo="$registry_with_port/$repo" +tag="0.0.0-$(uuidgen)" # always a new tag to force K8s to reload the image on redeploy + + +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 - 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 @@ -253,33 +261,52 @@ if [[ "$do_build" == "yes" ]]; then fi fi -# Load it into the cluster -log_note "Loading the app's container image into the kind cluster..." -kind load docker-image "$registry_repo_tag" --name pinniped +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 + + +# +# Call a pre-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 [ "$pre_install" != "undefined" ] ; then + log_note "The pre-install script will be called with $tag..." + $pre_install pre-install-script $tag $registry_with_port $repo +fi + # # Deploy local-user-authenticator # manifest=/tmp/pinniped-local-user-authenticator.yaml +data_values_path="/tmp/local-user-authenticator" +data_values_file="${data_values_path}/values.yml" +mkdir -p "${data_values_path}" +cat < "$data_values_file" +--- +image_repo: $registry_repo +image_tag: $tag +EOF -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 - 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 - fi +if [ "$alternate_deploy" != "undefined" ]; then + $alternate_deploy local-user-authenticator $tag $registry_with_port $repo $data_values_file else log_note "Deploying the local-user-authenticator app to the cluster using kapp..." pushd deploy/local-user-authenticator >/dev/null - ytt --file . \ - --data-value "image_repo=$registry_repo" \ - --data-value "image_tag=$tag" >"$manifest" + + ytt --file . --data-values-file "$data_values_file" >"$manifest" kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. + popd >/dev/null fi @@ -303,18 +330,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 # @@ -326,31 +341,31 @@ log_level="debug" service_https_nodeport_port="443" service_https_nodeport_nodeport="31243" service_https_clusterip_port="443" +data_values_path="/tmp/supervisor" +data_values_file="${data_values_path}/values.yml" +mkdir -p "${data_values_path}" +cat < "$data_values_file" +--- +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 +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 +EOF -if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_supervisor" != "undefined" ] ; then - if [ "$alternate_deploy" != "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 - 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 - fi + $alternate_deploy pinniped-supervisor $tag $registry_with_port $repo $data_values_file else log_note "Deploying the Pinniped Supervisor app to the cluster using kapp..." pushd deploy/supervisor >/dev/null - ytt --file . \ - --data-value "app_name=$supervisor_app_name" \ - --data-value "namespace=$supervisor_namespace" \ - --data-value "api_group_suffix=$api_group_suffix" \ - --data-value "image_repo=$registry_repo" \ - --data-value "image_tag=$tag" \ - --data-value "log_level=$log_level" \ - --data-value-yaml "custom_labels=$supervisor_custom_labels" \ - --data-value-yaml "service_https_nodeport_port=$service_https_nodeport_port" \ - --data-value-yaml "service_https_nodeport_nodeport=$service_https_nodeport_nodeport" \ - --data-value-yaml "service_https_clusterip_port=$service_https_clusterip_port" \ - >"$manifest" + + ytt --file . --data-values-file "$data_values_file" >"$manifest" kapp deploy --yes --app "$supervisor_app_name" --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. @@ -364,38 +379,61 @@ 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}')" discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" log_level="debug" +data_values_path="/tmp/concierge" +data_values_file="${data_values_path}/values.yml" +mkdir -p "${data_values_path}" +cat < "$data_values_file" +--- +app_name: $concierge_app_name +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 +discovery_url: $discovery_url +EOF -if [ "$alternate_deploy" != "undefined" ] || [ "$alternate_deploy_concierge" != "undefined" ] ; then - if [ "$alternate_deploy" != "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 - 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 - fi + $alternate_deploy pinniped-concierge $tag $registry_with_port $repo $data_values_file else log_note "Deploying the Pinniped Concierge app to the cluster using kapp..." pushd deploy/concierge >/dev/null - ytt --file . \ - --data-value "app_name=$concierge_app_name" \ - --data-value "namespace=$concierge_namespace" \ - --data-value "api_group_suffix=$api_group_suffix" \ - --data-value "log_level=$log_level" \ - --data-value-yaml "custom_labels=$concierge_custom_labels" \ - --data-value "image_repo=$registry_repo" \ - --data-value "image_tag=$tag" \ - --data-value "discovery_url=$discovery_url" >"$manifest" + + ytt --file . --data-values-file "$data_values_file" >"$manifest" kapp deploy --yes --app "$concierge_app_name" --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. popd >/dev/null 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. @@ -412,7 +450,9 @@ 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") -cat </tmp/integration-test-env +env_file_name="/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} @@ -484,6 +524,7 @@ PINNIPED_TEST_CLUSTER_CAPABILITY_YAML_EOF export PINNIPED_TEST_CLUSTER_CAPABILITY_YAML EOF + # # Print instructions for next steps. # @@ -491,7 +532,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" @@ -500,4 +541,9 @@ log_note "You can rerun this script to redeploy local production code changes wh log_note 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." +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then + log_note "When you're finished, use 'PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/kind-down.sh' to tear down the cluster." +else + log_note "When you're finished, use './hack/kind-down.sh' to tear down the cluster." +fi +log_note From 07e9c5bd939a43936c37c716d2f71ff324de43f1 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Thu, 2 Nov 2023 15:54:19 -0700 Subject: [PATCH 02/15] refactor carvel packaing scripts --- .gitignore | 5 - deploy/concierge/values.yaml | 12 +- deploy/local-user-authenticator/values.yaml | 1 - deploy/supervisor/values.yaml | 28 ++--- hack/kind-down.sh | 21 +++- hack/kind-up.sh | 26 ++-- hack/lib/carvel_packages/README.md | 10 -- hack/lib/carvel_packages/build.sh | 50 ++++---- hack/lib/carvel_packages/deploy.sh | 56 +++------ .../local-user-authenticator/build.yml | 0 .../local-user-authenticator/metadata.yml | 0 .../package-template.yml | 0 .../release_notes.txt | 0 .../local-user-authenticator/vendir.yml | 0 .../pinniped-concierge/build.yml | 0 .../pinniped-concierge/metadata.yml | 0 .../pinniped-concierge/package-template.yml | 0 .../pinniped-concierge/release_notes.txt | 0 .../pinniped-concierge/vendir.yml | 0 .../pinniped-supervisor/build.yml | 0 .../pinniped-supervisor/metadata.yml | 0 .../pinniped-supervisor/package-template.yml | 0 .../pinniped-supervisor/release_notes.txt | 0 .../pinniped-supervisor/vendir.yml | 0 hack/lib/carvel_packages/tpl/.gitignore | 12 -- .../kind-config/kind-registry-overlay.yaml | 2 +- hack/prepare-for-integration-tests.sh | 111 ++++++------------ 27 files changed, 125 insertions(+), 209 deletions(-) delete mode 100644 hack/lib/carvel_packages/README.md rename hack/lib/carvel_packages/{tpl => templates}/local-user-authenticator/build.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/local-user-authenticator/metadata.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/local-user-authenticator/package-template.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/local-user-authenticator/release_notes.txt (100%) rename hack/lib/carvel_packages/{tpl => templates}/local-user-authenticator/vendir.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-concierge/build.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-concierge/metadata.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-concierge/package-template.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-concierge/release_notes.txt (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-concierge/vendir.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-supervisor/build.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-supervisor/metadata.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-supervisor/package-template.yml (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-supervisor/release_notes.txt (100%) rename hack/lib/carvel_packages/{tpl => templates}/pinniped-supervisor/vendir.yml (100%) delete mode 100644 hack/lib/carvel_packages/tpl/.gitignore diff --git a/.gitignore b/.gitignore index ab430bda6..4d1df9312 100644 --- a/.gitignore +++ b/.gitignore @@ -22,8 +22,3 @@ # Hugo temp file .hugo_build.lock - -# deploy_carvel is an ephemeral directory generated when certain scripts are executed. -# this directory will be created and populated with files that can be applied to a -# kubernetes cluster (specifically kind) in order to deploy Pinniped in an alternative way. -deploy_carvel diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 4807cfc02..2721e27d0 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -1,9 +1,9 @@ -#! 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-schema --- -#@schema/desc "Name of pinniped-concierge." +#@schema/desc "Used to help determine the names of various resources and labels." app_name: pinniped-concierge #@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." @@ -57,13 +57,14 @@ image_pull_dockerconfigjson: "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm #@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." +#@ about every 25 days. Specify this as an integer or as a string which contains an integer value." #@schema/desc api_serving_certificate_desc +#@schema/type any=True api_serving_certificate_duration_seconds: 2592000 #@schema/desc api_serving_certificate_desc +#@schema/type any=True api_serving_certificate_renew_before_seconds: 2160000 #! Specify the verbosity of logging: info ("nice to know" information), debug (developer information), trace (timing information), @@ -90,7 +91,6 @@ run_as_group: 65532 #@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". @@ -117,10 +117,8 @@ impersonation_proxy_spec: #! 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." diff --git a/deploy/local-user-authenticator/values.yaml b/deploy/local-user-authenticator/values.yaml index c05913049..df991aa7b 100644 --- a/deploy/local-user-authenticator/values.yaml +++ b/deploy/local-user-authenticator/values.yaml @@ -3,7 +3,6 @@ #@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." diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 1af809217..217f8680a 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -1,9 +1,9 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 #@data/values-schema --- -#@schema/desc "Name of pinniped-supervisor." +#@schema/desc "Used to help determine the names of various resources and labels." app_name: pinniped-supervisor #@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." @@ -18,9 +18,9 @@ into_namespace: my-preexisting-namespace #@ 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." +#@ 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, \ +#@ or, 2.) 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} @@ -61,19 +61,19 @@ 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/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/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/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/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/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. \ @@ -94,9 +94,9 @@ log_level: info #@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" +#@schema/desc "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" +#@schema/desc "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 \ @@ -114,8 +114,8 @@ api_group_suffix: pinniped.dev #@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" +#@schema/desc "Endpoints that should not use the proxy." +no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints #! Control the HTTP and HTTPS listeners of the Supervisor. #! diff --git a/hack/kind-down.sh b/hack/kind-down.sh index 59ea0d0a0..1f510e2c6 100755 --- a/hack/kind-down.sh +++ b/hack/kind-down.sh @@ -1,18 +1,29 @@ #!/usr/bin/env bash -# Copyright 2020 the Pinniped contributors. All Rights Reserved. +# Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 set -euo pipefail -ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )" +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" 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 + + # If the container is running... + if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" == 'true' ]; then + # Disconnect it from the kind network, if it was connected. + if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" != 'null' ]; then + docker network disconnect "kind" "${reg_name}" >/dev/null + fi + + echo "Stopping container $reg_name ..." + docker stop "${reg_name}" >/dev/null + + # Delete it. + docker rm "${reg_name}" >/dev/null + fi fi kind delete cluster --name pinniped diff --git a/hack/kind-up.sh b/hack/kind-up.sh index d92524a2b..d626e581b 100755 --- a/hack/kind-up.sh +++ b/hack/kind-up.sh @@ -8,45 +8,47 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" - if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then - # create registry container unless it already exists + # 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 + echo "Running the registry:2 docker image..." docker run \ - -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \ + --detach \ + --restart=always \ + --publish "127.0.0.1:${reg_port}:5000" \ + --name "${reg_name}" \ registry:2 fi fi - use_contour_registry="" -if [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then +if [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then echo "Adding Contour port mapping to Kind config." use_contour_registry="--file=${ROOT}/hack/lib/kind-config/contour-overlay.yaml" fi - use_kind_registry="" -if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then +if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then echo "Adding local registry to Kind config." use_kind_registry="--file=${ROOT}/hack/lib/kind-config/kind-registry-overlay.yaml" fi -$(ytt ${use_kind_registry} ${use_contour_registry} --file=${ROOT}/hack/lib/kind-config/single-node.yaml >/tmp/kind-config.yaml) +# Do not quote ${use_kind_registry} ${use_contour_registry} in this command because they might be empty. +ytt ${use_kind_registry} ${use_contour_registry} --file="${ROOT}"/hack/lib/kind-config/single-node.yaml >/tmp/kind-config.yaml + # 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` kind create cluster --config /tmp/kind-config.yaml --name pinniped - 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 + # 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 + # Configure kind to use the local registry. # https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry cat < "${pinniped_package_repository_file}" -cat <> "${pinniped_package_repository_file}" +pinniped_package_repository_file="${dest_dir}/install/packagerepository.${pinniped_package_version}.yml" +cat < "${pinniped_package_repository_file}" --- apiVersion: packaging.carvel.dev/v1alpha1 kind: PackageRepository @@ -124,20 +106,18 @@ EOT kapp deploy --app "${pinniped_package_repository_name}" --file "${pinniped_package_repository_file}" -y kapp inspect --app "${pinniped_package_repository_name}" --tree - resource_name="${app}" log_note "Creating RBAC for ${resource_name} PackageInstall..." namespace="${resource_name}-install-ns" pinniped_package_rbac_prefix="pinniped-package-rbac-${resource_name}" -pinniped_package_rbac_file="deploy_carvel/install/${pinniped_package_rbac_prefix}-${resource_name}-rbac.yml" -echo -n "" > "${pinniped_package_rbac_file}" -# NOTE: this script is for development purposes running on a local kind cluster. +pinniped_package_rbac_file="${dest_dir}/install/${pinniped_package_rbac_prefix}-${resource_name}-rbac.yml" +# NOTE: This script is for development purposes running on a local kind cluster. # For any other use case, the generated artifacts should be properly reviewed. # For example, the RBAC generated here should be adjusted to conform to the # principle of LEAST privilege. -cat <> "${pinniped_package_rbac_file}" +cat < "${pinniped_package_rbac_file}" --- apiVersion: v1 kind: Namespace @@ -176,12 +156,11 @@ EOF kapp deploy --app "${pinniped_package_rbac_prefix}" --file "${pinniped_package_rbac_file}" -y - log_note "Creating ${resource_name} PackageInstall..." 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/install/${resource_name}-pkginstall.yml" +PACKAGE_INSTALL_FILE_NAME="${dest_dir}/install/${resource_name}-pkginstall.yml" SECRET_NAME="${resource_name}-package-install-secret" log_note "Generating ${PACKAGE_INSTALL_FILE_NAME}..." @@ -211,7 +190,6 @@ 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 - log_note "Verifying PackageInstall resources..." kubectl get PackageInstall -A | grep pinniped kubectl get secret -A | grep pinniped diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/build.yml b/hack/lib/carvel_packages/templates/local-user-authenticator/build.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/local-user-authenticator/build.yml rename to hack/lib/carvel_packages/templates/local-user-authenticator/build.yml diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/metadata.yml b/hack/lib/carvel_packages/templates/local-user-authenticator/metadata.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/local-user-authenticator/metadata.yml rename to hack/lib/carvel_packages/templates/local-user-authenticator/metadata.yml diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/package-template.yml b/hack/lib/carvel_packages/templates/local-user-authenticator/package-template.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/local-user-authenticator/package-template.yml rename to hack/lib/carvel_packages/templates/local-user-authenticator/package-template.yml diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/release_notes.txt b/hack/lib/carvel_packages/templates/local-user-authenticator/release_notes.txt similarity index 100% rename from hack/lib/carvel_packages/tpl/local-user-authenticator/release_notes.txt rename to hack/lib/carvel_packages/templates/local-user-authenticator/release_notes.txt diff --git a/hack/lib/carvel_packages/tpl/local-user-authenticator/vendir.yml b/hack/lib/carvel_packages/templates/local-user-authenticator/vendir.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/local-user-authenticator/vendir.yml rename to hack/lib/carvel_packages/templates/local-user-authenticator/vendir.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/build.yml b/hack/lib/carvel_packages/templates/pinniped-concierge/build.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-concierge/build.yml rename to hack/lib/carvel_packages/templates/pinniped-concierge/build.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/metadata.yml b/hack/lib/carvel_packages/templates/pinniped-concierge/metadata.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-concierge/metadata.yml rename to hack/lib/carvel_packages/templates/pinniped-concierge/metadata.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/package-template.yml b/hack/lib/carvel_packages/templates/pinniped-concierge/package-template.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-concierge/package-template.yml rename to hack/lib/carvel_packages/templates/pinniped-concierge/package-template.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/release_notes.txt b/hack/lib/carvel_packages/templates/pinniped-concierge/release_notes.txt similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-concierge/release_notes.txt rename to hack/lib/carvel_packages/templates/pinniped-concierge/release_notes.txt diff --git a/hack/lib/carvel_packages/tpl/pinniped-concierge/vendir.yml b/hack/lib/carvel_packages/templates/pinniped-concierge/vendir.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-concierge/vendir.yml rename to hack/lib/carvel_packages/templates/pinniped-concierge/vendir.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/build.yml b/hack/lib/carvel_packages/templates/pinniped-supervisor/build.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-supervisor/build.yml rename to hack/lib/carvel_packages/templates/pinniped-supervisor/build.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/metadata.yml b/hack/lib/carvel_packages/templates/pinniped-supervisor/metadata.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-supervisor/metadata.yml rename to hack/lib/carvel_packages/templates/pinniped-supervisor/metadata.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/package-template.yml b/hack/lib/carvel_packages/templates/pinniped-supervisor/package-template.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-supervisor/package-template.yml rename to hack/lib/carvel_packages/templates/pinniped-supervisor/package-template.yml diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/release_notes.txt b/hack/lib/carvel_packages/templates/pinniped-supervisor/release_notes.txt similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-supervisor/release_notes.txt rename to hack/lib/carvel_packages/templates/pinniped-supervisor/release_notes.txt diff --git a/hack/lib/carvel_packages/tpl/pinniped-supervisor/vendir.yml b/hack/lib/carvel_packages/templates/pinniped-supervisor/vendir.yml similarity index 100% rename from hack/lib/carvel_packages/tpl/pinniped-supervisor/vendir.yml rename to hack/lib/carvel_packages/templates/pinniped-supervisor/vendir.yml diff --git a/hack/lib/carvel_packages/tpl/.gitignore b/hack/lib/carvel_packages/tpl/.gitignore deleted file mode 100644 index d6ba8ff17..000000000 --- a/hack/lib/carvel_packages/tpl/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -# package_repository/packages/{pkg}/ contains specific SHAs of images -# we are using 0.0.0- to indicate dev versions of images -*0.0.0* - -# installation artifacts will be generated here -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/hack/lib/kind-config/kind-registry-overlay.yaml b/hack/lib/kind-config/kind-registry-overlay.yaml index e4901dec0..506134d7b 100644 --- a/hack/lib/kind-config/kind-registry-overlay.yaml +++ b/hack/lib/kind-config/kind-registry-overlay.yaml @@ -2,7 +2,7 @@ #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:overlay", "overlay") -#@overlay/match by=overlay.all +#@overlay/match by=overlay.subset({"kind": "Cluster"}), expects=1 --- #@overlay/match missing_ok=True containerdConfigPatches: diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index 034f0611c..b1f353087 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -6,15 +6,13 @@ # # 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. +# It will also output instructions on how to run the integration tests. # -# When invoked with the PINNIPED_USE_LOCAL_KIND_REGISTRY environment variable set to a non-empty value, -# the script will create a local docker registry and configure kind to use the registry. When building -# and installing Pinniped normally this is unnecessary. However, if an alternative build and install approach -# is taken, such as via a Carvel packaging mechanism, a local registry might be needed (for example, the -# kbld tool requires a registry to resolve images to shas). -# -# Example usage: +# When invoked with the PINNIPED_USE_LOCAL_KIND_REGISTRY environment variable set to a non-empty value, then +# this script will create a local registry and configure kind to use that registry. This is normally unnecessary. +# However, if an alternative build and deploy approach is used, such as via a Carvel packaging mechanism, then a local +# registry could be needed (e.g. the kbld tool requires a registry to resolve images to shas). +# For example, to alternatively build and deploy Pinniped as a Carvel package, use: # PINNIPED_USE_LOCAL_KIND_REGISTRY=1 ./hack/prepare-for-integration-tests.sh --clean --pre-install ./hack/lib/carvel_packages/build.sh --alternate-deploy ./hack/lib/carvel_packages/deploy.sh # set -euo pipefail @@ -62,10 +60,6 @@ get_active_directory_vars="" # specify a filename for a script to get AD related alternate_deploy="undefined" pre_install="undefined" -# supported variable style: -# --dockerfile-path ./foo.sh -# unsupported variable style (using = will fail the script): -# --dockerfile-path=./foo.sh while (("$#")); do case "$1" in -h | --help) @@ -148,13 +142,13 @@ if [[ "$help" == "yes" ]]; then log_note " $me [flags]" log_note log_note "Flags:" - log_note " -h, --help: print this usage" - log_note " -c, --clean: destroy the current kind cluster and make a new one" - log_note " -g, --api-group-suffix: deploy Pinniped with an alternate API group suffix" - log_note " -s, --skip-build: reuse the most recently built image of the app instead of building" - log_note " -a, --get-active-directory-vars: specify a script that exports active directory environment variables" - log_note " --alternate-deploy: specify an alternate deploy script to install all components of Pinniped" - log_note " --pre-install: specify an pre-install script such as a build script" + log_note " -h, --help: print this usage" + log_note " -c, --clean: destroy the current kind cluster and make a new one" + log_note " -g, --api-group-suffix: deploy Pinniped with an alternate API group suffix" + log_note " -s, --skip-build: reuse the most recently built image of the app instead of building" + log_note " -a, --get-active-directory-vars: specify a script that exports active directory environment variables" + log_note " --alternate-deploy: specify an alternate deploy script to install all components of Pinniped" + log_note " --pre-install: specify an pre-install script such as a build script" exit 1 fi @@ -217,7 +211,6 @@ repo="test/build" registry_repo="$registry_with_port/$repo" tag="0.0.0-$(uuidgen)" # always a new tag to force K8s to reload the image on redeploy - if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then etc_hosts_local_registry_missing=no if ! grep -q "$registry" /etc/hosts; then @@ -251,7 +244,7 @@ registry_repo_tag="${registry_repo}:${tag}" if [[ "$do_build" == "yes" ]]; then # Rebuild the code testing_version="${KUBE_GIT_VERSION:-}" - if [[ "$dockerfile_path" != "" ]]; then + if [[ "$dockerfile_path" != "" ]]; then log_note "Docker building the app with dockerfile $dockerfile_path and KUBE_GIT_VERSION='$testing_version'" DOCKER_BUILDKIT=1 docker build . --tag "$registry_repo_tag" --file "$dockerfile_path" --build-arg "KUBE_GIT_VERSION=$testing_version" else @@ -262,51 +255,40 @@ if [[ "$do_build" == "yes" ]]; then fi if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then - # if registry used, push to the registry + # 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 + # 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 - -# -# Call a pre-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 [ "$pre_install" != "undefined" ] ; then - log_note "The pre-install script will be called with $tag..." - $pre_install pre-install-script $tag $registry_with_port $repo +if [ "$pre_install" != "undefined" ]; then + log_note "Calling the pre-install script with args: $tag $registry_with_port $repo ..." + $pre_install pre-install-script "$tag" $registry_with_port $repo fi - # # Deploy local-user-authenticator # manifest=/tmp/pinniped-local-user-authenticator.yaml -data_values_path="/tmp/local-user-authenticator" -data_values_file="${data_values_path}/values.yml" -mkdir -p "${data_values_path}" -cat < "$data_values_file" +data_values_file=/tmp/local-user-authenticator-values.yml +cat <"$data_values_file" --- image_repo: $registry_repo image_tag: $tag EOF if [ "$alternate_deploy" != "undefined" ]; then - $alternate_deploy local-user-authenticator $tag $registry_with_port $repo $data_values_file + log_note "The local-user-authenticator will be deployed with $alternate_deploy local-user-authenticator $tag $registry_with_port $repo $data_values_file ..." + $alternate_deploy local-user-authenticator "$tag" $registry_with_port $repo $data_values_file else log_note "Deploying the local-user-authenticator app to the cluster using kapp..." pushd deploy/local-user-authenticator >/dev/null - - ytt --file . --data-values-file "$data_values_file" >"$manifest" - + ytt --file . --data-values-file "$data_values_file" >"$manifest" kapp deploy --yes --app local-user-authenticator --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. - popd >/dev/null fi @@ -324,16 +306,15 @@ ytt --file . \ --data-value "pinny_ldap_password=$ldap_test_password" \ --data-value "pinny_bcrypt_passwd_hash=$(htpasswd -nbBC 10 x "$dex_test_password" | sed -e "s/^x://")" \ >"$manifest" - kapp deploy --yes --app tools --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. - popd >/dev/null # # Deploy the Pinniped Supervisor # manifest=/tmp/pinniped-supervisor.yaml +data_values_file=/tmp/supervisor-values.yml supervisor_app_name="pinniped-supervisor" supervisor_namespace="supervisor" supervisor_custom_labels="{mySupervisorCustomLabelName: mySupervisorCustomLabelValue}" @@ -341,10 +322,7 @@ log_level="debug" service_https_nodeport_port="443" service_https_nodeport_nodeport="31243" service_https_clusterip_port="443" -data_values_path="/tmp/supervisor" -data_values_file="${data_values_path}/values.yml" -mkdir -p "${data_values_path}" -cat < "$data_values_file" +cat <"$data_values_file" --- app_name: $supervisor_app_name namespace: $supervisor_namespace @@ -359,14 +337,12 @@ service_https_clusterip_port: $service_https_clusterip_port EOF if [ "$alternate_deploy" != "undefined" ]; then - log_note "The Pinniped Supervisor will be deployed with $alternate_deploy pinniped-supervisor $tag..." - $alternate_deploy pinniped-supervisor $tag $registry_with_port $repo $data_values_file + log_note "The Pinniped Supervisor will be deployed with $alternate_deploy pinniped-supervisor $tag $registry_with_port $repo $data_values_file ..." + $alternate_deploy pinniped-supervisor "$tag" $registry_with_port $repo $data_values_file else log_note "Deploying the Pinniped Supervisor app to the cluster using kapp..." pushd deploy/supervisor >/dev/null - - ytt --file . --data-values-file "$data_values_file" >"$manifest" - + ytt --file . --data-values-file "$data_values_file" >"$manifest" kapp deploy --yes --app "$supervisor_app_name" --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. popd >/dev/null @@ -376,16 +352,14 @@ fi # Deploy the Pinniped Concierge # manifest=/tmp/pinniped-concierge.yaml +data_values_file=/tmp/concierge-values.yml concierge_app_name="pinniped-concierge" concierge_namespace="concierge" webhook_url="https://local-user-authenticator.local-user-authenticator.svc/authenticate" discovery_url="$(TERM=dumb kubectl cluster-info | awk '/master|control plane/ {print $NF}')" concierge_custom_labels="{myConciergeCustomLabelName: myConciergeCustomLabelValue}" log_level="debug" -data_values_path="/tmp/concierge" -data_values_file="${data_values_path}/values.yml" -mkdir -p "${data_values_path}" -cat < "$data_values_file" +cat <"$data_values_file" --- app_name: $concierge_app_name namespace: $concierge_namespace @@ -398,23 +372,19 @@ discovery_url: $discovery_url EOF if [ "$alternate_deploy" != "undefined" ]; then - log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag..." - $alternate_deploy pinniped-concierge $tag $registry_with_port $repo $data_values_file + log_note "The Pinniped Concierge will be deployed with $alternate_deploy pinniped-concierge $tag $registry_with_port $repo $data_values_file ..." + $alternate_deploy pinniped-concierge "$tag" $registry_with_port $repo $data_values_file else log_note "Deploying the Pinniped Concierge app to the cluster using kapp..." pushd deploy/concierge >/dev/null - - ytt --file . --data-values-file "$data_values_file" >"$manifest" - + ytt --file . --data-values-file "$data_values_file" >"$manifest" kapp deploy --yes --app "$concierge_app_name" --diff-changes --file "$manifest" kubectl apply --dry-run=client -f "$manifest" # Validate manifest schema. popd >/dev/null fi - # -# Test user for the authenticator -# the authenticator may be deployed in alternative ways (ex. carvel package) but regardless we need a test user. +# Create a test user in the local-user-authenticator and get its CA bundle. # log_note "Creating test user for local-user-authenticator..." test_username="test-username" @@ -429,9 +399,6 @@ kubectl create secret generic "$test_username" \ --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}')" # @@ -450,9 +417,7 @@ 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 </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} @@ -524,7 +489,6 @@ PINNIPED_TEST_CLUSTER_CAPABILITY_YAML_EOF export PINNIPED_TEST_CLUSTER_CAPABILITY_YAML EOF - # # Print instructions for next steps. # @@ -532,7 +496,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 $env_file_name && go test -v -race -count 1 -timeout 0 ./test/integration" +log_note ' source /tmp/integration-test-env && 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" @@ -546,4 +510,3 @@ if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then else log_note "When you're finished, use './hack/kind-down.sh' to tear down the cluster." fi -log_note From 1e9f9181a1f6a7562ec26a3d9759688c23ff1c8b Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Fri, 3 Nov 2023 17:09:30 -0400 Subject: [PATCH 03/15] Enhance schemas with validations, etc. Co-authored-by: Ryan Richard --- deploy/concierge/values.yaml | 182 +++++++++---- deploy/local-user-authenticator/values.yaml | 40 ++- deploy/supervisor/values.yaml | 279 ++++++++++++-------- 3 files changed, 318 insertions(+), 183 deletions(-) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 2721e27d0..7bbfbfcd7 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -3,135 +3,207 @@ #@data/values-schema --- +#@schema/title "App name" #@schema/desc "Used to help determine the names of various resources and labels." +#@schema/validation min_len=1 app_name: pinniped-concierge +#@schema/title "Namespace" #@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." +#@schema/validation min_len=1 namespace: pinniped-concierge + +#@schema/title "Into 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/examples ("The name of an existing namespace", "my-preexisting-namespace") #@schema/nullable -into_namespace: my-preexisting-namespace +#@schema/validation min_len=1 +into_namespace: "" +#@schema/title "Custom labels" #@ 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." +#@ 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, or 2.) deleting all resources by label, which does \ +#@ not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc +#@schema/examples ("Example set of labels", {"myCustomLabelName": "myCustomLabelValue", "otherCustomLabelName": "otherCustomLabelValue"}) #@schema/type any=True -custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} +#@schema/validation ("a map of keys and values", lambda v: type(v) in ["yamlfragment"]) +custom_labels: {} +#@schema/title "Replicas" #@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." +#@schema/title "Image repo" +#@schema/desc "The repository for the Concierge container image." +#@schema/validation min_len=1 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/title "Image digest" +#@schema/desc "The image digest for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/examples ("Digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") #@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." +#@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_tag"] == None +image_digest: "" + +#@schema/title "Image tag" +#@schema/desc "The image tag for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/examples ("Tag", "v0.25.0") +#@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_digest"] == None image_tag: latest +#@schema/title "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/examples ("Image including tag or digest", "projects.registry.vmware.com/pinniped/pinniped-server:latest") #@schema/nullable -kube_cert_agent_image: projects.registry.vmware.com/pinniped/pinniped-server +#@schema/validation min_len=1 +kube_cert_agent_image: "" -#@ 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." -#! base64 encoded: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} -#! result: eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ== +#@schema/title "Image pull dockerconfigjson" +#@ image_pull_dockerconfigjson_desc = "A base64 encoded secret to be used when pulling the `image_repo` container image. \ +#@ Can be used when the 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\"]'" #@schema/desc image_pull_dockerconfigjson_desc +#@ example_desc = 'base64 encoding of: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}' +#@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" +#@schema/examples (example_desc, example_value) #@schema/nullable -image_pull_dockerconfigjson: "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" +#@schema/validation min_len=1 +image_pull_dockerconfigjson: "" +#@schema/title "Discovery URL" #@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/examples ("Kubernetes API URL","https://example.com") #@schema/nullable -discovery_url: https://example.com +#@schema/validation min_len=1 +discovery_url: "" -#@ 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. Specify this as an integer or as a string which contains an integer value." -#@schema/desc api_serving_certificate_desc +#@schema/title "API serving certificate duration seconds" +#@ api_serving_certificate_duration_seconds_desc = "Specify the duration for the API serving certificate. \ +#@ The default is set to expire the cert about every 30 days. \ +#@ Specify this as an integer or as a string which contains an integer value." +#@schema/desc api_serving_certificate_duration_seconds_desc #@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) api_serving_certificate_duration_seconds: 2592000 -#@schema/desc api_serving_certificate_desc + +#@schema/title "API serving certificate renew before seconds" +#@ api_serving_certificate_renew_before_seconds_desc = "Specify the renewal interval for the API serving certificate. \ +#@ The default is set to rotate it about every 25 days. \ +#@ Specify this as an integer or as a string which contains an integer value." +#@schema/desc api_serving_certificate_renew_before_seconds_desc #@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) 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/title "Log level" +#@ log_level_desc = "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. \ +#@ When this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." +#@schema/desc log_level_desc +#@schema/examples ("Developer logging information","debug") #@schema/nullable -log_level: info +#@schema/validation one_of=["info", "debug", "trace", "all"] +log_level: "" + +#@schema/title "Log format" #@ 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/examples ("Set logs to JSON format","json") #@schema/nullable -deprecated_log_format: json +#@schema/validation one_of=["json", "text"] +#@schema/deprecated "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 "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +#@schema/title "Run as user" +#@schema/desc "The user ID that will own the process." +#! See the Dockerfile for the reasoning behind this default value. 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" + +#@schema/title "Run as group" +#@schema/desc "The group ID that will own the process." +#! See the Dockerfile for the reasoning behind this default value. run_as_group: 65532 +#@schema/title "API group suffix" #@ 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 +#@schema/validation min_len=1 api_group_suffix: pinniped.dev +#@schema/title "Impersonation proxy spec" #@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." + + #@schema/title "Mode" + #@ impersonation_mode_desc = "If enabled, the impersonation proxy will always run regardless of other strategies available. \ + #@ 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." + #@schema/desc impersonation_mode_desc + #@schema/examples ("Always run, regardless of available strategies", "enabled"),("Detect if cluster signing key is available for use","auto") mode: auto + + #@schema/title "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/examples ("Specified impersonation proxy endpoint", "1.2.3.4:5678") #@schema/nullable - external_endpoint: 1.2.3.4:5678 + #@schema/validation min_len=1 + external_endpoint: "" + + #@schema/title "Service" #@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/title "Type" + #@ impersonation_service_type_desc = "Service backing the impersonation proxy. 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 impersonation_service_type_desc + #@schema/examples ("Fall back to ClusterIP", "ClusterIP") + #@schema/validation one_of=["LoadBalancer", "ClusterIP", "None"] type: LoadBalancer + + #@schema/title "Annotations" #@schema/desc "The annotations that should be set on the ClusterIP or LoadBalancer Service." 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 + #@schema/title "Load balancer IP" + #@schema/desc "When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP." + #@schema/examples ("Specified IP with port", "1.2.3.4:5678") + #@schema/nullable + #@schema/validation min_len=1 + load_balancer_ip: "" + +#@schema/title "HTTPS proxy" #@ 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/examples ("Provide a proxy endpoint","http://proxy.example.com") #@schema/nullable -https_proxy: http://proxy.example.com -#@schema/desc "do not proxy Kubernetes endpoints" +https_proxy: "" + +#@schema/title "No proxy" +#@schema/desc "Endpoints that should not be proxied. Defaults to some sensible known values on public cloud providers." 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/local-user-authenticator/values.yaml b/deploy/local-user-authenticator/values.yaml index df991aa7b..7341cd889 100644 --- a/deploy/local-user-authenticator/values.yaml +++ b/deploy/local-user-authenticator/values.yaml @@ -3,23 +3,41 @@ #@data/values-schema --- -#@schema/desc "Specify either an image_digest or an image_tag. If both are given, only image_digest will be used." +#@schema/title "Image repo" +#@schema/desc "The repository for the local-user-authenticator container image." +#@schema/validation min_len=1 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/title "Image digest" +#@schema/desc "The image digest for the local-user-authenticator container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/examples ("Digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") #@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." +#@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_tag"] == None +image_digest: "" + +#@schema/title "Image tag" +#@schema/desc "The image tag for the local-user-authenticator container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/examples ("Tag", "v0.25.0") +#@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_digest"] == None 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/title "Image pull dockerconfigjson" +#@ image_pull_dockerconfigjson_desc = "A base64 encoded secret to be used when pulling the `image_repo` container image. \ +#@ Can be used when the 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\"]'" #@schema/desc image_pull_dockerconfigjson_desc +#@ example_desc = 'base64 encoding of: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}' +#@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" +#@schema/examples (example_desc, example_value) #@schema/nullable -image_pull_dockerconfigjson: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} +image_pull_dockerconfigjson: "" -#@schema/desc "run_as_user specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +#@schema/title "Run as user" +#@schema/desc "The user ID that will own the process." +#! See the Dockerfile for the reasoning behind this default value. 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" + +#@schema/title "Run as group" +#@schema/desc "The group ID that will own the process." +#! See the Dockerfile for the reasoning behind this default value. run_as_group: 65532 diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 217f8680a..8cf5e928f 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -3,175 +3,220 @@ #@data/values-schema --- +#@schema/title "App name" #@schema/desc "Used to help determine the names of various resources and labels." +#@schema/validation min_len=1 app_name: pinniped-supervisor +#@schema/title "Namespace" #@schema/desc "Creates a new namespace statically in yaml with the given name and installs the app into that namespace." +#@schema/validation min_len=1 namespace: pinniped-supervisor + +#@schema/title "Into 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/examples ("The name of an existing namespace", "my-preexisting-namespace") #@schema/nullable -into_namespace: my-preexisting-namespace +#@schema/validation min_len=1 +into_namespace: "" +#@schema/title "Custom labels" #@ 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, \ -#@ or, 2.) deleting all resources by label, which does not assume that there was a static install-time yaml namespace." +#@ 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, or 2.) deleting all resources by label, which does \ +#@ not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc +#@schema/examples ("Example set of labels", {"myCustomLabelName": "myCustomLabelValue", "otherCustomLabelName": "otherCustomLabelValue"}) #@schema/type any=True -custom_labels: {} #! {myCustomLabelName: myCustomLabelValue, otherCustomLabelName: otherCustomLabelValue} +#@schema/validation ("a map of keys and values", lambda v: type(v) in ["yamlfragment"]) +custom_labels: {} +#@schema/title "Replicas" #@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." +#@schema/title "Image repo" +#@schema/desc "The repository for the Concierge container image." +#@schema/validation min_len=1 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/title "Image digest" +#@schema/desc "The image digest for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/examples ("Digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") #@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." +#@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_tag"] == None +image_digest: "" + +#@schema/title "Image tag" +#@schema/desc "The image tag for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/examples ("Tag", "v0.25.0") +#@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_digest"] == None 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." -#! base64 encoded: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}} -#! result: eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ== +#@schema/title "Image pull dockerconfigjson" +#@ image_pull_dockerconfigjson_desc = "A base64 encoded secret to be used when pulling the `image_repo` container image. \ +#@ Can be used when the 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\"]'" #@schema/desc image_pull_dockerconfigjson_desc +#@ example_desc = 'base64 encoding of: {"auths":{"https://registry.example.com":{"username":"USERNAME","password":"PASSWORD","auth":"BASE64_ENCODED_USERNAME_COLON_PASSWORD"}}}' +#@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" +#@schema/examples (example_desc, example_value) #@schema/nullable -image_pull_dockerconfigjson: "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" +#@schema/validation min_len=1 +image_pull_dockerconfigjson: "" -#! 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/title "Deprecated service HTTP nodeport port" +#@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/examples ("Specify port","31234") #@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 +#@schema/deprecated "This data value will be removed in a future release" +deprecated_service_http_nodeport_port: "" -#! 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/title "Deprecated service http nodeport nodeport" +#@schema/desc "The `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified" +#@schema/examples ("Specify port","31234") #@schema/nullable -log_level: info +#@schema/deprecated "This data value will be removed in a future release" +deprecated_service_http_nodeport_nodeport: "" + +#@schema/title "Deprecated service http loadbalancer port" +#@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/examples ("Specify port","8443") +#@schema/nullable +#@schema/deprecated "This data value will be removed in a future release" +deprecated_service_http_loadbalancer_port: "" + +#@schema/title "Deprecated service http clusterip port" +#@schema/desc "Creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`" +#@schema/examples ("Specify port","8443") +#@schema/nullable +#@schema/deprecated "This data value will be removed in a future release" +deprecated_service_http_clusterip_port: "" + +#@schema/title "Service https nodeport port" +#@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/examples ("Specify port","31243") +#@schema/nullable +service_https_nodeport_port: "" + +#@schema/title "Service https nodeport nodeport" +#@schema/desc "The `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified" +#@schema/examples ("Specify port","31243") +#@schema/nullable +service_https_nodeport_nodeport: "" + +#@schema/title "Service https loadbalancer port" +#@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/examples ("Specify port","8443") +#@schema/nullable +service_https_loadbalancer_port: "" + +#@schema/title "Service https clusterip port" +#@schema/desc "When specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`" +#@schema/examples ("Specify port","8443") +#@schema/nullable +service_https_clusterip_port: "" + +#@schema/title "Service loadbalancer ip" +#@schema/desc "The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided." +#@schema/examples ("Example IP address","1.2.3.4") +#@schema/nullable +service_loadbalancer_ip: "" + +#@schema/title "Log level" +#@ log_level_desc = "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. \ +#@ When this value is left unset, only warnings and errors are printed. There is no way to suppress warning and error logs." +#@schema/desc log_level_desc +#@schema/examples ("Developer logging information","debug") +#@schema/nullable +#@schema/validation one_of=["info", "debug", "trace", "all"] +log_level: "" + +#@schema/title "Log format" #@ 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/examples ("Set logs to JSON format","json") #@schema/nullable -deprecated_log_format: json +#@schema/validation one_of=["json", "text"] +#@schema/deprecated "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 "specifies the user ID that will own the process, see the Dockerfile for the reasoning behind this choice" +#@schema/title "Run as user" +#@schema/desc "The user ID that will own the process." +#! See the Dockerfile for the reasoning behind this default value. run_as_user: 65532 -#@schema/desc "specifies the group ID that will own the process, see the Dockerfile for the reasoning behind this choice" + +#@schema/title "Run as group" +#@schema/desc "The group ID that will own the process." +#! See the Dockerfile for the reasoning behind this default value. run_as_group: 65532 +#@schema/title "API group suffix" #@ 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 +#@schema/validation min_len=1 api_group_suffix: pinniped.dev +#@schema/title "HTTPS proxy" #@ 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/examples ("Provide a proxy endpoint","http://proxy.example.com") #@schema/nullable -https_proxy: http://proxy.example.com -#@schema/desc "Endpoints that should not use the proxy." +https_proxy: "" + +#@schema/title "No proxy" +#@schema/desc "Endpoints that should not be proxied. Defaults to some sensible known values on public cloud providers." +#@schema/validation min_len=1 no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints -#! 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/title "Endpoints" +#@ endpoints_desc = "Control the HTTP and HTTPS listeners of the Supervisor. The current defaults are: \ +#@ {\"https\":{\"network\":\"tcp\",\"address\":\":8443\"},\"http\":\"disabled\"}. \ +#@ These defaults mean: 1.) For HTTPS listening, bind to all interfaces using TCP on port 8443 and \ +#@ 2.) Disable HTTP listening by default. \ +#@ The schema of this config is as follows: \ +#@ {'https':{'network':'tcp | unix | disabled','address':'host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix'},'http':{'network':'tcp | unix | disabled','address':'same as https, except that when network=tcp then the address is only allowed to bind to loopback interfaces'}} \ +#@ 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 endpoints_desc +#@schema/examples ("Example matching default settings", '{"https":{"network":"tcp","address":":8443"},"http":"disabled"}') +#@schema/type any=True +#@schema/validation ("a map of keys and values", lambda v: type(v) in ["yamlfragment"]) #@schema/nullable -endpoints: - https: - network: tcp - address: 1.2.3.4:5678 +endpoints: {} -#! 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_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." +#@schema/desc deprecated_insecure_accept_external_unencrypted_http_requests_desc +#@schema/type any=True +#@schema/validation ("a boolean or string version of boolean", lambda v: type(v) in ["string", "boolean"]) +#@schema/validation one_of=["true", "false", True, False] +#@schema/deprecated "This data value will be removed in a future release" deprecated_insecure_accept_external_unencrypted_http_requests: false From c3410c4b144746d9099ac7540a41b4aecca74a35 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 10:29:53 -0500 Subject: [PATCH 04/15] improve custom_labels validation func --- deploy/concierge/values.yaml | 14 +++++++++++++- deploy/supervisor/values.yaml | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 7bbfbfcd7..5964abb97 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -31,8 +31,20 @@ into_namespace: "" #@ not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc #@schema/examples ("Example set of labels", {"myCustomLabelName": "myCustomLabelValue", "otherCustomLabelName": "otherCustomLabelValue"}) +#@ def validate_labels(labels): +#@ """ +#@ Returns True if labels is an associative data structure string→string, +#@ and False otherwise. +#@ """ +#@ for label in labels: +#@ if type(label) != "string" or type(labels[label]) != "string": +#@ return False +#@ end +#@ end +#@ return True +#@ end #@schema/type any=True -#@schema/validation ("a map of keys and values", lambda v: type(v) in ["yamlfragment"]) +#@schema/validation ("a map of keys and values", validate_labels) custom_labels: {} #@schema/title "Replicas" diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 8cf5e928f..223515ef1 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -31,8 +31,20 @@ into_namespace: "" #@ not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc #@schema/examples ("Example set of labels", {"myCustomLabelName": "myCustomLabelValue", "otherCustomLabelName": "otherCustomLabelValue"}) +#@ def validate_labels(labels): +#@ """ +#@ Returns True if labels is an associative data structure string→string, +#@ and False otherwise. +#@ """ +#@ for label in labels: +#@ if type(label) != "string" or type(labels[label]) != "string": +#@ return False +#@ end +#@ end +#@ return True +#@ end #@schema/type any=True -#@schema/validation ("a map of keys and values", lambda v: type(v) in ["yamlfragment"]) +#@schema/validation ("a map of keys and values", validate_labels) custom_labels: {} #@schema/title "Replicas" From 98bd12241d3b8d7540535a1deb96dc7af650cfea Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 11:21:58 -0500 Subject: [PATCH 05/15] extract helpers to lib file and use in various hack scripts --- hack/kind-down.sh | 2 +- hack/kind-up.sh | 8 +++--- hack/lib/carvel_packages/build.sh | 33 ++----------------------- hack/lib/carvel_packages/deploy.sh | 34 +++----------------------- hack/lib/helpers.sh | 34 ++++++++++++++++++++++++++ hack/prepare-for-integration-tests.sh | 35 +++------------------------ hack/prepare-impersonator-on-kind.sh | 16 ++++++------ hack/prepare-supervisor-on-kind.sh | 11 ++------- 8 files changed, 59 insertions(+), 114 deletions(-) create mode 100644 hack/lib/helpers.sh diff --git a/hack/kind-down.sh b/hack/kind-down.sh index 1f510e2c6..b52b9fe92 100755 --- a/hack/kind-down.sh +++ b/hack/kind-down.sh @@ -18,7 +18,7 @@ if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then docker network disconnect "kind" "${reg_name}" >/dev/null fi - echo "Stopping container $reg_name ..." + log_note "Stopping container $reg_name ..." docker stop "${reg_name}" >/dev/null # Delete it. diff --git a/hack/kind-up.sh b/hack/kind-up.sh index d626e581b..43d46be89 100755 --- a/hack/kind-up.sh +++ b/hack/kind-up.sh @@ -8,12 +8,14 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" +source hack/lib/helpers.sh + 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 - echo "Running the registry:2 docker image..." + log_note "Running the registry:2 docker image..." docker run \ --detach \ --restart=always \ @@ -25,13 +27,13 @@ fi use_contour_registry="" if [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then - echo "Adding Contour port mapping to Kind config." + log_note "Adding Contour port mapping to Kind config." use_contour_registry="--file=${ROOT}/hack/lib/kind-config/contour-overlay.yaml" fi use_kind_registry="" if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then - echo "Adding local registry to Kind config." + log_note "Adding local registry to Kind config." use_kind_registry="--file=${ROOT}/hack/lib/kind-config/kind-registry-overlay.yaml" fi diff --git a/hack/lib/carvel_packages/build.sh b/hack/lib/carvel_packages/build.sh index d068fb7e1..f2a88fde3 100755 --- a/hack/lib/carvel_packages/build.sh +++ b/hack/lib/carvel_packages/build.sh @@ -17,42 +17,13 @@ # 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 -} - # This script is best invoked from the root directory. # It is designed to be passed as --pre-install flag to hack/prepare-for-integration-tests.sh. hack_lib_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${hack_lib_path}/../../" || exit 1 +source hack/lib/helpers.sh + # Check for dependencies check_dependency kbld "Please install kbld. e.g. 'brew tap vmware-tanzu/carvel && brew install kbld' for MacOS" check_dependency imgpkg "Please install imgpkg. e.g. 'brew tap vmware-tanzu/carvel && brew install imgpkg' for MacOS" diff --git a/hack/lib/carvel_packages/deploy.sh b/hack/lib/carvel_packages/deploy.sh index c5cde2773..ea76255f7 100755 --- a/hack/lib/carvel_packages/deploy.sh +++ b/hack/lib/carvel_packages/deploy.sh @@ -14,42 +14,14 @@ # 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 -} - # This script is best invoked from the root directory. # It is designed to be passed as --alternate-deploy flag to hack/prepare-for-integration-tests.sh. hack_lib_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$hack_lib_path/../../" || exit 1 +source hack/lib/helpers.sh + + # Expected arguments. app=${1:-"app-argument-not-provided"} tag=${2:-"tag-argument-not-provided"} diff --git a/hack/lib/helpers.sh b/hack/lib/helpers.sh new file mode 100644 index 000000000..4695a793e --- /dev/null +++ b/hack/lib/helpers.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# Copyright 2023 the Pinniped contributors. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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 +} diff --git a/hack/prepare-for-integration-tests.sh b/hack/prepare-for-integration-tests.sh index b1f353087..7159b9a15 100755 --- a/hack/prepare-for-integration-tests.sh +++ b/hack/prepare-for-integration-tests.sh @@ -17,36 +17,10 @@ # 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 -} +pinniped_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$pinniped_path" || exit 1 -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 -} +source hack/lib/helpers.sh # # Handle argument parsing and help message @@ -152,9 +126,6 @@ if [[ "$help" == "yes" ]]; then exit 1 fi -pinniped_path="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -cd "$pinniped_path" || exit 1 - # # Check for dependencies # diff --git a/hack/prepare-impersonator-on-kind.sh b/hack/prepare-impersonator-on-kind.sh index 3734f16f1..0a17cfecc 100755 --- a/hack/prepare-impersonator-on-kind.sh +++ b/hack/prepare-impersonator-on-kind.sh @@ -26,6 +26,8 @@ LOCAL_HOST="127.0.0.1:${LOCAL_PORT}" ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" +source hack/lib/helpers.sh + # Build the CLI for use later in the script. go build ./cmd/pinniped @@ -85,10 +87,10 @@ EOF # Wait for the CredentialIssuer's impersonator status to update to be successful. while [[ -z "$(kubectl get credentialissuer pinniped-concierge-config -o json | jq '.status.strategies[] | select((.type=="ImpersonationProxy") and (.status=="Success"))')" ]]; do - echo "Waiting for a successful ImpersonationProxy strategy on CredentialIssuer..." + log_note "Waiting for a successful ImpersonationProxy strategy on CredentialIssuer..." sleep 2 done -echo "Impersonator is available on https://${LOCAL_HOST}" +log_note "Impersonator is available on https://${LOCAL_HOST}" # Make the impersonation proxy's port from the inside the cluster available locally. kubectl port-forward -n $CONCIERGE_NAMESPACE deployment/$CONCIERGE_DEPLOYMENT ${LOCAL_PORT}:${IMPERSONATION_PROXY_PORT} & @@ -97,12 +99,12 @@ port_forward_pid=$! # Kill the kubectl port-forward command whenever the script is control-c cancelled or otherwise ends. function cleanup() { echo - echo "Cleaning up cluster resources..." + log_note "Cleaning up cluster resources..." kubectl delete secret -n $LOCAL_USER_AUTHENTICATOR_NAMESPACE pinny-the-seal kubectl delete configmap -n $CONCIERGE_NAMESPACE pinniped-concierge-impersonation-proxy-config kubectl delete clusterrolebinding pinny-the-seal-can-edit kubectl delete webhookauthenticator local-user-authenticator - echo "Stopping kubectl port-forward and exiting..." + log_note "Stopping kubectl port-forward and exiting..." # It may have already shut down, so ignore errors. kill -9 $port_forward_pid &> /dev/null || true } @@ -113,7 +115,7 @@ trap cleanup EXIT --static-token "pinny-the-seal:password123" \ --concierge-mode ImpersonationProxy >/tmp/kubeconfig -echo -echo 'Ready. In another tab, use "kubectl --kubeconfig /tmp/kubeconfig " to make requests through the impersonation proxy.' -echo "When done, cancel with ctrl-C to clean up." +log_note +log_note 'Ready. In another tab, use "kubectl --kubeconfig /tmp/kubeconfig " to make requests through the impersonation proxy.' +log_note "When done, cancel with ctrl-C to clean up." wait $port_forward_pid diff --git a/hack/prepare-supervisor-on-kind.sh b/hack/prepare-supervisor-on-kind.sh index ba6443886..5a0cb7202 100755 --- a/hack/prepare-supervisor-on-kind.sh +++ b/hack/prepare-supervisor-on-kind.sh @@ -37,15 +37,8 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT" -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 -} +source hack/lib/helpers.sh + use_oidc_upstream=no use_ldap_upstream=no From 46bea27cb7114dfe6e7b35358d9eadd89561cd52 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 11:51:00 -0500 Subject: [PATCH 06/15] no_proxy adjustment for 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 223515ef1..f8382dbd0 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -192,9 +192,9 @@ https_proxy: "" #@schema/title "No proxy" #@schema/desc "Endpoints that should not be proxied. Defaults to some sensible known values on public cloud providers." -#@schema/validation min_len=1 no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints + #@schema/title "Endpoints" #@ endpoints_desc = "Control the HTTP and HTTPS listeners of the Supervisor. The current defaults are: \ #@ {\"https\":{\"network\":\"tcp\",\"address\":\":8443\"},\"http\":\"disabled\"}. \ From 1f8aa6c262c093b3bd3e65e4b357fb4c68bfe35c Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 11:59:29 -0500 Subject: [PATCH 07/15] import helpers in kind-down.sh --- hack/kind-down.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hack/kind-down.sh b/hack/kind-down.sh index b52b9fe92..7aa392a5c 100755 --- a/hack/kind-down.sh +++ b/hack/kind-down.sh @@ -8,6 +8,8 @@ set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "${ROOT}" +source hack/lib/helpers.sh + if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then reg_name='kind-registry.local' From 1b540181a73f654ac717c49bda32fdf4f8aed9a4 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 12:15:03 -0500 Subject: [PATCH 08/15] Adjust types on some supervisor validations --- deploy/supervisor/values.yaml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index f8382dbd0..1d3734b69 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -85,6 +85,8 @@ image_pull_dockerconfigjson: "" #@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`" #@schema/examples ("Specify port","31234") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" deprecated_service_http_nodeport_port: "" @@ -92,6 +94,8 @@ deprecated_service_http_nodeport_port: "" #@schema/desc "The `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified" #@schema/examples ("Specify port","31234") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" deprecated_service_http_nodeport_nodeport: "" @@ -99,6 +103,8 @@ deprecated_service_http_nodeport_nodeport: "" #@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`" #@schema/examples ("Specify port","8443") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" deprecated_service_http_loadbalancer_port: "" @@ -106,6 +112,8 @@ deprecated_service_http_loadbalancer_port: "" #@schema/desc "Creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`" #@schema/examples ("Specify port","8443") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" deprecated_service_http_clusterip_port: "" @@ -113,24 +121,32 @@ deprecated_service_http_clusterip_port: "" #@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`" #@schema/examples ("Specify port","31243") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) service_https_nodeport_port: "" #@schema/title "Service https nodeport nodeport" #@schema/desc "The `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified" #@schema/examples ("Specify port","31243") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) service_https_nodeport_nodeport: "" #@schema/title "Service https loadbalancer port" #@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`" #@schema/examples ("Specify port","8443") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) service_https_loadbalancer_port: "" #@schema/title "Service https clusterip port" #@schema/desc "When specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`" #@schema/examples ("Specify port","8443") #@schema/nullable +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) service_https_clusterip_port: "" #@schema/title "Service loadbalancer ip" From 9a632134ae1d4bc1ce5a524bff770be881d088f2 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 12:15:35 -0500 Subject: [PATCH 09/15] Rearrange carvel build & deploy scripts --- .../{build.sh => build_and_deploy.sh} | 32 +++++++++++++++++++ .../carvel_packages/{deploy.sh => install.sh} | 29 ----------------- 2 files changed, 32 insertions(+), 29 deletions(-) rename hack/lib/carvel_packages/{build.sh => build_and_deploy.sh} (84%) rename hack/lib/carvel_packages/{deploy.sh => install.sh} (83%) diff --git a/hack/lib/carvel_packages/build.sh b/hack/lib/carvel_packages/build_and_deploy.sh similarity index 84% rename from hack/lib/carvel_packages/build.sh rename to hack/lib/carvel_packages/build_and_deploy.sh index f2a88fde3..2ef07dd20 100755 --- a/hack/lib/carvel_packages/build.sh +++ b/hack/lib/carvel_packages/build_and_deploy.sh @@ -132,4 +132,36 @@ imgpkg push --bundle "${package_repository_repo_tag}" --file "${dest_dir}/packag # manually validate the package bundle by pulling it from the registry and examining its contents: # imgpkg pull --bundle "${package_repository_repo_tag}" --output "/tmp/${package_repository_repo_tag}" + +log_note "Deploying PackageRepository & Packages to kind cluster..." + +# Deploy kapp-controller onto kind cluster. +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 + +# Ensure this directory exists though this script will run several times. +mkdir -p "${dest_dir}/install" + +log_note "Deploying Pinniped PackageRepository..." +pinniped_package_repository_name="pinniped-package-repository" +pinniped_package_repository_file="${dest_dir}/install/packagerepository.${pinniped_package_version}.yml" +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 + +resource_name="${app}" + log_note "Building Carvel Packages for Supervisor, Concierge & local-user-authenticator complete." diff --git a/hack/lib/carvel_packages/deploy.sh b/hack/lib/carvel_packages/install.sh similarity index 83% rename from hack/lib/carvel_packages/deploy.sh rename to hack/lib/carvel_packages/install.sh index ea76255f7..00e000dbf 100755 --- a/hack/lib/carvel_packages/deploy.sh +++ b/hack/lib/carvel_packages/install.sh @@ -47,37 +47,8 @@ registry_repo="$registry/$repo" # Pinniped Package repository package_repository_repo="pinniped-package-repository" package_repository_repo_tag="${registry_repo}/${package_repository_repo}:${tag}" - # Use the same directory as build.sh. dest_dir="deploy_carvel_tmp" - -# Deploy kapp-controller onto kind cluster. -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 - -# Ensure this directory exists though this script will run several times. -mkdir -p "${dest_dir}/install" - -log_note "Deploying Pinniped PackageRepository..." -pinniped_package_repository_name="pinniped-package-repository" -pinniped_package_repository_file="${dest_dir}/install/packagerepository.${pinniped_package_version}.yml" -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 - resource_name="${app}" log_note "Creating RBAC for ${resource_name} PackageInstall..." From c455a17abe177ee1da68d6dab5fcb7e9c616d6ac Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 12:39:11 -0500 Subject: [PATCH 10/15] Adjust validation for run_as_user,run_as_group --- deploy/concierge/values.yaml | 4 ++++ deploy/supervisor/values.yaml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 5964abb97..5252aa5da 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -139,11 +139,15 @@ deprecated_log_format: "" #@schema/title "Run as user" #@schema/desc "The user ID that will own the process." +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_user: 65532 #@schema/title "Run as group" #@schema/desc "The group ID that will own the process." +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_group: 65532 diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 1d3734b69..ba84a675e 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -178,11 +178,15 @@ deprecated_log_format: "" #@schema/title "Run as user" #@schema/desc "The user ID that will own the process." +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_user: 65532 #@schema/title "Run as group" #@schema/desc "The group ID that will own the process." +#@schema/type any=True +#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_group: 65532 From c4f9869e7c157dc271e1fe71041e19ad6fe6f445 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Tue, 7 Nov 2023 15:24:08 -0500 Subject: [PATCH 11/15] Relax image_pull_dockerconfigjson validation, improve endpoints validation --- deploy/concierge/values.yaml | 1 - deploy/supervisor/values.yaml | 22 ++++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 5252aa5da..88027f59e 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -88,7 +88,6 @@ kube_cert_agent_image: "" #@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" #@schema/examples (example_desc, example_value) #@schema/nullable -#@schema/validation min_len=1 image_pull_dockerconfigjson: "" #@schema/title "Discovery URL" diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index ba84a675e..95090a17a 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -78,7 +78,6 @@ image_tag: latest #@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" #@schema/examples (example_desc, example_value) #@schema/nullable -#@schema/validation min_len=1 image_pull_dockerconfigjson: "" #@schema/title "Deprecated service HTTP nodeport port" @@ -233,7 +232,26 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,. #@schema/desc endpoints_desc #@schema/examples ("Example matching default settings", '{"https":{"network":"tcp","address":":8443"},"http":"disabled"}') #@schema/type any=True -#@schema/validation ("a map of keys and values", lambda v: type(v) in ["yamlfragment"]) +#@ def validate_endpoint(endpoint): +#@ if(type(endpoint) not in ["yamlfragment", "string"]): +#@ return False +#@ end +#@ if(type(endpoint) in ["string"]): +#@ if (endpoint != "disabled"): +#@ return False +#@ end +#@ end +#@ return True +#@ end +#@ def validate_endpoints(endpoints): +#@ """ +#@ Returns True if endpoints fulfill the expected structure +#@ """ +#@ http_val = endpoints["http"] +#@ https_val = endpoints["https"] +#@ return validate_endpoint(http_val) and validate_endpoint(https_val) +#@ end +#@schema/validation ("a map with keys 'http' and 'https', both having keys 'network' and 'address' or set to 'disabled'", validate_endpoints) #@schema/nullable endpoints: {} From 88a97033fb00187d8576726b8e53b9f7e5fd2d04 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 8 Nov 2023 12:56:16 -0800 Subject: [PATCH 12/15] Refined ytt schemas Co-authored-by: Benjamin A. Petersen --- deploy/concierge/deployment.yaml | 5 + deploy/concierge/values.yaml | 83 +++++++------- deploy/local-user-authenticator/values.yaml | 5 +- deploy/supervisor/values.yaml | 120 +++++++++----------- hack/prepare-impersonator-on-kind.sh | 4 +- hack/prepare-supervisor-on-kind.sh | 13 +-- 6 files changed, 113 insertions(+), 117 deletions(-) diff --git a/deploy/concierge/deployment.yaml b/deploy/concierge/deployment.yaml index 9b3c344b2..bb10f9f60 100644 --- a/deploy/concierge/deployment.yaml +++ b/deploy/concierge/deployment.yaml @@ -347,7 +347,12 @@ spec: #@ if data.values.impersonation_proxy_spec.service.load_balancer_ip: loadBalancerIP: #@ data.values.impersonation_proxy_spec.service.load_balancer_ip #@ end + #@ if data.values.impersonation_proxy_spec.service.annotations == None: + annotations: + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000" + #@ else: annotations: #@ data.values.impersonation_proxy_spec.service.annotations + #@ end --- apiVersion: v1 kind: Secret diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 88027f59e..d41f14b0b 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -1,6 +1,16 @@ #! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 +#@ def validate_strings_map(obj): +#@ # Returns True if obj is an associative data structure string→string, and False otherwise. +#@ for key in obj: +#@ if type(key) != "string" or type(obj[key]) != "string": +#@ return False +#@ end +#@ end +#@ return True +#@ end + #@data/values-schema --- #@schema/title "App name" @@ -31,21 +41,9 @@ into_namespace: "" #@ not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc #@schema/examples ("Example set of labels", {"myCustomLabelName": "myCustomLabelValue", "otherCustomLabelName": "otherCustomLabelValue"}) -#@ def validate_labels(labels): -#@ """ -#@ Returns True if labels is an associative data structure string→string, -#@ and False otherwise. -#@ """ -#@ for label in labels: -#@ if type(label) != "string" or type(labels[label]) != "string": -#@ return False -#@ end -#@ end -#@ return True -#@ end #@schema/type any=True -#@schema/validation ("a map of keys and values", validate_labels) -custom_labels: {} +#@schema/validation ("a map of string keys and string values", validate_strings_map) +custom_labels: { } #@schema/title "Replicas" #@schema/desc "Specify how many replicas of the Pinniped server to run." @@ -58,14 +56,14 @@ image_repo: projects.registry.vmware.com/pinniped/pinniped-server #@schema/title "Image digest" #@schema/desc "The image digest for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." -#@schema/examples ("Digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") +#@schema/examples ("Providing a digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") #@schema/nullable #@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_tag"] == None image_digest: "" #@schema/title "Image tag" #@schema/desc "The image tag for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." -#@schema/examples ("Tag", "v0.25.0") +#@schema/examples ("Providing a tag", "v0.25.0") #@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_digest"] == None image_tag: latest @@ -88,6 +86,7 @@ kube_cert_agent_image: "" #@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" #@schema/examples (example_desc, example_value) #@schema/nullable +#@schema/validation min_len=1 image_pull_dockerconfigjson: "" #@schema/title "Discovery URL" @@ -103,7 +102,7 @@ discovery_url: "" #@ Specify this as an integer or as a string which contains an integer value." #@schema/desc api_serving_certificate_duration_seconds_desc #@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) +#@schema/validation ("an int or string which contains an integer value", lambda v: type(v) in ["int", "string"]) api_serving_certificate_duration_seconds: 2592000 #@schema/title "API serving certificate renew before seconds" @@ -112,7 +111,7 @@ api_serving_certificate_duration_seconds: 2592000 #@ Specify this as an integer or as a string which contains an integer value." #@schema/desc api_serving_certificate_renew_before_seconds_desc #@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) +#@schema/validation ("an int or string which contains an integer value", lambda v: type(v) in ["int", "string"]) api_serving_certificate_renew_before_seconds: 2160000 #@schema/title "Log level" @@ -138,15 +137,11 @@ deprecated_log_format: "" #@schema/title "Run as user" #@schema/desc "The user ID that will own the process." -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_user: 65532 #@schema/title "Run as group" #@schema/desc "The group ID that will own the process." -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_group: 65532 @@ -164,19 +159,21 @@ api_group_suffix: pinniped.dev impersonation_proxy_spec: #@schema/title "Mode" - #@ impersonation_mode_desc = "If enabled, the impersonation proxy will always run regardless of other strategies available. \ - #@ 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 \ + #@ impersonation_mode_desc = "Enables or disables the impersonation proxy. 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 enabled, the impersonation proxy will always run regardless of other strategies available. \ + #@ If disabled, the impersonation proxy will never run, which could mean \ #@ that the concierge doesn't work at all." #@schema/desc impersonation_mode_desc - #@schema/examples ("Always run, regardless of available strategies", "enabled"),("Detect if cluster signing key is available for use","auto") + #@schema/validation one_of=["auto", "disabled", "enabled"] mode: auto #@schema/title "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/examples ("Specified impersonation proxy endpoint", "1.2.3.4:5678") + #@schema/examples ("Specified impersonation proxy endpoint", "https://1.2.3.4:5678") #@schema/nullable #@schema/validation min_len=1 external_endpoint: "" @@ -192,33 +189,39 @@ impersonation_proxy_spec: #@ 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 impersonation_service_type_desc - #@schema/examples ("Fall back to ClusterIP", "ClusterIP") #@schema/validation one_of=["LoadBalancer", "ClusterIP", "None"] type: LoadBalancer #@schema/title "Annotations" - #@schema/desc "The annotations that should be set on the ClusterIP or LoadBalancer Service." + #@ annotations_desc = "The annotations that should be set on the ClusterIP or LoadBalancer Service. The default includes \ + #@ a value for the AWS-specific service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout annotation, which will \ + #@ be ignored except when using AWS to provide load balancer Services." + #@schema/desc annotations_desc + #@schema/nullable + #@schema/type any=True + #@schema/validation ("a map of string keys and string values", validate_strings_map) annotations: - {service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: "4000"} #@schema/title "Load balancer IP" - #@schema/desc "When mode LoadBalancer is set, this will set the LoadBalancer Service's Spec.LoadBalancerIP." - #@schema/examples ("Specified IP with port", "1.2.3.4:5678") + #@schema/desc "When mode LoadBalancer is set, this will set the LoadBalancer Service's spec.loadBalancerIP." + #@schema/examples ("Specifying an IP", "1.2.3.4") #@schema/nullable #@schema/validation min_len=1 load_balancer_ip: "" #@schema/title "HTTPS proxy" -#@ 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." +#@ https_proxy_desc = "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 and JWKS keys for JWTAuthenticators and POSTs to webhooks for WebhookAuthenticators. \ +#@ The Concierge never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY." #@schema/desc https_proxy_desc -#@schema/examples ("Provide a proxy endpoint","http://proxy.example.com") +#@schema/examples ("Providing a proxy endpoint","http://proxy.example.com") #@schema/nullable +#@schema/validation min_len=1 https_proxy: "" #@schema/title "No proxy" -#@schema/desc "Endpoints that should not be proxied. Defaults to some sensible known values on public cloud providers." -no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints +#@ no_proxy_desc = "Endpoints that should not be proxied. Defaults to not proxying internal Kubernetes endpoints, \ +#@ localhost endpoints, and the known instance metadata IP address for public cloud providers." +#@schema/desc no_proxy_desc +no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" diff --git a/deploy/local-user-authenticator/values.yaml b/deploy/local-user-authenticator/values.yaml index 7341cd889..45021a698 100644 --- a/deploy/local-user-authenticator/values.yaml +++ b/deploy/local-user-authenticator/values.yaml @@ -10,14 +10,14 @@ image_repo: projects.registry.vmware.com/pinniped/pinniped-server #@schema/title "Image digest" #@schema/desc "The image digest for the local-user-authenticator container image. If both image_digest or an image_tag are given, only image_digest will be used." -#@schema/examples ("Digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") +#@schema/examples ("Providing a digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") #@schema/nullable #@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_tag"] == None image_digest: "" #@schema/title "Image tag" #@schema/desc "The image tag for the local-user-authenticator container image. If both image_digest or an image_tag are given, only image_digest will be used." -#@schema/examples ("Tag", "v0.25.0") +#@schema/examples ("Providing a tag", "v0.25.0") #@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_digest"] == None image_tag: latest @@ -30,6 +30,7 @@ image_tag: latest #@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" #@schema/examples (example_desc, example_value) #@schema/nullable +#@schema/validation min_len=1 image_pull_dockerconfigjson: "" #@schema/title "Run as user" diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 95090a17a..f35c22036 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -1,6 +1,16 @@ #! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 +#@ def validate_strings_map(obj): +#@ # Returns True if obj is an associative data structure string→string, and False otherwise. +#@ for key in obj: +#@ if type(key) != "string" or type(obj[key]) != "string": +#@ return False +#@ end +#@ end +#@ return True +#@ end + #@data/values-schema --- #@schema/title "App name" @@ -31,40 +41,28 @@ into_namespace: "" #@ not assume that there was a static install-time yaml namespace." #@schema/desc custom_labels_desc #@schema/examples ("Example set of labels", {"myCustomLabelName": "myCustomLabelValue", "otherCustomLabelName": "otherCustomLabelValue"}) -#@ def validate_labels(labels): -#@ """ -#@ Returns True if labels is an associative data structure string→string, -#@ and False otherwise. -#@ """ -#@ for label in labels: -#@ if type(label) != "string" or type(labels[label]) != "string": -#@ return False -#@ end -#@ end -#@ return True -#@ end #@schema/type any=True -#@schema/validation ("a map of keys and values", validate_labels) -custom_labels: {} +#@schema/validation ("a map of keys and values", validate_strings_map) +custom_labels: { } #@schema/title "Replicas" #@schema/desc "Specify how many replicas of the Pinniped server to run." replicas: 2 #@schema/title "Image repo" -#@schema/desc "The repository for the Concierge container image." +#@schema/desc "The repository for the Supervisor container image." #@schema/validation min_len=1 image_repo: projects.registry.vmware.com/pinniped/pinniped-server #@schema/title "Image digest" -#@schema/desc "The image digest for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/desc "The image digest for the Supervisor container image. If both image_digest or an image_tag are given, only image_digest will be used." #@schema/examples ("Digest", "sha256:f3c4fdfd3ef865d4b97a1fd295d94acc3f0c654c46b6f27ffad5cf80216903c8") #@schema/nullable #@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_tag"] == None image_digest: "" #@schema/title "Image tag" -#@schema/desc "The image tag for the Concierge container image. If both image_digest or an image_tag are given, only image_digest will be used." +#@schema/desc "The image tag for the Supervisor container image. If both image_digest or an image_tag are given, only image_digest will be used." #@schema/examples ("Tag", "v0.25.0") #@schema/validation min_len=1, when=lambda _, ctx: ctx.parent["image_digest"] == None image_tag: latest @@ -78,75 +76,60 @@ image_tag: latest #@ example_value = "eyJhdXRocyI6eyJodHRwczovL2V4YW1wbGUuaW8iOnsidXNlcm5hbWUiOiJVU0VSTkFNRSIsInBhc3N3b3JkIjoiUEFTU1dPUkQiLCJhdXRoIjoiVlZORlVrNUJUVVU2VUVGVFUxZFBVa1E9In19fQ==" #@schema/examples (example_desc, example_value) #@schema/nullable +#@schema/validation min_len=1 image_pull_dockerconfigjson: "" #@schema/title "Deprecated service HTTP nodeport port" #@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/examples ("Specify port","31234") +#@schema/examples ("Specify port",31234) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_nodeport_port: "" +deprecated_service_http_nodeport_port: 0 #@schema/title "Deprecated service http nodeport nodeport" #@schema/desc "The `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified" -#@schema/examples ("Specify port","31234") +#@schema/examples ("Specify port",31234) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_nodeport_nodeport: "" +deprecated_service_http_nodeport_nodeport: 0 #@schema/title "Deprecated service http loadbalancer port" #@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/examples ("Specify port","8443") +#@schema/examples ("Specify port",8443) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_loadbalancer_port: "" +deprecated_service_http_loadbalancer_port: 0 #@schema/title "Deprecated service http clusterip port" #@schema/desc "Creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/examples ("Specify port","8443") +#@schema/examples ("Specify port",8443) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_clusterip_port: "" +deprecated_service_http_clusterip_port: 0 #@schema/title "Service https nodeport port" #@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`" -#@schema/examples ("Specify port","31243") +#@schema/examples ("Specify port",31243) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) -service_https_nodeport_port: "" +service_https_nodeport_port: 0 #@schema/title "Service https nodeport nodeport" #@schema/desc "The `nodePort` value of the NodePort Service, optional when `service_https_nodeport_port` is specified" -#@schema/examples ("Specify port","31243") +#@schema/examples ("Specify port",31243) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) -service_https_nodeport_nodeport: "" +service_https_nodeport_nodeport: 0 #@schema/title "Service https loadbalancer port" #@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8443 as its `targetPort`" -#@schema/examples ("Specify port","8443") +#@schema/examples ("Specify port",8443) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) -service_https_loadbalancer_port: "" +service_https_loadbalancer_port: 0 #@schema/title "Service https clusterip port" #@schema/desc "When specified, creates a ClusterIP Service with this `port` value, with port 8443 as its `targetPort`" -#@schema/examples ("Specify port","8443") +#@schema/examples ("Specify port",8443) #@schema/nullable -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) -service_https_clusterip_port: "" +service_https_clusterip_port: 0 #@schema/title "Service loadbalancer ip" #@schema/desc "The `loadBalancerIP` value of the LoadBalancer Service. Ignored unless service_https_loadbalancer_port is provided." @@ -177,23 +160,19 @@ deprecated_log_format: "" #@schema/title "Run as user" #@schema/desc "The user ID that will own the process." -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_user: 65532 #@schema/title "Run as group" #@schema/desc "The group ID that will own the process." -#@schema/type any=True -#@schema/validation ("an int or string", lambda v: type(v) in ["int", "string"]) #! See the Dockerfile for the reasoning behind this default value. run_as_group: 65532 #@schema/title "API group suffix" #@ 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." +#@ config.supervisor.pinniped.dev, etc. As an example, if this is set to tuna.io, then \ +#@ Pinniped API groups will look like foo.tuna.io. config.supervisor.tuna.io, etc." #@schema/desc api_group_suffix_desc #@schema/validation min_len=1 api_group_suffix: pinniped.dev @@ -202,25 +181,26 @@ 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." +#@ The Supervisor never makes insecure HTTP calls, so there is no reason to set HTTP_PROXY." #@schema/desc https_proxy_desc -#@schema/examples ("Provide a proxy endpoint","http://proxy.example.com") +#@schema/examples ("Providing a proxy endpoint","http://proxy.example.com") #@schema/nullable +#@schema/validation min_len=1 https_proxy: "" #@schema/title "No proxy" -#@schema/desc "Endpoints that should not be proxied. Defaults to some sensible known values on public cloud providers." -no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #! do not proxy Kubernetes endpoints - +#@ no_proxy_desc = "Endpoints that should not be proxied. Defaults to not proxying internal Kubernetes endpoints, \ +#@ localhost endpoints, and the known instance metadata IP address for public cloud providers." +#@schema/desc no_proxy_desc +no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #@schema/title "Endpoints" #@ endpoints_desc = "Control the HTTP and HTTPS listeners of the Supervisor. The current defaults are: \ #@ {\"https\":{\"network\":\"tcp\",\"address\":\":8443\"},\"http\":\"disabled\"}. \ -#@ These defaults mean: 1.) For HTTPS listening, bind to all interfaces using TCP on port 8443 and \ -#@ 2.) Disable HTTP listening by default. \ +#@ These defaults mean: 1.) for HTTPS listening, bind to all interfaces using TCP on port 8443 and \ +#@ 2.) disable HTTP listening by default. \ #@ The schema of this config is as follows: \ -#@ {'https':{'network':'tcp | unix | disabled','address':'host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix'},'http':{'network':'tcp | unix | disabled','address':'same as https, except that when network=tcp then the address is only allowed to bind to loopback interfaces'}} \ +#@ {\"https\":{\"network\":\"tcp | unix | disabled\",\"address\":\"host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix\"},\"http\":{\"network\":\"tcp | unix | disabled\",\"address\":\"same as https, except that when network=tcp then the address is only allowed to bind to loopback interfaces\"}} \ #@ 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 \ @@ -241,6 +221,14 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,. #@ return False #@ end #@ end +#@ if(type(endpoint) in ["yamlfragment"]): +#@ if (endpoint["network"] not in ["tcp", "unix", "disabled"]): +#@ return False +#@ end +#@ if (type(endpoint["address"]) not in ["string"]): +#@ return False +#@ end +#@ end #@ return True #@ end #@ def validate_endpoints(endpoints): @@ -251,9 +239,9 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,. #@ https_val = endpoints["https"] #@ return validate_endpoint(http_val) and validate_endpoint(https_val) #@ end -#@schema/validation ("a map with keys 'http' and 'https', both having keys 'network' and 'address' or set to 'disabled'", validate_endpoints) #@schema/nullable -endpoints: {} +#@schema/validation ("a map with keys 'http' and 'https', whose values are either the string 'disabled' or a map having keys 'network' and 'address', and the value of 'network' must be one of the allowed values", validate_endpoints) +endpoints: { } #@ 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. \ diff --git a/hack/prepare-impersonator-on-kind.sh b/hack/prepare-impersonator-on-kind.sh index 0a17cfecc..df0355747 100755 --- a/hack/prepare-impersonator-on-kind.sh +++ b/hack/prepare-impersonator-on-kind.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright 2021 the Pinniped contributors. All Rights Reserved. +# Copyright 2021-2023 the Pinniped contributors. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 # @@ -106,7 +106,7 @@ function cleanup() { kubectl delete webhookauthenticator local-user-authenticator log_note "Stopping kubectl port-forward and exiting..." # It may have already shut down, so ignore errors. - kill -9 $port_forward_pid &> /dev/null || true + kill -9 $port_forward_pid &>/dev/null || true } trap cleanup EXIT diff --git a/hack/prepare-supervisor-on-kind.sh b/hack/prepare-supervisor-on-kind.sh index 5a0cb7202..147a1869d 100755 --- a/hack/prepare-supervisor-on-kind.sh +++ b/hack/prepare-supervisor-on-kind.sh @@ -39,7 +39,6 @@ cd "$ROOT" source hack/lib/helpers.sh - use_oidc_upstream=no use_ldap_upstream=no use_ad_upstream=no @@ -115,8 +114,8 @@ if [[ "${PINNIPED_USE_CONTOUR:-}" != "" ]]; then # Wait for its pods to be ready. echo "Waiting for Contour to be ready..." - kubectl wait --for 'jsonpath={.status.phase}=Succeeded' pods -l 'app=contour-certgen' -n projectcontour --timeout 60s - kubectl wait --for 'jsonpath={.status.phase}=Running' pods -l 'app!=contour-certgen' -n projectcontour --timeout 60s + kubectl wait --for 'jsonpath={.status.phase}=Succeeded' pods -l 'app=contour-certgen' -n projectcontour --timeout 60s + kubectl wait --for 'jsonpath={.status.phase}=Running' pods -l 'app!=contour-certgen' -n projectcontour --timeout 60s # Create an ingress for the Supervisor which uses TLS passthrough to allow the Supervisor to terminate TLS. cat < $fd_file +cat <$fd_file apiVersion: config.supervisor.pinniped.dev/v1alpha1 kind: FederationDomain metadata: @@ -327,7 +326,7 @@ EOF if [[ "$use_oidc_upstream" == "yes" ]]; then # Indenting the heredoc by 4 spaces to make it indented the correct amount in the FederationDomain below. - cat << EOF >> $fd_file + cat <>$fd_file - displayName: "My OIDC IDP 🚀" objectRef: @@ -351,7 +350,7 @@ fi if [[ "$use_ldap_upstream" == "yes" ]]; then # Indenting the heredoc by 4 spaces to make it indented the correct amount in the FederationDomain below. - cat << EOF >> $fd_file + cat <>$fd_file - displayName: "My LDAP IDP 🚀" objectRef: @@ -405,7 +404,7 @@ fi if [[ "$use_ad_upstream" == "yes" ]]; then # Indenting the heredoc by 4 spaces to make it indented the correct amount in the FederationDomain below. - cat << EOF >> $fd_file + cat <>$fd_file - displayName: "My AD IDP" objectRef: From d4e2622ea898dbf5479dd989b53d1eb6031d88e7 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 8 Nov 2023 13:38:22 -0800 Subject: [PATCH 13/15] Revert "Rearrange carvel build & deploy scripts" This reverts commit 9a632134ae1d4bc1ce5a524bff770be881d088f2. --- .../{build_and_deploy.sh => build.sh} | 32 ------------------- .../carvel_packages/{install.sh => deploy.sh} | 29 +++++++++++++++++ 2 files changed, 29 insertions(+), 32 deletions(-) rename hack/lib/carvel_packages/{build_and_deploy.sh => build.sh} (84%) rename hack/lib/carvel_packages/{install.sh => deploy.sh} (83%) diff --git a/hack/lib/carvel_packages/build_and_deploy.sh b/hack/lib/carvel_packages/build.sh similarity index 84% rename from hack/lib/carvel_packages/build_and_deploy.sh rename to hack/lib/carvel_packages/build.sh index 2ef07dd20..f2a88fde3 100755 --- a/hack/lib/carvel_packages/build_and_deploy.sh +++ b/hack/lib/carvel_packages/build.sh @@ -132,36 +132,4 @@ imgpkg push --bundle "${package_repository_repo_tag}" --file "${dest_dir}/packag # manually validate the package bundle by pulling it from the registry and examining its contents: # imgpkg pull --bundle "${package_repository_repo_tag}" --output "/tmp/${package_repository_repo_tag}" - -log_note "Deploying PackageRepository & Packages to kind cluster..." - -# Deploy kapp-controller onto kind cluster. -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 - -# Ensure this directory exists though this script will run several times. -mkdir -p "${dest_dir}/install" - -log_note "Deploying Pinniped PackageRepository..." -pinniped_package_repository_name="pinniped-package-repository" -pinniped_package_repository_file="${dest_dir}/install/packagerepository.${pinniped_package_version}.yml" -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 - -resource_name="${app}" - log_note "Building Carvel Packages for Supervisor, Concierge & local-user-authenticator complete." diff --git a/hack/lib/carvel_packages/install.sh b/hack/lib/carvel_packages/deploy.sh similarity index 83% rename from hack/lib/carvel_packages/install.sh rename to hack/lib/carvel_packages/deploy.sh index 00e000dbf..ea76255f7 100755 --- a/hack/lib/carvel_packages/install.sh +++ b/hack/lib/carvel_packages/deploy.sh @@ -47,8 +47,37 @@ registry_repo="$registry/$repo" # Pinniped Package repository package_repository_repo="pinniped-package-repository" package_repository_repo_tag="${registry_repo}/${package_repository_repo}:${tag}" + # Use the same directory as build.sh. dest_dir="deploy_carvel_tmp" + +# Deploy kapp-controller onto kind cluster. +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 + +# Ensure this directory exists though this script will run several times. +mkdir -p "${dest_dir}/install" + +log_note "Deploying Pinniped PackageRepository..." +pinniped_package_repository_name="pinniped-package-repository" +pinniped_package_repository_file="${dest_dir}/install/packagerepository.${pinniped_package_version}.yml" +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 + resource_name="${app}" log_note "Creating RBAC for ${resource_name} PackageInstall..." From b61557d3c3fa9d1392ae0b80660dd75183df514e Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 8 Nov 2023 13:45:48 -0800 Subject: [PATCH 14/15] Auto-format build.sh and deploy.sh Co-authored-by: Benjamin A. Petersen --- hack/lib/carvel_packages/build.sh | 14 +++++++------- hack/lib/carvel_packages/deploy.sh | 7 +++---- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/hack/lib/carvel_packages/build.sh b/hack/lib/carvel_packages/build.sh index f2a88fde3..8d4f1781c 100755 --- a/hack/lib/carvel_packages/build.sh +++ b/hack/lib/carvel_packages/build.sh @@ -67,8 +67,7 @@ mkdir -p "${dest_dir}" # Generate the OpenAPI v3 Schema files, imgpkg images.yml files declare -a packages_to_build=("local-user-authenticator" "pinniped-concierge" "pinniped-supervisor") -for resource_name in "${packages_to_build[@]}" -do +for resource_name in "${packages_to_build[@]}"; do resource_qualified_name="${resource_name}.${api_group_suffix}" package_repo_tag="${package_repo_prefix}-${resource_name}:${tag}" @@ -85,9 +84,10 @@ do cp "${resource_package_template_source_dir}/vendir.yml" "${resource_destination_dir}/vendir.yml" cp "${resource_package_template_source_dir}/release_notes.txt" "${resource_destination_dir}/release_notes.txt" # dummy log_note "Vendir sync deploy directory for ${resource_name} to package bundle..." - pushd "${resource_destination_dir}" > /dev/null - vendir sync - popd > /dev/null + + pushd "${resource_destination_dir}" >/dev/null + vendir sync + popd >/dev/null log_note "Generating OpenAPI v3 schema for ${resource_name}..." ytt \ @@ -99,7 +99,7 @@ do log_note "Generating .imgpkg/images.yml for ${resource_name}..." mkdir -p "${resource_destination_dir}/.imgpkg" ytt \ - --file "${resource_config_destination_dir}" | \ + --file "${resource_config_destination_dir}" | kbld -f- --imgpkg-lock-output "${resource_destination_dir}/.imgpkg/images.yml" log_note "Pushing Pinniped ${resource_name} Package bundle..." @@ -118,7 +118,7 @@ do --data-value-file openapi="${resource_destination_dir}/schema-openapi.yml" \ --data-value-file releaseNotes="${resource_destination_dir}/release_notes.txt" \ --data-value repo_host="${package_repo_prefix}-${resource_name}" \ - --data-value version="${pinniped_package_version}" > "${package_repository_dir}/${pinniped_package_version}.yml" + --data-value version="${pinniped_package_version}" >"${package_repository_dir}/${pinniped_package_version}.yml" cp "${resource_package_template_source_dir}/metadata.yml" "${package_repository_dir}/metadata.yml" done diff --git a/hack/lib/carvel_packages/deploy.sh b/hack/lib/carvel_packages/deploy.sh index ea76255f7..7dff5c39e 100755 --- a/hack/lib/carvel_packages/deploy.sh +++ b/hack/lib/carvel_packages/deploy.sh @@ -21,7 +21,6 @@ cd "$hack_lib_path/../../" || exit 1 source hack/lib/helpers.sh - # Expected arguments. app=${1:-"app-argument-not-provided"} tag=${2:-"tag-argument-not-provided"} @@ -62,7 +61,7 @@ mkdir -p "${dest_dir}/install" log_note "Deploying Pinniped PackageRepository..." pinniped_package_repository_name="pinniped-package-repository" pinniped_package_repository_file="${dest_dir}/install/packagerepository.${pinniped_package_version}.yml" -cat < "${pinniped_package_repository_file}" +cat <"${pinniped_package_repository_file}" --- apiVersion: packaging.carvel.dev/v1alpha1 kind: PackageRepository @@ -89,7 +88,7 @@ pinniped_package_rbac_file="${dest_dir}/install/${pinniped_package_rbac_prefix}- # For any other use case, the generated artifacts should be properly reviewed. # For example, the RBAC generated here should be adjusted to conform to the # principle of LEAST privilege. -cat < "${pinniped_package_rbac_file}" +cat <"${pinniped_package_rbac_file}" --- apiVersion: v1 kind: Namespace @@ -136,7 +135,7 @@ PACKAGE_INSTALL_FILE_NAME="${dest_dir}/install/${resource_name}-pkginstall.yml" SECRET_NAME="${resource_name}-package-install-secret" log_note "Generating ${PACKAGE_INSTALL_FILE_NAME}..." -cat > "${PACKAGE_INSTALL_FILE_NAME}" << EOF +cat >"${PACKAGE_INSTALL_FILE_NAME}" < Date: Wed, 8 Nov 2023 13:56:11 -0800 Subject: [PATCH 15/15] Fix a comment Co-authored-by: Benjamin A. Petersen --- hack/kind-up.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hack/kind-up.sh b/hack/kind-up.sh index 43d46be89..f4a92b46c 100755 --- a/hack/kind-up.sh +++ b/hack/kind-up.sh @@ -50,8 +50,8 @@ if [[ "${PINNIPED_USE_LOCAL_KIND_REGISTRY:-}" != "" ]]; then docker network connect "kind" "${reg_name}" fi - # Configure kind to use the local registry. - # https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry + # Document the local registry. + # See https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry cat <