From 470195c83f1e526bed733965e0a4777f76847eb0 Mon Sep 17 00:00:00 2001 From: Alessio Dionisi Date: Fri, 20 Sep 2024 15:47:05 +0200 Subject: [PATCH] feat: add support for custom registry on 1.27 and prepare v1.27.9 release (#261) * feat: add support for custom registry on 1.27 * fix: generate docs and schemas * docs: change upgrade links * feat: prepare v1.27.9 release * docs: apply suggestions * docs(schemas): add description for grafana's advanced configuration * docs(schema): improve Pomerium documentation * chore(ci/linting): allow bare URLs in markdown * chore: add missing new line * tests: use latest furyctl * tests: fix 1.27.8 version --------- Co-authored-by: Ramiro Algozino --- .drone.yml | 8 +- .rules/.markdown-lint.yml | 1 + README.md | 6 +- docs/COMPATIBILITY_MATRIX.md | 1 + docs/releases/v1.27.9.md | 43 ++ docs/schemas/ekscluster-kfd-v1alpha2.md | 55 +- docs/schemas/kfddistribution-kfd-v1alpha2.md | 55 +- docs/schemas/onpremises-kfd-v1alpha2.md | 60 ++- kfd.yaml | 2 +- .../ekscluster/v1alpha2/private/schema.go | 58 +- pkg/apis/ekscluster/v1alpha2/public/schema.go | 58 +- .../kfddistribution/v1alpha2/public/schema.go | 58 +- pkg/apis/onpremises/v1alpha2/public/schema.go | 59 +- schemas/private/ekscluster-kfd-v1alpha2.json | 10 +- schemas/public/ekscluster-kfd-v1alpha2.json | 502 ++++++++++++++---- .../public/kfddistribution-kfd-v1alpha2.json | 342 +++++++++--- schemas/public/onpremises-kfd-v1alpha2.json | 429 ++++++++++++--- ...ec-distribution-modules-auth-pomerium.json | 49 +- templates/distribution/scripts/apply.sh.tpl | 8 + .../98.cluster-certificates-renewal.yaml.tpl | 2 +- .../kubernetes/onpremises/hosts.yaml.tpl | 4 + tests/e2e-kfddistribution-upgrades.sh | 6 +- .../furyctl-init-cluster-1.27.9.yaml | 104 ++++ 23 files changed, 1588 insertions(+), 332 deletions(-) create mode 100644 docs/releases/v1.27.9.md create mode 100644 tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.9.yaml diff --git a/.drone.yml b/.drone.yml index 0fb21ac6d..8ba079161 100644 --- a/.drone.yml +++ b/.drone.yml @@ -157,7 +157,7 @@ steps: environment: CLUSTER_NAME: ${DRONE_REPO_NAME}-${DRONE_BUILD_NUMBER} KUBECONFIG: /drone/src/kubeconfig - FURYCTL_VERSION: v0.29.5-rc.2 + FURYCTL_VERSION: v0.29.7-rc.0 depends_on: [create Kind cluster] commands: - export KUBECONFIG=/drone/src/kubeconfig @@ -196,7 +196,7 @@ volumes: host: path: /var/run/docker.sock --- -name: e2e-kubernetes-1.27.5-1.27.6-1.27.7-1.27.8 +name: e2e-kubernetes-1.27.5-1.27.6-1.27.7-1.27.8-1.27.9 kind: pipeline type: docker @@ -261,7 +261,7 @@ steps: environment: CLUSTER_NAME: ${DRONE_REPO_NAME}-${DRONE_BUILD_NUMBER}-upgrades KUBECONFIG: /drone/src/kubeconfig-upgrades - FURYCTL_VERSION: v0.29.5-rc.2 + FURYCTL_VERSION: v0.29.7-rc.0 depends_on: [create Kind cluster] commands: - export KUBECONFIG=/drone/src/kubeconfig-upgrades @@ -306,7 +306,7 @@ type: docker depends_on: - e2e-kubernetes-1.27 - - e2e-kubernetes-1.27.5-1.27.6-1.27.7-1.27.8 + - e2e-kubernetes-1.27.5-1.27.6-1.27.7-1.27.8-1.27.9 platform: os: linux diff --git a/.rules/.markdown-lint.yml b/.rules/.markdown-lint.yml index 364cfb6ee..d2ae0d5b6 100644 --- a/.rules/.markdown-lint.yml +++ b/.rules/.markdown-lint.yml @@ -32,6 +32,7 @@ MD026: punctuation: ".,;:!。,;:" # List of not allowed MD029: false # Ordered list item prefix MD033: false # Allow inline HTML +MD034: false # Allow bare-URLs in Markdown, GitHub and Docusaurus support them MD036: false # Emphasis used instead of a heading MD041: false diff --git a/README.md b/README.md index 785e30a09..d3b2ec7ff 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@

Kubernetes Fury Distribution (KFD) is a certified battle-tested Kubernetes distribution based purely on upstream Kubernetes.

-[![Build Status](http://ci.sighup.io/api/badges/sighupio/fury-distribution/status.svg?ref=refs/tags/v1.27.8)](http://ci.sighup.io/sighupio/fury-distribution) -[![Release](https://img.shields.io/badge/release-v1.27.8-blue?label=FuryDistributionRelease)](https://github.com/sighupio/fury-distribution/releases/latest) +[![Build Status](http://ci.sighup.io/api/badges/sighupio/fury-distribution/status.svg?ref=refs/tags/v1.27.9)](http://ci.sighup.io/sighupio/fury-distribution) +[![Release](https://img.shields.io/badge/release-v1.27.9-blue?label=FuryDistributionRelease)](https://github.com/sighupio/fury-distribution/releases/latest) [![Slack](https://img.shields.io/badge/slack-@kubernetes/fury-yellow.svg?logo=slack)](https://kubernetes.slack.com/archives/C0154HYTAQH) [![License](https://img.shields.io/github/license/sighupio/fury-distribution)](https://github.com/sighupio/fury-distribution/blob/main/LICENSE) @@ -132,7 +132,7 @@ Current supported versions of KFD are: | :----------------------------------------------------------------------------: | :----------------: | | [`1.29.3`](https://github.com/sighupio/fury-distribution/releases/tag/v1.29.3) | `1.29.x` | | [`1.28.3`](https://github.com/sighupio/fury-distribution/releases/tag/v1.28.3) | `1.28.x` | -| [`1.27.8`](https://github.com/sighupio/fury-distribution/releases/tag/v1.27.8) | `1.27.x` | +| [`1.27.9`](https://github.com/sighupio/fury-distribution/releases/tag/v1.27.9) | `1.27.x` | Check the [compatibility matrix][compatibility-matrix] for additional information about previous releases of the Distribution and the compatibility with `furyctl`. diff --git a/docs/COMPATIBILITY_MATRIX.md b/docs/COMPATIBILITY_MATRIX.md index 6b8cc96ee..df7337f61 100644 --- a/docs/COMPATIBILITY_MATRIX.md +++ b/docs/COMPATIBILITY_MATRIX.md @@ -10,6 +10,7 @@ For a complete list of all KFD releases and their compatibility with Kubernetes | KFD / Kubernetes Version | v1.27.X | | ----------------------------------------------------------------------------- | ------------------ | +| [v1.27.9](https://github.com/sighupio/fury-distribution/releases/tag/v1.27.9) | :white_check_mark: | | [v1.27.8](https://github.com/sighupio/fury-distribution/releases/tag/v1.27.8) | :white_check_mark: | | [v1.27.7](https://github.com/sighupio/fury-distribution/releases/tag/v1.27.7) | :white_check_mark: | | [v1.27.6](https://github.com/sighupio/fury-distribution/releases/tag/v1.27.6) | :white_check_mark: | diff --git a/docs/releases/v1.27.9.md b/docs/releases/v1.27.9.md new file mode 100644 index 000000000..f9fb8a81f --- /dev/null +++ b/docs/releases/v1.27.9.md @@ -0,0 +1,43 @@ +# Kubernetes Fury Distribution Release v1.27.9 + +Welcome to KFD release `v1.27.9`. + +The distribution is maintained with ❤️ by the team [SIGHUP](https://sighup.io/) it is battle tested in production environments. + +## New Features since `v1.27.8` + +### Installer Updates + +No changes + +### Module updates + +No changes + +## New features 🌟 + +- **Configurable distribution registry**: Now the registry used by the distribution can be configured. An example configuration: + + ```yaml + spec: + distribution: + common: + registry: myregistry.mydomain.ext + ``` + +- **Configurable on-premises registry**: Now the registry used by the on-premises kind can be configured. An example configuration: + + ```yaml + spec: + kubernetes: + advanced: + registry: myregistry.mydomain.ext + ``` + +## Fixes 🐞 + +No changes + +## Upgrade procedure + +Check the [upgrade docs](https://docs.kubernetesfury.com/docs/upgrades/upgrades) for the detailed procedure. diff --git a/docs/schemas/ekscluster-kfd-v1alpha2.md b/docs/schemas/ekscluster-kfd-v1alpha2.md index 459800f96..89a4bee81 100644 --- a/docs/schemas/ekscluster-kfd-v1alpha2.md +++ b/docs/schemas/ekscluster-kfd-v1alpha2.md @@ -88,6 +88,7 @@ A Fury Cluster deployed through AWS's Elastic Kubernetes Service |:----------------------------------------------------------------|:---------|:---------| | [nodeSelector](#specdistributioncommonnodeselector) | `object` | Optional | | [provider](#specdistributioncommonprovider) | `object` | Optional | +| [registry](#specdistributioncommonregistry) | `string` | Optional | | [relativeVendorPath](#specdistributioncommonrelativevendorpath) | `string` | Optional | | [tolerations](#specdistributioncommontolerations) | `array` | Optional | @@ -111,6 +112,14 @@ The node selector to use to place the pods for all the KFD modules The type of the provider, must be EKS if specified +## .spec.distribution.common.registry + +### Description + +URL of the registry where to pull images from for the Distribution phase. (Default is registry.sighup.io/fury). + +NOTE: If plugins are pulling from the default registry, the registry will be replaced for these plugins too. + ## .spec.distribution.common.relativeVendorPath ### Description @@ -711,6 +720,10 @@ The value of the toleration | [routes](#specdistributionmodulesauthpomeriumroutes) | `array` | Optional | | [secrets](#specdistributionmodulesauthpomeriumsecrets) | `object` | Required | +### Description + +Configuration for Pomerium, an identity-aware reverse proxy used for SSO. + ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy ### Properties @@ -728,6 +741,10 @@ The value of the toleration | [monitoringPrometheus](#specdistributionmodulesauthpomeriumdefaultroutespolicymonitoringprometheus) | `array` | Optional | | [tracingMinioConsole](#specdistributionmodulesauthpomeriumdefaultroutespolicytracingminioconsole) | `array` | Optional | +### Description + +override default routes for KFD components + ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy.gatekeeperPolicyManager ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy.hubbleUi @@ -807,7 +824,7 @@ DEPRECATED: Use defaultRoutesPolicy and/or routes ### Description -Routes configuration for pomerium +Additional routes configuration for Pomerium. Follows Pomerium's route format: https://www.pomerium.com/docs/reference/routes ## .spec.distribution.modules.auth.pomerium.secrets @@ -820,17 +837,23 @@ Routes configuration for pomerium | [SHARED_SECRET](#specdistributionmodulesauthpomeriumsecretsshared_secret) | `string` | Required | | [SIGNING_KEY](#specdistributionmodulesauthpomeriumsecretssigning_key) | `string` | Required | +### Description + +Pomerium needs some user-provided secrets to be fully configured. These secrets should be unique between clusters. + ## .spec.distribution.modules.auth.pomerium.secrets.COOKIE_SECRET ### Description Cookie Secret is the secret used to encrypt and sign session cookies. +To generate a random key, run the following command: `head -c32 /dev/urandom | base64` + ## .spec.distribution.modules.auth.pomerium.secrets.IDP_CLIENT_SECRET ### Description -Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved from your identity provider. +Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth type is SSO, this value will be the secret used to authenticate Pomerium with Dex, **use a strong random value**. ## .spec.distribution.modules.auth.pomerium.secrets.SHARED_SECRET @@ -838,11 +861,21 @@ Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved fro Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate requests between Pomerium services. It's critical that secret keys are random, and stored safely. +To generate a key, run the following command: `head -c32 /dev/urandom | base64` + ## .spec.distribution.modules.auth.pomerium.secrets.SIGNING_KEY ### Description -Signing Key is one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups. +Signing Key is the base64 representation of one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups. + +To generates an P-256 (ES256) signing key: + +```bash +openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem +# careful! this will output your private key in terminal +cat ec_private.pem | base64 +``` ## .spec.distribution.modules.auth.provider @@ -2906,6 +2939,12 @@ The value of the toleration ## .spec.distribution.modules.monitoring.grafana.basicAuthIngress +### Description + +Setting this to true will deploy an additional `grafana-basic-auth` ingress protected with Grafana's basic auth instead of SSO. It's intended use is as a temporary ingress for when there are problems with the SSO login flow. + +Notice that by default anonymous access is enabled. + ## .spec.distribution.modules.monitoring.grafana.overrides ### Properties @@ -2973,6 +3012,16 @@ The value of the toleration ## .spec.distribution.modules.monitoring.grafana.usersRoleAttributePath +### Description + +[JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's role. Example: + +```yaml +usersRoleAttributePath: "contains(groups[*], 'beta') && 'Admin' || contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && 'Viewer' +``` + +More details in [Grafana's documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping). + ## .spec.distribution.modules.monitoring.kubeStateMetrics ### Properties diff --git a/docs/schemas/kfddistribution-kfd-v1alpha2.md b/docs/schemas/kfddistribution-kfd-v1alpha2.md index ca5a3c494..1098c9799 100644 --- a/docs/schemas/kfddistribution-kfd-v1alpha2.md +++ b/docs/schemas/kfddistribution-kfd-v1alpha2.md @@ -80,6 +80,7 @@ An example file can be found [here](https://github.com/sighupio/fury-distributio |:----------------------------------------------------------------|:---------|:---------| | [nodeSelector](#specdistributioncommonnodeselector) | `object` | Optional | | [provider](#specdistributioncommonprovider) | `object` | Optional | +| [registry](#specdistributioncommonregistry) | `string` | Optional | | [relativeVendorPath](#specdistributioncommonrelativevendorpath) | `string` | Optional | | [tolerations](#specdistributioncommontolerations) | `array` | Optional | @@ -103,6 +104,14 @@ The node selector to use to place the pods for all the KFD modules The type of the provider +## .spec.distribution.common.registry + +### Description + +URL of the registry where to pull images from for the Distribution phase. (Default is registry.sighup.io/fury). + +NOTE: If plugins are pulling from the default registry, the registry will be replaced for the plugin too. + ## .spec.distribution.common.relativeVendorPath ### Description @@ -708,6 +717,10 @@ The value of the toleration | [routes](#specdistributionmodulesauthpomeriumroutes) | `array` | Optional | | [secrets](#specdistributionmodulesauthpomeriumsecrets) | `object` | Required | +### Description + +Configuration for Pomerium, an identity-aware reverse proxy used for SSO. + ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy ### Properties @@ -725,6 +738,10 @@ The value of the toleration | [monitoringPrometheus](#specdistributionmodulesauthpomeriumdefaultroutespolicymonitoringprometheus) | `array` | Optional | | [tracingMinioConsole](#specdistributionmodulesauthpomeriumdefaultroutespolicytracingminioconsole) | `array` | Optional | +### Description + +override default routes for KFD components + ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy.gatekeeperPolicyManager ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy.hubbleUi @@ -804,7 +821,7 @@ DEPRECATED: Use defaultRoutesPolicy and/or routes ### Description -Routes configuration for pomerium +Additional routes configuration for Pomerium. Follows Pomerium's route format: https://www.pomerium.com/docs/reference/routes ## .spec.distribution.modules.auth.pomerium.secrets @@ -817,17 +834,23 @@ Routes configuration for pomerium | [SHARED_SECRET](#specdistributionmodulesauthpomeriumsecretsshared_secret) | `string` | Required | | [SIGNING_KEY](#specdistributionmodulesauthpomeriumsecretssigning_key) | `string` | Required | +### Description + +Pomerium needs some user-provided secrets to be fully configured. These secrets should be unique between clusters. + ## .spec.distribution.modules.auth.pomerium.secrets.COOKIE_SECRET ### Description Cookie Secret is the secret used to encrypt and sign session cookies. +To generate a random key, run the following command: `head -c32 /dev/urandom | base64` + ## .spec.distribution.modules.auth.pomerium.secrets.IDP_CLIENT_SECRET ### Description -Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved from your identity provider. +Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth type is SSO, this value will be the secret used to authenticate Pomerium with Dex, **use a strong random value**. ## .spec.distribution.modules.auth.pomerium.secrets.SHARED_SECRET @@ -835,11 +858,21 @@ Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved fro Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate requests between Pomerium services. It's critical that secret keys are random, and stored safely. +To generate a key, run the following command: `head -c32 /dev/urandom | base64` + ## .spec.distribution.modules.auth.pomerium.secrets.SIGNING_KEY ### Description -Signing Key is one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups. +Signing Key is the base64 representation of one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups. + +To generates an P-256 (ES256) signing key: + +```bash +openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem +# careful! this will output your private key in terminal +cat ec_private.pem | base64 +``` ## .spec.distribution.modules.auth.provider @@ -2381,6 +2414,12 @@ The value of the toleration ## .spec.distribution.modules.monitoring.grafana.basicAuthIngress +### Description + +Setting this to true will deploy an additional `grafana-basic-auth` ingress protected with Grafana's basic auth instead of SSO. It's intended use is as a temporary ingress for when there are problems with the SSO login flow. + +Notice that by default anonymous access is enabled. + ## .spec.distribution.modules.monitoring.grafana.overrides ### Properties @@ -2448,6 +2487,16 @@ The value of the toleration ## .spec.distribution.modules.monitoring.grafana.usersRoleAttributePath +### Description + +[JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's role. Example: + +```yaml +usersRoleAttributePath: "contains(groups[*], 'beta') && 'Admin' || contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && 'Viewer' +``` + +More details in [Grafana's documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping). + ## .spec.distribution.modules.monitoring.kubeStateMetrics ### Properties diff --git a/docs/schemas/onpremises-kfd-v1alpha2.md b/docs/schemas/onpremises-kfd-v1alpha2.md index a519552cc..b30ecfb4e 100644 --- a/docs/schemas/onpremises-kfd-v1alpha2.md +++ b/docs/schemas/onpremises-kfd-v1alpha2.md @@ -80,6 +80,7 @@ An example file can be found [here](https://github.com/sighupio/fury-distributio |:----------------------------------------------------------------|:---------|:---------| | [nodeSelector](#specdistributioncommonnodeselector) | `object` | Optional | | [provider](#specdistributioncommonprovider) | `object` | Optional | +| [registry](#specdistributioncommonregistry) | `string` | Optional | | [relativeVendorPath](#specdistributioncommonrelativevendorpath) | `string` | Optional | | [tolerations](#specdistributioncommontolerations) | `array` | Optional | @@ -103,6 +104,12 @@ The node selector to use to place the pods for all the KFD modules The type of the provider +## .spec.distribution.common.registry + +### Description + +URL of the registry where to pull images from for the Distribution phase. (Default is registry.sighup.io/fury). + ## .spec.distribution.common.relativeVendorPath ### Description @@ -773,6 +780,10 @@ The value of the toleration | [routes](#specdistributionmodulesauthpomeriumroutes) | `array` | Optional | | [secrets](#specdistributionmodulesauthpomeriumsecrets) | `object` | Required | +### Description + +Configuration for Pomerium, an identity-aware reverse proxy used for SSO. + ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy ### Properties @@ -790,6 +801,10 @@ The value of the toleration | [monitoringPrometheus](#specdistributionmodulesauthpomeriumdefaultroutespolicymonitoringprometheus) | `array` | Optional | | [tracingMinioConsole](#specdistributionmodulesauthpomeriumdefaultroutespolicytracingminioconsole) | `array` | Optional | +### Description + +override default routes for KFD components + ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy.gatekeeperPolicyManager ## .spec.distribution.modules.auth.pomerium.defaultRoutesPolicy.hubbleUi @@ -869,7 +884,7 @@ DEPRECATED: Use defaultRoutesPolicy and/or routes ### Description -Routes configuration for pomerium +Additional routes configuration for Pomerium. Follows Pomerium's route format: https://www.pomerium.com/docs/reference/routes ## .spec.distribution.modules.auth.pomerium.secrets @@ -882,17 +897,23 @@ Routes configuration for pomerium | [SHARED_SECRET](#specdistributionmodulesauthpomeriumsecretsshared_secret) | `string` | Required | | [SIGNING_KEY](#specdistributionmodulesauthpomeriumsecretssigning_key) | `string` | Required | +### Description + +Pomerium needs some user-provided secrets to be fully configured. These secrets should be unique between clusters. + ## .spec.distribution.modules.auth.pomerium.secrets.COOKIE_SECRET ### Description Cookie Secret is the secret used to encrypt and sign session cookies. +To generate a random key, run the following command: `head -c32 /dev/urandom | base64` + ## .spec.distribution.modules.auth.pomerium.secrets.IDP_CLIENT_SECRET ### Description -Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved from your identity provider. +Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth type is SSO, this value will be the secret used to authenticate Pomerium with Dex, **use a strong random value**. ## .spec.distribution.modules.auth.pomerium.secrets.SHARED_SECRET @@ -900,11 +921,21 @@ Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved fro Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate requests between Pomerium services. It's critical that secret keys are random, and stored safely. +To generate a key, run the following command: `head -c32 /dev/urandom | base64` + ## .spec.distribution.modules.auth.pomerium.secrets.SIGNING_KEY ### Description -Signing Key is one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups. +Signing Key is the base64 representation of one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups. + +To generates an P-256 (ES256) signing key: + +```bash +openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem +# careful! this will output your private key in terminal +cat ec_private.pem | base64 +``` ## .spec.distribution.modules.auth.provider @@ -2449,6 +2480,12 @@ The value of the toleration ## .spec.distribution.modules.monitoring.grafana.basicAuthIngress +### Description + +Setting this to true will deploy an additional `grafana-basic-auth` ingress protected with Grafana's basic auth instead of SSO. It's intended use is as a temporary ingress for when there are problems with the SSO login flow. + +Notice that by default anonymous access is enabled. + ## .spec.distribution.modules.monitoring.grafana.overrides ### Properties @@ -2516,6 +2553,16 @@ The value of the toleration ## .spec.distribution.modules.monitoring.grafana.usersRoleAttributePath +### Description + +[JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's role. Example: + +```yaml +usersRoleAttributePath: "contains(groups[*], 'beta') && 'Admin' || contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && 'Viewer' +``` + +More details in [Grafana's documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping). + ## .spec.distribution.modules.monitoring.kubeStateMetrics ### Properties @@ -4087,6 +4134,7 @@ The type of tracing to use, either ***none*** or ***tempo*** | [containerd](#speckubernetesadvancedcontainerd) | `object` | Optional | | [encryption](#speckubernetesadvancedencryption) | `object` | Optional | | [oidc](#speckubernetesadvancedoidc) | `object` | Optional | +| [registry](#speckubernetesadvancedregistry) | `string` | Optional | | [users](#speckubernetesadvancedusers) | `object` | Optional | ## .spec.kubernetes.advanced.airGap @@ -4328,6 +4376,12 @@ The issuer url of the oidc provider ## .spec.kubernetes.advanced.oidc.username_prefix +## .spec.kubernetes.advanced.registry + +### Description + +URL of the registry where to pull images from for the Kubernetes phase. (Default is registry.sighup.io/fury/on-premises). + ## .spec.kubernetes.advanced.users ### Properties diff --git a/kfd.yaml b/kfd.yaml index 53f87c038..bd464b5d4 100644 --- a/kfd.yaml +++ b/kfd.yaml @@ -2,7 +2,7 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. -version: v1.27.8 +version: v1.27.9 modules: auth: v0.3.0 aws: v4.2.1 diff --git a/pkg/apis/ekscluster/v1alpha2/private/schema.go b/pkg/apis/ekscluster/v1alpha2/private/schema.go index af145d7bb..85a0d6d39 100644 --- a/pkg/apis/ekscluster/v1alpha2/private/schema.go +++ b/pkg/apis/ekscluster/v1alpha2/private/schema.go @@ -77,6 +77,13 @@ type SpecDistributionCommon struct { // Provider corresponds to the JSON schema field "provider". Provider *SpecDistributionCommonProvider `json:"provider,omitempty" yaml:"provider,omitempty" mapstructure:"provider,omitempty"` + // URL of the registry where to pull images from for the Distribution phase. + // (Default is registry.sighup.io/fury). + // + // NOTE: If plugins are pulling from the default registry, the registry will be + // replaced for these plugins too. + Registry *string `json:"registry,omitempty" yaml:"registry,omitempty" mapstructure:"registry,omitempty"` + // The relative path to the vendor directory, does not need to be changed RelativeVendorPath *string `json:"relativeVendorPath,omitempty" yaml:"relativeVendorPath,omitempty" mapstructure:"relativeVendorPath,omitempty"` @@ -349,6 +356,7 @@ type SpecDistributionModulesAuthOverridesIngresses map[string]SpecDistributionMo type SpecDistributionModulesAuthPomerium interface{} +// override default routes for KFD components type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy struct { // GatekeeperPolicyManager corresponds to the JSON schema field // "gatekeeperPolicyManager". @@ -409,25 +417,43 @@ type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicyTracingMinioConsoleEl type SpecDistributionModulesAuthPomeriumRoutesElem map[string]interface{} +// Pomerium needs some user-provided secrets to be fully configured. These secrets +// should be unique between clusters. type SpecDistributionModulesAuthPomeriumSecrets struct { // Cookie Secret is the secret used to encrypt and sign session cookies. + // + // To generate a random key, run the following command: `head -c32 /dev/urandom | + // base64` COOKIESECRET string `json:"COOKIE_SECRET" yaml:"COOKIE_SECRET" mapstructure:"COOKIE_SECRET"` - // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved - // from your identity provider. + // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth + // type is SSO, this value will be the secret used to authenticate Pomerium with + // Dex, **use a strong random value**. IDPCLIENTSECRET string `json:"IDP_CLIENT_SECRET" yaml:"IDP_CLIENT_SECRET" mapstructure:"IDP_CLIENT_SECRET"` // Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate // requests between Pomerium services. It's critical that secret keys are random, // and stored safely. + // + // To generate a key, run the following command: `head -c32 /dev/urandom | base64` SHAREDSECRET string `json:"SHARED_SECRET" yaml:"SHARED_SECRET" mapstructure:"SHARED_SECRET"` - // Signing Key is one or more PEM-encoded private keys used to sign a user's - // attestation JWT, which can be consumed by upstream applications to pass along - // identifying user information like username, id, and groups. + // Signing Key is the base64 representation of one or more PEM-encoded private + // keys used to sign a user's attestation JWT, which can be consumed by upstream + // applications to pass along identifying user information like username, id, and + // groups. + // + // To generates an P-256 (ES256) signing key: + // + // ```bash + // openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem + // # careful! this will output your private key in terminal + // cat ec_private.pem | base64 + // ``` SIGNINGKEY string `json:"SIGNING_KEY" yaml:"SIGNING_KEY" mapstructure:"SIGNING_KEY"` } +// Configuration for Pomerium, an identity-aware reverse proxy used for SSO. type SpecDistributionModulesAuthPomerium_2 struct { // DefaultRoutesPolicy corresponds to the JSON schema field "defaultRoutesPolicy". DefaultRoutesPolicy *SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy `json:"defaultRoutesPolicy,omitempty" yaml:"defaultRoutesPolicy,omitempty" mapstructure:"defaultRoutesPolicy,omitempty"` @@ -438,7 +464,8 @@ type SpecDistributionModulesAuthPomerium_2 struct { // DEPRECATED: Use defaultRoutesPolicy and/or routes Policy *string `json:"policy,omitempty" yaml:"policy,omitempty" mapstructure:"policy,omitempty"` - // Routes configuration for pomerium + // Additional routes configuration for Pomerium. Follows Pomerium's route format: + // https://www.pomerium.com/docs/reference/routes Routes []SpecDistributionModulesAuthPomeriumRoutesElem `json:"routes,omitempty" yaml:"routes,omitempty" mapstructure:"routes,omitempty"` // Secrets corresponds to the JSON schema field "secrets". @@ -978,14 +1005,27 @@ type SpecDistributionModulesMonitoringBlackboxExporter struct { } type SpecDistributionModulesMonitoringGrafana struct { - // BasicAuthIngress corresponds to the JSON schema field "basicAuthIngress". + // Setting this to true will deploy an additional `grafana-basic-auth` ingress + // protected with Grafana's basic auth instead of SSO. It's intended use is as a + // temporary ingress for when there are problems with the SSO login flow. + // + // Notice that by default anonymous access is enabled. BasicAuthIngress *bool `json:"basicAuthIngress,omitempty" yaml:"basicAuthIngress,omitempty" mapstructure:"basicAuthIngress,omitempty"` // Overrides corresponds to the JSON schema field "overrides". Overrides *TypesFuryModuleComponentOverrides `json:"overrides,omitempty" yaml:"overrides,omitempty" mapstructure:"overrides,omitempty"` - // UsersRoleAttributePath corresponds to the JSON schema field - // "usersRoleAttributePath". + // [JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's + // role. Example: + // + // ```yaml + // usersRoleAttributePath: "contains(groups[*], 'beta') && 'Admin' || + // contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && + // 'Viewer' + // ``` + // + // More details in [Grafana's + // documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping). UsersRoleAttributePath *string `json:"usersRoleAttributePath,omitempty" yaml:"usersRoleAttributePath,omitempty" mapstructure:"usersRoleAttributePath,omitempty"` } diff --git a/pkg/apis/ekscluster/v1alpha2/public/schema.go b/pkg/apis/ekscluster/v1alpha2/public/schema.go index 732dc243f..adaa80c83 100644 --- a/pkg/apis/ekscluster/v1alpha2/public/schema.go +++ b/pkg/apis/ekscluster/v1alpha2/public/schema.go @@ -77,6 +77,13 @@ type SpecDistributionCommon struct { // Provider corresponds to the JSON schema field "provider". Provider *SpecDistributionCommonProvider `json:"provider,omitempty" yaml:"provider,omitempty" mapstructure:"provider,omitempty"` + // URL of the registry where to pull images from for the Distribution phase. + // (Default is registry.sighup.io/fury). + // + // NOTE: If plugins are pulling from the default registry, the registry will be + // replaced for these plugins too. + Registry *string `json:"registry,omitempty" yaml:"registry,omitempty" mapstructure:"registry,omitempty"` + // The relative path to the vendor directory, does not need to be changed RelativeVendorPath *string `json:"relativeVendorPath,omitempty" yaml:"relativeVendorPath,omitempty" mapstructure:"relativeVendorPath,omitempty"` @@ -349,6 +356,7 @@ type SpecDistributionModulesAuthOverridesIngresses map[string]SpecDistributionMo type SpecDistributionModulesAuthPomerium interface{} +// override default routes for KFD components type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy struct { // GatekeeperPolicyManager corresponds to the JSON schema field // "gatekeeperPolicyManager". @@ -409,25 +417,43 @@ type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicyTracingMinioConsoleEl type SpecDistributionModulesAuthPomeriumRoutesElem map[string]interface{} +// Pomerium needs some user-provided secrets to be fully configured. These secrets +// should be unique between clusters. type SpecDistributionModulesAuthPomeriumSecrets struct { // Cookie Secret is the secret used to encrypt and sign session cookies. + // + // To generate a random key, run the following command: `head -c32 /dev/urandom | + // base64` COOKIESECRET string `json:"COOKIE_SECRET" yaml:"COOKIE_SECRET" mapstructure:"COOKIE_SECRET"` - // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved - // from your identity provider. + // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth + // type is SSO, this value will be the secret used to authenticate Pomerium with + // Dex, **use a strong random value**. IDPCLIENTSECRET string `json:"IDP_CLIENT_SECRET" yaml:"IDP_CLIENT_SECRET" mapstructure:"IDP_CLIENT_SECRET"` // Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate // requests between Pomerium services. It's critical that secret keys are random, // and stored safely. + // + // To generate a key, run the following command: `head -c32 /dev/urandom | base64` SHAREDSECRET string `json:"SHARED_SECRET" yaml:"SHARED_SECRET" mapstructure:"SHARED_SECRET"` - // Signing Key is one or more PEM-encoded private keys used to sign a user's - // attestation JWT, which can be consumed by upstream applications to pass along - // identifying user information like username, id, and groups. + // Signing Key is the base64 representation of one or more PEM-encoded private + // keys used to sign a user's attestation JWT, which can be consumed by upstream + // applications to pass along identifying user information like username, id, and + // groups. + // + // To generates an P-256 (ES256) signing key: + // + // ```bash + // openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem + // # careful! this will output your private key in terminal + // cat ec_private.pem | base64 + // ``` SIGNINGKEY string `json:"SIGNING_KEY" yaml:"SIGNING_KEY" mapstructure:"SIGNING_KEY"` } +// Configuration for Pomerium, an identity-aware reverse proxy used for SSO. type SpecDistributionModulesAuthPomerium_2 struct { // DefaultRoutesPolicy corresponds to the JSON schema field "defaultRoutesPolicy". DefaultRoutesPolicy *SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy `json:"defaultRoutesPolicy,omitempty" yaml:"defaultRoutesPolicy,omitempty" mapstructure:"defaultRoutesPolicy,omitempty"` @@ -438,7 +464,8 @@ type SpecDistributionModulesAuthPomerium_2 struct { // DEPRECATED: Use defaultRoutesPolicy and/or routes Policy *string `json:"policy,omitempty" yaml:"policy,omitempty" mapstructure:"policy,omitempty"` - // Routes configuration for pomerium + // Additional routes configuration for Pomerium. Follows Pomerium's route format: + // https://www.pomerium.com/docs/reference/routes Routes []SpecDistributionModulesAuthPomeriumRoutesElem `json:"routes,omitempty" yaml:"routes,omitempty" mapstructure:"routes,omitempty"` // Secrets corresponds to the JSON schema field "secrets". @@ -938,14 +965,27 @@ type SpecDistributionModulesMonitoringBlackboxExporter struct { } type SpecDistributionModulesMonitoringGrafana struct { - // BasicAuthIngress corresponds to the JSON schema field "basicAuthIngress". + // Setting this to true will deploy an additional `grafana-basic-auth` ingress + // protected with Grafana's basic auth instead of SSO. It's intended use is as a + // temporary ingress for when there are problems with the SSO login flow. + // + // Notice that by default anonymous access is enabled. BasicAuthIngress *bool `json:"basicAuthIngress,omitempty" yaml:"basicAuthIngress,omitempty" mapstructure:"basicAuthIngress,omitempty"` // Overrides corresponds to the JSON schema field "overrides". Overrides *TypesFuryModuleComponentOverrides `json:"overrides,omitempty" yaml:"overrides,omitempty" mapstructure:"overrides,omitempty"` - // UsersRoleAttributePath corresponds to the JSON schema field - // "usersRoleAttributePath". + // [JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's + // role. Example: + // + // ```yaml + // usersRoleAttributePath: "contains(groups[*], 'beta') && 'Admin' || + // contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && + // 'Viewer' + // ``` + // + // More details in [Grafana's + // documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping). UsersRoleAttributePath *string `json:"usersRoleAttributePath,omitempty" yaml:"usersRoleAttributePath,omitempty" mapstructure:"usersRoleAttributePath,omitempty"` } diff --git a/pkg/apis/kfddistribution/v1alpha2/public/schema.go b/pkg/apis/kfddistribution/v1alpha2/public/schema.go index 3f4206c23..d6f1b3eb9 100644 --- a/pkg/apis/kfddistribution/v1alpha2/public/schema.go +++ b/pkg/apis/kfddistribution/v1alpha2/public/schema.go @@ -63,6 +63,13 @@ type SpecDistributionCommon struct { // Provider corresponds to the JSON schema field "provider". Provider *SpecDistributionCommonProvider `json:"provider,omitempty" yaml:"provider,omitempty" mapstructure:"provider,omitempty"` + // URL of the registry where to pull images from for the Distribution phase. + // (Default is registry.sighup.io/fury). + // + // NOTE: If plugins are pulling from the default registry, the registry will be + // replaced for the plugin too. + Registry *string `json:"registry,omitempty" yaml:"registry,omitempty" mapstructure:"registry,omitempty"` + // The relative path to the vendor directory, does not need to be changed RelativeVendorPath *string `json:"relativeVendorPath,omitempty" yaml:"relativeVendorPath,omitempty" mapstructure:"relativeVendorPath,omitempty"` @@ -332,6 +339,7 @@ type SpecDistributionModulesAuthOverridesIngresses map[string]SpecDistributionMo type SpecDistributionModulesAuthPomerium interface{} +// override default routes for KFD components type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy struct { // GatekeeperPolicyManager corresponds to the JSON schema field // "gatekeeperPolicyManager". @@ -392,25 +400,43 @@ type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicyTracingMinioConsoleEl type SpecDistributionModulesAuthPomeriumRoutesElem map[string]interface{} +// Pomerium needs some user-provided secrets to be fully configured. These secrets +// should be unique between clusters. type SpecDistributionModulesAuthPomeriumSecrets struct { // Cookie Secret is the secret used to encrypt and sign session cookies. + // + // To generate a random key, run the following command: `head -c32 /dev/urandom | + // base64` COOKIESECRET string `json:"COOKIE_SECRET" yaml:"COOKIE_SECRET" mapstructure:"COOKIE_SECRET"` - // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved - // from your identity provider. + // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth + // type is SSO, this value will be the secret used to authenticate Pomerium with + // Dex, **use a strong random value**. IDPCLIENTSECRET string `json:"IDP_CLIENT_SECRET" yaml:"IDP_CLIENT_SECRET" mapstructure:"IDP_CLIENT_SECRET"` // Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate // requests between Pomerium services. It's critical that secret keys are random, // and stored safely. + // + // To generate a key, run the following command: `head -c32 /dev/urandom | base64` SHAREDSECRET string `json:"SHARED_SECRET" yaml:"SHARED_SECRET" mapstructure:"SHARED_SECRET"` - // Signing Key is one or more PEM-encoded private keys used to sign a user's - // attestation JWT, which can be consumed by upstream applications to pass along - // identifying user information like username, id, and groups. + // Signing Key is the base64 representation of one or more PEM-encoded private + // keys used to sign a user's attestation JWT, which can be consumed by upstream + // applications to pass along identifying user information like username, id, and + // groups. + // + // To generates an P-256 (ES256) signing key: + // + // ```bash + // openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem + // # careful! this will output your private key in terminal + // cat ec_private.pem | base64 + // ``` SIGNINGKEY string `json:"SIGNING_KEY" yaml:"SIGNING_KEY" mapstructure:"SIGNING_KEY"` } +// Configuration for Pomerium, an identity-aware reverse proxy used for SSO. type SpecDistributionModulesAuthPomerium_2 struct { // DefaultRoutesPolicy corresponds to the JSON schema field "defaultRoutesPolicy". DefaultRoutesPolicy *SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy `json:"defaultRoutesPolicy,omitempty" yaml:"defaultRoutesPolicy,omitempty" mapstructure:"defaultRoutesPolicy,omitempty"` @@ -421,7 +447,8 @@ type SpecDistributionModulesAuthPomerium_2 struct { // DEPRECATED: Use defaultRoutesPolicy and/or routes Policy *string `json:"policy,omitempty" yaml:"policy,omitempty" mapstructure:"policy,omitempty"` - // Routes configuration for pomerium + // Additional routes configuration for Pomerium. Follows Pomerium's route format: + // https://www.pomerium.com/docs/reference/routes Routes []SpecDistributionModulesAuthPomeriumRoutesElem `json:"routes,omitempty" yaml:"routes,omitempty" mapstructure:"routes,omitempty"` // Secrets corresponds to the JSON schema field "secrets". @@ -871,14 +898,27 @@ type SpecDistributionModulesMonitoringBlackboxExporter struct { } type SpecDistributionModulesMonitoringGrafana struct { - // BasicAuthIngress corresponds to the JSON schema field "basicAuthIngress". + // Setting this to true will deploy an additional `grafana-basic-auth` ingress + // protected with Grafana's basic auth instead of SSO. It's intended use is as a + // temporary ingress for when there are problems with the SSO login flow. + // + // Notice that by default anonymous access is enabled. BasicAuthIngress *bool `json:"basicAuthIngress,omitempty" yaml:"basicAuthIngress,omitempty" mapstructure:"basicAuthIngress,omitempty"` // Overrides corresponds to the JSON schema field "overrides". Overrides *TypesFuryModuleComponentOverrides `json:"overrides,omitempty" yaml:"overrides,omitempty" mapstructure:"overrides,omitempty"` - // UsersRoleAttributePath corresponds to the JSON schema field - // "usersRoleAttributePath". + // [JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's + // role. Example: + // + // ```yaml + // usersRoleAttributePath: "contains(groups[*], 'beta') && 'Admin' || + // contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && + // 'Viewer' + // ``` + // + // More details in [Grafana's + // documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping). UsersRoleAttributePath *string `json:"usersRoleAttributePath,omitempty" yaml:"usersRoleAttributePath,omitempty" mapstructure:"usersRoleAttributePath,omitempty"` } diff --git a/pkg/apis/onpremises/v1alpha2/public/schema.go b/pkg/apis/onpremises/v1alpha2/public/schema.go index 277f039d1..4bed7ebe0 100644 --- a/pkg/apis/onpremises/v1alpha2/public/schema.go +++ b/pkg/apis/onpremises/v1alpha2/public/schema.go @@ -63,6 +63,10 @@ type SpecDistributionCommon struct { // Provider corresponds to the JSON schema field "provider". Provider *SpecDistributionCommonProvider `json:"provider,omitempty" yaml:"provider,omitempty" mapstructure:"provider,omitempty"` + // URL of the registry where to pull images from for the Distribution phase. + // (Default is registry.sighup.io/fury). + Registry *string `json:"registry,omitempty" yaml:"registry,omitempty" mapstructure:"registry,omitempty"` + // The relative path to the vendor directory, does not need to be changed RelativeVendorPath *string `json:"relativeVendorPath,omitempty" yaml:"relativeVendorPath,omitempty" mapstructure:"relativeVendorPath,omitempty"` @@ -364,6 +368,7 @@ type SpecDistributionModulesAuthOverridesIngresses map[string]SpecDistributionMo type SpecDistributionModulesAuthPomerium interface{} +// override default routes for KFD components type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy struct { // GatekeeperPolicyManager corresponds to the JSON schema field // "gatekeeperPolicyManager". @@ -424,25 +429,43 @@ type SpecDistributionModulesAuthPomeriumDefaultRoutesPolicyTracingMinioConsoleEl type SpecDistributionModulesAuthPomeriumRoutesElem map[string]interface{} +// Pomerium needs some user-provided secrets to be fully configured. These secrets +// should be unique between clusters. type SpecDistributionModulesAuthPomeriumSecrets struct { // Cookie Secret is the secret used to encrypt and sign session cookies. + // + // To generate a random key, run the following command: `head -c32 /dev/urandom | + // base64` COOKIESECRET string `json:"COOKIE_SECRET" yaml:"COOKIE_SECRET" mapstructure:"COOKIE_SECRET"` - // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved - // from your identity provider. + // Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth + // type is SSO, this value will be the secret used to authenticate Pomerium with + // Dex, **use a strong random value**. IDPCLIENTSECRET string `json:"IDP_CLIENT_SECRET" yaml:"IDP_CLIENT_SECRET" mapstructure:"IDP_CLIENT_SECRET"` // Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate // requests between Pomerium services. It's critical that secret keys are random, // and stored safely. + // + // To generate a key, run the following command: `head -c32 /dev/urandom | base64` SHAREDSECRET string `json:"SHARED_SECRET" yaml:"SHARED_SECRET" mapstructure:"SHARED_SECRET"` - // Signing Key is one or more PEM-encoded private keys used to sign a user's - // attestation JWT, which can be consumed by upstream applications to pass along - // identifying user information like username, id, and groups. + // Signing Key is the base64 representation of one or more PEM-encoded private + // keys used to sign a user's attestation JWT, which can be consumed by upstream + // applications to pass along identifying user information like username, id, and + // groups. + // + // To generates an P-256 (ES256) signing key: + // + // ```bash + // openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem + // # careful! this will output your private key in terminal + // cat ec_private.pem | base64 + // ``` SIGNINGKEY string `json:"SIGNING_KEY" yaml:"SIGNING_KEY" mapstructure:"SIGNING_KEY"` } +// Configuration for Pomerium, an identity-aware reverse proxy used for SSO. type SpecDistributionModulesAuthPomerium_2 struct { // DefaultRoutesPolicy corresponds to the JSON schema field "defaultRoutesPolicy". DefaultRoutesPolicy *SpecDistributionModulesAuthPomeriumDefaultRoutesPolicy `json:"defaultRoutesPolicy,omitempty" yaml:"defaultRoutesPolicy,omitempty" mapstructure:"defaultRoutesPolicy,omitempty"` @@ -453,7 +476,8 @@ type SpecDistributionModulesAuthPomerium_2 struct { // DEPRECATED: Use defaultRoutesPolicy and/or routes Policy *string `json:"policy,omitempty" yaml:"policy,omitempty" mapstructure:"policy,omitempty"` - // Routes configuration for pomerium + // Additional routes configuration for Pomerium. Follows Pomerium's route format: + // https://www.pomerium.com/docs/reference/routes Routes []SpecDistributionModulesAuthPomeriumRoutesElem `json:"routes,omitempty" yaml:"routes,omitempty" mapstructure:"routes,omitempty"` // Secrets corresponds to the JSON schema field "secrets". @@ -909,14 +933,27 @@ type SpecDistributionModulesMonitoringBlackboxExporter struct { } type SpecDistributionModulesMonitoringGrafana struct { - // BasicAuthIngress corresponds to the JSON schema field "basicAuthIngress". + // Setting this to true will deploy an additional `grafana-basic-auth` ingress + // protected with Grafana's basic auth instead of SSO. It's intended use is as a + // temporary ingress for when there are problems with the SSO login flow. + // + // Notice that by default anonymous access is enabled. BasicAuthIngress *bool `json:"basicAuthIngress,omitempty" yaml:"basicAuthIngress,omitempty" mapstructure:"basicAuthIngress,omitempty"` // Overrides corresponds to the JSON schema field "overrides". Overrides *TypesFuryModuleComponentOverrides `json:"overrides,omitempty" yaml:"overrides,omitempty" mapstructure:"overrides,omitempty"` - // UsersRoleAttributePath corresponds to the JSON schema field - // "usersRoleAttributePath". + // [JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's + // role. Example: + // + // ```yaml + // usersRoleAttributePath: "contains(groups[*], 'beta') && 'Admin' || + // contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && + // 'Viewer' + // ``` + // + // More details in [Grafana's + // documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping). UsersRoleAttributePath *string `json:"usersRoleAttributePath,omitempty" yaml:"usersRoleAttributePath,omitempty" mapstructure:"usersRoleAttributePath,omitempty"` } @@ -1274,6 +1311,10 @@ type SpecKubernetesAdvanced struct { // Oidc corresponds to the JSON schema field "oidc". Oidc *SpecKubernetesAdvancedOIDC `json:"oidc,omitempty" yaml:"oidc,omitempty" mapstructure:"oidc,omitempty"` + // URL of the registry where to pull images from for the Kubernetes phase. + // (Default is registry.sighup.io/fury/on-premises). + Registry *string `json:"registry,omitempty" yaml:"registry,omitempty" mapstructure:"registry,omitempty"` + // Users corresponds to the JSON schema field "users". Users *SpecKubernetesAdvancedUsers `json:"users,omitempty" yaml:"users,omitempty" mapstructure:"users,omitempty"` } diff --git a/schemas/private/ekscluster-kfd-v1alpha2.json b/schemas/private/ekscluster-kfd-v1alpha2.json index 731e23efa..c4235bcd8 100644 --- a/schemas/private/ekscluster-kfd-v1alpha2.json +++ b/schemas/private/ekscluster-kfd-v1alpha2.json @@ -205,6 +205,10 @@ "relativeVendorPath": { "type": "string", "description": "The relative path to the vendor directory, does not need to be changed" + }, + "registry": { + "type": "string", + "description": "URL of the registry where to pull images from for the Distribution phase. (Default is registry.sighup.io/fury).\n\nNOTE: If plugins are pulling from the default registry, the registry will be replaced for these plugins too." } } }, @@ -1258,10 +1262,12 @@ "additionalProperties": false, "properties": { "usersRoleAttributePath": { - "type": "string" + "type": "string", + "description": "[JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's role. Example:\n\n```yaml\nusersRoleAttributePath: \"contains(groups[*], 'beta') && 'Admin' || contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && 'Viewer'\n```\n\nMore details in [Grafana's documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping)." }, "basicAuthIngress": { - "type": "boolean" + "type": "boolean", + "description": "Setting this to true will deploy an additional `grafana-basic-auth` ingress protected with Grafana's basic auth instead of SSO. It's intended use is as a temporary ingress for when there are problems with the SSO login flow.\n\nNotice that by default anonymous access is enabled." }, "overrides": { "$ref": "#/$defs/Types.FuryModuleComponentOverrides" diff --git a/schemas/public/ekscluster-kfd-v1alpha2.json b/schemas/public/ekscluster-kfd-v1alpha2.json index 9dd6d4552..74266be21 100644 --- a/schemas/public/ekscluster-kfd-v1alpha2.json +++ b/schemas/public/ekscluster-kfd-v1alpha2.json @@ -9,7 +9,9 @@ }, "kind": { "type": "string", - "enum": ["EKSCluster"] + "enum": [ + "EKSCluster" + ] }, "metadata": { "$ref": "#/$defs/Metadata" @@ -19,7 +21,12 @@ } }, "additionalProperties": false, - "required": ["apiVersion", "kind", "metadata", "spec"], + "required": [ + "apiVersion", + "kind", + "metadata", + "spec" + ], "$defs": { "Metadata": { "type": "object", @@ -31,7 +38,9 @@ "maxLength": 56 } }, - "required": ["name"] + "required": [ + "name" + ] }, "Spec": { "type": "object", @@ -96,7 +105,10 @@ "then": { "properties": { "kubernetes": { - "required": ["vpcId", "subnetIds"] + "required": [ + "vpcId", + "subnetIds" + ] } } }, @@ -124,7 +136,9 @@ "$ref": "#/$defs/Spec.ToolsConfiguration.Terraform" } }, - "required": ["terraform"] + "required": [ + "terraform" + ] }, "Spec.ToolsConfiguration.Terraform": { "type": "object", @@ -134,7 +148,9 @@ "$ref": "#/$defs/Spec.ToolsConfiguration.Terraform.State" } }, - "required": ["state"] + "required": [ + "state" + ] }, "Spec.ToolsConfiguration.Terraform.State": { "type": "object", @@ -144,7 +160,9 @@ "$ref": "#/$defs/Spec.ToolsConfiguration.Terraform.State.S3" } }, - "required": ["s3"] + "required": [ + "s3" + ] }, "Spec.ToolsConfiguration.Terraform.State.S3": { "type": "object", @@ -167,7 +185,11 @@ "description": "This value defines if the region of the bucket should be validated or not by Terraform, useful when using a bucket in a recently added region" } }, - "required": ["bucketName", "keyPrefix", "region"] + "required": [ + "bucketName", + "keyPrefix", + "region" + ] }, "Spec.Infrastructure": { "type": "object", @@ -207,7 +229,9 @@ "then": { "properties": { "vpn": { - "required": ["vpcId"] + "required": [ + "vpcId" + ] } } } @@ -261,7 +285,9 @@ "$ref": "#/$defs/Spec.Infrastructure.Vpc.Network" } }, - "required": ["network"] + "required": [ + "network" + ] }, "Spec.Infrastructure.Vpc.Network": { "type": "object", @@ -275,7 +301,10 @@ "$ref": "#/$defs/Spec.Infrastructure.Vpc.Network.SubnetsCidrs" } }, - "required": ["cidr", "subnetsCidrs"] + "required": [ + "cidr", + "subnetsCidrs" + ] }, "Spec.Infrastructure.Vpc.Network.SubnetsCidrs": { "type": "object", @@ -296,7 +325,10 @@ "description": "These are the CIDRs for the public subnets, where the public load balancers and the VPN servers will be created" } }, - "required": ["private", "public"] + "required": [ + "private", + "public" + ] }, "Spec.Infrastructure.Vpn": { "type": "object", @@ -346,7 +378,10 @@ "description": "Overrides the default IAM user name for the VPN" } }, - "required": ["ssh", "vpnClientsSubnetCidr"] + "required": [ + "ssh", + "vpnClientsSubnetCidr" + ] }, "Spec.Infrastructure.Vpn.Ssh": { "type": "object", @@ -382,7 +417,10 @@ "description": "The CIDR enabled in the security group that can access the bastions in SSH" } }, - "required": ["allowedFromCidrs", "githubUsersName"] + "required": [ + "allowedFromCidrs", + "githubUsersName" + ] }, "Spec.Kubernetes": { "type": "object", @@ -427,7 +465,11 @@ }, "nodePoolsLaunchKind": { "type": "string", - "enum": ["launch_configurations", "launch_templates", "both"], + "enum": [ + "launch_configurations", + "launch_templates", + "both" + ], "description": "Either `launch_configurations`, `launch_templates` or `both`. For new clusters use `launch_templates`, for existing cluster you'll need to migrate from `launch_configurations` to `launch_templates` using `both` as interim." }, "logRetentionDays": { @@ -495,7 +537,10 @@ "description": "This value defines if the API server will be accessible from the public subnets" } }, - "required": ["privateAccess", "publicAccess"] + "required": [ + "privateAccess", + "publicAccess" + ] }, "Spec.Kubernetes.NodePool": { "type": "object", @@ -503,7 +548,10 @@ "properties": { "type": { "type": "string", - "enum": ["eks-managed", "self-managed"] + "enum": [ + "eks-managed", + "self-managed" + ] }, "name": { "type": "string", @@ -514,7 +562,10 @@ }, "containerRuntime": { "type": "string", - "enum": ["docker", "containerd"], + "enum": [ + "docker", + "containerd" + ], "description": "The container runtime to use for the nodes" }, "size": { @@ -553,7 +604,11 @@ "$ref": "#/$defs/Spec.Kubernetes.NodePool.AdditionalFirewallRules" } }, - "required": ["instance", "name", "size"] + "required": [ + "instance", + "name", + "size" + ] }, "Spec.Kubernetes.NodePool.Ami": { "type": "object", @@ -568,7 +623,10 @@ "description": "The owner of the AMI" } }, - "required": ["id", "owner"] + "required": [ + "id", + "owner" + ] }, "Spec.Kubernetes.NodePool.Instance": { "type": "object", @@ -588,13 +646,20 @@ }, "volumeType": { "type": "string", - "enum": ["gp2", "gp3", "io1", "standard"] + "enum": [ + "gp2", + "gp3", + "io1", + "standard" + ] }, "maxPods": { "type": "integer" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Kubernetes.NodePool.Size": { "type": "object", @@ -611,7 +676,10 @@ "description": "The maximum number of nodes in the node pool" } }, - "required": ["max", "min"] + "required": [ + "max", + "min" + ] }, "Spec.Kubernetes.NodePool.AdditionalFirewallRules": { "type": "object", @@ -650,7 +718,10 @@ }, "type": { "type": "string", - "enum": ["ingress", "egress"] + "enum": [ + "ingress", + "egress" + ] }, "tags": { "$ref": "#/$defs/Types.AwsTags" @@ -669,7 +740,13 @@ "$ref": "#/$defs/Spec.Kubernetes.NodePool.AdditionalFirewallRule.Ports" } }, - "required": ["cidrBlocks", "name", "ports", "protocol", "type"] + "required": [ + "cidrBlocks", + "name", + "ports", + "protocol", + "type" + ] }, "Spec.Kubernetes.NodePool.AdditionalFirewallRule.SourceSecurityGroupId": { "type": "object", @@ -681,7 +758,10 @@ }, "type": { "type": "string", - "enum": ["ingress", "egress"], + "enum": [ + "ingress", + "egress" + ], "description": "The type of the FW rule can be ingress or egress" }, "tags": { @@ -700,7 +780,13 @@ "$ref": "#/$defs/Spec.Kubernetes.NodePool.AdditionalFirewallRule.Ports" } }, - "required": ["sourceSecurityGroupId", "name", "ports", "protocol", "type"] + "required": [ + "sourceSecurityGroupId", + "name", + "ports", + "protocol", + "type" + ] }, "Spec.Kubernetes.NodePool.AdditionalFirewallRule.Self": { "type": "object", @@ -712,7 +798,10 @@ }, "type": { "type": "string", - "enum": ["ingress", "egress"], + "enum": [ + "ingress", + "egress" + ], "description": "The type of the FW rule can be ingress or egress" }, "tags": { @@ -731,7 +820,13 @@ "$ref": "#/$defs/Spec.Kubernetes.NodePool.AdditionalFirewallRule.Ports" } }, - "required": ["self", "name", "ports", "protocol", "type"] + "required": [ + "self", + "name", + "ports", + "protocol", + "type" + ] }, "Spec.Kubernetes.NodePool.AdditionalFirewallRule.Ports": { "type": "object", @@ -744,7 +839,10 @@ "$ref": "#/$defs/Types.TcpPort" } }, - "required": ["from", "to"] + "required": [ + "from", + "to" + ] }, "Spec.Kubernetes.AwsAuth": { "type": "object", @@ -790,7 +888,11 @@ "$ref": "#/$defs/Types.AwsArn" } }, - "required": ["groups", "rolearn", "username"] + "required": [ + "groups", + "rolearn", + "username" + ] }, "Spec.Kubernetes.AwsAuth.User": { "type": "object", @@ -809,7 +911,11 @@ "$ref": "#/$defs/Types.AwsArn" } }, - "required": ["groups", "userarn", "username"] + "required": [ + "groups", + "userarn", + "username" + ] }, "Spec.Distribution": { "type": "object", @@ -825,16 +931,22 @@ "$ref": "../public/spec-distribution-custompatches.json" } }, - "required": ["modules"], + "required": [ + "modules" + ], "if": { "allOf": [ { - "required": ["common"] + "required": [ + "common" + ] }, { "properties": { "common": { - "required": ["provider"] + "required": [ + "provider" + ] } } }, @@ -843,7 +955,9 @@ "common": { "properties": { "provider": { - "required": ["type"] + "required": [ + "type" + ] } } } @@ -869,7 +983,9 @@ "then": { "properties": { "modules": { - "required": ["aws"] + "required": [ + "aws" + ] } } }, @@ -906,6 +1022,10 @@ "relativeVendorPath": { "type": "string", "description": "The relative path to the vendor directory, does not need to be changed" + }, + "registry": { + "type": "string", + "description": "URL of the registry where to pull images from for the Distribution phase. (Default is registry.sighup.io/fury).\n\nNOTE: If plugins are pulling from the default registry, the registry will be replaced for these plugins too." } } }, @@ -918,7 +1038,9 @@ "description": "The type of the provider, must be EKS if specified" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules": { "type": "object", @@ -952,7 +1074,12 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Policy" } }, - "required": ["dr", "ingress", "logging", "policy"] + "required": [ + "dr", + "ingress", + "logging", + "policy" + ] }, "Spec.Distribution.Modules.Ingress": { "type": "object", @@ -979,7 +1106,11 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Ingress.Forecastle" } }, - "required": ["baseDomain", "dns", "nginx"], + "required": [ + "baseDomain", + "dns", + "nginx" + ], "if": { "properties": { "nginx": { @@ -996,7 +1127,9 @@ } }, "then": { - "required": ["certManager"] + "required": [ + "certManager" + ] } }, "Spec.Distribution.Modules.Ingress.Overrides": { @@ -1043,7 +1176,11 @@ "properties": { "type": { "type": "string", - "enum": ["none", "single", "dual"], + "enum": [ + "none", + "single", + "dual" + ], "description": "The type of the nginx ingress controller, must be ***none***, ***single*** or ***dual***" }, "tls": { @@ -1053,7 +1190,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Ingress.Nginx.TLS": { "type": "object", @@ -1061,14 +1200,20 @@ "properties": { "provider": { "type": "string", - "enum": ["certManager", "secret", "none"], + "enum": [ + "certManager", + "secret", + "none" + ], "description": "The provider of the TLS certificate, must be ***none***, ***certManager*** or ***secret***" }, "secret": { "$ref": "#/$defs/Spec.Distribution.Modules.Ingress.Nginx.TLS.Secret" } }, - "required": ["provider"], + "required": [ + "provider" + ], "if": { "properties": { "provider": { @@ -1077,7 +1222,9 @@ } }, "then": { - "required": ["secret"] + "required": [ + "secret" + ] } }, "Spec.Distribution.Modules.Ingress.Nginx.TLS.Secret": { @@ -1095,7 +1242,11 @@ "type": "string" } }, - "required": ["ca", "cert", "key"] + "required": [ + "ca", + "cert", + "key" + ] }, "Spec.Distribution.Modules.Ingress.CertManager": { "type": "object", @@ -1108,7 +1259,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["clusterIssuer"] + "required": [ + "clusterIssuer" + ] }, "Spec.Distribution.Modules.Ingress.CertManager.ClusterIssuer": { "type": "object", @@ -1125,7 +1278,10 @@ }, "type": { "type": "string", - "enum": ["dns01", "http01"], + "enum": [ + "dns01", + "http01" + ], "description": "The type of the cluster issuer, must be ***dns01*** or ***http01***" }, "solvers": { @@ -1133,13 +1289,20 @@ "description": "The custom solvers configurations" } }, - "required": ["name", "email"], + "required": [ + "name", + "email" + ], "oneOf": [ { - "required": ["type"] + "required": [ + "type" + ] }, { - "required": ["solvers"] + "required": [ + "solvers" + ] } ] }, @@ -1157,7 +1320,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["public", "private"] + "required": [ + "public", + "private" + ] }, "Spec.Distribution.Modules.Ingress.DNS.Public": { "type": "object", @@ -1172,7 +1338,10 @@ "description": "If true, the public hosted zone will be created" } }, - "required": ["name", "create"] + "required": [ + "name", + "create" + ] }, "Spec.Distribution.Modules.Ingress.DNS.Private": { "type": "object", @@ -1187,7 +1356,10 @@ "description": "If true, the private hosted zone will be created" } }, - "required": ["name", "create"] + "required": [ + "name", + "create" + ] }, "Spec.Distribution.Modules.Logging": { "type": "object", @@ -1198,7 +1370,12 @@ }, "type": { "type": "string", - "enum": ["none", "opensearch", "loki", "customOutputs"], + "enum": [ + "none", + "opensearch", + "loki", + "customOutputs" + ], "description": "selects the logging stack. Choosing none will disable the centralized logging. Choosing opensearch will deploy and configure the Logging Operator and an OpenSearch cluster (can be single or triple for HA) where the logs will be stored. Choosing loki will use a distributed Grafana Loki instead of OpenSearh for storage. Choosing customOuput the Logging Operator will be deployed and installed but with no local storage, you will have to create the needed Outputs and ClusterOutputs to ship the logs to your desired storage." }, "opensearch": { @@ -1220,7 +1397,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Logging.CustomOutputs" } }, - "required": ["type"], + "required": [ + "type" + ], "allOf": [ { "if": { @@ -1231,7 +1410,9 @@ } }, "then": { - "required": ["opensearch"] + "required": [ + "opensearch" + ] } }, { @@ -1243,7 +1424,9 @@ } }, "then": { - "required": ["customOutputs"] + "required": [ + "customOutputs" + ] } } ] @@ -1254,7 +1437,10 @@ "properties": { "type": { "type": "string", - "enum": ["single", "triple"], + "enum": [ + "single", + "triple" + ], "description": "The type of the opensearch, must be ***single*** or ***triple***" }, "resources": { @@ -1268,7 +1454,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Logging.Cerebro": { "type": "object", @@ -1312,7 +1500,10 @@ "properties": { "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"] + "enum": [ + "minio", + "externalEndpoint" + ] }, "externalEndpoint": { "type": "object", @@ -1410,7 +1601,12 @@ "properties": { "type": { "type": "string", - "enum": ["none", "prometheus", "prometheusAgent", "mimir"], + "enum": [ + "none", + "prometheus", + "prometheusAgent", + "mimir" + ], "description": "The type of the monitoring, must be ***none***, ***prometheus***, ***prometheusAgent*** or ***mimir***.\n\n- `none`: will disable the whole monitoring stack.\n- `prometheus`: will install Prometheus Operator and a preconfigured Prometheus instance, Alertmanager, a set of alert rules, exporters needed to monitor all the components of the cluster, Grafana and a series of dashboards to view the collected metrics, and more.\n- `prometheusAgent`: wil install Prometheus operator, an instance of Prometheus in Agent mode (no alerting, no queries, no storage), and all the exporters needed to get metrics for the status of the cluster and the workloads. Useful when having a centralized (remote) Prometheus where to ship the metrics and not storing them locally in the cluster.\n- `mimir`: will install the same as the `prometheus` option, and in addition Grafana Mimir that allows for longer retention of metrics and the usage of Object Storage." }, "overrides": { @@ -1444,7 +1640,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Monitoring.Minio" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Monitoring.Prometheus": { "type": "object", @@ -1513,10 +1711,12 @@ "additionalProperties": false, "properties": { "usersRoleAttributePath": { - "type": "string" + "type": "string", + "description": "[JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's role. Example:\n\n```yaml\nusersRoleAttributePath: \"contains(groups[*], 'beta') && 'Admin' || contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && 'Viewer'\n```\n\nMore details in [Grafana's documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping)." }, "basicAuthIngress": { - "type": "boolean" + "type": "boolean", + "description": "Setting this to true will deploy an additional `grafana-basic-auth` ingress protected with Grafana's basic auth instead of SSO. It's intended use is as a temporary ingress for when there are problems with the SSO login flow.\n\nNotice that by default anonymous access is enabled." }, "overrides": { "$ref": "#/$defs/Types.FuryModuleComponentOverrides" @@ -1560,7 +1760,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for the mimir pods, must be ***minio*** or ***externalEndpoint***" }, "externalEndpoint": { @@ -1630,7 +1833,10 @@ }, "type": { "type": "string", - "enum": ["none", "tempo"], + "enum": [ + "none", + "tempo" + ], "description": "The type of tracing to use, either ***none*** or ***tempo***" }, "tempo": { @@ -1640,7 +1846,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Tracing.Minio" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Tracing.Tempo": { "type": "object", @@ -1652,7 +1860,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for the tempo pods, must be ***minio*** or ***externalEndpoint***" }, "externalEndpoint": { @@ -1743,7 +1954,11 @@ }, "type": { "type": "string", - "enum": ["none", "gatekeeper", "kyverno"], + "enum": [ + "none", + "gatekeeper", + "kyverno" + ], "description": "The type of security to use, either ***none***, ***gatekeeper*** or ***kyverno***" }, "gatekeeper": { @@ -1753,7 +1968,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Policy.Kyverno" } }, - "required": ["type"], + "required": [ + "type" + ], "allOf": [ { "if": { @@ -1764,7 +1981,9 @@ } }, "then": { - "required": ["gatekeeper"] + "required": [ + "gatekeeper" + ] } }, { @@ -1776,7 +1995,9 @@ } }, "then": { - "required": ["kyverno"] + "required": [ + "kyverno" + ] } } ] @@ -1794,7 +2015,11 @@ }, "enforcementAction": { "type": "string", - "enum": ["deny", "dryrun", "warn"], + "enum": [ + "deny", + "dryrun", + "warn" + ], "description": "The enforcement action to use for the gatekeeper module" }, "installDefaultPolicies": { @@ -1805,7 +2030,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["enforcementAction", "installDefaultPolicies"] + "required": [ + "enforcementAction", + "installDefaultPolicies" + ] }, "Spec.Distribution.Modules.Policy.Kyverno": { "type": "object", @@ -1820,7 +2048,10 @@ }, "validationFailureAction": { "type": "string", - "enum": ["audit", "enforce"], + "enum": [ + "audit", + "enforce" + ], "description": "The validation failure action to use for the kyverno module" }, "installDefaultPolicies": { @@ -1831,7 +2062,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["validationFailureAction", "installDefaultPolicies"] + "required": [ + "validationFailureAction", + "installDefaultPolicies" + ] }, "Spec.Distribution.Modules.Dr": { "type": "object", @@ -1842,14 +2076,19 @@ }, "type": { "type": "string", - "enum": ["none", "eks"], + "enum": [ + "none", + "eks" + ], "description": "The type of the DR, must be ***none*** or ***eks***" }, "velero": { "$ref": "#/$defs/Spec.Distribution.Modules.Dr.Velero" } }, - "required": ["type"], + "required": [ + "type" + ], "if": { "properties": { "type": { @@ -1858,7 +2097,10 @@ } }, "then": { - "required": ["type", "velero"] + "required": [ + "type", + "velero" + ] } }, "Spec.Distribution.Modules.Dr.Velero": { @@ -1872,7 +2114,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["eks"] + "required": [ + "eks" + ] }, "Spec.Distribution.Modules.Dr.Velero.Eks": { "type": "object", @@ -1888,7 +2132,10 @@ "description": "The name of the velero bucket" } }, - "required": ["region", "bucketName"] + "required": [ + "region", + "bucketName" + ] }, "Spec.Distribution.Modules.Auth": { "type": "object", @@ -1911,7 +2158,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Auth.Dex" } }, - "required": ["provider"], + "required": [ + "provider" + ], "allOf": [ { "if": { @@ -1926,7 +2175,11 @@ } }, "then": { - "required": ["dex", "pomerium", "baseDomain"] + "required": [ + "dex", + "pomerium", + "baseDomain" + ] }, "else": { "properties": { @@ -1954,7 +2207,9 @@ "then": { "properties": { "provider": { - "required": ["basicAuth"] + "required": [ + "basicAuth" + ] } } }, @@ -1979,7 +2234,10 @@ "description": "The node selector to use to place the pods for the auth module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -2006,7 +2264,10 @@ "description": "The ingress class of the ingress" } }, - "required": ["host", "ingressClass"] + "required": [ + "host", + "ingressClass" + ] }, "Spec.Distribution.Modules.Auth.Provider": { "type": "object", @@ -2014,14 +2275,20 @@ "properties": { "type": { "type": "string", - "enum": ["none", "basicAuth", "sso"], + "enum": [ + "none", + "basicAuth", + "sso" + ], "description": "The type of the provider, must be ***none***, ***sso*** or ***basicAuth***" }, "basicAuth": { "$ref": "#/$defs/Spec.Distribution.Modules.Auth.Provider.BasicAuth" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Auth.Provider.BasicAuth": { "type": "object", @@ -2036,7 +2303,10 @@ "description": "The password for the basic auth" } }, - "required": ["username", "password"] + "required": [ + "username", + "password" + ] }, "Spec.Distribution.Modules.Auth.Pomerium": { "$ref": "../public/spec-distribution-modules-auth-pomerium.json" @@ -2071,7 +2341,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["connectors"] + "required": [ + "connectors" + ] }, "Spec.Distribution.Modules.Aws": { "type": "object", @@ -2265,7 +2537,10 @@ } }, "Types.KubeNodeSelector": { - "type": ["object", "null"], + "type": [ + "object", + "null" + ], "additionalProperties": { "type": "string" } @@ -2276,11 +2551,18 @@ "properties": { "effect": { "type": "string", - "enum": ["NoSchedule", "PreferNoSchedule", "NoExecute"] + "enum": [ + "NoSchedule", + "PreferNoSchedule", + "NoExecute" + ] }, "operator": { "type": "string", - "enum": ["Exists", "Equal"] + "enum": [ + "Exists", + "Equal" + ] }, "key": { "type": "string", @@ -2291,13 +2573,20 @@ "description": "The value of the toleration" } }, - "required": ["effect", "key"], + "required": [ + "effect", + "key" + ], "anyOf": [ { - "required": ["operator"] + "required": [ + "operator" + ] }, { - "required": ["value"] + "required": [ + "value" + ] } ] }, @@ -2344,7 +2633,10 @@ "description": "The node selector to use to place the pods for the dr module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -2367,7 +2659,10 @@ "description": "The node selector to use to place the pods for the minio module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -2384,7 +2679,10 @@ "description": "The node selector to use to place the pods for the load balancer controller module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -2414,4 +2712,4 @@ } } } -} +} \ No newline at end of file diff --git a/schemas/public/kfddistribution-kfd-v1alpha2.json b/schemas/public/kfddistribution-kfd-v1alpha2.json index c746fb6ed..d8e8377a8 100644 --- a/schemas/public/kfddistribution-kfd-v1alpha2.json +++ b/schemas/public/kfddistribution-kfd-v1alpha2.json @@ -9,7 +9,9 @@ }, "kind": { "type": "string", - "enum": ["KFDDistribution"] + "enum": [ + "KFDDistribution" + ] }, "metadata": { "$ref": "#/$defs/Metadata" @@ -19,7 +21,12 @@ } }, "additionalProperties": false, - "required": ["apiVersion", "kind", "metadata", "spec"], + "required": [ + "apiVersion", + "kind", + "metadata", + "spec" + ], "$defs": { "Metadata": { "type": "object", @@ -31,7 +38,9 @@ "maxLength": 56 } }, - "required": ["name"] + "required": [ + "name" + ] }, "Spec": { "type": "object", @@ -48,7 +57,10 @@ "$ref": "./spec-plugins.json" } }, - "required": ["distributionVersion", "distribution"] + "required": [ + "distributionVersion", + "distribution" + ] }, "Spec.Distribution": { "type": "object", @@ -68,16 +80,23 @@ "$ref": "../public/spec-distribution-custompatches.json" } }, - "required": ["modules", "kubeconfig"], + "required": [ + "modules", + "kubeconfig" + ], "if": { "allOf": [ { - "required": ["common"] + "required": [ + "common" + ] }, { "properties": { "common": { - "required": ["provider"] + "required": [ + "provider" + ] } } }, @@ -86,7 +105,9 @@ "common": { "properties": { "provider": { - "required": ["type"] + "required": [ + "type" + ] } } } @@ -131,6 +152,10 @@ "relativeVendorPath": { "type": "string", "description": "The relative path to the vendor directory, does not need to be changed" + }, + "registry": { + "type": "string", + "description": "URL of the registry where to pull images from for the Distribution phase. (Default is registry.sighup.io/fury).\n\nNOTE: If plugins are pulling from the default registry, the registry will be replaced for the plugin too." } } }, @@ -143,7 +168,9 @@ "description": "The type of the provider" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules": { "type": "object", @@ -174,7 +201,12 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Policy" } }, - "required": ["dr", "ingress", "logging", "policy"] + "required": [ + "dr", + "ingress", + "logging", + "policy" + ] }, "Spec.Distribution.Modules.Ingress": { "type": "object", @@ -198,7 +230,10 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Ingress.Forecastle" } }, - "required": ["baseDomain", "nginx"], + "required": [ + "baseDomain", + "nginx" + ], "if": { "properties": { "nginx": { @@ -215,7 +250,9 @@ } }, "then": { - "required": ["certManager"] + "required": [ + "certManager" + ] } }, "Spec.Distribution.Modules.Ingress.Overrides": { @@ -262,7 +299,11 @@ "properties": { "type": { "type": "string", - "enum": ["none", "single", "dual"], + "enum": [ + "none", + "single", + "dual" + ], "description": "The type of the nginx ingress controller, must be ***none***, ***single*** or ***dual***" }, "tls": { @@ -272,7 +313,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Ingress.Nginx.TLS": { "type": "object", @@ -280,14 +323,20 @@ "properties": { "provider": { "type": "string", - "enum": ["certManager", "secret", "none"], + "enum": [ + "certManager", + "secret", + "none" + ], "description": "The provider of the TLS certificate, must be ***none***, ***certManager*** or ***secret***" }, "secret": { "$ref": "#/$defs/Spec.Distribution.Modules.Ingress.Nginx.TLS.Secret" } }, - "required": ["provider"], + "required": [ + "provider" + ], "if": { "properties": { "provider": { @@ -296,7 +345,9 @@ } }, "then": { - "required": ["secret"] + "required": [ + "secret" + ] } }, "Spec.Distribution.Modules.Ingress.Nginx.TLS.Secret": { @@ -314,7 +365,11 @@ "type": "string" } }, - "required": ["ca", "cert", "key"] + "required": [ + "ca", + "cert", + "key" + ] }, "Spec.Distribution.Modules.Ingress.CertManager": { "type": "object", @@ -327,7 +382,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["clusterIssuer"] + "required": [ + "clusterIssuer" + ] }, "Spec.Distribution.Modules.Ingress.CertManager.ClusterIssuer": { "type": "object", @@ -344,7 +401,9 @@ }, "type": { "type": "string", - "enum": ["http01"], + "enum": [ + "http01" + ], "description": "The type of the cluster issuer, must be ***http01***" }, "solvers": { @@ -352,13 +411,20 @@ "description": "The custom solvers configurations" } }, - "required": ["name", "email"], + "required": [ + "name", + "email" + ], "oneOf": [ { - "required": ["type"] + "required": [ + "type" + ] }, { - "required": ["solvers"] + "required": [ + "solvers" + ] } ] }, @@ -371,7 +437,12 @@ }, "type": { "type": "string", - "enum": ["none", "opensearch", "loki", "customOutputs"], + "enum": [ + "none", + "opensearch", + "loki", + "customOutputs" + ], "description": "selects the logging stack. Choosing none will disable the centralized logging. Choosing opensearch will deploy and configure the Logging Operator and an OpenSearch cluster (can be single or triple for HA) where the logs will be stored. Choosing loki will use a distributed Grafana Loki instead of OpenSearh for storage. Choosing customOuput the Logging Operator will be deployed and installed but with no local storage, you will have to create the needed Outputs and ClusterOutputs to ship the logs to your desired storage." }, "opensearch": { @@ -393,7 +464,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Logging.CustomOutputs" } }, - "required": ["type"], + "required": [ + "type" + ], "allOf": [ { "if": { @@ -404,7 +477,9 @@ } }, "then": { - "required": ["opensearch"] + "required": [ + "opensearch" + ] } }, { @@ -416,7 +491,9 @@ } }, "then": { - "required": ["customOutputs"] + "required": [ + "customOutputs" + ] } } ] @@ -427,7 +504,10 @@ "properties": { "type": { "type": "string", - "enum": ["single", "triple"], + "enum": [ + "single", + "triple" + ], "description": "The type of the opensearch, must be ***single*** or ***triple***" }, "resources": { @@ -441,7 +521,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Logging.Cerebro": { "type": "object", @@ -485,7 +567,10 @@ "properties": { "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"] + "enum": [ + "minio", + "externalEndpoint" + ] }, "externalEndpoint": { "type": "object", @@ -583,7 +668,12 @@ "properties": { "type": { "type": "string", - "enum": ["none", "prometheus", "prometheusAgent", "mimir"], + "enum": [ + "none", + "prometheus", + "prometheusAgent", + "mimir" + ], "description": "The type of the monitoring, must be ***none***, ***prometheus***, ***prometheusAgent*** or ***mimir***.\n\n- `none`: will disable the whole monitoring stack.\n- `prometheus`: will install Prometheus Operator and a preconfigured Prometheus instace, Alertmanager, a set of alert rules, exporters needed to monitor all the components of the cluster, Grafana and a series of dashboards to view the collected metrics, and more.\n- `prometheusAgent`: wil install Prometheus operator, an instance of Prometheus in Agent mode (no alerting, no queries, no storage), and all the exporters needed to get metrics for the status of the cluster and the workloads. Useful when having a centralized (remote) Prometheus where to ship the metrics and not storing them locally in the cluster.\n- `mimir`: will install the same as the `prometheus` option, and in addition Grafana Mimir that allows for longer retention of metrics and the usage of Object Storage." }, "overrides": { @@ -617,7 +707,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Monitoring.Minio" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Monitoring.Prometheus": { "type": "object", @@ -686,10 +778,12 @@ "additionalProperties": false, "properties": { "usersRoleAttributePath": { - "type": "string" + "type": "string", + "description": "[JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's role. Example:\n\n```yaml\nusersRoleAttributePath: \"contains(groups[*], 'beta') && 'Admin' || contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && 'Viewer'\n```\n\nMore details in [Grafana's documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping)." }, "basicAuthIngress": { - "type": "boolean" + "type": "boolean", + "description": "Setting this to true will deploy an additional `grafana-basic-auth` ingress protected with Grafana's basic auth instead of SSO. It's intended use is as a temporary ingress for when there are problems with the SSO login flow.\n\nNotice that by default anonymous access is enabled." }, "overrides": { "$ref": "#/$defs/Types.FuryModuleComponentOverrides" @@ -733,7 +827,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for the mimir pods, must be ***minio*** or ***externalEndpoint***" }, "externalEndpoint": { @@ -803,7 +900,10 @@ }, "type": { "type": "string", - "enum": ["none", "tempo"], + "enum": [ + "none", + "tempo" + ], "description": "The type of tracing to use, either ***none*** or ***tempo***" }, "tempo": { @@ -813,7 +913,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Tracing.Minio" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Tracing.Tempo": { "type": "object", @@ -825,7 +927,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for the tempo pods, must be ***minio*** or ***externalEndpoint***" }, "externalEndpoint": { @@ -901,11 +1006,17 @@ }, "type": { "type": "string", - "enum": ["none", "calico", "cilium"], + "enum": [ + "none", + "calico", + "cilium" + ], "description": "The type of networking to use, either ***none***, ***calico*** or ***cilium***" } }, - "required": ["type"], + "required": [ + "type" + ], "allOf": [ { "if": { @@ -916,7 +1027,9 @@ } }, "then": { - "required": ["cilium"] + "required": [ + "cilium" + ] } } ] @@ -944,7 +1057,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["podCidr", "maskSize"] + "required": [ + "podCidr", + "maskSize" + ] }, "Spec.Distribution.Modules.Policy": { "type": "object", @@ -955,7 +1071,11 @@ }, "type": { "type": "string", - "enum": ["none", "gatekeeper", "kyverno"], + "enum": [ + "none", + "gatekeeper", + "kyverno" + ], "description": "The type of security to use, either ***none***, ***gatekeeper*** or ***kyverno***" }, "gatekeeper": { @@ -965,7 +1085,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Policy.Kyverno" } }, - "required": ["type"], + "required": [ + "type" + ], "allOf": [ { "if": { @@ -976,7 +1098,9 @@ } }, "then": { - "required": ["gatekeeper"] + "required": [ + "gatekeeper" + ] } }, { @@ -988,7 +1112,9 @@ } }, "then": { - "required": ["kyverno"] + "required": [ + "kyverno" + ] } } ] @@ -1006,7 +1132,11 @@ }, "enforcementAction": { "type": "string", - "enum": ["deny", "dryrun", "warn"], + "enum": [ + "deny", + "dryrun", + "warn" + ], "description": "The enforcement action to use for the gatekeeper module" }, "installDefaultPolicies": { @@ -1017,7 +1147,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["enforcementAction", "installDefaultPolicies"] + "required": [ + "enforcementAction", + "installDefaultPolicies" + ] }, "Spec.Distribution.Modules.Policy.Kyverno": { "type": "object", @@ -1032,7 +1165,10 @@ }, "validationFailureAction": { "type": "string", - "enum": ["audit", "enforce"], + "enum": [ + "audit", + "enforce" + ], "description": "The validation failure action to use for the kyverno module" }, "installDefaultPolicies": { @@ -1043,7 +1179,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["validationFailureAction", "installDefaultPolicies"] + "required": [ + "validationFailureAction", + "installDefaultPolicies" + ] }, "Spec.Distribution.Modules.Dr": { "type": "object", @@ -1054,14 +1193,19 @@ }, "type": { "type": "string", - "enum": ["none", "on-premises"], + "enum": [ + "none", + "on-premises" + ], "description": "The type of the DR, must be ***none*** or ***on-premises***" }, "velero": { "$ref": "#/$defs/Spec.Distribution.Modules.Dr.Velero" } }, - "required": ["type"], + "required": [ + "type" + ], "if": { "properties": { "type": { @@ -1070,7 +1214,10 @@ } }, "then": { - "required": ["type", "velero"] + "required": [ + "type", + "velero" + ] } }, "Spec.Distribution.Modules.Dr.Velero": { @@ -1083,7 +1230,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for velero" }, "externalEndpoint": { @@ -1138,7 +1288,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Auth.Dex" } }, - "required": ["provider"], + "required": [ + "provider" + ], "allOf": [ { "if": { @@ -1153,7 +1305,11 @@ } }, "then": { - "required": ["dex", "pomerium", "baseDomain"] + "required": [ + "dex", + "pomerium", + "baseDomain" + ] }, "else": { "properties": { @@ -1181,7 +1337,9 @@ "then": { "properties": { "provider": { - "required": ["basicAuth"] + "required": [ + "basicAuth" + ] } } }, @@ -1206,7 +1364,10 @@ "description": "The node selector to use to place the pods for the auth module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -1233,7 +1394,10 @@ "description": "The ingress class of the ingress" } }, - "required": ["host", "ingressClass"] + "required": [ + "host", + "ingressClass" + ] }, "Spec.Distribution.Modules.Auth.Provider": { "type": "object", @@ -1241,14 +1405,20 @@ "properties": { "type": { "type": "string", - "enum": ["none", "basicAuth", "sso"], + "enum": [ + "none", + "basicAuth", + "sso" + ], "description": "The type of the provider, must be ***none***, ***sso*** or ***basicAuth***" }, "basicAuth": { "$ref": "#/$defs/Spec.Distribution.Modules.Auth.Provider.BasicAuth" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Auth.Provider.BasicAuth": { "type": "object", @@ -1263,7 +1433,10 @@ "description": "The password for the basic auth" } }, - "required": ["username", "password"] + "required": [ + "username", + "password" + ] }, "Spec.Distribution.Modules.Auth.Pomerium": { "$ref": "./spec-distribution-modules-auth-pomerium.json" @@ -1298,7 +1471,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["connectors"] + "required": [ + "connectors" + ] }, "Types.SemVer": { "type": "string", @@ -1347,7 +1522,10 @@ } }, "Types.KubeNodeSelector": { - "type": ["object", "null"], + "type": [ + "object", + "null" + ], "additionalProperties": { "type": "string" } @@ -1358,11 +1536,18 @@ "properties": { "effect": { "type": "string", - "enum": ["NoSchedule", "PreferNoSchedule", "NoExecute"] + "enum": [ + "NoSchedule", + "PreferNoSchedule", + "NoExecute" + ] }, "operator": { "type": "string", - "enum": ["Exists", "Equal"] + "enum": [ + "Exists", + "Equal" + ] }, "key": { "type": "string", @@ -1373,13 +1558,20 @@ "description": "The value of the toleration" } }, - "required": ["effect", "key"], + "required": [ + "effect", + "key" + ], "anyOf": [ { - "required": ["operator"] + "required": [ + "operator" + ] }, { - "required": ["value"] + "required": [ + "value" + ] } ] }, @@ -1426,7 +1618,10 @@ "description": "The node selector to use to place the pods for the security module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -1449,7 +1644,10 @@ "description": "The node selector to use to place the pods for the minio module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -1476,4 +1674,4 @@ } } } -} +} \ No newline at end of file diff --git a/schemas/public/onpremises-kfd-v1alpha2.json b/schemas/public/onpremises-kfd-v1alpha2.json index 665eec7b8..84446d1f0 100644 --- a/schemas/public/onpremises-kfd-v1alpha2.json +++ b/schemas/public/onpremises-kfd-v1alpha2.json @@ -9,7 +9,9 @@ }, "kind": { "type": "string", - "enum": ["OnPremises"] + "enum": [ + "OnPremises" + ] }, "metadata": { "$ref": "#/$defs/Metadata" @@ -19,7 +21,12 @@ } }, "additionalProperties": false, - "required": ["apiVersion", "kind", "metadata", "spec"], + "required": [ + "apiVersion", + "kind", + "metadata", + "spec" + ], "$defs": { "Metadata": { "type": "object", @@ -31,7 +38,9 @@ "maxLength": 56 } }, - "required": ["name"] + "required": [ + "name" + ] }, "Spec": { "type": "object", @@ -51,7 +60,10 @@ "$ref": "./spec-plugins.json" } }, - "required": ["distributionVersion", "distribution"] + "required": [ + "distributionVersion", + "distribution" + ] }, "Spec.Kubernetes": { "type": "object", @@ -124,7 +136,10 @@ "description": "The path to the private key to use to connect to the nodes" } }, - "required": ["username", "keyPath"] + "required": [ + "username", + "keyPath" + ] }, "Spec.Kubernetes.Proxy": { "type": "object", @@ -170,7 +185,9 @@ "description": "The additional config to use" } }, - "required": ["enabled"], + "required": [ + "enabled" + ], "if": { "properties": { "enabled": { @@ -179,7 +196,11 @@ } }, "then": { - "required": ["hosts", "keepalived", "stats"] + "required": [ + "hosts", + "keepalived", + "stats" + ] } }, "Spec.Kubernetes.LoadBalancers.Host": { @@ -195,7 +216,10 @@ "description": "The IP of the host" } }, - "required": ["name", "ip"] + "required": [ + "name", + "ip" + ] }, "Spec.Kubernetes.LoadBalancers.Keepalived": { "type": "object", @@ -222,7 +246,9 @@ "description": "The passphrase to use" } }, - "required": ["enabled"], + "required": [ + "enabled" + ], "if": { "properties": { "enabled": { @@ -231,7 +257,12 @@ } }, "then": { - "required": ["interface", "ip", "virtualRouterId", "passphrase"] + "required": [ + "interface", + "ip", + "virtualRouterId", + "passphrase" + ] } }, "Spec.Kubernetes.LoadBalancers.Stats": { @@ -247,7 +278,10 @@ "description": "The password to use" } }, - "required": ["username", "password"] + "required": [ + "username", + "password" + ] }, "Spec.Kubernetes.Masters": { "type": "object", @@ -260,7 +294,9 @@ } } }, - "required": ["hosts"] + "required": [ + "hosts" + ] }, "Spec.Kubernetes.Masters.Host": { "type": "object", @@ -275,7 +311,10 @@ "description": "The IP of the host" } }, - "required": ["name", "ip"] + "required": [ + "name", + "ip" + ] }, "Spec.Kubernetes.Nodes": { "type": "array", @@ -299,13 +338,19 @@ } }, "taints": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeTaints" } } }, - "required": ["name", "hosts"] + "required": [ + "name", + "hosts" + ] }, "Spec.Kubernetes.Nodes.Node.Host": { "type": "object", @@ -318,7 +363,10 @@ "type": "string" } }, - "required": ["name", "ip"] + "required": [ + "name", + "ip" + ] }, "Spec.Kubernetes.AdvancedAnsible": { "type": "object", @@ -355,6 +403,10 @@ }, "airGap": { "$ref": "#/$defs/Spec.Kubernetes.Advanced.AirGap" + }, + "registry": { + "type": "string", + "description": "URL of the registry where to pull images from for the Kubernetes phase. (Default is registry.sighup.io/fury/on-premises)." } } }, @@ -519,7 +571,12 @@ "description": "The gpg key id of the apt dependency" } }, - "required": ["name", "repo", "gpg_key", "gpg_key_id"] + "required": [ + "name", + "repo", + "gpg_key", + "gpg_key_id" + ] }, "yum": { "type": "object", @@ -572,16 +629,22 @@ "$ref": "../public/spec-distribution-custompatches.json" } }, - "required": ["modules"], + "required": [ + "modules" + ], "if": { "allOf": [ { - "required": ["common"] + "required": [ + "common" + ] }, { "properties": { "common": { - "required": ["provider"] + "required": [ + "provider" + ] } } }, @@ -590,7 +653,9 @@ "common": { "properties": { "provider": { - "required": ["type"] + "required": [ + "type" + ] } } } @@ -635,6 +700,10 @@ "relativeVendorPath": { "type": "string", "description": "The relative path to the vendor directory, does not need to be changed" + }, + "registry": { + "type": "string", + "description": "URL of the registry where to pull images from for the Distribution phase. (Default is registry.sighup.io/fury)." } } }, @@ -647,7 +716,9 @@ "description": "The type of the provider" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules": { "type": "object", @@ -678,7 +749,12 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Policy" } }, - "required": ["dr", "ingress", "logging", "policy"] + "required": [ + "dr", + "ingress", + "logging", + "policy" + ] }, "Spec.Distribution.Modules.Ingress": { "type": "object", @@ -717,10 +793,15 @@ } }, "then": { - "required": ["certManager"] + "required": [ + "certManager" + ] } }, - "required": ["baseDomain", "nginx"] + "required": [ + "baseDomain", + "nginx" + ] }, "Spec.Distribution.Modules.Ingress.Overrides": { "type": "object", @@ -766,7 +847,11 @@ "properties": { "type": { "type": "string", - "enum": ["none", "single", "dual"], + "enum": [ + "none", + "single", + "dual" + ], "description": "The type of the nginx ingress controller, must be ***none***, ***single*** or ***dual***" }, "tls": { @@ -776,7 +861,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Ingress.Nginx.TLS": { "type": "object", @@ -784,14 +871,20 @@ "properties": { "provider": { "type": "string", - "enum": ["certManager", "secret", "none"], + "enum": [ + "certManager", + "secret", + "none" + ], "description": "The provider of the TLS certificate, must be ***none***, ***certManager*** or ***secret***" }, "secret": { "$ref": "#/$defs/Spec.Distribution.Modules.Ingress.Nginx.TLS.Secret" } }, - "required": ["provider"], + "required": [ + "provider" + ], "if": { "properties": { "provider": { @@ -800,7 +893,9 @@ } }, "then": { - "required": ["secret"] + "required": [ + "secret" + ] } }, "Spec.Distribution.Modules.Ingress.Nginx.TLS.Secret": { @@ -818,7 +913,11 @@ "type": "string" } }, - "required": ["ca", "cert", "key"] + "required": [ + "ca", + "cert", + "key" + ] }, "Spec.Distribution.Modules.Ingress.CertManager": { "type": "object", @@ -831,7 +930,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["clusterIssuer"] + "required": [ + "clusterIssuer" + ] }, "Spec.Distribution.Modules.Ingress.CertManager.ClusterIssuer": { "type": "object", @@ -848,7 +949,9 @@ }, "type": { "type": "string", - "enum": ["http01"], + "enum": [ + "http01" + ], "description": "The type of the cluster issuer, must be ***http01***" }, "solvers": { @@ -856,13 +959,20 @@ "description": "The custom solvers configurations" } }, - "required": ["name", "email"], + "required": [ + "name", + "email" + ], "oneOf": [ { - "required": ["type"] + "required": [ + "type" + ] }, { - "required": ["solvers"] + "required": [ + "solvers" + ] } ] }, @@ -875,7 +985,12 @@ }, "type": { "type": "string", - "enum": ["none", "opensearch", "loki", "customOutputs"], + "enum": [ + "none", + "opensearch", + "loki", + "customOutputs" + ], "description": "selects the logging stack. Choosing none will disable the centralized logging. Choosing opensearch will deploy and configure the Logging Operator and an OpenSearch cluster (can be single or triple for HA) where the logs will be stored. Choosing loki will use a distributed Grafana Loki instead of OpenSearh for storage. Choosing customOuput the Logging Operator will be deployed and installed but with no local storage, you will have to create the needed Outputs and ClusterOutputs to ship the logs to your desired storage." }, "opensearch": { @@ -897,7 +1012,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Logging.CustomOutputs" } }, - "required": ["type"], + "required": [ + "type" + ], "allOf": [ { "if": { @@ -908,7 +1025,9 @@ } }, "then": { - "required": ["opensearch"] + "required": [ + "opensearch" + ] } }, { @@ -920,7 +1039,9 @@ } }, "then": { - "required": ["customOutputs"] + "required": [ + "customOutputs" + ] } } ] @@ -931,7 +1052,10 @@ "properties": { "type": { "type": "string", - "enum": ["single", "triple"], + "enum": [ + "single", + "triple" + ], "description": "The type of the opensearch, must be ***single*** or ***triple***" }, "resources": { @@ -945,7 +1069,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Logging.Cerebro": { "type": "object", @@ -989,7 +1115,10 @@ "properties": { "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"] + "enum": [ + "minio", + "externalEndpoint" + ] }, "externalEndpoint": { "type": "object", @@ -1087,7 +1216,12 @@ "properties": { "type": { "type": "string", - "enum": ["none", "prometheus", "prometheusAgent", "mimir"], + "enum": [ + "none", + "prometheus", + "prometheusAgent", + "mimir" + ], "description": "The type of the monitoring, must be ***none***, ***prometheus***, ***prometheusAgent*** or ***mimir***.\n\n- `none`: will disable the whole monitoring stack.\n- `prometheus`: will install Prometheus Operator and a preconfigured Prometheus instace, Alertmanager, a set of alert rules, exporters needed to monitor all the components of the cluster, Grafana and a series of dashboards to view the collected metrics, and more.\n- `prometheusAgent`: wil install Prometheus operator, an instance of Prometheus in Agent mode (no alerting, no queries, no storage), and all the exporters needed to get metrics for the status of the cluster and the workloads. Useful when having a centralized (remote) Prometheus where to ship the metrics and not storing them locally in the cluster.\n- `mimir`: will install the same as the `prometheus` option, and in addition Grafana Mimir that allows for longer retention of metrics and the usage of Object Storage." }, "overrides": { @@ -1121,7 +1255,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Monitoring.Minio" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Monitoring.Prometheus": { "type": "object", @@ -1190,10 +1326,12 @@ "additionalProperties": false, "properties": { "usersRoleAttributePath": { - "type": "string" + "type": "string", + "description": "[JMESPath](http://jmespath.org/examples.html) expression to retrieve the user's role. Example:\n\n```yaml\nusersRoleAttributePath: \"contains(groups[*], 'beta') && 'Admin' || contains(groups[*], 'gamma') && 'Editor' || contains(groups[*], 'delta') && 'Viewer'\n```\n\nMore details in [Grafana's documentation](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/generic-oauth/#configure-role-mapping)." }, "basicAuthIngress": { - "type": "boolean" + "type": "boolean", + "description": "Setting this to true will deploy an additional `grafana-basic-auth` ingress protected with Grafana's basic auth instead of SSO. It's intended use is as a temporary ingress for when there are problems with the SSO login flow.\n\nNotice that by default anonymous access is enabled." }, "overrides": { "$ref": "#/$defs/Types.FuryModuleComponentOverrides" @@ -1237,7 +1375,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for the mimir pods, must be ***minio*** or ***externalEndpoint***" }, "externalEndpoint": { @@ -1307,7 +1448,10 @@ }, "type": { "type": "string", - "enum": ["none", "tempo"], + "enum": [ + "none", + "tempo" + ], "description": "The type of tracing to use, either ***none*** or ***tempo***" }, "tempo": { @@ -1317,7 +1461,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Tracing.Minio" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Tracing.Tempo": { "type": "object", @@ -1329,7 +1475,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for the tempo pods, must be ***minio*** or ***externalEndpoint***" }, "externalEndpoint": { @@ -1405,11 +1554,16 @@ }, "type": { "type": "string", - "enum": ["calico", "cilium"], + "enum": [ + "calico", + "cilium" + ], "description": "The type of networking to use, either ***calico*** or ***cilium***" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Networking.TigeraOperator": { "type": "object", @@ -1446,7 +1600,11 @@ }, "type": { "type": "string", - "enum": ["none", "gatekeeper", "kyverno"], + "enum": [ + "none", + "gatekeeper", + "kyverno" + ], "description": "The type of security to use, either ***none***, ***gatekeeper*** or ***kyverno***" }, "gatekeeper": { @@ -1456,7 +1614,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Policy.Kyverno" } }, - "required": ["type"], + "required": [ + "type" + ], "allOf": [ { "if": { @@ -1467,7 +1627,9 @@ } }, "then": { - "required": ["gatekeeper"] + "required": [ + "gatekeeper" + ] } }, { @@ -1479,7 +1641,9 @@ } }, "then": { - "required": ["kyverno"] + "required": [ + "kyverno" + ] } } ] @@ -1497,7 +1661,11 @@ }, "enforcementAction": { "type": "string", - "enum": ["deny", "dryrun", "warn"], + "enum": [ + "deny", + "dryrun", + "warn" + ], "description": "The enforcement action to use for the gatekeeper module" }, "installDefaultPolicies": { @@ -1508,7 +1676,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["enforcementAction", "installDefaultPolicies"] + "required": [ + "enforcementAction", + "installDefaultPolicies" + ] }, "Spec.Distribution.Modules.Policy.Kyverno": { "type": "object", @@ -1523,7 +1694,10 @@ }, "validationFailureAction": { "type": "string", - "enum": ["audit", "enforce"], + "enum": [ + "audit", + "enforce" + ], "description": "The validation failure action to use for the kyverno module" }, "installDefaultPolicies": { @@ -1534,7 +1708,10 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["validationFailureAction", "installDefaultPolicies"] + "required": [ + "validationFailureAction", + "installDefaultPolicies" + ] }, "Spec.Distribution.Modules.Dr": { "type": "object", @@ -1545,14 +1722,19 @@ }, "type": { "type": "string", - "enum": ["none", "on-premises"], + "enum": [ + "none", + "on-premises" + ], "description": "The type of the DR, must be ***none*** or ***on-premises***" }, "velero": { "$ref": "#/$defs/Spec.Distribution.Modules.Dr.Velero" } }, - "required": ["type"], + "required": [ + "type" + ], "if": { "properties": { "type": { @@ -1561,7 +1743,10 @@ } }, "then": { - "required": ["type", "velero"] + "required": [ + "type", + "velero" + ] } }, "Spec.Distribution.Modules.Dr.Velero": { @@ -1574,7 +1759,10 @@ }, "backend": { "type": "string", - "enum": ["minio", "externalEndpoint"], + "enum": [ + "minio", + "externalEndpoint" + ], "description": "The backend for velero" }, "externalEndpoint": { @@ -1632,7 +1820,9 @@ "$ref": "#/$defs/Spec.Distribution.Modules.Auth.OIDCKubernetesAuth" } }, - "required": ["provider"], + "required": [ + "provider" + ], "allOf": [ { "if": { @@ -1647,7 +1837,11 @@ } }, "then": { - "required": ["dex", "pomerium", "baseDomain"] + "required": [ + "dex", + "pomerium", + "baseDomain" + ] } }, { @@ -1665,7 +1859,9 @@ "then": { "properties": { "provider": { - "required": ["basicAuth"] + "required": [ + "basicAuth" + ] } } } @@ -1696,7 +1892,10 @@ } ], "then": { - "required": ["baseDomain", "dex"] + "required": [ + "baseDomain", + "dex" + ] } } ] @@ -1710,7 +1909,10 @@ "description": "The node selector to use to place the pods for the auth module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -1737,7 +1939,10 @@ "description": "The ingress class of the ingress" } }, - "required": ["host", "ingressClass"] + "required": [ + "host", + "ingressClass" + ] }, "Spec.Distribution.Modules.Auth.Provider": { "type": "object", @@ -1745,14 +1950,20 @@ "properties": { "type": { "type": "string", - "enum": ["none", "basicAuth", "sso"], + "enum": [ + "none", + "basicAuth", + "sso" + ], "description": "The type of the provider, must be ***none***, ***sso*** or ***basicAuth***" }, "basicAuth": { "$ref": "#/$defs/Spec.Distribution.Modules.Auth.Provider.BasicAuth" } }, - "required": ["type"] + "required": [ + "type" + ] }, "Spec.Distribution.Modules.Auth.Provider.BasicAuth": { "type": "object", @@ -1767,7 +1978,10 @@ "description": "The password for the basic auth" } }, - "required": ["username", "password"] + "required": [ + "username", + "password" + ] }, "Spec.Distribution.Modules.Auth.Pomerium": { "$ref": "./spec-distribution-modules-auth-pomerium.json" @@ -1802,7 +2016,9 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["connectors"] + "required": [ + "connectors" + ] }, "Spec.Distribution.Modules.Auth.OIDCKubernetesAuth": { "type": "object", @@ -1848,7 +2064,9 @@ "description": "The namespace to set in the context of the kubeconfig file" } }, - "required": ["enabled"], + "required": [ + "enabled" + ], "if": { "properties": { "enabled": { @@ -1857,7 +2075,11 @@ } }, "then": { - "required": ["clientID", "clientSecret", "sessionSecurityKey"] + "required": [ + "clientID", + "clientSecret", + "sessionSecurityKey" + ] } }, "Types.SemVer": { @@ -1905,7 +2127,11 @@ "properties": { "effect": { "type": "string", - "enum": ["NoSchedule", "PreferNoSchedule", "NoExecute"] + "enum": [ + "NoSchedule", + "PreferNoSchedule", + "NoExecute" + ] }, "key": { "type": "string" @@ -1914,10 +2140,17 @@ "type": "string" } }, - "required": ["effect", "key", "value"] + "required": [ + "effect", + "key", + "value" + ] }, "Types.KubeNodeSelector": { - "type": ["object", "null"], + "type": [ + "object", + "null" + ], "additionalProperties": { "type": "string" } @@ -1928,11 +2161,18 @@ "properties": { "effect": { "type": "string", - "enum": ["NoSchedule", "PreferNoSchedule", "NoExecute"] + "enum": [ + "NoSchedule", + "PreferNoSchedule", + "NoExecute" + ] }, "operator": { "type": "string", - "enum": ["Exists", "Equal"] + "enum": [ + "Exists", + "Equal" + ] }, "key": { "type": "string", @@ -1943,13 +2183,20 @@ "description": "The value of the toleration" } }, - "required": ["effect", "key"], + "required": [ + "effect", + "key" + ], "anyOf": [ { - "required": ["operator"] + "required": [ + "operator" + ] }, { - "required": ["value"] + "required": [ + "value" + ] } ] }, @@ -1996,7 +2243,10 @@ "description": "The node selector to use to place the pods for the tracing module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -2019,7 +2269,10 @@ "description": "The node selector to use to place the pods for the minio module" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" }, @@ -2046,4 +2299,4 @@ } } } -} +} \ No newline at end of file diff --git a/schemas/public/spec-distribution-modules-auth-pomerium.json b/schemas/public/spec-distribution-modules-auth-pomerium.json index 770215ee1..e51e45199 100644 --- a/schemas/public/spec-distribution-modules-auth-pomerium.json +++ b/schemas/public/spec-distribution-modules-auth-pomerium.json @@ -1,5 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Configuration for Pomerium, an identity-aware reverse proxy used for SSO.", "type": "object", "additionalProperties": false, "properties": { @@ -11,7 +12,7 @@ }, "routes": { "type": "array", - "description": "Routes configuration for pomerium", + "description": "Additional routes configuration for Pomerium. Follows Pomerium's route format: https://www.pomerium.com/docs/reference/routes", "items": { "type": "object" } @@ -24,10 +25,13 @@ "$ref": "#/$defs/Types.FuryModuleComponentOverrides" } }, - "required": ["secrets"], + "required": [ + "secrets" + ], "$defs": { "Spec.Distribution.Modules.Auth.Pomerium.DefaultRoutesPolicy": { "type": "object", + "description": "override default routes for KFD components", "additionalProperties": false, "properties": { "monitoringPrometheus": { @@ -95,22 +99,23 @@ "Spec.Distribution.Modules.Auth.Pomerium.Secrets": { "type": "object", "additionalProperties": false, + "description": "Pomerium needs some user-provided secrets to be fully configured. These secrets should be unique between clusters.", "properties": { "COOKIE_SECRET": { "type": "string", - "description": "Cookie Secret is the secret used to encrypt and sign session cookies." + "description": "Cookie Secret is the secret used to encrypt and sign session cookies.\n\nTo generate a random key, run the following command: `head -c32 /dev/urandom | base64`" }, "IDP_CLIENT_SECRET": { "type": "string", - "description": "Identity Provider Client Secret is the OAuth 2.0 Secret Identifier retrieved from your identity provider." + "description": "Identity Provider Client Secret is the OAuth 2.0 Secret Identifier. When auth type is SSO, this value will be the secret used to authenticate Pomerium with Dex, **use a strong random value**." }, "SHARED_SECRET": { "type": "string", - "description": "Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate requests between Pomerium services. It's critical that secret keys are random, and stored safely." + "description": "Shared Secret is the base64-encoded, 256-bit key used to mutually authenticate requests between Pomerium services. It's critical that secret keys are random, and stored safely.\n\nTo generate a key, run the following command: `head -c32 /dev/urandom | base64`" }, "SIGNING_KEY": { "type": "string", - "description": "Signing Key is one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups." + "description": "Signing Key is the base64 representation of one or more PEM-encoded private keys used to sign a user's attestation JWT, which can be consumed by upstream applications to pass along identifying user information like username, id, and groups.\n\nTo generates an P-256 (ES256) signing key:\n\n```bash\nopenssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem\n# careful! this will output your private key in terminal\ncat ec_private.pem | base64\n```" } }, "required": [ @@ -120,7 +125,6 @@ "SIGNING_KEY" ] }, - "Types.FuryModuleComponentOverrides": { "type": "object", "additionalProperties": false, @@ -129,7 +133,10 @@ "$ref": "#/$defs/Types.KubeNodeSelector" }, "tolerations": { - "type": ["array", "null"], + "type": [ + "array", + "null" + ], "items": { "$ref": "#/$defs/Types.KubeToleration" } @@ -137,8 +144,13 @@ } }, "Types.KubeNodeSelector": { - "type": ["object", "null"], - "additionalProperties": { "type": "string" } + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "string" + } }, "Types.KubeToleration": { "type": "object", @@ -146,11 +158,18 @@ "properties": { "effect": { "type": "string", - "enum": ["NoSchedule", "PreferNoSchedule", "NoExecute"] + "enum": [ + "NoSchedule", + "PreferNoSchedule", + "NoExecute" + ] }, "operator": { "type": "string", - "enum": ["Exists", "Equal"] + "enum": [ + "Exists", + "Equal" + ] }, "key": { "type": "string" @@ -159,7 +178,11 @@ "type": "string" } }, - "required": ["effect", "key", "value"] + "required": [ + "effect", + "key", + "value" + ] } } } diff --git a/templates/distribution/scripts/apply.sh.tpl b/templates/distribution/scripts/apply.sh.tpl index 08af8ad3b..e04b62446 100644 --- a/templates/distribution/scripts/apply.sh.tpl +++ b/templates/distribution/scripts/apply.sh.tpl @@ -9,6 +9,14 @@ vendorPath="{{ .paths.vendorPath }}" $kustomizebin build --load_restrictor LoadRestrictionsNone . > out.yaml +{{- if and (index .spec.distribution.common "registry") (ne .spec.distribution.common.registry "") }} +if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i "" 's#registry.sighup.io/fury#{{.spec.distribution.common.registry}}#g' out.yaml +else + sed -i 's#registry.sighup.io/fury#{{.spec.distribution.common.registry}}#g' out.yaml +fi +{{- end }} + {{- if eq .spec.distribution.modules.monitoring.type "none" }} if ! $kubectlbin get apiservice v1.monitoring.coreos.com; then cat out.yaml | $yqbin 'select(.apiVersion != "monitoring.coreos.com/v1")' > out-filtered.yaml diff --git a/templates/kubernetes/onpremises/98.cluster-certificates-renewal.yaml.tpl b/templates/kubernetes/onpremises/98.cluster-certificates-renewal.yaml.tpl index bccd49556..919718197 100644 --- a/templates/kubernetes/onpremises/98.cluster-certificates-renewal.yaml.tpl +++ b/templates/kubernetes/onpremises/98.cluster-certificates-renewal.yaml.tpl @@ -29,7 +29,7 @@ serial: 1 tasks: - # Get Kubernetes version and modify the output from something like “v1.29.3” to “1.29”. + # Get Kubernetes version and modify the output from something like "v1.29.3" to "1.29". - name: Get the current Kubernetes version shell: | K8S_VERSION=$(kubectl version --kubeconfig=/etc/kubernetes/admin.conf --short 2>/dev/null | grep 'Server Version:' | awk '{print $3}') diff --git a/templates/kubernetes/onpremises/hosts.yaml.tpl b/templates/kubernetes/onpremises/hosts.yaml.tpl index b26f70b9b..100d7b2b0 100644 --- a/templates/kubernetes/onpremises/hosts.yaml.tpl +++ b/templates/kubernetes/onpremises/hosts.yaml.tpl @@ -77,6 +77,10 @@ all: {{- end }} {{- end }} + + {{- if and (index .spec.kubernetes.advanced "registry") (ne .spec.kubernetes.advanced.registry "") }} + kubernetes_image_registry: "{{ .spec.kubernetes.advanced.registry }}" + {{- end }} nodes: children: {{- range $n := .spec.kubernetes.nodes }} diff --git a/tests/e2e-kfddistribution-upgrades.sh b/tests/e2e-kfddistribution-upgrades.sh index c41af4083..4d570b55d 100755 --- a/tests/e2e-kfddistribution-upgrades.sh +++ b/tests/e2e-kfddistribution-upgrades.sh @@ -17,6 +17,10 @@ echo "-------------------------------------------------------------------------- echo "Executing upgrade to the next version" /tmp/furyctl apply --upgrade --config tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.7.yaml --outdir "$PWD" --force upgrades --disable-analytics +echo "----------------------------------------------------------------------------" +echo "Executing upgrade to the next version" +/tmp/furyctl apply --upgrade --config tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.8.yaml --outdir "$PWD" --force upgrades --disable-analytics + echo "----------------------------------------------------------------------------" echo "Executing upgrade to the latest version" -/tmp/furyctl apply --upgrade --config tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.8.yaml --outdir "$PWD" --distro-location ./ --force upgrades --disable-analytics +/tmp/furyctl apply --upgrade --config tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.9.yaml --outdir "$PWD" --distro-location ./ --force upgrades --disable-analytics diff --git a/tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.9.yaml b/tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.9.yaml new file mode 100644 index 000000000..c548bab52 --- /dev/null +++ b/tests/e2e/kfddistribution-upgrades/furyctl-init-cluster-1.27.9.yaml @@ -0,0 +1,104 @@ +# Copyright (c) 2017-present SIGHUP s.r.l All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +--- +apiVersion: kfd.sighup.io/v1alpha2 +kind: KFDDistribution +metadata: + name: sighup +spec: + distributionVersion: v1.27.9 + # This section describes how the KFD distribution will be installed + distribution: + kubeconfig: "{env://KUBECONFIG}" + # This common configuration will be applied to all the packages that will be installed in the cluster + common: {} + # This section contains all the configurations for all the KFD core modules + modules: + networking: + type: calico + # This section contains all the configurations for the ingress module + ingress: + baseDomain: fury.sighup.cc + nginx: + type: single + tls: + provider: certManager + certManager: + clusterIssuer: + name: letsencrypt-fury + email: sighup@sighup.cc + type: http01 + logging: + type: loki + minio: + storageSize: 20Gi + rootUser: + username: sighup + password: secretpassword1 + monitoring: + type: prometheus + prometheus: + resources: + requests: + cpu: 10m + limits: + cpu: 2000m + memory: 6Gi + tracing: + type: none + policy: + type: kyverno + kyverno: + additionalExcludedNamespaces: ["local-path-storage"] + validationFailureAction: enforce + installDefaultPolicies: true + dr: + type: on-premises + velero: {} + auth: + provider: + type: basicAuth + basicAuth: + username: test + password: testpassword + # patches for kind compatibility and resource setting + customPatches: + patchesStrategicMerge: + - | + apiVersion: apps/v1 + kind: StatefulSet + metadata: + name: minio-logging + namespace: logging + spec: + template: + spec: + containers: + - name: minio + resources: + requests: + cpu: 10m + memory: 50Mi + - | + $patch: delete + apiVersion: logging-extensions.banzaicloud.io/v1alpha1 + kind: HostTailer + metadata: + name: systemd-common + namespace: logging + - | + $patch: delete + apiVersion: logging-extensions.banzaicloud.io/v1alpha1 + kind: HostTailer + metadata: + name: systemd-etcd + namespace: logging + - | + $patch: delete + apiVersion: apps/v1 + kind: DaemonSet + metadata: + name: x509-certificate-exporter-control-plane + namespace: monitoring