From 60a39a2ce98fe3ec89f9e79d947d0b8fee8a92ed Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Thu, 6 Jun 2024 13:40:48 -0400 Subject: [PATCH] feat(cryostat3): deploy Cryostat 3.0 (#124) Co-authored-by: Atif Ali <56743004+aali309@users.noreply.github.com> Co-authored-by: Thuan Vo --- .github/workflows/ci.yml | 38 +- charts/cryostat/Chart.yaml | 2 +- charts/cryostat/README.md | 162 ++++--- charts/cryostat/ci/minimal-deploy-values.yaml | 1 - .../ci/non-minimal-deploy-values.yaml | 1 - charts/cryostat/templates/NOTES.txt | 56 +-- charts/cryostat/templates/_helpers.tpl | 80 +++- charts/cryostat/templates/alpha_config.yaml | 29 ++ .../templates/clusterrolebinding.yaml | 16 + .../templates/db_connection_key_secret.yaml | 7 + .../templates/db_encryption_key_secret.yaml | 9 + charts/cryostat/templates/deployment.yaml | 253 ++++++---- charts/cryostat/templates/ingress.yaml | 3 - charts/cryostat/templates/oauth2Proxy.tpl | 40 ++ .../templates/openshiftOauthProxy.tpl | 42 ++ charts/cryostat/templates/role.yaml | 26 +- charts/cryostat/templates/rolebinding.yaml | 19 +- charts/cryostat/templates/route.yaml | 5 +- charts/cryostat/templates/secret.yaml | 9 - charts/cryostat/templates/service.yaml | 30 +- charts/cryostat/templates/serviceaccount.yaml | 5 + .../templates/storage_access_key_secret.yaml | 7 + ...nection.yaml => test-core-connection.yaml} | 12 +- .../tests/test-grafana-connection.yaml | 17 + .../tests/test-storage-connection.yaml | 17 + charts/cryostat/values.schema.json | 447 +++++++++++++----- charts/cryostat/values.yaml | 170 +++++-- 27 files changed, 1083 insertions(+), 420 deletions(-) delete mode 100644 charts/cryostat/ci/minimal-deploy-values.yaml delete mode 100644 charts/cryostat/ci/non-minimal-deploy-values.yaml create mode 100644 charts/cryostat/templates/alpha_config.yaml create mode 100644 charts/cryostat/templates/clusterrolebinding.yaml create mode 100644 charts/cryostat/templates/db_connection_key_secret.yaml create mode 100644 charts/cryostat/templates/db_encryption_key_secret.yaml create mode 100644 charts/cryostat/templates/oauth2Proxy.tpl create mode 100644 charts/cryostat/templates/openshiftOauthProxy.tpl delete mode 100644 charts/cryostat/templates/secret.yaml create mode 100644 charts/cryostat/templates/storage_access_key_secret.yaml rename charts/cryostat/templates/tests/{test-connection.yaml => test-core-connection.yaml} (54%) create mode 100644 charts/cryostat/templates/tests/test-grafana-connection.yaml create mode 100644 charts/cryostat/templates/tests/test-storage-connection.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b6011826..2986688d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,21 +27,22 @@ on: env: TARGET_BRANCH: ${{ github.event.pull_request.base.ref || github.ref_name }} + TEST_NAMESPACE: helm-test jobs: lint-chart: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Helm - uses: azure/setup-helm@v3 + uses: azure/setup-helm@v4 with: - version: v3.11.2 - - uses: actions/setup-python@v4 + version: v3.14.4 + - uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.x' check-latest: true - name: Set up chart-testing uses: helm/chart-testing-action@v2.6.1 @@ -53,23 +54,30 @@ jobs: - name: Fail if safe-to-test label NOT applied if: ${{ github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'safe-to-test') }} run: exit 1 - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Helm - uses: azure/setup-helm@v3 + uses: azure/setup-helm@v4 with: - version: v3.11.2 - - uses: actions/setup-python@v4 + version: v3.14.4 + - uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.x' check-latest: true - uses: helm/chart-testing-action@v2.6.1 - name: Set up Kind cluster - run: kind create cluster -n ci-${{ github.run_id }} + uses: helm/kind-action@v1 + with: + cluster_name: ci-${{ github.run_id }} - name: Install and test chart run: | - kubectl create ns helm-test - ct install --target-branch ${TARGET_BRANCH} --upgrade --namespace=helm-test --config ct.yaml - - name: Clean up Kind cluster - run: kind delete cluster -n ci-${{ github.run_id }} + # FIXME: Remove when chart-testing fixes the issue https://github.com/helm/chart-testing/issues/525 + + HELM_LOCATION="$(which helm)" + sudo mv $HELM_LOCATION "$(dirname $HELM_LOCATION)/.helm" + cat <(echo '#!/usr/bin/env bash') <(echo 'exec .helm "${@//--reuse-values/--reset-then-reuse-values}"') | sudo tee $HELM_LOCATION + sudo chmod +x $HELM_LOCATION + + kubectl create ns $TEST_NAMESPACE + ct install --target-branch ${TARGET_BRANCH} --upgrade --namespace=$TEST_NAMESPACE --config ct.yaml --debug diff --git a/charts/cryostat/Chart.yaml b/charts/cryostat/Chart.yaml index 7ad00479..4be55185 100644 --- a/charts/cryostat/Chart.yaml +++ b/charts/cryostat/Chart.yaml @@ -8,7 +8,7 @@ version: "0.5.0-dev" kubeVersion: ">= 1.19.0-0" -appVersion: "2.5.0-dev" +appVersion: "3.0.0-dev" home: "https://cryostat.io" diff --git a/charts/cryostat/README.md b/charts/cryostat/README.md index a1e9b254..d16815b2 100644 --- a/charts/cryostat/README.md +++ b/charts/cryostat/README.md @@ -5,59 +5,78 @@ A Helm chart for deploying [Cryostat](https://cryostat.io/) on Kubernetes and Op ### Cryostat Container -| Name | Description | Value | -| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | -| `core` | Configuration for the core Cryostat application | | -| `core.image.repository` | Repository for the main Cryostat container image | `quay.io/cryostat/cryostat` | -| `core.image.pullPolicy` | Image pull policy for the main Cryostat container image | `Always` | -| `core.image.tag` | Tag for the main Cryostat container image | `latest` | -| `core.service.type` | Type of Service to create for the Cryostat application | `ClusterIP` | -| `core.service.httpPort` | Port number to expose on the Service for Cryostat's HTTP server | `8181` | -| `core.service.jmxPort` | Port number to expose on the Service for remote JMX connections to Cryostat | `9091` | -| `core.sslProxied` | Enables SSL Proxied Environment Variables, useful when you are offloading SSL/TLS at External Loadbalancer instead of Ingress | `false` | -| `core.ingress.enabled` | Whether to create an Ingress object for the Cryostat service | `false` | -| `core.ingress.className` | Ingress class name for the Cryostat application Ingress | `""` | -| `core.ingress.annotations` | Annotations to apply to the Cryostat application Ingress | `{}` | -| `core.ingress.hosts` | Hosts to create rules for in the Cryostat application Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) | `[]` | -| `core.ingress.tls` | TLS configuration for the Cryostat application Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) | `[]` | -| `core.route.enabled` | Whether to create a Route object for the Cryostat service. Available only on OpenShift | `false` | -| `core.route.tls.enabled` | Whether to secure the Cryostat application Route with TLS. See: [TLSConfig](https://docs.openshift.com/container-platform/4.10/rest_api/network_apis/route-route-openshift-io-v1.html#spec-tls) | `true` | -| `core.route.tls.termination` | Type of TLS termination to use for the Cryostat application Route. One of: `edge`, `passthrough`, `reencrypt` | `edge` | -| `core.route.tls.insecureEdgeTerminationPolicy` | Specify how to handle insecure traffic for the Cryostat application Route. One of: `Allow`, `Disable`, `Redirect` | `Redirect` | -| `core.route.tls.key` | Custom private key to use when securing the Cryostat application Route | `""` | -| `core.route.tls.certificate` | Custom certificate to use when securing the Cryostat application Route | `""` | -| `core.route.tls.caCertificate` | Custom CA certificate to use, if needed to complete the certificate chain, when securing the Cryostat application Route | `""` | -| `core.route.tls.destinationCACertificate` | Provides the contents of the CA certificate of the final destination when using reencrypt termination for the Cryostat application Route | `""` | -| `core.resources` | Resource requests/limits for the Cryostat container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) | `{}` | -| `core.securityContext` | Security Context for the Cryostat container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | -| `core.databaseSecretName` | Name of the secret to extract password for credentials database. | `""` | +| Name | Description | Value | +| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `core` | Configuration for the core Cryostat application | | +| `core.image.repository` | Repository for the main Cryostat container image | `quay.io/cryostat/cryostat` | +| `core.image.pullPolicy` | Image pull policy for the main Cryostat container image | `Always` | +| `core.image.tag` | Tag for the main Cryostat container image | `3.0.0-snapshot` | +| `core.service.type` | Type of Service to create for the Cryostat application | `ClusterIP` | +| `core.service.httpPort` | Port number to expose on the Service for Cryostat's HTTP server | `8181` | +| `core.sslProxied` | Enables SSL Proxied Environment Variables, useful when you are offloading SSL/TLS at External Loadbalancer instead of Ingress | `false` | +| `core.ingress.enabled` | Whether to create an Ingress object for the Cryostat service | `false` | +| `core.ingress.className` | Ingress class name for the Cryostat application Ingress | `""` | +| `core.ingress.annotations` | Annotations to apply to the Cryostat application Ingress | `{}` | +| `core.ingress.hosts` | Hosts to create rules for in the Cryostat application Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) | `[]` | +| `core.ingress.tls` | TLS configuration for the Cryostat application Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) | `[]` | +| `core.route.enabled` | Whether to create a Route object for the Cryostat service. Available only on OpenShift | `false` | +| `core.route.tls.enabled` | Whether to secure the Cryostat application Route with TLS. See: [TLSConfig](https://docs.openshift.com/container-platform/4.10/rest_api/network_apis/route-route-openshift-io-v1.html#spec-tls) | `true` | +| `core.route.tls.termination` | Type of TLS termination to use for the Cryostat application Route. One of: `edge`, `passthrough`, `reencrypt` | `edge` | +| `core.route.tls.insecureEdgeTerminationPolicy` | Specify how to handle insecure traffic for the Cryostat application Route. One of: `Allow`, `Disable`, `Redirect` | `Redirect` | +| `core.route.tls.key` | Custom private key to use when securing the Cryostat application Route | `""` | +| `core.route.tls.certificate` | Custom certificate to use when securing the Cryostat application Route | `""` | +| `core.route.tls.caCertificate` | Custom CA certificate to use, if needed to complete the certificate chain, when securing the Cryostat application Route | `""` | +| `core.route.tls.destinationCACertificate` | Provides the contents of the CA certificate of the final destination when using reencrypt termination for the Cryostat application Route | `""` | +| `core.resources` | Resource requests/limits for the Cryostat container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) | `{}` | +| `core.securityContext` | Security Context for the Cryostat container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | +| `core.databaseSecretName` | Name of the secret to extract password for credentials database. | `""` | +| `core.discovery` | Configuration options to the Cryostat application's target discovery mechanisms | | +| `core.discovery.kubernetes.enabled` | Enables Kubernetes API discovery mechanism | `true` | +| `core.discovery.kubernetes.installNamespaceDisabled` | When false and `namespaces` is empty, the Cryostat application will default to discovery targets in the install namespace (i.e. `{{ .Release.Namespace }}`) | `false` | +| `core.discovery.kubernetes.namespaces` | List of namespaces whose workloads the Cryostat application should be permitted to access and profile | `[]` | +| `core.discovery.kubernetes.builtInPortNamesDisabled` | When false and `portNames` is empty, the Cryostat application will use the default port name `jfr-jmx` to look for JMX connectable targets. | `false` | +| `core.discovery.kubernetes.portNames` | List of port names that the Cryostat application should look for in order to consider a target as JMX connectable | `[]` | +| `core.discovery.kubernetes.builtInPortNumbersDisabled` | When false and `portNumbers` is empty, the Cryostat application will use the default port number `9091` to look for JMX connectable targets. | `false` | +| `core.discovery.kubernetes.portNumbers` | List of port numbers that the Cryostat application should look for in order to consider a target as JMX connectable | `[]` | + + +### Database Container + +| Name | Description | Value | +| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | +| `db` | Configuration for Cryostat's database | | +| `db.image.repository` | Repository for the database container image | `quay.io/cryostat/cryostat-db` | +| `db.image.pullPolicy` | Image pull policy for the database container image | `Always` | +| `db.image.tag` | Tag for the database container image | `latest` | +| `db.resources` | Resource requests/limits for the database container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) | `{}` | +| `db.securityContext` | Security Context for the database container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | + + +### Storage Container + +| Name | Description | Value | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | +| `storage` | Configuration for Cryostat's object storage provider | | +| `storage.image.repository` | Repository for the storage container image | `quay.io/cryostat/cryostat-storage` | +| `storage.image.pullPolicy` | Image pull policy for the storage container image | `Always` | +| `storage.image.tag` | Tag for the storage container image | `latest` | +| `storage.resources` | Resource requests/limits for the storage container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) | `{}` | +| `storage.securityContext` | Security Context for the storage container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | + ### Grafana Container -| Name | Description | Value | -| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | -| `grafana` | Configuration for the customized Grafana instance for Cryostat | | -| `grafana.image.repository` | Repository for the Grafana container image | `quay.io/cryostat/cryostat-grafana-dashboard` | -| `grafana.image.pullPolicy` | Image pull policy for the Grafana container image | `Always` | -| `grafana.image.tag` | Tag for the Grafana container image | `latest` | -| `grafana.service.type` | Type of Service to create for Grafana | `ClusterIP` | -| `grafana.service.port` | Port number to expose on the Service for Grafana's HTTP server | `3000` | -| `grafana.sslProxied` | Enables SSL Proxied Environment Variables, useful when you are offloading SSL/TLS at External Loadbalancer instead of Ingress | `false` | -| `grafana.ingress.enabled` | Whether to create an Ingress object for the Grafana service | `false` | -| `grafana.ingress.className` | Ingress class name for the Grafana Ingress | `""` | -| `grafana.ingress.annotations` | Annotations to apply to the Grafana Ingress | `{}` | -| `grafana.ingress.hosts` | Hosts to create rules for in the Grafana Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) | `[]` | -| `grafana.ingress.tls` | TLS configuration for the Grafana Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) | `[]` | -| `grafana.route.enabled` | Whether to create a Route object for the Grafana service. Available only on OpenShift | `false` | -| `grafana.route.tls.enabled` | Whether to secure the Grafana Route with TLS. See: [TLSConfig](https://docs.openshift.com/container-platform/4.10/rest_api/network_apis/route-route-openshift-io-v1.html#spec-tls) | `true` | -| `grafana.route.tls.termination` | Type of TLS termination to use for the Grafana Route. One of: `edge`, `passthrough`, `reencrypt` | `edge` | -| `grafana.route.tls.insecureEdgeTerminationPolicy` | Specify how to handle insecure traffic for the Grafana Route. One of: `Allow`, `Disable`, `Redirect` | `Redirect` | -| `grafana.route.tls.key` | Custom private key to use when securing the Grafana Route | `""` | -| `grafana.route.tls.certificate` | Custom certificate to use when securing the Grafana Route | `""` | -| `grafana.route.tls.caCertificate` | Custom CA certificate to use, if needed to complete the certificate chain, when securing the Grafana Route | `""` | -| `grafana.route.tls.destinationCACertificate` | Provides the contents of the CA certificate of the final destination when using reencrypt termination for the Grafana Route | `""` | -| `grafana.resources` | Resource requests/limits for the Grafana container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) | `{}` | -| `grafana.securityContext` | Security Context for the Grafana container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | +| Name | Description | Value | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | +| `grafana` | Configuration for the customized Grafana instance for Cryostat | | +| `grafana.image.repository` | Repository for the Grafana container image | `quay.io/cryostat/cryostat-grafana-dashboard` | +| `grafana.image.pullPolicy` | Image pull policy for the Grafana container image | `Always` | +| `grafana.image.tag` | Tag for the Grafana container image | `latest` | +| `grafana.service.type` | Type of Service to create for Grafana | `ClusterIP` | +| `grafana.service.port` | Port number to expose on the Service for Grafana's HTTP server | `3000` | +| `grafana.resources` | Resource requests/limits for the Grafana container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) | `{}` | +| `grafana.securityContext` | Security Context for the Grafana container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | + ### JFR Data Source Container @@ -70,19 +89,50 @@ A Helm chart for deploying [Cryostat](https://cryostat.io/) on Kubernetes and Op | `datasource.resources` | Resource requests/limits for the JFR Data Source container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) | `{}` | | `datasource.securityContext` | Security Context for the JFR Data Source container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | + ### Authentication -| Name | Description | Value | -| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| `authentication.basicAuth.enabled` | Whether Cryostat should use basic authentication for users. When false, Cryostat will not perform any form of authentication | `false` | -| `authentication.basicAuth.secretName` | Name of the Secret that contains the credentials within Cryostat's namespace **(Required if basicAuth is enabled)** | `""` | -| `authentication.basicAuth.filename` | Key within Secret containing the properties file. The properties file should contain one user per line, with the syntax "user=passHex", where "user" is the username and "passHex" is the SHA-256 hash of the desired password **(Required if basicAuth is enabled)** | `""` | +| Name | Description | Value | +| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `authentication.openshift.enabled` | Whether the OAuth Proxy deployed for securing Cryostat's Pods should be one that integrates with OpenShift-specific features, or a generic one. | `false` | +| `authentication.openshift.clusterRole.name` | The name of the ClusterRole to bind for the OpenShift OAuth Proxy | `system:auth-delegator` | +| `authentication.basicAuth.enabled` | Whether Cryostat should use basic authentication for users. When false, Cryostat will not perform any form of authentication | `false` | +| `authentication.basicAuth.secretName` | Name of the Secret that contains the credentials within Cryostat's namespace **(Required if basicAuth is enabled)** | `""` | +| `authentication.basicAuth.filename` | Key within Secret containing the `htpasswd` file. The file should contain one user definition entry per line, with the syntax "user:passHash", where "user" is the username and "passHash" is the `bcrypt` hash of the desired password. Such an entry can be generated with ex. `htpasswd -nbB username password` **(Required if basicAuth is enabled)** | `""` | + + +### OAuth2 Proxy + +| Name | Description | Value | +| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | +| `oauth2Proxy.image.repository` | Repository for the OAuth2 Proxy container image | `quay.io/oauth2-proxy/oauth2-proxy` | +| `oauth2Proxy.image.pullPolicy` | Image pull policy for the OAuth2 Proxy container image | `Always` | +| `oauth2Proxy.image.tag` | Tag for the OAuth2 Proxy container image | `latest` | +| `oauth2Proxy.securityContext` | Security Context for the OAuth2 Proxy container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1). If the chart is installed in default namespaces (e.g. default), `securityContext.runAsUser` must be set if the proxy image does not specify a numeric non-root user. This is due to OpenShift Security Context Constraints are not applied in default namespaces. See [Understanding and Managing Pod Security Admission](https://docs.openshift.com/container-platform/4.15/authentication/understanding-and-managing-pod-security-admission.html#psa-privileged-namespaces_understanding-and-managing-pod-security-admission). | `{}` | + + +### OpenShift OAuth Proxy + +| Name | Description | Value | +| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| `openshiftOauthProxy.image.repository` | Repository for the OpenShift OAuth Proxy container image | `quay.io/openshift/origin-oauth-proxy` | +| `openshiftOauthProxy.image.pullPolicy` | Image pull policy for the OpenShift OAuth Proxy container image | `Always` | +| `openshiftOauthProxy.image.tag` | Tag for the OpenShift OAuth Proxy container image | `latest` | +| `openshiftOauthProxy.accessReview.enabled` | Whether the SubjectAccessReview/TokenAccessReview role checks for users and clients are enabled. If this is disabled then the proxy will only check that the user has valid credentials or holds a valid token. | `true` | +| `openshiftOauthProxy.accessReview.group` | The OpenShift resource group that the SubjectAccessReview/TokenAccessReview will be performed for. See https://github.com/openshift/oauth-proxy/?tab=readme-ov-file#delegate-authentication-and-authorization-to-openshift-for-infrastructure | `""` | +| `openshiftOauthProxy.accessReview.resource` | The OpenShift resource that the SubjectAccessReview/TokenAccessReview will be performed for. | `pods` | +| `openshiftOauthProxy.accessReview.subresource` | The OpenShift resource that the SubjectAccessReview/TokenAccessReview will be performed for. | `exec` | +| `openshiftOauthProxy.accessReview.name` | The OpenShift resource name that the SubjectAccessReview/TokenAccessReview will be performed for. | `""` | +| `openshiftOauthProxy.accessReview.namespace` | The OpenShift namespace that the SubjectAccessReview/TokenAccessReview will be performed for. | `{{ .Release.Namespace }}` | +| `openshiftOauthProxy.accessReview.verb` | The OpenShift resource name that the SubjectAccessReview/TokenAccessReview will be performed for. | `create` | +| `openshiftOauthProxy.accessReview.version` | The OpenShift resource version that the SubjectAccessReview/TokenAccessReview will be performed for. | `""` | +| `openshiftOauthProxy.securityContext` | Security Context for the OpenShift OAuth Proxy container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) | `{}` | + ### Other Parameters | Name | Description | Value | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | -| `minimal` | Specify whether to deploy a Cryostat instance with no Grafana Dashboard or JFR Data Source | `false` | | `imagePullSecrets` | Image pull secrets to be used for the Cryostat deployment | `[]` | | `nameOverride` | Overrides the name of this Chart | `""` | | `fullnameOverride` | Overrides the fully qualified application name of `[release name]-[chart name]` | `""` | diff --git a/charts/cryostat/ci/minimal-deploy-values.yaml b/charts/cryostat/ci/minimal-deploy-values.yaml deleted file mode 100644 index 55ab29ca..00000000 --- a/charts/cryostat/ci/minimal-deploy-values.yaml +++ /dev/null @@ -1 +0,0 @@ -minimal: true diff --git a/charts/cryostat/ci/non-minimal-deploy-values.yaml b/charts/cryostat/ci/non-minimal-deploy-values.yaml deleted file mode 100644 index b3a97109..00000000 --- a/charts/cryostat/ci/non-minimal-deploy-values.yaml +++ /dev/null @@ -1 +0,0 @@ -minimal: false diff --git a/charts/cryostat/templates/NOTES.txt b/charts/cryostat/templates/NOTES.txt index 67daa503..b88db2d8 100644 --- a/charts/cryostat/templates/NOTES.txt +++ b/charts/cryostat/templates/NOTES.txt @@ -1,61 +1,39 @@ {{- $envVars := list }} {{- $portForwards := list }} {{- $listNum := 1 }} -{{- if not (and .Values.core.ingress.enabled .Values.grafana.ingress.enabled) }} +{{- if not .Values.core.ingress.enabled }} {{ $listNum }}. Tell Cryostat how to serve external traffic: {{- $listNum = add1 $listNum }} ``` {{- if .Values.core.route.enabled }} export ROUTE_HOST=$(oc get route -n {{ .Release.Namespace }} {{ include "cryostat.fullname" . }} -o jsonpath="{.status.ingress[0].host}") -{{- $envVars = list "CRYOSTAT_WEB_HOST=$ROUTE_HOST" }} +{{- $envVars = list ( tpl "STORAGE_EXT_URL={{ ternary \"https\" \"http\" .Values.core.route.tls.enabled }}://$ROUTE_HOST/storage/" . ) }} +{{- $envVars = append $envVars ( tpl "GRAFANA_DASHBOARD_EXT_URL={{ ternary \"https\" \"http\" .Values.core.route.tls.enabled}}://$ROUTE_HOST/grafana/" . ) }} {{- else if .Values.core.ingress.enabled }} {{- /* Do nothing */}} {{- else if contains "NodePort" .Values.core.service.type }} export NODE_IP=$(kubectl get nodes -n {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") export NODE_PORT=$(kubectl get -n {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "cryostat.fullname" . }}) -{{- $envVars = list "CRYOSTAT_WEB_HOST=$NODE_IP" "CRYOSTAT_EXT_WEB_PORT=$NODE_PORT" }} +{{- $envVars = list "QUARKUS_HTTP_HOST=$NODE_IP" }} +{{- $envVars = append $envVars ( tpl "STORAGE_EXT_URL=http://$NODE_IP:$NODE_PORT/storage/" . ) }} +{{- $envVars = append $envVars ( tpl "GRAFANA_DASHBOARD_EXT_URL=http://$NODE_IP:$NODE_PORT/grafana/" . ) }} {{- else if contains "LoadBalancer" .Values.core.service.type }} NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get -n {{ .Release.Namespace }} -w svc/{{ include "cryostat.fullname" . }} svc/{{ include "cryostat.fullname" . }}-grafana' + You can watch the status by running 'kubectl get -n {{ .Release.Namespace }} -w svc/{{ include "cryostat.fullname" . }}' export SERVICE_IP=$(kubectl get svc -n {{ .Release.Namespace }} {{ include "cryostat.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") -{{- $envVars = list "CRYOSTAT_WEB_HOST=$SERVICE_IP" (printf "CRYOSTAT_EXT_WEB_PORT=%v" .Values.core.service.httpPort) }} +{{- $envVars = list "QUARKUS_HTTP_HOST=$SERVICE_IP" }} +{{- $envVars = append $envVars ( tpl "STORAGE_EXT_URL=http://$SERVICE_IP:{{ .Values.core.service.httpPort }}/storage/" . ) }} +{{- $envVars = append $envVars ( tpl "GRAFANA_DASHBOARD_EXT_URL=http://$SERVICE_IP:{{ .Values.core.service.httpPort }}/grafana/" . ) }} {{- else if contains "ClusterIP" .Values.core.service.type }} export POD_NAME=$(kubectl get pods -n {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "cryostat.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" --sort-by=.metadata.creationTimestamp -o jsonpath="{.items[-1:].metadata.name}") export CONTAINER_PORT=$(kubectl get pod -n {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") -{{- $envVars = list "CRYOSTAT_WEB_HOST=127.0.0.1" "CRYOSTAT_EXT_WEB_PORT=8080" }} + export CRYOSTAT_WEB_HOST=localhost +{{- $envVars = list "QUARKUS_HTTP_HOST=$CRYOSTAT_WEB_HOST" }} +{{- $envVars = append $envVars ( tpl "STORAGE_EXT_URL=http://$CRYOSTAT_WEB_HOST:8080/storage/" . ) }} +{{- $envVars = append $envVars ( tpl "GRAFANA_DASHBOARD_EXT_URL=http://$CRYOSTAT_WEB_HOST:8080/grafana/" . ) }} {{- $portForwards = prepend $portForwards "8080:$CONTAINER_PORT" }} {{- end }} -{{- if not .Values.minimal }} -{{- if .Values.grafana.route.enabled }} - export GRAFANA_ROUTE_HOST=$(oc get route -n {{ .Release.Namespace }} {{ include "cryostat.fullname" . }}-grafana -o jsonpath="{.status.ingress[0].host}") -{{- $envVars = append $envVars ( tpl "GRAFANA_DASHBOARD_URL=http{{ if .Values.grafana.route.tls.enabled }}s{{ end }}://$GRAFANA_ROUTE_HOST" . ) }} -{{- else if .Values.grafana.ingress.enabled }} -{{- /* Do nothing */}} -{{- else if contains "NodePort" .Values.grafana.service.type }} -{{- if not (contains "NodePort" .Values.core.service.type) }} - export NODE_IP=$(kubectl get nodes -n {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") -{{- end }} - export GRAFANA_NODE_PORT=$(kubectl get -n {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "cryostat.fullname" . }}-grafana) -{{- $envVars = append $envVars "GRAFANA_DASHBOARD_URL=http://$NODE_IP:$GRAFANA_NODE_PORT"}} -{{- else if contains "LoadBalancer" .Values.grafana.service.type }} -{{- if not (contains "LoadBalancer" .Values.core.service.type) }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get -n {{ .Release.Namespace }} -w svc/{{ include "cryostat.fullname" . }} svc/{{ include "cryostat.fullname" . }}-grafana' -{{- end }} - export GRAFANA_SERVICE_IP=$(kubectl get svc -n {{ .Release.Namespace }} {{ include "cryostat.fullname" . }}-grafana --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") -{{- $envVars = append $envVars (printf "GRAFANA_DASHBOARD_URL=http://$GRAFANA_SERVICE_IP:%v" .Values.grafana.service.port) }} -{{- else if contains "ClusterIP" .Values.grafana.service.type }} -{{- if not (contains "ClusterIP" .Values.core.service.type) }} - export POD_NAME=$(kubectl get pods -n {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "cryostat.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" --sort-by=.metadata.creationTimestamp -o jsonpath="{.items[-1:].metadata.name}") -{{- end }} - export GRAFANA_CONTAINER_PORT=$(kubectl get pod -n {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[1].ports[0].containerPort}") -{{- $envVars = concat $envVars ( list "GRAFANA_DASHBOARD_URL=http://127.0.0.1:$GRAFANA_CONTAINER_PORT" "GRAFANA_DASHBOARD_EXT_URL=http://127.0.0.1:8081" )}} -{{- $portForwards = append $portForwards "8081:$GRAFANA_CONTAINER_PORT" }} -{{- end }} -{{- end }} - - {{- if not (empty $envVars) }} kubectl -n {{ .Release.Namespace }} set env deploy --containers={{ .Chart.Name }} {{ include "cryostat.fullname" . }} {{ join " " $envVars }} {{- end }} @@ -76,11 +54,11 @@ {{ $listNum }}. {{ "Visit the " }}{{ .Chart.Name | camelcase }}{{ " application at: " }} ``` {{- if .Values.core.route.enabled }} - echo http{{ if $.Values.core.route.tls.enabled }}s{{ end }}://$ROUTE_HOST + echo {{ ternary "https" "http" .Values.core.route.tls.enabled }}://$ROUTE_HOST {{- else if .Values.core.ingress.enabled -}} {{- range $host := .Values.core.ingress.hosts -}} {{- range .paths -}} - http{{ if $.Values.core.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{ ternary "https" "http" .Values.core.ingress.tls }}://{{ $host.host }}{{ .path }} {{- end }} {{- end }} {{- else if contains "NodePort" .Values.core.service.type }} @@ -88,6 +66,6 @@ {{- else if contains "LoadBalancer" .Values.core.service.type }} echo http://$SERVICE_IP:{{ .Values.core.service.httpPort }} {{- else if contains "ClusterIP" .Values.core.service.type }} - http://127.0.0.1:8080 + http://localhost:8080 {{- end }} ``` diff --git a/charts/cryostat/templates/_helpers.tpl b/charts/cryostat/templates/_helpers.tpl index 33c7369a..e3f0b068 100644 --- a/charts/cryostat/templates/_helpers.tpl +++ b/charts/cryostat/templates/_helpers.tpl @@ -62,19 +62,87 @@ Create the name of the service account to use {{- end }} {{/* -Get or generate a default password for credentials database +Get or generate a default connection key for credentials database */}} -{{- define "cryostat.databasePassword" -}} -{{- $secret := (lookup "v1" "Secret" .Release.Namespace (printf "%s-jmx-credentials-db" .Release.Name)) -}} +{{- define "cryostat.databaseConnectionKey" -}} +{{- $secret := (lookup "v1" "Secret" .Release.Namespace (printf "%s-db-connection-key" .Release.Name)) -}} {{- if $secret -}} {{/* - Use current password. Do not regenerate + Use current key. Do not regenerate */}} -{{- $secret.data.CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD -}} +{{- $secret.data.CONNECTION_KEY -}} {{- else -}} {{/* - Generate new password + Generate new key */}} {{- (randAlphaNum 32) | b64enc | quote -}} {{- end -}} {{- end -}} + +{{/* +Get or generate a default encryption key for credentials database +*/}} +{{- define "cryostat.databaseEncryptionKey" -}} +{{- $secret := (lookup "v1" "Secret" .Release.Namespace (printf "%s-db-encryption-key" .Release.Name)) -}} +{{- if $secret -}} +{{/* + Use current key. Do not regenerate +*/}} +{{- $secret.data.ENCRYPTION_KEY -}} +{{- else -}} +{{/* + Generate new key +*/}} +{{- (randAlphaNum 32) | b64enc | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Get or generate a default secret key for object storage +*/}} +{{- define "cryostat.objectStorageSecretKey" -}} +{{- $secret := (lookup "v1" "Secret" .Release.Namespace (printf "%s-storage-secret-key" .Release.Name)) -}} +{{- if $secret -}} +{{/* + Use current secret. Do not regenerate +*/}} +{{- $secret.data.SECRET_KEY -}} +{{- else -}} +{{/* + Generate new secret +*/}} +{{- (randAlphaNum 32) | b64enc | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Generate or retrieve a default value for cookieSecret. +*/}} +{{- define "cryostat.cookieSecret" -}} +{{- $secret := (lookup "v1" "Secret" .Release.Namespace (printf "%s-cookie-secret" .Release.Name)) -}} +{{- if $secret -}} +{{/* + Use the current secret. Do not regenerate. +*/}} +{{- $secret.data.COOKIE_SECRET | b64dec | quote -}} +{{- else -}} +{{/* + Generate a new secret. +*/}} +{{- $newSecret := randAlphaNum 24 | b64enc -}} +{{- $newSecret | quote -}} +{{- end }} +{{- end }} + +{{/* + Get sanitized list or defaults (if not disabled) as comma-separated list +*/}} +{{- define "cryostat.commaSepList" -}} +{{- $l := index . 0 -}} +{{- $default := index . 1 -}} +{{- $disableDefaults := index . 2 -}} +{{- if and (not $l) (not $disableDefaults) -}} +{{- $l = list $default -}} +{{- end -}} +{{- join "," (default list $l | compact | uniq) | quote -}} +{{- end -}} diff --git a/charts/cryostat/templates/alpha_config.yaml b/charts/cryostat/templates/alpha_config.yaml new file mode 100644 index 00000000..e86013b8 --- /dev/null +++ b/charts/cryostat/templates/alpha_config.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-alpha-config +data: + alpha_config.yaml: |- + server: + BindAddress: http://0.0.0.0:4180 + upstreamConfig: + proxyRawPath: true + upstreams: + - id: cryostat + path: / + uri: http://localhost:8181 + - id: grafana + path: /grafana/ + uri: http://localhost:3000 + - id: storage + path: ^/storage/(.*)$ + rewriteTarget: /$1 + uri: http://localhost:8333 + passHostHeader: false + proxyWebSockets: false + providers: + - id: dummy + name: Unused - Sign In Below + clientId: CLIENT_ID + clientSecret: CLIENT_SECRET + provider: google diff --git a/charts/cryostat/templates/clusterrolebinding.yaml b/charts/cryostat/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..4721c7c3 --- /dev/null +++ b/charts/cryostat/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and (.Values.rbac.create) (.Values.authentication.openshift.enabled) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "cryostat.fullname" . }} + labels: + {{- include "cryostat.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Values.authentication.openshift.clusterRole.name }} +subjects: +- kind: ServiceAccount + name: {{ include "cryostat.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/cryostat/templates/db_connection_key_secret.yaml b/charts/cryostat/templates/db_connection_key_secret.yaml new file mode 100644 index 00000000..2c1c5894 --- /dev/null +++ b/charts/cryostat/templates/db_connection_key_secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-db-connection-key +type: Opaque +data: + CONNECTION_KEY: {{ include "cryostat.databaseConnectionKey" . }} diff --git a/charts/cryostat/templates/db_encryption_key_secret.yaml b/charts/cryostat/templates/db_encryption_key_secret.yaml new file mode 100644 index 00000000..2d287010 --- /dev/null +++ b/charts/cryostat/templates/db_encryption_key_secret.yaml @@ -0,0 +1,9 @@ +{{- if empty .Values.core.databaseSecretName -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-db-encryption-key +type: Opaque +data: + ENCRYPTION_KEY: {{ include "cryostat.databaseEncryptionKey" . }} +{{- end -}} diff --git a/charts/cryostat/templates/deployment.yaml b/charts/cryostat/templates/deployment.yaml index 22c041c2..90b28fb8 100644 --- a/charts/cryostat/templates/deployment.yaml +++ b/charts/cryostat/templates/deployment.yaml @@ -1,3 +1,5 @@ +{{- $fullName := include "cryostat.fullname" . -}} +--- apiVersion: apps/v1 kind: Deployment metadata: @@ -28,75 +30,78 @@ spec: securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} containers: + {{- if (.Values.authentication.openshift).enabled }} + {{- include "openshiftOauthProxy" . | nindent 8 }} + {{- else }} + {{- include "oauth2Proxy" . | nindent 8 }} + {{- end }} - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.core.securityContext | nindent 12 }} image: "{{ .Values.core.image.repository }}:{{ .Values.core.image.tag }}" imagePullPolicy: {{ .Values.core.image.pullPolicy }} env: - - name: CRYOSTAT_WEB_PORT + - name: QUARKUS_HTTP_HOST + value: localhost + - name: QUARKUS_HTTP_PORT value: "8181" - - name: CRYOSTAT_CONFIG_PATH - value: /opt/cryostat.d/conf.d - - name: CRYOSTAT_ARCHIVE_PATH - value: /opt/cryostat.d/recordings.d - - name: CRYOSTAT_TEMPLATE_PATH - value: /opt/cryostat.d/templates.d - - name: CRYOSTAT_CLIENTLIB_PATH - value: /opt/cryostat.d/clientlib.d - - name: CRYOSTAT_PROBE_TEMPLATE_PATH - value: /opt/cryostat.d/probes.d - - name: CRYOSTAT_EXT_WEB_PORT - value: "{{ if (or (and .Values.core.route.enabled .Values.core.route.tls.enabled) (and .Values.core.ingress.enabled .Values.core.ingress.tls) (.Values.core.sslProxied)) }}443{{ else }}80{{ end }}" - - name: CRYOSTAT_WEB_HOST - value: "{{ if .Values.core.ingress.enabled }}{{ with index .Values.core.ingress.hosts 0 }}{{ .host }}{{ end }}{{ end }}" - - name: CRYOSTAT_PLATFORM - value: io.cryostat.platform.internal.KubeApiPlatformStrategy - {{- if not .Values.minimal }} - - name: GRAFANA_DATASOURCE_URL - value: http://127.0.0.1:8080 - - name: GRAFANA_DASHBOARD_URL - value: "{{ if .Values.grafana.ingress.enabled }}http{{ if (or (.Values.grafana.ingress.tls) (.Values.grafana.sslProxied)) }}s{{ end }}://{{ with index .Values.grafana.ingress.hosts 0 }}{{ .host }}{{ end }}{{ end }}" - {{- end }} - - name: CRYOSTAT_DISABLE_SSL - value: "true" - - name: CRYOSTAT_DISABLE_JMX_AUTH - value: "true" - - name: CRYOSTAT_ALLOW_UNTRUSTED_SSL - value: "true" - - name: CRYOSTAT_ENABLE_JDP_BROADCAST - value: "false" - - name: CRYOSTAT_K8S_NAMESPACES - value: "{{ .Release.Namespace }}" - {{- if (or (and .Values.core.route.enabled .Values.core.route.tls.enabled) (and .Values.core.ingress.enabled .Values.core.ingress.tls) (.Values.core.sslProxied)) }} - - name: CRYOSTAT_SSL_PROXIED + - name: QUARKUS_HTTP_PROXY_PROXY_ADDRESS_FORWARDING + value: 'true' + - name: QUARKUS_HTTP_PROXY_ALLOW_X_FORWARDED + value: 'true' + - name: QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_HOST + value: 'true' + - name: QUARKUS_HTTP_PROXY_ENABLE_FORWARDED_PREFIX + value: 'true' + - name: QUARKUS_HIBERNATE_ORM_DATABASE_GENERATION + value: drop-and-create + - name: QUARKUS_DATASOURCE_USERNAME + value: cryostat3 + - name: QUARKUS_DATASOURCE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ printf "%s-db-connection-key" .Release.Name }} + key: CONNECTION_KEY + optional: false + - name: QUARKUS_DATASOURCE_JDBC_URL + value: jdbc:postgresql://localhost:5432/cryostat3 + - name: STORAGE_BUCKETS_ARCHIVES_NAME + value: archivedrecordings + - name: QUARKUS_S3_ENDPOINT_OVERRIDE + value: http://localhost:8333 + - name: QUARKUS_S3_PATH_STYLE_ACCESS value: "true" - {{- end }} - {{- if ((.Values.pvc).enabled) }} - - name: CRYOSTAT_JDBC_URL - value: jdbc:h2:file:/opt/cryostat.d/conf.d/h2;INIT=create domain if not exists jsonb as varchar - - name: CRYOSTAT_HBM2DDL - value: update - - name: CRYOSTAT_JDBC_DRIVER - value: org.h2.Driver - - name: CRYOSTAT_HIBERNATE_DIALECT - value: org.hibernate.dialect.H2Dialect - - name: CRYOSTAT_JDBC_USERNAME - value: {{ include "cryostat.fullname" . }} - - name: CRYOSTAT_JDBC_PASSWORD - value: {{ include "cryostat.fullname" . }} - {{- end }} - - name: CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD + - name: QUARKUS_S3_AWS_REGION + value: us-east-1 + - name: QUARKUS_S3_AWS_CREDENTIALS_TYPE + value: static + - name: QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID + value: cryostat + - name: AWS_ACCESS_KEY_ID + value: $(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID) + - name: QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY valueFrom: secretKeyRef: - name: {{ default (printf "%s-jmx-credentials-db" .Release.Name) .Values.core.databaseSecretName }} - key: CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD + name: {{ printf "%s-storage-secret-key" .Release.Name }} + key: SECRET_KEY optional: false - - name: CRYOSTAT_AUTH_MANAGER - {{- if (.Values.authentication).basicAuth.enabled }} - value: io.cryostat.net.BasicAuthManager - {{- else }} - value: io.cryostat.net.NoopAuthManager + - name: AWS_SECRET_ACCESS_KEY + value: $(QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY) + - name: GRAFANA_DATASOURCE_URL + value: http://localhost:8800 + - name: GRAFANA_DASHBOARD_URL + value: http://localhost:3000 + {{- if .Values.core.discovery.kubernetes.enabled }} + - name: CRYOSTAT_DISCOVERY_KUBERNETES_ENABLED + value: "true" + {{- with .Values.core.discovery.kubernetes }} + - name: CRYOSTAT_DISCOVERY_KUBERNETES_NAMESPACES + value: {{ include "cryostat.commaSepList" (list .namespaces $.Release.Namespace .installNamespaceDisabled) }} + - name: CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NAMES + value: {{ include "cryostat.commaSepList" (list .portNames "jfr-jmx" .builtInPortNamesDisabled) }} + - name: CRYOSTAT_DISCOVERY_KUBERNETES_PORT_NUMBERS + value: {{ include "cryostat.commaSepList" (list .portNumbers 9091 .builtInPortNumbersDisabled) }} + {{- end }} {{- end }} ports: - containerPort: 8181 @@ -116,39 +121,102 @@ spec: failureThreshold: 18 resources: {{- toYaml .Values.core.resources | nindent 12 }} + - name: {{ printf "%s-%s" .Chart.Name "db" }} + securityContext: + {{- toYaml (.Values.db).securityContext | nindent 12 }} + image: "{{ (.Values.db).image.repository }}:{{ (.Values.db).image.tag }}" + imagePullPolicy: {{ (.Values.db).image.pullPolicy }} + env: + - name: POSTGRESQL_USER + value: cryostat3 + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ printf "%s-db-connection-key" .Release.Name }} + key: CONNECTION_KEY + optional: false + - name: POSTGRESQL_DATABASE + value: cryostat3 + - name: PG_ENCRYPT_KEY + valueFrom: + secretKeyRef: + name: {{ default (printf "%s-db-encryption-key" .Release.Name) .Values.core.databaseSecretName }} + key: ENCRYPTION_KEY + optional: false + ports: + - containerPort: 5432 + protocol: TCP volumeMounts: - - mountPath: /opt/cryostat.d/conf.d + - mountPath: /var/lib/pgsql/data name: {{ .Chart.Name }} - subPath: config - - mountPath: /opt/cryostat.d/recordings.d - name: {{ .Chart.Name }} - subPath: flightrecordings - - mountPath: /opt/cryostat.d/templates.d - name: {{ .Chart.Name }} - subPath: templates - - mountPath: /opt/cryostat.d/clientlib.d - name: {{ .Chart.Name }} - subPath: clientlib - - mountPath: /opt/cryostat.d/probes.d + subPath: postgres + readinessProbe: + exec: + command: + - pg_isready + - -U + - cryostat3 + - -d + - cryostat3 + - name: {{ printf "%s-%s" .Chart.Name "storage" }} + securityContext: + {{- toYaml (.Values.storage).securityContext | nindent 12 }} + image: "{{ (.Values.storage).image.repository }}:{{ (.Values.storage).image.tag }}" + imagePullPolicy: {{ (.Values.storage).image.pullPolicy }} + env: + - name: CRYOSTAT_BUCKETS + value: archivedrecordings,archivedreports,eventtemplates,probes + - name: CRYOSTAT_ACCESS_KEY + value: cryostat + - name: CRYOSTAT_SECRET_KEY + valueFrom: + secretKeyRef: + name: {{ printf "%s-storage-secret-key" .Release.Name }} + key: SECRET_KEY + optional: false + - name: DATA_DIR + value: /data + - name: IP_BIND + value: 0.0.0.0 + ports: + - containerPort: 8333 + protocol: TCP + volumeMounts: + - mountPath: /data name: {{ .Chart.Name }} - subPath: probes - {{- if (.Values.authentication).basicAuth.enabled }} - - mountPath: /opt/cryostat.d/conf.d/cryostat-users.properties - name: basic-auth-properties - subPath: cryostat-users.properties - readOnly: true - {{- end }} - {{- if not .Values.minimal }} + subPath: seaweed + livenessProbe: + httpGet: + path: "/status" + port: 8333 + periodSeconds: 10 + failureThreshold: 2 + startupProbe: + httpGet: + path: "/status" + port: 8333 + periodSeconds: 10 + failureThreshold: 9 + resources: + {{- toYaml (.Values.storage).resources | nindent 12 }} + securityContext: + {{- toYaml (.Values.storage).securityContext | nindent 12 }} - name: {{ printf "%s-%s" .Chart.Name "grafana" }} securityContext: {{- toYaml .Values.grafana.securityContext | nindent 12 }} image: "{{ .Values.grafana.image.repository }}:{{ .Values.grafana.image.tag }}" imagePullPolicy: {{ .Values.grafana.image.pullPolicy }} env: - - name: JFR_DATASOURCE_URL - value: http://127.0.0.1:8080 - name: GF_AUTH_ANONYMOUS_ENABLED value: "true" + - name: GF_SERVER_DOMAIN + value: localhost + - name: GF_SERVER_ROOT_URL + value: http://localhost:4180/grafana/ + - name: GF_SERVER_SERVE_FROM_SUB_PATH + value: "true" + - name: JFR_DATASOURCE_URL + value: http://localhost:8800 ports: - containerPort: 3000 protocol: TCP @@ -165,19 +233,20 @@ spec: imagePullPolicy: {{ .Values.datasource.image.pullPolicy }} env: - name: LISTEN_HOST - value: 127.0.0.1 + value: localhost + - name: QUARKUS_HTTP_PORT + value: "8800" ports: - - containerPort: 8080 + - containerPort: 8800 protocol: TCP livenessProbe: exec: command: - curl - --fail - - http://127.0.0.1:8080 + - http://localhost:8800 resources: {{- toYaml .Values.datasource.resources | nindent 12 }} - {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} @@ -200,11 +269,17 @@ spec: - name: {{ .Chart.Name }} emptyDir: {} {{- end }} - {{- if (.Values.authentication).basicAuth.enabled }} - - name: basic-auth-properties + - name: alpha-config + configMap: + name: {{ .Release.Name }}-alpha-config + {{- if .Values.authentication.basicAuth.enabled }} + - name: {{ .Release.Name }}-htpasswd secret: + defaultMode: 0440 secretName: {{ .Values.authentication.basicAuth.secretName }} - items: - - key: {{ .Values.authentication.basicAuth.filename }} - path: cryostat-users.properties + {{- end }} + {{- if (.Values.authentication.openshift).enabled }} + - name: {{ .Release.Name }}-proxy-tls + secret: + secretName: {{ .Release.Name }}-proxy-tls {{- end }} diff --git a/charts/cryostat/templates/ingress.yaml b/charts/cryostat/templates/ingress.yaml index 40eb0bda..0a9535c0 100644 --- a/charts/cryostat/templates/ingress.yaml +++ b/charts/cryostat/templates/ingress.yaml @@ -68,6 +68,3 @@ spec: {{- if .Values.core.ingress.enabled }} {{- include "createIngress" (list $fullName .Values.core.service.httpPort $ .Values.core)}} {{- end }} -{{- if and (not .Values.minimal) .Values.grafana.ingress.enabled }} -{{- include "createIngress" (list (printf "%s-%s" $fullName "grafana") .Values.grafana.service.port $ .Values.grafana)}} -{{- end }} diff --git a/charts/cryostat/templates/oauth2Proxy.tpl b/charts/cryostat/templates/oauth2Proxy.tpl new file mode 100644 index 00000000..447bb9fb --- /dev/null +++ b/charts/cryostat/templates/oauth2Proxy.tpl @@ -0,0 +1,40 @@ +{{- define "oauth2Proxy" }} +- name: {{ printf "%s-%s" .Chart.Name "authproxy" }} + securityContext: + {{- toYaml (.Values.oauth2Proxy).securityContext | nindent 12 }} + image: "{{ (.Values.oauth2Proxy).image.repository }}:{{ (.Values.oauth2Proxy).image.tag }}" + args: + - "--alpha-config=/etc/oauth2_proxy/alpha_config/alpha_config.yaml" + imagePullPolicy: {{ (.Values.oauth2Proxy).image.pullPolicy }} + env: + - name: OAUTH2_PROXY_REDIRECT_URL + value: "http://localhost:4180/oauth2/callback" + - name: OAUTH2_PROXY_COOKIE_SECRET + value: {{ include "cryostat.cookieSecret" . }} + - name: OAUTH2_PROXY_EMAIL_DOMAINS + value: "*" + {{- if .Values.authentication.basicAuth.enabled }} + - name: OAUTH2_PROXY_HTPASSWD_USER_GROUP + value: write + - name: OAUTH2_PROXY_HTPASSWD_FILE + value: /etc/oauth2_proxy/basicauth/{{ .Values.authentication.basicAuth.filename }} + {{- end }} + {{- if not .Values.authentication.basicAuth.enabled }} + - name: OAUTH2_PROXY_SKIP_AUTH_ROUTES + value: ".*" + {{- else }} + - name: OAUTH2_PROXY_SKIP_AUTH_ROUTES + value: "^/health(/liveness)?$" + {{- end }} + ports: + - containerPort: 4180 + protocol: TCP + volumeMounts: + - name: alpha-config + mountPath: /etc/oauth2_proxy/alpha_config + {{- if .Values.authentication.basicAuth.enabled }} + - name: {{ .Release.Name }}-htpasswd + mountPath: /etc/oauth2_proxy/basicauth + readOnly: true + {{- end }} +{{- end}} diff --git a/charts/cryostat/templates/openshiftOauthProxy.tpl b/charts/cryostat/templates/openshiftOauthProxy.tpl new file mode 100644 index 00000000..0c045cb5 --- /dev/null +++ b/charts/cryostat/templates/openshiftOauthProxy.tpl @@ -0,0 +1,42 @@ +{{- define "openshiftOauthProxy" }} +- name: {{ printf "%s-%s" .Chart.Name "authproxy" }} + securityContext: + {{- toYaml .Values.openshiftOauthProxy.securityContext | nindent 12 }} + image: "{{ .Values.openshiftOauthProxy.image.repository }}:{{ .Values.openshiftOauthProxy.image.tag }}" + args: + - --skip-provider-button={{ not .Values.authentication.basicAuth.enabled }} + - --upstream=http://localhost:8181/ + - --upstream=http://localhost:3000/grafana/ + - --upstream=http://localhost:8333/storage/ + - --cookie-secret={{ include "cryostat.cookieSecret" . }} + - --openshift-service-account={{ include "cryostat.serviceAccountName" . }} + - --proxy-websockets=true + - --http-address=0.0.0.0:4180 + - --https-address=:8443 + - --tls-cert=/etc/tls/private/tls.crt + - --tls-key=/etc/tls/private/tls.key + - --proxy-prefix=/oauth2 + {{- if .Values.openshiftOauthProxy.accessReview.enabled }} + - --openshift-sar=[{{ tpl ( omit .Values.openshiftOauthProxy.accessReview "enabled" | toJson ) . }}] + - --openshift-delegate-urls={"/":{{ tpl ( omit .Values.openshiftOauthProxy.accessReview "enabled" | toJson ) . }}} + {{- end }} + - --bypass-auth-for=^/health(/liveness)?$ + {{- if .Values.authentication.basicAuth.enabled }} + - --htpasswd-file=/etc/openshift_oauth_proxy/basicauth/{{ .Values.authentication.basicAuth.filename }} + {{- end }} + imagePullPolicy: {{ .Values.openshiftOauthProxy.image.pullPolicy }} + ports: + - containerPort: 4180 + protocol: TCP + volumeMounts: + {{- if .Values.authentication.basicAuth.enabled }} + - name: {{ .Release.Name }}-htpasswd + mountPath: /etc/openshift_oauth_proxy/basicauth + readOnly: true + {{- end }} + - name: {{ .Release.Name }}-proxy-tls + mountPath: /etc/tls/private + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File +{{- end}} diff --git a/charts/cryostat/templates/role.yaml b/charts/cryostat/templates/role.yaml index b47c0444..0945ae97 100644 --- a/charts/cryostat/templates/role.yaml +++ b/charts/cryostat/templates/role.yaml @@ -1,8 +1,12 @@ -{{- if .Values.rbac.create -}} +{{- define "createRole" -}} +{{- $ns := index . 0 -}} +{{- with index . 1 -}} +--- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ include "cryostat.fullname" . }} + namespace: {{ $ns }} labels: {{- include "cryostat.labels" . | nindent 4 }} rules: @@ -36,4 +40,22 @@ rules: - deploymentconfigs verbs: - get -{{- end }} +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - get + - list +{{- end -}} +{{- end -}} + +{{- if and .Values.rbac.create .Values.core.discovery.kubernetes.enabled -}} +{{- $watchNs := compact (default list .Values.core.discovery.kubernetes.namespaces) | uniq -}} +{{- if and (not $watchNs) (not .Values.core.discovery.kubernetes.installNamespaceDisabled) -}} +{{- $watchNs = list .Release.Namespace -}} +{{- end -}} +{{- range $ns := $watchNs }} +{{ include "createRole" (list $ns $) }} +{{- end -}} +{{- end -}} diff --git a/charts/cryostat/templates/rolebinding.yaml b/charts/cryostat/templates/rolebinding.yaml index 22278c28..9354e7b6 100644 --- a/charts/cryostat/templates/rolebinding.yaml +++ b/charts/cryostat/templates/rolebinding.yaml @@ -1,8 +1,12 @@ -{{- if .Values.rbac.create -}} +{{- define "createRolebinding" -}} +{{- $ns := index . 0 -}} +{{- with index . 1 -}} +--- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ include "cryostat.fullname" . }} + namespace: {{ $ns }} labels: {{- include "cryostat.labels" . | nindent 4 }} roleRef: @@ -13,4 +17,15 @@ subjects: - kind: ServiceAccount name: {{ include "cryostat.serviceAccountName" . }} namespace: {{ .Release.Namespace }} -{{- end }} +{{- end -}} +{{- end -}} + +{{- if and .Values.rbac.create .Values.core.discovery.kubernetes.enabled -}} +{{- $watchNs := compact (default list .Values.core.discovery.kubernetes.namespaces) | uniq -}} +{{- if and (not $watchNs) (not .Values.core.discovery.kubernetes.installNamespaceDisabled) -}} +{{- $watchNs = list .Release.Namespace -}} +{{- end -}} +{{- range $ns := $watchNs }} +{{ include "createRolebinding" (list $ns $) }} +{{- end -}} +{{- end -}} diff --git a/charts/cryostat/templates/route.yaml b/charts/cryostat/templates/route.yaml index aa4a389c..dcb05f92 100644 --- a/charts/cryostat/templates/route.yaml +++ b/charts/cryostat/templates/route.yaml @@ -46,8 +46,5 @@ spec: {{- $fullName := include "cryostat.fullname" . -}} {{- if .Values.core.route.enabled }} -{{- include "createRoute" (list $fullName 8181 $ .Values.core)}} -{{- end }} -{{- if and (not .Values.minimal) .Values.grafana.route.enabled }} -{{- include "createRoute" (list (printf "%s-%s" $fullName "grafana") 3000 $ .Values.grafana)}} +{{- include "createRoute" (list $fullName 4180 $ .Values.core)}} {{- end }} diff --git a/charts/cryostat/templates/secret.yaml b/charts/cryostat/templates/secret.yaml deleted file mode 100644 index 5fc98aa9..00000000 --- a/charts/cryostat/templates/secret.yaml +++ /dev/null @@ -1,9 +0,0 @@ -{{- if empty .Values.core.databaseSecretName -}} -apiVersion: v1 -kind: Secret -metadata: - name: {{ .Release.Name }}-jmx-credentials-db -type: Opaque -data: - CRYOSTAT_JMX_CREDENTIALS_DB_PASSWORD: {{ include "cryostat.databasePassword" . }} -{{- end -}} diff --git a/charts/cryostat/templates/service.yaml b/charts/cryostat/templates/service.yaml index 8bbc9eb2..bfadcf62 100644 --- a/charts/cryostat/templates/service.yaml +++ b/charts/cryostat/templates/service.yaml @@ -6,34 +6,20 @@ metadata: name: {{ $fullName }} labels: {{- include "cryostat.labels" $ | nindent 4 }} + {{- if (.Values.authentication.openshift).enabled }} + annotations: + service.alpha.openshift.io/serving-cert-secret-name: {{ .Release.Name }}-proxy-tls + {{- end }} spec: type: {{ .Values.core.service.type }} ports: - port: {{ .Values.core.service.httpPort }} - targetPort: 8181 + targetPort: 4180 protocol: TCP name: cryostat-http - - port: {{ .Values.core.service.jmxPort }} - targetPort: 9091 + - port: 443 + targetPort: 8443 protocol: TCP - name: jfr-jmx + name: cryostat-https selector: {{- include "cryostat.selectorLabels" $ | nindent 4 }} ---- -{{- if not .Values.minimal }} -apiVersion: v1 -kind: Service -metadata: - name: {{ printf "%s-%s" $fullName "grafana" }} - labels: - {{- include "cryostat.labels" $ | nindent 4 }} -spec: - type: {{ .Values.grafana.service.type }} - ports: - - port: {{ .Values.grafana.service.port }} - targetPort: 3000 - protocol: TCP - name: grafana-http - selector: - {{- include "cryostat.selectorLabels" $ | nindent 4 }} -{{- end -}} diff --git a/charts/cryostat/templates/serviceaccount.yaml b/charts/cryostat/templates/serviceaccount.yaml index 74ae9986..e6da50e6 100644 --- a/charts/cryostat/templates/serviceaccount.yaml +++ b/charts/cryostat/templates/serviceaccount.yaml @@ -1,3 +1,8 @@ +{{- if (.Values.authentication.openshift).enabled -}} +{{- $fullName := include "cryostat.fullname" . -}} +{{- $redirectAnnotations := dict "serviceaccounts.openshift.io/oauth-redirectreference.primary" (printf "{\"kind\":\"OAuthRedirectReference\",\"apiVersion\":\"v1\",\"reference\":{\"kind\":\"Route\",\"name\":\"%s\"}}" $fullName) -}} +{{- $_ := merge .Values.serviceAccount.annotations $redirectAnnotations -}} +{{- end -}} {{- if .Values.serviceAccount.create -}} apiVersion: v1 kind: ServiceAccount diff --git a/charts/cryostat/templates/storage_access_key_secret.yaml b/charts/cryostat/templates/storage_access_key_secret.yaml new file mode 100644 index 00000000..e06e723e --- /dev/null +++ b/charts/cryostat/templates/storage_access_key_secret.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-storage-secret-key +type: Opaque +data: + SECRET_KEY: {{ include "cryostat.objectStorageSecretKey" . }} diff --git a/charts/cryostat/templates/tests/test-connection.yaml b/charts/cryostat/templates/tests/test-core-connection.yaml similarity index 54% rename from charts/cryostat/templates/tests/test-connection.yaml rename to charts/cryostat/templates/tests/test-core-connection.yaml index 0e3b3037..cfb91744 100644 --- a/charts/cryostat/templates/tests/test-connection.yaml +++ b/charts/cryostat/templates/tests/test-core-connection.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Pod metadata: - name: "{{ include "cryostat.fullname" . }}-test-connection" + name: "{{ include "cryostat.fullname" . }}-test-core-connection" labels: {{- include "cryostat.labels" . | nindent 4 }} annotations: @@ -12,13 +12,15 @@ spec: image: registry.access.redhat.com/ubi8/ubi:latest command: - '/bin/bash' - - '-ec' + - '-exc' - > dnf install --disableplugin=subscription-manager -yq jq; curl -sSf --retry 10 --retry-connrefused -o /tmp/out.json http://{{ include "cryostat.fullname" . }}:{{ .Values.core.service.httpPort }}/health; cat /tmp/out.json; - jq -e '{{ printf "(.cryostatVersion | test(\"^v%s\")) and .datasourceAvailable == %t" (.Chart.AppVersion | squote) (not .Values.minimal) }}' /tmp/out.json; - {{- if not .Values.minimal }} - curl -sSf --retry 10 --retry-connrefused http://{{ include "cryostat.fullname" . }}-grafana:{{ .Values.grafana.service.port }}/api/health + {{- if hasSuffix "-dev" .Chart.AppVersion }} + jq -e '{{ printf "(.cryostatVersion | test(\"^v%s-snapshot$\"))" (.Chart.AppVersion | trimSuffix "-dev" | squote) }}' /tmp/out.json; + {{- else }} + jq -e '{{ printf "(.cryostatVersion | test(\"^v%s\"))" (.Chart.AppVersion | squote) }}' /tmp/out.json; {{- end }} + jq -e '.datasourceAvailable' /tmp/out.json restartPolicy: Never diff --git a/charts/cryostat/templates/tests/test-grafana-connection.yaml b/charts/cryostat/templates/tests/test-grafana-connection.yaml new file mode 100644 index 00000000..d68c007e --- /dev/null +++ b/charts/cryostat/templates/tests/test-grafana-connection.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "cryostat.fullname" . }}-test-grafana-connection" + labels: + {{- include "cryostat.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: curl + image: registry.access.redhat.com/ubi8/ubi:latest + command: + - '/bin/bash' + - '-exc' + - curl -sSf --retry 10 --retry-connrefused http://{{ include "cryostat.fullname" . }}:{{ .Values.core.service.httpPort }}/grafana/api/health + restartPolicy: Never diff --git a/charts/cryostat/templates/tests/test-storage-connection.yaml b/charts/cryostat/templates/tests/test-storage-connection.yaml new file mode 100644 index 00000000..d7435975 --- /dev/null +++ b/charts/cryostat/templates/tests/test-storage-connection.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "cryostat.fullname" . }}-test-storage-connection" + labels: + {{- include "cryostat.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: curl + image: registry.access.redhat.com/ubi8/ubi:latest + command: + - '/bin/bash' + - '-exc' + - curl -sSf --retry 10 --retry-connrefused http://{{ include "cryostat.fullname" . }}:{{ .Values.core.service.httpPort }}/storage/ + restartPolicy: Never diff --git a/charts/cryostat/values.schema.json b/charts/cryostat/values.schema.json index 7dfa3baa..d0590ed0 100644 --- a/charts/cryostat/values.schema.json +++ b/charts/cryostat/values.schema.json @@ -21,7 +21,7 @@ "tag": { "type": "string", "description": "Tag for the main Cryostat container image", - "default": "latest" + "default": "3.0.0-snapshot" } } }, @@ -37,11 +37,6 @@ "type": "number", "description": "Port number to expose on the Service for Cryostat's HTTP server", "default": 8181 - }, - "jmxPort": { - "type": "number", - "description": "Port number to expose on the Service for remote JMX connections to Cryostat", - "default": 9091 } } }, @@ -185,153 +180,170 @@ "type": "string", "description": "Name of the secret to extract password for credentials database.", "default": "" + }, + "discovery": { + "type": "object", + "properties": { + "kubernetes": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Enables Kubernetes API discovery mechanism", + "default": true + }, + "installNamespaceDisabled": { + "type": "boolean", + "description": "When false and `namespaces` is empty, the Cryostat application will default to discovery targets in the install namespace (i.e. `{{ .Release.Namespace }}`)", + "default": false + }, + "namespaces": { + "type": "array", + "description": "List of namespaces whose workloads the Cryostat application should be permitted to access and profile", + "default": [], + "items": {} + }, + "builtInPortNamesDisabled": { + "type": "boolean", + "description": "When false and `portNames` is empty, the Cryostat application will use the default port name `jfr-jmx` to look for JMX connectable targets.", + "default": false + }, + "portNames": { + "type": "array", + "description": "List of port names that the Cryostat application should look for in order to consider a target as JMX connectable", + "default": [], + "items": {} + }, + "builtInPortNumbersDisabled": { + "type": "boolean", + "description": "When false and `portNumbers` is empty, the Cryostat application will use the default port number `9091` to look for JMX connectable targets.", + "default": false + }, + "portNumbers": { + "type": "array", + "description": "List of port numbers that the Cryostat application should look for in order to consider a target as JMX connectable", + "default": [], + "items": {} + } + } + } + } } } }, - "grafana": { + "db": { "type": "object", "properties": { + "securityContext": { + "type": "object", + "properties": { + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "", + "default": false + } + } + }, "image": { "type": "object", "properties": { "repository": { "type": "string", - "description": "Repository for the Grafana container image", - "default": "quay.io/cryostat/cryostat-grafana-dashboard" + "description": "Repository for the database container image", + "default": "quay.io/cryostat/cryostat-db" }, "pullPolicy": { "type": "string", - "description": "Image pull policy for the Grafana container image", + "description": "Image pull policy for the database container image", "default": "Always" }, "tag": { "type": "string", - "description": "Tag for the Grafana container image", + "description": "Tag for the database container image", "default": "latest" } } }, - "service": { + "resources": { "type": "object", - "properties": { - "type": { - "type": "string", - "description": "Type of Service to create for Grafana", - "default": "ClusterIP" - }, - "port": { - "type": "number", - "description": "Port number to expose on the Service for Grafana's HTTP server", - "default": 3000 - } - } - }, - "ingress": { + "description": "Resource requests/limits for the database container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)", + "default": {} + } + } + }, + "storage": { + "type": "object", + "properties": { + "securityContext": { "type": "object", "properties": { - "hosts": { - "type": "array", - "description": "", - "items": { - "type": "object", - "properties": { - "host": { - "type": "string", - "description": "" - }, - "paths": { - "type": "array", - "description": "", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string", - "description": "" - }, - "pathType": { - "type": "string", - "description": "" - } - } - } + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "", + "default": [ + "ALL" + ], + "items": { + "type": "string" } } } }, - "enabled": { + "allowPrivilegeEscalation": { "type": "boolean", - "description": "Whether to create an Ingress object for the Grafana service", + "description": "", "default": false - }, - "className": { - "type": "string", - "description": "Ingress class name for the Grafana Ingress", - "default": "" - }, - "tls": { - "type": "array", - "description": "TLS configuration for the Grafana Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec)", - "default": [], - "items": {} } } }, - "sslProxied": { - "type": "boolean", - "description": "Enables SSL Proxied Environment Variables, useful when you are offloading SSL/TLS at External Loadbalancer instead of Ingress", - "default": false - }, - "route": { + "image": { "type": "object", "properties": { - "enabled": { - "type": "boolean", - "description": "Whether to create a Route object for the Grafana service. Available only on OpenShift", - "default": false + "repository": { + "type": "string", + "description": "Repository for the storage container image", + "default": "quay.io/cryostat/cryostat-storage" }, - "tls": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "description": "Whether to secure the Grafana Route with TLS. See: [TLSConfig](https://docs.openshift.com/container-platform/4.10/rest_api/network_apis/route-route-openshift-io-v1.html#spec-tls)", - "default": true - }, - "termination": { - "type": "string", - "description": "Type of TLS termination to use for the Grafana Route. One of: `edge`, `passthrough`, `reencrypt`", - "default": "edge" - }, - "insecureEdgeTerminationPolicy": { - "type": "string", - "description": "Specify how to handle insecure traffic for the Grafana Route. One of: `Allow`, `Disable`, `Redirect`", - "default": "Redirect" - }, - "key": { - "type": "string", - "description": "Custom private key to use when securing the Grafana Route", - "default": "" - }, - "certificate": { - "type": "string", - "description": "Custom certificate to use when securing the Grafana Route", - "default": "" - }, - "caCertificate": { - "type": "string", - "description": "Custom CA certificate to use, if needed to complete the certificate chain, when securing the Grafana Route", - "default": "" - }, - "destinationCACertificate": { - "type": "string", - "description": "Provides the contents of the CA certificate of the final destination when using reencrypt termination for the Grafana Route", - "default": "" - } - } + "pullPolicy": { + "type": "string", + "description": "Image pull policy for the storage container image", + "default": "Always" + }, + "tag": { + "type": "string", + "description": "Tag for the storage container image", + "default": "latest" } } }, + "resources": { + "type": "object", + "description": "Resource requests/limits for the storage container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)", + "default": {} + } + } + }, + "grafana": { + "type": "object", + "properties": { "securityContext": { "type": "object", "properties": { @@ -357,6 +369,41 @@ } } }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "description": "Repository for the Grafana container image", + "default": "quay.io/cryostat/cryostat-grafana-dashboard" + }, + "pullPolicy": { + "type": "string", + "description": "Image pull policy for the Grafana container image", + "default": "Always" + }, + "tag": { + "type": "string", + "description": "Tag for the Grafana container image", + "default": "latest" + } + } + }, + "service": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "Type of Service to create for Grafana", + "default": "ClusterIP" + }, + "port": { + "type": "number", + "description": "Port number to expose on the Service for Grafana's HTTP server", + "default": 3000 + } + } + }, "resources": { "type": "object", "description": "Resource requests/limits for the Grafana container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources)", @@ -419,9 +466,79 @@ } } }, + "oauth2Proxy": { + "type": "object", + "properties": { + "securityContext": { + "type": "object", + "properties": { + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "", + "default": false + } + } + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "description": "Repository for the OAuth2 Proxy container image", + "default": "quay.io/oauth2-proxy/oauth2-proxy" + }, + "pullPolicy": { + "type": "string", + "description": "Image pull policy for the OAuth2 Proxy container image", + "default": "Always" + }, + "tag": { + "type": "string", + "description": "Tag for the OAuth2 Proxy container image", + "default": "latest" + } + } + } + } + }, "authentication": { "type": "object", "properties": { + "openshift": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether the OAuth Proxy deployed for securing Cryostat's Pods should be one that integrates with OpenShift-specific features, or a generic one.", + "default": false + }, + "clusterRole": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the ClusterRole to bind for the OpenShift OAuth Proxy", + "default": "system:auth-delegator" + } + } + } + } + }, "basicAuth": { "type": "object", "properties": { @@ -437,7 +554,102 @@ }, "filename": { "type": "string", - "description": "Key within Secret containing the properties file. The properties file should contain one user per line, with the syntax \"user=passHex\", where \"user\" is the username and \"passHex\" is the SHA-256 hash of the desired password **(Required if basicAuth is enabled)**", + "description": "Key within Secret containing the `htpasswd` file. The file should contain one user definition entry per line, with the syntax \"user:passHash\", where \"user\" is the username and \"passHash\" is the `bcrypt` hash of the desired password. Such an entry can be generated with ex. `htpasswd -nbB username password` **(Required if basicAuth is enabled)**", + "default": "" + } + } + } + } + }, + "openshiftOauthProxy": { + "type": "object", + "properties": { + "securityContext": { + "type": "object", + "properties": { + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "description": "", + "default": [ + "ALL" + ], + "items": { + "type": "string" + } + } + } + }, + "allowPrivilegeEscalation": { + "type": "boolean", + "description": "", + "default": false + } + } + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "description": "Repository for the OpenShift OAuth Proxy container image", + "default": "quay.io/openshift/origin-oauth-proxy" + }, + "pullPolicy": { + "type": "string", + "description": "Image pull policy for the OpenShift OAuth Proxy container image", + "default": "Always" + }, + "tag": { + "type": "string", + "description": "Tag for the OpenShift OAuth Proxy container image", + "default": "latest" + } + } + }, + "accessReview": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether the SubjectAccessReview/TokenAccessReview role checks for users and clients are enabled. If this is disabled then the proxy will only check that the user has valid credentials or holds a valid token.", + "default": true + }, + "group": { + "type": "string", + "description": "The OpenShift resource group that the SubjectAccessReview/TokenAccessReview will be performed for. See https://github.com/openshift/oauth-proxy/?tab=readme-ov-file#delegate-authentication-and-authorization-to-openshift-for-infrastructure", + "default": "" + }, + "resource": { + "type": "string", + "description": "The OpenShift resource that the SubjectAccessReview/TokenAccessReview will be performed for.", + "default": "pods" + }, + "subresource": { + "type": "string", + "description": "The OpenShift resource that the SubjectAccessReview/TokenAccessReview will be performed for.", + "default": "exec" + }, + "name": { + "type": "string", + "description": "The OpenShift resource name that the SubjectAccessReview/TokenAccessReview will be performed for.", + "default": "" + }, + "namespace": { + "type": "string", + "description": "The OpenShift namespace that the SubjectAccessReview/TokenAccessReview will be performed for.", + "default": "{{ .Release.Namespace }}" + }, + "verb": { + "type": "string", + "description": "The OpenShift resource name that the SubjectAccessReview/TokenAccessReview will be performed for.", + "default": "create" + }, + "version": { + "type": "string", + "description": "The OpenShift resource version that the SubjectAccessReview/TokenAccessReview will be performed for.", "default": "" } } @@ -464,11 +676,6 @@ } } }, - "minimal": { - "type": "boolean", - "description": "Specify whether to deploy a Cryostat instance with no Grafana Dashboard or JFR Data Source", - "default": false - }, "imagePullSecrets": { "type": "array", "description": "Image pull secrets to be used for the Cryostat deployment", diff --git a/charts/cryostat/values.yaml b/charts/cryostat/values.yaml index b8c15165..9efb1eb3 100644 --- a/charts/cryostat/values.yaml +++ b/charts/cryostat/values.yaml @@ -7,14 +7,12 @@ core: ## @param core.image.pullPolicy Image pull policy for the main Cryostat container image pullPolicy: Always ## @param core.image.tag Tag for the main Cryostat container image - tag: "latest" + tag: "3.0.0-snapshot" service: ## @param core.service.type Type of Service to create for the Cryostat application type: ClusterIP ## @param core.service.httpPort Port number to expose on the Service for Cryostat's HTTP server httpPort: 8181 - ## @param core.service.jmxPort Port number to expose on the Service for remote JMX connections to Cryostat - jmxPort: 9091 ## @param core.sslProxied Enables SSL Proxied Environment Variables, useful when you are offloading SSL/TLS at External Loadbalancer instead of Ingress sslProxied: false ingress: @@ -59,9 +57,68 @@ core: ## @skip core.securityContext.capabilities capabilities: drop: - - ALL + - ALL ## @param core.databaseSecretName Name of the secret to extract password for credentials database. databaseSecretName: "" + ## @extra core.discovery Configuration options to the Cryostat application's target discovery mechanisms + discovery: + kubernetes: + ## @param core.discovery.kubernetes.enabled Enables Kubernetes API discovery mechanism + enabled: true + ## @param core.discovery.kubernetes.installNamespaceDisabled When false and `namespaces` is empty, the Cryostat application will default to discovery targets in the install namespace (i.e. `{{ .Release.Namespace }}`) + installNamespaceDisabled: false + ## @param core.discovery.kubernetes.namespaces [array] List of namespaces whose workloads the Cryostat application should be permitted to access and profile + namespaces: [] + ## @param core.discovery.kubernetes.builtInPortNamesDisabled When false and `portNames` is empty, the Cryostat application will use the default port name `jfr-jmx` to look for JMX connectable targets. + builtInPortNamesDisabled: false + ## @param core.discovery.kubernetes.portNames [array] List of port names that the Cryostat application should look for in order to consider a target as JMX connectable + portNames: [] + ## @param core.discovery.kubernetes.builtInPortNumbersDisabled When false and `portNumbers` is empty, the Cryostat application will use the default port number `9091` to look for JMX connectable targets. + builtInPortNumbersDisabled: false + ## @param core.discovery.kubernetes.portNumbers [array] List of port numbers that the Cryostat application should look for in order to consider a target as JMX connectable + portNumbers: [] + +## @section Database Container +## @extra db Configuration for Cryostat's database +db: + image: + ## @param db.image.repository Repository for the database container image + repository: "quay.io/cryostat/cryostat-db" + ## @param db.image.pullPolicy Image pull policy for the database container image + pullPolicy: Always + ## @param db.image.tag Tag for the database container image + tag: "latest" + ## @param db.resources Resource requests/limits for the database container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) + resources: {} + ## @param db.securityContext [object] Security Context for the database container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) + securityContext: + ## @skip db.securityContext.allowPrivilegeEscalation + allowPrivilegeEscalation: false + ## @skip db.securityContext.capabilities + capabilities: + drop: + - ALL + +## @section Storage Container +## @extra storage Configuration for Cryostat's object storage provider +storage: + image: + ## @param storage.image.repository Repository for the storage container image + repository: "quay.io/cryostat/cryostat-storage" + ## @param storage.image.pullPolicy Image pull policy for the storage container image + pullPolicy: Always + ## @param storage.image.tag Tag for the storage container image + tag: "latest" + ## @param storage.resources Resource requests/limits for the storage container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) + resources: {} + ## @param storage.securityContext [object] Security Context for the storage container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) + securityContext: + ## @skip storage.securityContext.allowPrivilegeEscalation + allowPrivilegeEscalation: false + ## @skip storage.securityContext.capabilities + capabilities: + drop: + - ALL ## @section Grafana Container ## @extra grafana Configuration for the customized Grafana instance for Cryostat @@ -78,41 +135,6 @@ grafana: type: ClusterIP ## @param grafana.service.port Port number to expose on the Service for Grafana's HTTP server port: 3000 - ## @param grafana.sslProxied Enables SSL Proxied Environment Variables, useful when you are offloading SSL/TLS at External Loadbalancer instead of Ingress - sslProxied: false - ingress: - ## @param grafana.ingress.enabled Whether to create an Ingress object for the Grafana service - enabled: false - ## @param grafana.ingress.className Ingress class name for the Grafana Ingress - className: "" - ## @param grafana.ingress.annotations [object] Annotations to apply to the Grafana Ingress - annotations: {} - ## @param grafana.ingress.hosts [array] Hosts to create rules for in the Grafana Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) - hosts: - - host: cryostat-grafana.local - paths: - - path: / - pathType: ImplementationSpecific - ## @param grafana.ingress.tls [array] TLS configuration for the Grafana Ingress. See: [IngressSpec](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) - tls: [] - route: - ## @param grafana.route.enabled Whether to create a Route object for the Grafana service. Available only on OpenShift - enabled: false - tls: - ## @param grafana.route.tls.enabled Whether to secure the Grafana Route with TLS. See: [TLSConfig](https://docs.openshift.com/container-platform/4.10/rest_api/network_apis/route-route-openshift-io-v1.html#spec-tls) - enabled: true - ## @param grafana.route.tls.termination Type of TLS termination to use for the Grafana Route. One of: `edge`, `passthrough`, `reencrypt` - termination: edge - ## @param grafana.route.tls.insecureEdgeTerminationPolicy Specify how to handle insecure traffic for the Grafana Route. One of: `Allow`, `Disable`, `Redirect` - insecureEdgeTerminationPolicy: Redirect - ## @param grafana.route.tls.key Custom private key to use when securing the Grafana Route - key: "" - ## @param grafana.route.tls.certificate Custom certificate to use when securing the Grafana Route - caCertificate: "" - ## @param grafana.route.tls.caCertificate Custom CA certificate to use, if needed to complete the certificate chain, when securing the Grafana Route - certificate: "" - ## @param grafana.route.tls.destinationCACertificate Provides the contents of the CA certificate of the final destination when using reencrypt termination for the Grafana Route - destinationCACertificate: "" ## @param grafana.resources Resource requests/limits for the Grafana container. See: [ResourceRequirements](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) resources: {} ## @param grafana.securityContext [object] Security Context for the Grafana container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) @@ -122,7 +144,7 @@ grafana: ## @skip grafana.securityContext.capabilities capabilities: drop: - - ALL + - ALL ## @section JFR Data Source Container ## @extra datasource Configuration for the JFR Data Source component, which translates recording events into a format consumable by Grafana @@ -143,23 +165,81 @@ datasource: ## @skip datasource.securityContext.capabilities capabilities: drop: - - ALL + - ALL ## @section Authentication authentication: + openshift: + ## @param authentication.openshift.enabled Whether the OAuth Proxy deployed for securing Cryostat's Pods should be one that integrates with OpenShift-specific features, or a generic one. + enabled: false + clusterRole: + ## @param authentication.openshift.clusterRole.name The name of the ClusterRole to bind for the OpenShift OAuth Proxy + name: system:auth-delegator basicAuth: ## @param authentication.basicAuth.enabled Whether Cryostat should use basic authentication for users. When false, Cryostat will not perform any form of authentication enabled: false ## @param authentication.basicAuth.secretName Name of the Secret that contains the credentials within Cryostat's namespace **(Required if basicAuth is enabled)** secretName: "" - ## @param authentication.basicAuth.filename Key within Secret containing the properties file. The properties file should contain one user per line, with the syntax "user=passHex", where "user" is the username and "passHex" is the SHA-256 hash of the desired password **(Required if basicAuth is enabled)** + ## @param authentication.basicAuth.filename Key within Secret containing the `htpasswd` file. The file should contain one user definition entry per line, with the syntax "user:passHash", where "user" is the username and "passHash" is the `bcrypt` hash of the desired password. Such an entry can be generated with ex. `htpasswd -nbB username password` **(Required if basicAuth is enabled)** filename: "" -## @section Other Parameters +## @section OAuth2 Proxy + +oauth2Proxy: + image: + ## @param oauth2Proxy.image.repository Repository for the OAuth2 Proxy container image + repository: "quay.io/oauth2-proxy/oauth2-proxy" + ## @param oauth2Proxy.image.pullPolicy Image pull policy for the OAuth2 Proxy container image + pullPolicy: Always + ## @param oauth2Proxy.image.tag Tag for the OAuth2 Proxy container image + tag: "latest" + ## @param oauth2Proxy.securityContext [object] Security Context for the OAuth2 Proxy container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1). If the chart is installed in default namespaces (e.g. default), `securityContext.runAsUser` must be set if the proxy image does not specify a numeric non-root user. This is due to OpenShift Security Context Constraints are not applied in default namespaces. See [Understanding and Managing Pod Security Admission](https://docs.openshift.com/container-platform/4.15/authentication/understanding-and-managing-pod-security-admission.html#psa-privileged-namespaces_understanding-and-managing-pod-security-admission). + securityContext: + ## @skip oauth2Proxy.securityContext.allowPrivilegeEscalation + allowPrivilegeEscalation: false + ## @skip oauth2Proxy.securityContext.capabilities + capabilities: + drop: + - ALL + +## @section OpenShift OAuth Proxy -## @param minimal Specify whether to deploy a Cryostat instance with no Grafana Dashboard or JFR Data Source -minimal: false +openshiftOauthProxy: + image: + ## @param openshiftOauthProxy.image.repository Repository for the OpenShift OAuth Proxy container image + repository: "quay.io/openshift/origin-oauth-proxy" + ## @param openshiftOauthProxy.image.pullPolicy Image pull policy for the OpenShift OAuth Proxy container image + pullPolicy: Always + ## @param openshiftOauthProxy.image.tag Tag for the OpenShift OAuth Proxy container image + tag: "latest" + accessReview: + ## @param openshiftOauthProxy.accessReview.enabled Whether the SubjectAccessReview/TokenAccessReview role checks for users and clients are enabled. If this is disabled then the proxy will only check that the user has valid credentials or holds a valid token. + enabled: true + ## @param openshiftOauthProxy.accessReview.group The OpenShift resource group that the SubjectAccessReview/TokenAccessReview will be performed for. See https://github.com/openshift/oauth-proxy/?tab=readme-ov-file#delegate-authentication-and-authorization-to-openshift-for-infrastructure + group: "" + ## @param openshiftOauthProxy.accessReview.resource The OpenShift resource that the SubjectAccessReview/TokenAccessReview will be performed for. + resource: "pods" + ## @param openshiftOauthProxy.accessReview.subresource The OpenShift resource that the SubjectAccessReview/TokenAccessReview will be performed for. + subresource: "exec" + ## @param openshiftOauthProxy.accessReview.name The OpenShift resource name that the SubjectAccessReview/TokenAccessReview will be performed for. + name: "" + ## @param openshiftOauthProxy.accessReview.namespace The OpenShift namespace that the SubjectAccessReview/TokenAccessReview will be performed for. + namespace: "{{ .Release.Namespace }}" + ## @param openshiftOauthProxy.accessReview.verb The OpenShift resource name that the SubjectAccessReview/TokenAccessReview will be performed for. + verb: "create" + ## @param openshiftOauthProxy.accessReview.version The OpenShift resource version that the SubjectAccessReview/TokenAccessReview will be performed for. + version: "" + ## @param openshiftOauthProxy.securityContext [object] Security Context for the OpenShift OAuth Proxy container. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [SecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) + securityContext: + ## @skip openshiftOauthProxy.securityContext.allowPrivilegeEscalation + allowPrivilegeEscalation: false + ## @skip openshiftOauthProxy.securityContext.capabilities + capabilities: + drop: + - ALL + +## @section Other Parameters ## @param imagePullSecrets [array] Image pull secrets to be used for the Cryostat deployment imagePullSecrets: []