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