From 255503acb63d1cb28300fcb1d55c014c09be214a Mon Sep 17 00:00:00 2001 From: CJ_Clippy Date: Tue, 5 Nov 2024 11:48:21 -0800 Subject: [PATCH] use supertokens --- MANTRAS.md | 4 +- Makefile | 6 +- Tiltfile | 333 +- charts/README.md | 19 +- .../chisel-operator/.helmignore | 23 + .../chisel-operator/Chart.yaml | 6 + .../chisel-operator/templates/_helpers.tpl | 62 + .../templates/crds/exit-node-provisioner.yaml | 101 + .../templates/crds/exit-node.yaml | 84 + .../chisel-operator/templates/deployment.yaml | 49 + .../templates/serviceaccount.yaml | 58 + .../chisel-operator/values.yaml | 51 + charts/drupal/README.md | 3 + charts/drupal/drupal/.helmignore | 25 + charts/drupal/drupal/Chart.lock | 9 + charts/drupal/drupal/Chart.yaml | 42 + charts/drupal/drupal/README.md | 586 + charts/drupal/drupal/templates/NOTES.txt | 88 + charts/drupal/drupal/templates/_helpers.tpl | 144 + .../drupal/drupal/templates/deployment.yaml | 384 + .../drupal/templates/externaldb-secrets.yaml | 19 + .../drupal/drupal/templates/extra-list.yaml | 9 + charts/drupal/drupal/templates/ingress.yaml | 66 + .../drupal/drupal/templates/metrics-svc.yaml | 39 + .../drupal/templates/networkpolicy.yaml | 80 + charts/drupal/drupal/templates/pdb.yaml | 26 + .../drupal/templates/prometheusrule.yaml | 23 + charts/drupal/drupal/templates/pv.yaml | 23 + charts/drupal/drupal/templates/pvc.yaml | 33 + charts/drupal/drupal/templates/secrets.yaml | 26 + .../drupal/templates/serviceaccount.yaml | 18 + .../drupal/templates/servicemonitor.yaml | 43 + charts/drupal/drupal/templates/svc.yaml | 57 + .../drupal/drupal/templates/tls-secrets.yaml | 22 + charts/drupal/drupal/values.schema.json | 233 + charts/drupal/drupal/values.yaml | 982 ++ charts/drupal/values-overrides.yaml | 15 + charts/fp/templates-staging/chihaya.yaml | 39 + .../mailbox.yaml | 0 charts/fp/templates/chihaya.yaml | 79 - charts/fp/templates/chisel.yaml | 13 +- .../fp/templates/{build.yaml => factory.yaml} | 24 +- charts/fp/templates/game-2048.yaml | 102 - charts/fp/templates/gateway.yaml | 12 + charts/fp/templates/next.yaml | 63 +- charts/fp/templates/pgadmin4.yaml | 2 +- charts/fp/templates/postgrest.yaml | 31 +- charts/fp/templates/strapi.yaml | 227 - charts/fp/templates/supertokens.yaml | 138 + charts/fp/templates/traefik.yaml | 122 +- charts/fp/templates/whoami.yaml | 66 +- charts/fp/values.yaml | 27 +- charts/mariadb/mariadb/.helmignore | 25 + charts/mariadb/mariadb/Chart.lock | 6 + charts/mariadb/mariadb/Chart.yaml | 36 + charts/mariadb/mariadb/README.md | 650 + charts/mariadb/mariadb/templates/NOTES.txt | 77 + charts/mariadb/mariadb/templates/_helpers.tpl | 164 + .../mariadb/mariadb/templates/extra-list.yaml | 9 + .../mariadb/templates/networkpolicy.yaml | 76 + .../mariadb/templates/primary/configmap.yaml | 20 + .../primary/initialization-configmap.yaml | 19 + .../mariadb/templates/primary/pdb.yaml | 28 + .../templates/primary/statefulset.yaml | 443 + .../mariadb/templates/primary/svc.yaml | 62 + .../mariadb/templates/prometheusrules.yaml | 24 + charts/mariadb/mariadb/templates/role.yaml | 23 + .../mariadb/templates/rolebinding.yaml | 23 + .../templates/secondary/configmap.yaml | 20 + .../mariadb/templates/secondary/pdb.yaml | 28 + .../templates/secondary/statefulset.yaml | 414 + .../mariadb/templates/secondary/svc.yaml | 64 + charts/mariadb/mariadb/templates/secrets.yaml | 98 + .../mariadb/templates/serviceaccount.yaml | 18 + .../mariadb/templates/servicemonitor.yaml | 44 + charts/mariadb/mariadb/values.schema.json | 176 + charts/mariadb/mariadb/values.yaml | 1373 ++ charts/mariadb/values-overrides.yaml | 8 + charts/phpmyadmin/phpmyadmin/.helmignore | 25 + charts/phpmyadmin/phpmyadmin/Chart.lock | 9 + charts/phpmyadmin/phpmyadmin/Chart.yaml | 38 + charts/phpmyadmin/phpmyadmin/README.md | 588 + .../phpmyadmin/phpmyadmin/templates/NOTES.txt | 69 + .../phpmyadmin/templates/_helpers.tpl | 86 + .../phpmyadmin/templates/certs.yaml | 27 + .../phpmyadmin/templates/deployment.yaml | 306 + .../phpmyadmin/templates/extra-list.yaml | 9 + .../phpmyadmin/templates/ingress.yaml | 65 + .../phpmyadmin/templates/metrics-svc.yaml | 45 + .../phpmyadmin/templates/networkpolicy.yaml | 80 + .../phpmyadmin/phpmyadmin/templates/pdb.yaml | 26 + .../phpmyadmin/templates/service.yaml | 59 + .../phpmyadmin/templates/serviceaccount.yaml | 18 + .../phpmyadmin/templates/servicemonitor.yaml | 46 + .../phpmyadmin/templates/tls-secrets.yaml | 43 + charts/phpmyadmin/phpmyadmin/values.yaml | 803 ++ charts/phpmyadmin/values-overrides.yaml | 6 + charts/traefik/traefik/Changelog.md | 1370 ++ charts/traefik/traefik/Chart.yaml | 20 +- charts/traefik/traefik/EXAMPLES.md | 58 +- charts/traefik/traefik/Guidelines.md | 72 +- charts/traefik/traefik/VALUES.md | 257 +- .../crds/gateway-standard-install-v1.2.0.yaml | 10345 ++++++++++++++++ ....networking.k8s.io_backendtlspolicies.yaml | 281 - ...eway.networking.k8s.io_gatewayclasses.yaml | 381 - .../gateway.networking.k8s.io_gateways.yaml | 1037 -- .../gateway.networking.k8s.io_grpcroutes.yaml | 819 -- .../gateway.networking.k8s.io_httproutes.yaml | 2263 ---- ...way.networking.k8s.io_referencegrants.yaml | 205 - .../gateway.networking.k8s.io_tcproutes.yaml | 284 - .../gateway.networking.k8s.io_tlsroutes.yaml | 294 - .../gateway.networking.k8s.io_udproutes.yaml | 284 - .../crds/hub.traefik.io_apiaccesses.yaml | 35 + .../crds/hub.traefik.io_apibundles.yaml | 125 + .../traefik/crds/hub.traefik.io_apiplans.yaml | 103 + .../crds/traefik.io_ingressroutes.yaml | 30 +- .../crds/traefik.io_ingressroutetcps.yaml | 22 +- .../crds/traefik.io_ingressrouteudps.yaml | 4 +- .../traefik/crds/traefik.io_middlewares.yaml | 96 +- .../crds/traefik.io_middlewaretcps.yaml | 8 +- .../crds/traefik.io_serverstransports.yaml | 4 +- .../crds/traefik.io_serverstransporttcps.yaml | 4 +- .../traefik/crds/traefik.io_tlsoptions.yaml | 10 +- .../traefik/crds/traefik.io_tlsstores.yaml | 4 +- .../crds/traefik.io_traefikservices.yaml | 17 +- charts/traefik/traefik/templates/_helpers.tpl | 17 + .../traefik/templates/_podtemplate.tpl | 81 +- charts/traefik/traefik/templates/_service.tpl | 4 +- .../traefik/traefik/templates/daemonset.yaml | 12 +- .../traefik/traefik/templates/deployment.yaml | 14 +- charts/traefik/traefik/templates/gateway.yaml | 12 +- .../templates/hub-admission-controller.yaml | 100 +- .../traefik/templates/rbac/clusterrole.yaml | 117 +- .../templates/rbac/clusterrolebinding.yaml | 9 +- .../traefik/traefik/templates/rbac/role.yaml | 27 +- .../traefik/templates/requirements.yaml | 13 + charts/traefik/traefik/templates/service.yaml | 13 +- charts/traefik/traefik/values.schema.json | 1676 +++ charts/traefik/traefik/values.yaml | 559 +- charts/traefik/values-overrides.yaml | 27 +- devbox.json | 3 +- devbox.lock | 50 +- .../{build.dockerfile => factory.dockerfile} | 18 +- dockerfiles/strapi.dockerfile | 15 - dockerfiles/strapi.dockerfile.full | 58 - flux/apps/base/drupal/kustomization.yaml | 5 + flux/apps/base/drupal/release.yaml | 25 + flux/apps/base/mariadb/kustomization.yaml | 5 + flux/apps/base/mariadb/release.yaml | 23 + flux/apps/development/README.md | 10 + flux/apps/development/fp-values.yaml | 20 + flux/apps/development/kustomization.yaml | 19 + flux/apps/development/podinfo-values.yaml | 19 + package.json | 3 +- packages/types/src/index.ts | 6 + packages/types/tsconfig.json | 2 +- packages/utils/src/image.spec.ts | 2 +- .../2024-10-07-from-strapi-to-postgrest.sql | 350 + scripts/data-migrations/2024-10-18-drupal.php | 79 + ...024-10-25-from-strapi-to-postgrest-mk2.sql | 80 + scripts/data-migrations/README.md | 17 + scripts/data-migrations/a.migration.sh | 28 + scripts/data-migrations/scratch.sql | 14 + scripts/drupal-init-wrapper.sh | 8 + scripts/drupal-init.sh | 24 + scripts/k8s-chisel.sh | 13 - scripts/k8s-secrets.sh | 35 + scripts/supertokens-seed.sh | 4 + services/factory/.mocharc.json | 6 + services/{build => factory}/README.md | 0 services/factory/crontab | 17 + services/{build => factory}/package.json | 8 +- services/{build => factory}/pnpm-lock.yaml | 91 + services/{build => factory}/src/config.ts | 8 + services/{build => factory}/src/index.ts | 6 +- .../src/tasks/combine_video_segments.ts | 0 .../src/tasks/generate_thumbnail.ts | 0 .../src/tasks/process_video.ts | 0 .../src/tasks/remux_video.ts | 0 .../src/tasks/synchronize_patrons_list.ts | 252 + .../src/utils/importDirectory.ts | 0 services/{build => factory}/tsconfig.json | 0 .../migrations/00079_stream_id-optional.sql | 9 + .../00080_add-created_at-to-vtubers.sql | 11 + .../00081_add-id_deprecated-to-vods.sql | 3 + .../00082_add-id_deprecated-to-s3_files.sql | 3 + .../migrations/00083_create_vods_s3_join.sql | 5 + .../00084_add-file_id-to-s3_files.sql | 2 + .../migrations/00085_sync-s3_files.sql | 9 + .../00086_add-cdn_url-to-s3_files.sql | 2 + .../migrations/00087_remove-id_deprecated.sql | 2 + ...0088_remove-id_deprecated-from-vtubers.sql | 2 + .../00089_create-vods_s3_files_join.sql | 10 + .../00090_rename-vods-s3-files-joins.sql | 19 + .../00091_drop-vods_s3_file_join.sql | 2 + .../migrations/00092_use-s3_file_id.sql | 5 + .../migrations/00093_enable-pg_trgm.sql | 2 + .../migrations/00094_add-patrons-table.sql | 7 + .../migrations/00095_create-contributors.sql | 7 + services/next/app/404.tsx | 3 + .../next/app/api/auth/[[...path]]/route.ts | 39 + services/next/app/auth/[[...path]]/page.tsx | 27 + services/next/app/callback/route.ts | 11 + services/next/app/components/auth.tsx | 16 +- services/next/app/components/navbar.tsx | 15 +- .../app/components/supertokensProvider.tsx | 18 + services/next/app/components/tagger.tsx | 8 +- .../next/app/components/user-controls.tsx | 2 + services/next/app/components/video-player.tsx | 4 +- services/next/app/components/vod-card.tsx | 2 +- services/next/app/components/vod-page.tsx | 2 +- services/next/app/config/appInfo.ts | 8 + services/next/app/config/backend.ts | 75 + services/next/app/config/configs.ts | 43 + services/next/app/config/frontend.tsx | 48 + services/next/app/layout.tsx | 50 +- services/next/app/lib/constants.ts | 3 + services/next/app/lib/dates.ts | 7 +- services/next/app/lib/fetch-api.ts | 6 +- services/next/app/lib/patreon.ts | 17 +- services/next/app/lib/vods.ts | 73 +- services/next/app/logto.ts | 11 + services/next/app/page.tsx | 28 +- services/next/app/sign-in.tsx | 19 + services/next/app/sign-out.tsx | 19 + services/next/app/uppy.tsx | 76 +- services/next/logto.ts | 13 + services/next/package.json | 6 + services/next/pnpm-lock.yaml | 614 +- ...12.32.00.convert-to-video-src-b2.js.noexec | 4 +- 230 files changed, 27245 insertions(+), 7570 deletions(-) create mode 100644 charts/chisel-operator/chisel-operator/.helmignore create mode 100644 charts/chisel-operator/chisel-operator/Chart.yaml create mode 100644 charts/chisel-operator/chisel-operator/templates/_helpers.tpl create mode 100644 charts/chisel-operator/chisel-operator/templates/crds/exit-node-provisioner.yaml create mode 100644 charts/chisel-operator/chisel-operator/templates/crds/exit-node.yaml create mode 100644 charts/chisel-operator/chisel-operator/templates/deployment.yaml create mode 100644 charts/chisel-operator/chisel-operator/templates/serviceaccount.yaml create mode 100644 charts/chisel-operator/chisel-operator/values.yaml create mode 100644 charts/drupal/README.md create mode 100644 charts/drupal/drupal/.helmignore create mode 100644 charts/drupal/drupal/Chart.lock create mode 100644 charts/drupal/drupal/Chart.yaml create mode 100644 charts/drupal/drupal/README.md create mode 100644 charts/drupal/drupal/templates/NOTES.txt create mode 100644 charts/drupal/drupal/templates/_helpers.tpl create mode 100644 charts/drupal/drupal/templates/deployment.yaml create mode 100644 charts/drupal/drupal/templates/externaldb-secrets.yaml create mode 100644 charts/drupal/drupal/templates/extra-list.yaml create mode 100644 charts/drupal/drupal/templates/ingress.yaml create mode 100644 charts/drupal/drupal/templates/metrics-svc.yaml create mode 100644 charts/drupal/drupal/templates/networkpolicy.yaml create mode 100644 charts/drupal/drupal/templates/pdb.yaml create mode 100644 charts/drupal/drupal/templates/prometheusrule.yaml create mode 100644 charts/drupal/drupal/templates/pv.yaml create mode 100644 charts/drupal/drupal/templates/pvc.yaml create mode 100644 charts/drupal/drupal/templates/secrets.yaml create mode 100644 charts/drupal/drupal/templates/serviceaccount.yaml create mode 100644 charts/drupal/drupal/templates/servicemonitor.yaml create mode 100644 charts/drupal/drupal/templates/svc.yaml create mode 100644 charts/drupal/drupal/templates/tls-secrets.yaml create mode 100644 charts/drupal/drupal/values.schema.json create mode 100644 charts/drupal/drupal/values.yaml create mode 100644 charts/drupal/values-overrides.yaml create mode 100644 charts/fp/templates-staging/chihaya.yaml rename charts/fp/{templates => templates-staging}/mailbox.yaml (100%) delete mode 100644 charts/fp/templates/chihaya.yaml rename charts/fp/templates/{build.yaml => factory.yaml} (74%) delete mode 100644 charts/fp/templates/game-2048.yaml create mode 100644 charts/fp/templates/gateway.yaml delete mode 100644 charts/fp/templates/strapi.yaml create mode 100644 charts/fp/templates/supertokens.yaml create mode 100644 charts/mariadb/mariadb/.helmignore create mode 100644 charts/mariadb/mariadb/Chart.lock create mode 100644 charts/mariadb/mariadb/Chart.yaml create mode 100644 charts/mariadb/mariadb/README.md create mode 100644 charts/mariadb/mariadb/templates/NOTES.txt create mode 100644 charts/mariadb/mariadb/templates/_helpers.tpl create mode 100644 charts/mariadb/mariadb/templates/extra-list.yaml create mode 100644 charts/mariadb/mariadb/templates/networkpolicy.yaml create mode 100644 charts/mariadb/mariadb/templates/primary/configmap.yaml create mode 100644 charts/mariadb/mariadb/templates/primary/initialization-configmap.yaml create mode 100644 charts/mariadb/mariadb/templates/primary/pdb.yaml create mode 100644 charts/mariadb/mariadb/templates/primary/statefulset.yaml create mode 100644 charts/mariadb/mariadb/templates/primary/svc.yaml create mode 100644 charts/mariadb/mariadb/templates/prometheusrules.yaml create mode 100644 charts/mariadb/mariadb/templates/role.yaml create mode 100644 charts/mariadb/mariadb/templates/rolebinding.yaml create mode 100644 charts/mariadb/mariadb/templates/secondary/configmap.yaml create mode 100644 charts/mariadb/mariadb/templates/secondary/pdb.yaml create mode 100644 charts/mariadb/mariadb/templates/secondary/statefulset.yaml create mode 100644 charts/mariadb/mariadb/templates/secondary/svc.yaml create mode 100644 charts/mariadb/mariadb/templates/secrets.yaml create mode 100644 charts/mariadb/mariadb/templates/serviceaccount.yaml create mode 100644 charts/mariadb/mariadb/templates/servicemonitor.yaml create mode 100644 charts/mariadb/mariadb/values.schema.json create mode 100644 charts/mariadb/mariadb/values.yaml create mode 100644 charts/mariadb/values-overrides.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/.helmignore create mode 100644 charts/phpmyadmin/phpmyadmin/Chart.lock create mode 100644 charts/phpmyadmin/phpmyadmin/Chart.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/README.md create mode 100644 charts/phpmyadmin/phpmyadmin/templates/NOTES.txt create mode 100644 charts/phpmyadmin/phpmyadmin/templates/_helpers.tpl create mode 100644 charts/phpmyadmin/phpmyadmin/templates/certs.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/deployment.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/extra-list.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/ingress.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/metrics-svc.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/networkpolicy.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/pdb.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/service.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/serviceaccount.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/servicemonitor.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/templates/tls-secrets.yaml create mode 100644 charts/phpmyadmin/phpmyadmin/values.yaml create mode 100644 charts/phpmyadmin/values-overrides.yaml create mode 100644 charts/traefik/traefik/crds/gateway-standard-install-v1.2.0.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_backendtlspolicies.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_gatewayclasses.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_gateways.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_grpcroutes.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_httproutes.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_referencegrants.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_tcproutes.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_tlsroutes.yaml delete mode 100644 charts/traefik/traefik/crds/gateway.networking.k8s.io_udproutes.yaml create mode 100644 charts/traefik/traefik/crds/hub.traefik.io_apibundles.yaml create mode 100644 charts/traefik/traefik/crds/hub.traefik.io_apiplans.yaml create mode 100644 charts/traefik/traefik/values.schema.json rename dockerfiles/{build.dockerfile => factory.dockerfile} (79%) delete mode 100644 dockerfiles/strapi.dockerfile delete mode 100644 dockerfiles/strapi.dockerfile.full create mode 100644 flux/apps/base/drupal/kustomization.yaml create mode 100644 flux/apps/base/drupal/release.yaml create mode 100644 flux/apps/base/mariadb/kustomization.yaml create mode 100644 flux/apps/base/mariadb/release.yaml create mode 100644 flux/apps/development/README.md create mode 100644 flux/apps/development/fp-values.yaml create mode 100644 flux/apps/development/kustomization.yaml create mode 100644 flux/apps/development/podinfo-values.yaml create mode 100644 scripts/data-migrations/2024-10-07-from-strapi-to-postgrest.sql create mode 100644 scripts/data-migrations/2024-10-18-drupal.php create mode 100644 scripts/data-migrations/2024-10-25-from-strapi-to-postgrest-mk2.sql create mode 100644 scripts/data-migrations/README.md create mode 100755 scripts/data-migrations/a.migration.sh create mode 100644 scripts/data-migrations/scratch.sql create mode 100755 scripts/drupal-init-wrapper.sh create mode 100755 scripts/drupal-init.sh delete mode 100755 scripts/k8s-chisel.sh create mode 100755 scripts/supertokens-seed.sh create mode 100644 services/factory/.mocharc.json rename services/{build => factory}/README.md (100%) create mode 100644 services/factory/crontab rename services/{build => factory}/package.json (87%) rename services/{build => factory}/pnpm-lock.yaml (97%) rename services/{build => factory}/src/config.ts (80%) rename services/{build => factory}/src/index.ts (90%) rename services/{build => factory}/src/tasks/combine_video_segments.ts (100%) rename services/{build => factory}/src/tasks/generate_thumbnail.ts (100%) rename services/{build => factory}/src/tasks/process_video.ts (100%) rename services/{build => factory}/src/tasks/remux_video.ts (100%) create mode 100644 services/factory/src/tasks/synchronize_patrons_list.ts rename services/{build => factory}/src/utils/importDirectory.ts (100%) rename services/{build => factory}/tsconfig.json (100%) create mode 100644 services/migrations/migrations/00079_stream_id-optional.sql create mode 100644 services/migrations/migrations/00080_add-created_at-to-vtubers.sql create mode 100644 services/migrations/migrations/00081_add-id_deprecated-to-vods.sql create mode 100644 services/migrations/migrations/00082_add-id_deprecated-to-s3_files.sql create mode 100644 services/migrations/migrations/00083_create_vods_s3_join.sql create mode 100644 services/migrations/migrations/00084_add-file_id-to-s3_files.sql create mode 100644 services/migrations/migrations/00085_sync-s3_files.sql create mode 100644 services/migrations/migrations/00086_add-cdn_url-to-s3_files.sql create mode 100644 services/migrations/migrations/00087_remove-id_deprecated.sql create mode 100644 services/migrations/migrations/00088_remove-id_deprecated-from-vtubers.sql create mode 100644 services/migrations/migrations/00089_create-vods_s3_files_join.sql create mode 100644 services/migrations/migrations/00090_rename-vods-s3-files-joins.sql create mode 100644 services/migrations/migrations/00091_drop-vods_s3_file_join.sql create mode 100644 services/migrations/migrations/00092_use-s3_file_id.sql create mode 100644 services/migrations/migrations/00093_enable-pg_trgm.sql create mode 100644 services/migrations/migrations/00094_add-patrons-table.sql create mode 100644 services/migrations/migrations/00095_create-contributors.sql create mode 100644 services/next/app/404.tsx create mode 100644 services/next/app/api/auth/[[...path]]/route.ts create mode 100644 services/next/app/auth/[[...path]]/page.tsx create mode 100644 services/next/app/callback/route.ts create mode 100644 services/next/app/components/supertokensProvider.tsx create mode 100644 services/next/app/config/appInfo.ts create mode 100644 services/next/app/config/backend.ts create mode 100644 services/next/app/config/configs.ts create mode 100644 services/next/app/config/frontend.tsx create mode 100644 services/next/app/logto.ts create mode 100644 services/next/app/sign-in.tsx create mode 100644 services/next/app/sign-out.tsx create mode 100644 services/next/logto.ts diff --git a/MANTRAS.md b/MANTRAS.md index f752e20..ebee7de 100644 --- a/MANTRAS.md +++ b/MANTRAS.md @@ -48,4 +48,6 @@ In other words, pick something for a name and roll with the punches. ### Never Settle > "But it's also about looking at things anew and what they could be instead of what they are" -> -- Rodney Mullen \ No newline at end of file +> -- Rodney Mullen + +### Success requires continuing even when it's painful \ No newline at end of file diff --git a/Makefile b/Makefile index aeb4a96..3b8b6f8 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,10 @@ secrets: flux: ./scripts/flux-bootstrap.sh -chisel: - ./scripts/k8s-chisel.sh +cluster: echoenv kind namespaces gateway secrets velero flux metrics chisel -cluster: echoenv kind namespaces secrets velero flux metrics chisel +gateway: + kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml metrics: ./scripts/k8s-metrics.sh diff --git a/Tiltfile b/Tiltfile index 8854403..eb06f3e 100644 --- a/Tiltfile +++ b/Tiltfile @@ -9,6 +9,18 @@ secret_settings( disable_scrub=True ) +## @warning Don't use kubefwd, it's unreliable. In my testing, it deleted important /etc/hosts entries. +## Our workaround for SSL in dev is to use a VPS with caddy and chisel. +## Caddy handles SSL certs/termination and chisel proxies into our cluster. +## This means that cert-manager is only used in staging and production env (not development.) +## This also means Gateway and HTTPRoute is only used in staging and production. +## @todo Caddy/Chisel is not ideal since that setup is out-of-scope of the monorepo. For now it's the best solution because it unblocks our DX +## +## @see https://blog.tilt.dev/2021/09/09/kubefwd-operator.html +# v1alpha1.extension_repo(name='default', url='https://github.com/tilt-dev/tilt-extensions') +# v1alpha1.extension(name='kubefwd:config', repo_name='default', repo_path='kubefwd') + + ## helm_remote and deploy_cert_manager are BANNED because they use too much bandwidth and crash my computer ## ## cert-manager slows down Tilt updates so I prefer to keep it commented unless I specifically need to test certs @@ -26,6 +38,17 @@ load('ext://dotenv', 'dotenv') dotenv(fn='.env.development') +## Right now we use Tilt/Helm in dev and Flux/Kustomize/Helm in production. +## It is a pipedream to use the same deployment/templating tool in development as we do in production. This vastly simplifies deployment. +## We can't use Flux in development unless we figure out a way for flux/kustomize to reference our fp Helm chart as a relative directory. +## Right now, we reference gitea.futureporn.net (kind: GitRepository) where Kustomize downloads the fp Helm chart. +## We could possibly rewrite our fp Helm chart as a Kustomization and then deprecate Helm in development. +## k8s_yaml(kustomize('./flux/apps/development')) +## We are constrained to CrossNamespaceObjectReference kind list +## @see https://fluxcd.io/flux/components/helm/api/v2/#helm.toolkit.fluxcd.io/v2.CrossNamespaceObjectReference +## @see https://github.com/fluxcd/helm-controller/blob/c8ae4b6ad225d37b19bacb634db784d6096908ac/api/v2beta2/reference_types.go#L53 + + # helm_remote( # 'velero', # repo_name='velero', @@ -64,13 +87,8 @@ dotenv(fn='.env.development') # namespace='futureporn', # version='7.1.4', # ) -# helm_remote( -# 'frp-operator', -# repo_name='frp-operator', -# repo_url='https://zufardhiyaulhaq.com/frp-operator/charts/releases/', -# namespace='futureporn', -# version='1.0.0' -# ) + + # helm_remote( # 'kubernetes-ingress-controller', # repo_name='kubernetes-ingress-controller', @@ -91,18 +109,23 @@ dotenv(fn='.env.development') - - +k8s_yaml(helm( + './charts/traefik/traefik', + namespace='futureporn', + values=[ + './charts/traefik/values-overrides.yaml' + ] +)) k8s_yaml(helm( './charts/fp', values=['./charts/fp/values.yaml'], )) -## we are using a local helm chart instead of using helm_remote because that command makes the tilt builds Hella slow. -## to download this chart, we used the following commands. -## future re-pulling is needed to keep things up-to-date. -## -## helm repo add bitnami https://charts.bitnami.com/bitnami -## helm pull bitnami/postgresql --untar --destination ./charts/postgresql +# we are using a local helm chart instead of using helm_remote because that command makes the tilt builds Hella slow. +# to download this chart, we used the following commands. +# future re-pulling is needed to keep things up-to-date. +# +# helm repo add bitnami https://charts.bitnami.com/bitnami +# helm pull bitnami/postgresql --untar --destination ./charts/postgresql k8s_yaml(helm( './charts/postgresql/postgresql', namespace='futureporn', @@ -120,6 +143,32 @@ k8s_yaml(helm( ] )) + + +# k8s_yaml(helm( +# './charts/drupal/drupal', +# namespace='futureporn', +# values=[ +# './charts/drupal/values-overrides.yaml' +# ] +# )) + +# k8s_yaml(helm( +# './charts/phpmyadmin/phpmyadmin', +# namespace='futureporn', +# values=[ +# './charts/phpmyadmin/values-overrides.yaml' +# ] +# )) + +# k8s_yaml(helm( +# './charts/mariadb/mariadb', +# namespace='futureporn', +# values=[ +# './charts/mariadb/values-overrides.yaml' +# ] +# )) + # k8s_yaml(helm( # './charts/external-secrets/external-secrets', # namespace='futureporn', @@ -127,19 +176,11 @@ k8s_yaml(helm( -k8s_yaml(helm( - './charts/traefik/traefik', - namespace='futureporn', - values=[ - './charts/traefik/values-overrides.yaml' - ] -)) - -## redis is for uppy -## before you think of switching to valkey, dragonfly, or one of the other redis alternatives, STOP. Uppy is picky. -## I tested dragonfly, valkey, and KeyDB. Uppy's ioredis client was unable to connect. "ECONNREFUSED" ... -## Uppy was only happy connecting to official redis. +# ## redis is for uppy +# ## before you think of switching to valkey, dragonfly, or one of the other redis alternatives, STOP. Uppy is picky. +# ## I tested dragonfly, valkey, and KeyDB. Uppy's ioredis client was unable to connect. "ECONNREFUSED" ... +# ## Uppy was only happy connecting to official redis. k8s_yaml(helm( './charts/redis/redis', namespace='futureporn', @@ -154,14 +195,15 @@ k8s_yaml(helm( values=['./charts/cert-manager/values-overrides.yaml'] )) -## chisel-operator helm chart is not ready for general use. It has an invalid DNS name, "v1.1" that prevents successful deployment -## instead, we use kustomize to deploy -## @see ./Makefile -# k8s_yaml(helm( -# './charts/chisel-operator/chisel-operator', -# namespace='futureporn', -# values=['./charts/chisel-operator/values-overrides.yaml'] -# )) +k8s_yaml(helm( + './charts/chisel-operator/chisel-operator', + namespace='futureporn', + values=['./charts/chisel-operator/values-overrides.yaml'] +)) +k8s_resource( + workload='chisel-operator', + labels=['networking'], +) ## ngrok # k8s_yaml(helm( @@ -172,24 +214,7 @@ k8s_yaml(helm( # docker_build('fp/link2cid', './packages/link2cid') -docker_build( - 'fp/strapi', - '.', - dockerfile='./dockerfiles/strapi.dockerfile', - target='strapi', - only=[ - './.npmrc', - './package.json', - './pnpm-lock.yaml', - './pnpm-workspace.yaml', - './services/strapi', - './packages/types', - ], - live_update=[ - sync('./services/strapi', '/usr/src/app') - ], - pull=False, -) + docker_build( 'fp/bot', @@ -239,6 +264,12 @@ docker_build( load('ext://uibutton', 'cmd_button') +cmd_button('supertokens:seed', + argv=['./scripts/supertokens-seed.sh'], + resource='supertokens', + icon_name='start', + text='create supertokens database', +) cmd_button('postgres:restore', argv=['./scripts/postgres-restore.sh'], resource='postgresql-primary', @@ -265,6 +296,12 @@ cmd_button('capture-worker:create', icon_name='send', text='Recording Integration Test' ) +# cmd_button('drupal:init', +# argv=['./scripts/drupal-init-wrapper.sh'], +# resource='drupal', +# icon_name='send', +# text='Initialize Drupal' +# ) cmd_button('postgres:migrate', argv=['./scripts/postgres-migrations.sh'], @@ -304,9 +341,6 @@ docker_build( '.', dockerfile='dockerfiles/next.dockerfile', target='dev', - build_args={ - 'NEXT_PUBLIC_STRAPI_URL': 'https://strapi.fp.sbtp.xyz', - }, live_update=[ sync('./services/next', '/app/services/next') ], @@ -314,12 +348,12 @@ docker_build( ) docker_build( - 'fp/build', + 'fp/factory', '.', - dockerfile='./dockerfiles/build.dockerfile', + dockerfile='./dockerfiles/factory.dockerfile', target='dev', live_update=[ - sync('./services/build', '/app/services/build') + sync('./services/factory', '/app/services/factory') ], pull=False, ) @@ -327,30 +361,30 @@ docker_build( -docker_build( - 'fp/mailbox', - '.', - dockerfile='dockerfiles/mailbox.dockerfile', - target='mailbox', - only=[ - './.npmrc', - './package.json', - './pnpm-lock.yaml', - './pnpm-workspace.yaml', - './services/mailbox', - './packages/types', - './packages/utils', - './packages/fetchers', - './packages/video', - './packages/storage', - ], - live_update=[ - sync('./services/mailbox', '/app'), - run('cd /app && pnpm i', trigger=['./services/mailbox/package.json', './services/mailbox/pnpm-lock.yaml']), - ], - pull=False, - # entrypoint='pnpm nodemon --ext js,ts,json,yaml --exec node --no-warnings=ExperimentalWarning --loader ts-node/esm ./src/index.ts' -) +# docker_build( +# 'fp/mailbox', +# '.', +# dockerfile='dockerfiles/mailbox.dockerfile', +# target='mailbox', +# only=[ +# './.npmrc', +# './package.json', +# './pnpm-lock.yaml', +# './pnpm-workspace.yaml', +# './services/mailbox', +# './packages/types', +# './packages/utils', +# './packages/fetchers', +# './packages/video', +# './packages/storage', +# ], +# live_update=[ +# sync('./services/mailbox', '/app'), +# run('cd /app && pnpm i', trigger=['./services/mailbox/package.json', './services/mailbox/pnpm-lock.yaml']), +# ], +# pull=False, +# # entrypoint='pnpm nodemon --ext js,ts,json,yaml --exec node --no-warnings=ExperimentalWarning --loader ts-node/esm ./src/index.ts' +# ) @@ -380,30 +414,11 @@ docker_build( -# k8s_resource( -# workload='kubernetes-ingress-controller-manager', -# links=[ -# link(os.getenv('NGROK_URL'), 'Endpoint') -# ], -# labels='ngrok' -# ) -# k8s_resource( -# workload='frp-operator-controller-manager', -# labels='tunnel' -# ) -# k8s_resource( -# workload='echo', -# links=[ -# link('https://echo.fp.sbtp.xyz'), -# link('http://echo.futureporn.svc.cluster.local:8001') -# ], -# labels='debug' -# ) k8s_resource( workload='scout', resource_deps=['postgresql-primary'], - port_forwards=['8134'], + # port_forwards=['8134'], labels=['backend'], ) k8s_resource( @@ -416,32 +431,16 @@ k8s_resource( ) k8s_resource( workload='next', - port_forwards=['3000'], links=[ link('https://next.fp.sbtp.xyz'), + link('https://next.fp.sbtp.xyz/api/auth/dashboard'), ], resource_deps=['postgrest', 'postgresql-primary'], labels=['frontend'], ) -k8s_resource( - workload='strapi', - port_forwards=['1339'], - links=[ - link('https://strapi.fp.sbtp.xyz/admin'), - link('https://strapi.fp.sbtp.xyz'), - ], - resource_deps=['postgresql-primary'], - labels=['backend'], -) -k8s_resource( - workload='game-2048', - port_forwards=['8088:80'], - labels=['frontend'], - links=[ - link('https://game-2048.fp.sbtp.xyz/') - ] -) + +# whoami is for testing routing k8s_resource( workload='whoami', labels=['frontend'], @@ -451,7 +450,7 @@ k8s_resource( ) k8s_resource( workload='postgresql-primary', - port_forwards=['5432'], + # port_forwards=['5432'], labels=['database'], ) k8s_resource( @@ -459,18 +458,65 @@ k8s_resource( labels=['database'] ) +# k8s_resource( +# workload='mariadb', +# labels=['database'] +# ) +# k8s_resource( +# workload='drupal', +# resource_deps=['mariadb'], +# labels=['backend'], +# port_forwards=['9797:8080'], +# links=[ +# link('https://drupal.fp.sbtp.xyz'), +# ], +# ) k8s_resource( - workload='mailbox', - resource_deps=['postgresql-primary', 'strapi'], + workload='chart-velero', + resource_deps=['postgresql-primary'], labels=['backend'], ) k8s_resource( - workload='build', - resource_deps=['postgrest'], + workload='chart-velero-upgrade-crds', + resource_deps=['postgresql-primary'], labels=['backend'], ) +# k8s_resource( +# workload='logto', +# port_forwards=['3001', '3002'], +# links=[ +# link('https://logto.fp.sbtp.xyz'), +# link('https://logto-admin.fp.sbtp.xyz'), +# ], +# labels=['backend'], +# ) +# k8s_resource( +# workload='logto-database-seed', +# labels=['database'], +# ) +# k8s_resource( +# workload='phpmyadmin', +# port_forwards=['5151:8080'], +# labels=['database'], +# ) + +k8s_resource( + workload='supertokens', + links=[ + link('https://supertokens.fp.sbtp.xyz'), + ], + labels=['backend'], +) + + +# k8s_resource( +# workload='mailbox', +# resource_deps=['postgresql-primary', 'postgrest'], +# labels=['backend'], +# ) + # k8s_resource( # workload='nitter', # port_forwards=['6060:10606'], @@ -507,10 +553,11 @@ k8s_resource( labels=['networking'], ) -# k8s_resource( -# workload='ngrok-manager', -# labels=['networking'], -# ) + +k8s_resource( + workload='factory', + labels=['backend'], +) k8s_resource( workload='redis-master', @@ -526,20 +573,30 @@ k8s_resource( labels=['backend'], resource_deps=['postgrest', 'postgresql-primary'], ) -k8s_resource( - workload='chihaya', - labels=['backend'] -) +# k8s_resource( +# workload='chihaya', +# labels=['backend'] +# ) k8s_resource( workload='postgrest', - port_forwards=['9000'], + # port_forwards=['9000'], labels=['database'], + links=[ + link('https://postgrest.fp.sbtp.xyz'), + ], resource_deps=['postgresql-primary'], ) - +k8s_resource( + workload='traefik', + links=[ + link('https://traefik.fp.sbtp.xyz/whoami'), + link('https://traefik.fp.sbtp.xyz/postgrest'), + ], + labels=['networking'], +) k8s_resource( workload='pgadmin4', - port_forwards=['5050:80'], + # port_forwards=['5050:80'], labels=['database'], ) k8s_resource( diff --git a/charts/README.md b/charts/README.md index 4177dae..4910adc 100644 --- a/charts/README.md +++ b/charts/README.md @@ -35,7 +35,7 @@ We override default values in the parent folder. ### chisel-operator - pnpx tiged 'https://github.com/FyraLabs/chisel-operator/charts/chisel-operator#v0.3.4' ./charts/chisel-operator/chisel-operator + helm pull oci://ghcr.io/fyralabs/chisel-operator/chisel-operator --version 0.1.0 --untar --destination ./charts/chisel-operator ### ngrok @@ -45,7 +45,7 @@ We override default values in the parent folder. ### traefik helm repo add traefik https://traefik.github.io/charts - helm pull traefik/traefik --version 30.0.2 --untar --destination ./charts/traefik + helm pull traefik/traefik --version 33.0.0 --untar --destination ./charts/traefik ### velero @@ -55,4 +55,17 @@ We override default values in the parent folder. ### external-secrets-operator helm repo add external-secrets https://charts.external-secrets.io - helm pull external-secrets/external-secrets --version 0.10.2 --untar --destination ./charts/external-secrets \ No newline at end of file + helm pull external-secrets/external-secrets --version 0.10.2 --untar --destination ./charts/external-secrets + +### drupal + + helm pull oci://registry-1.docker.io/bitnamicharts/drupal --version 20.0.10 --untar --destination ./charts/drupal + +### mariadb + + helm repo add bitnami https://charts.bitnami.com/bitnami --force-update + helm pull bitnami/mariadb --untar --destination ./charts/mariadb + +### phpmyadmin + + helm pull bitnami/phpmyadmin --version 17.0.7 --untar --destination ./charts/phpmyadmin diff --git a/charts/chisel-operator/chisel-operator/.helmignore b/charts/chisel-operator/chisel-operator/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/chisel-operator/chisel-operator/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/chisel-operator/chisel-operator/Chart.yaml b/charts/chisel-operator/chisel-operator/Chart.yaml new file mode 100644 index 0000000..5c12ad5 --- /dev/null +++ b/charts/chisel-operator/chisel-operator/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: v0.4.1 +description: Kubernetes Operator for deploying Chisel reverse proxies +name: chisel-operator +type: application +version: 0.1.0 diff --git a/charts/chisel-operator/chisel-operator/templates/_helpers.tpl b/charts/chisel-operator/chisel-operator/templates/_helpers.tpl new file mode 100644 index 0000000..a13353f --- /dev/null +++ b/charts/chisel-operator/chisel-operator/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "chisel-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "chisel-operator.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "chisel-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "chisel-operator.labels" -}} +helm.sh/chart: {{ include "chisel-operator.chart" . }} +{{ include "chisel-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "chisel-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "chisel-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "chisel-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "chisel-operator.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/chisel-operator/chisel-operator/templates/crds/exit-node-provisioner.yaml b/charts/chisel-operator/chisel-operator/templates/crds/exit-node-provisioner.yaml new file mode 100644 index 0000000..64ff698 --- /dev/null +++ b/charts/chisel-operator/chisel-operator/templates/crds/exit-node-provisioner.yaml @@ -0,0 +1,101 @@ + + +{{- if .Values.createCrds }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: exitnodeprovisioners.chisel-operator.io +spec: + group: chisel-operator.io + names: + categories: [] + kind: ExitNodeProvisioner + plural: exitnodeprovisioners + shortNames: [] + singular: exitnodeprovisioner + scope: Namespaced + versions: + - additionalPrinterColumns: [] + name: v1 + schema: + openAPIV3Schema: + description: Auto-generated derived type for ExitNodeProvisionerSpec via `CustomResource` + properties: + spec: + description: ExitNodeProvisioner is a custom resource that represents a Chisel exit node provisioner on a cloud provider. + oneOf: + - required: + - DigitalOcean + - required: + - Linode + - required: + - AWS + properties: + AWS: + properties: + auth: + description: Reference to a secret containing the AWS access key ID and secret access key, under the `access_key_id` and `secret_access_key` secret keys + type: string + region: + description: Region ID for the AWS region to provision the exit node in See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html + type: string + security_group: + description: Security group name to use for the exit node, uses the default security group if not specified + nullable: true + type: string + size: + default: t2.micro + description: Size for the EC2 instance See https://aws.amazon.com/ec2/instance-types/ + type: string + required: + - auth + - region + type: object + DigitalOcean: + properties: + auth: + description: Reference to a secret containing the DigitalOcean API token, under the `DIGITALOCEAN_TOKEN` secret key + type: string + region: + default: '' + description: Region ID of the DigitalOcean datacenter to provision the exit node in If empty, DigitalOcean will randomly select a region for you, which might not be what you want See https://slugs.do-api.dev/ + type: string + size: + default: s-1vcpu-1gb + description: Size for the DigitalOcean droplet See https://slugs.do-api.dev/ + type: string + ssh_fingerprints: + default: [] + description: SSH key fingerprints to add to the exit node + items: + type: string + type: array + required: + - auth + type: object + Linode: + properties: + auth: + description: Name of the secret containing the Linode API token, under the `LINODE_TOKEN` secret key + type: string + region: + description: Region ID of the Linode datacenter to provision the exit node in See https://api.linode.com/v4/regions + type: string + size: + default: g6-nanode-1 + description: Size for the Linode instance See https://api.linode.com/v4/linode/ + type: string + required: + - auth + - region + type: object + type: object + required: + - spec + title: ExitNodeProvisioner + type: object + served: true + storage: true + subresources: {} + +{{- end }} \ No newline at end of file diff --git a/charts/chisel-operator/chisel-operator/templates/crds/exit-node.yaml b/charts/chisel-operator/chisel-operator/templates/crds/exit-node.yaml new file mode 100644 index 0000000..7d679f2 --- /dev/null +++ b/charts/chisel-operator/chisel-operator/templates/crds/exit-node.yaml @@ -0,0 +1,84 @@ +{{- if .Values.createCrds -}} + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: exitnodes.chisel-operator.io +spec: + group: chisel-operator.io + names: + categories: [] + kind: ExitNode + plural: exitnodes + shortNames: [] + singular: exitnode + scope: Namespaced + versions: + - additionalPrinterColumns: [] + name: v1 + schema: + openAPIV3Schema: + description: Auto-generated derived type for ExitNodeSpec via `CustomResource` + properties: + spec: + description: ExitNode is a custom resource that represents a Chisel exit node. It will be used as the reverse proxy for all services in the cluster. + properties: + auth: + description: Optional authentication secret name to connect to the control plane + nullable: true + type: string + chisel_image: + description: Optional value for the chisel client image used to connect to the chisel server If not provided, jpillora/chisel:latest is used + nullable: true + type: string + default_route: + default: false + description: Optional boolean value for whether to make the exit node the default route for the cluster If true, the exit node will be the default route for the cluster default value is false + type: boolean + external_host: + description: Optional real external hostname/IP of exit node If not provided, the host field will be used + nullable: true + type: string + fingerprint: + description: Optional but highly recommended fingerprint to perform host-key validation against the server's public key + nullable: true + type: string + host: + description: Hostname or IP address of the chisel server + type: string + port: + description: Control plane port of the chisel server + format: uint16 + minimum: 0.0 + type: integer + required: + - host + - port + type: object + status: + nullable: true + properties: + id: + nullable: true + type: string + ip: + type: string + name: + type: string + provider: + type: string + required: + - ip + - name + - provider + type: object + required: + - spec + title: ExitNode + type: object + served: true + storage: true + subresources: + status: {} + +{{- end -}} \ No newline at end of file diff --git a/charts/chisel-operator/chisel-operator/templates/deployment.yaml b/charts/chisel-operator/chisel-operator/templates/deployment.yaml new file mode 100644 index 0000000..af36049 --- /dev/null +++ b/charts/chisel-operator/chisel-operator/templates/deployment.yaml @@ -0,0 +1,49 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "chisel-operator.fullname" . }} + labels: + name: {{- include "chisel-operator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount}} + selector: + matchLabels: + {{- include "chisel-operator.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "chisel-operator.selectorLabels" . | nindent 8 }} + spec: + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ include "chisel-operator.serviceAccountName" . }} + automountServiceAccountToken: true # This is required + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "chisel-operator.serviceAccountName" . }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + diff --git a/charts/chisel-operator/chisel-operator/templates/serviceaccount.yaml b/charts/chisel-operator/chisel-operator/templates/serviceaccount.yaml new file mode 100644 index 0000000..beac4f6 --- /dev/null +++ b/charts/chisel-operator/chisel-operator/templates/serviceaccount.yaml @@ -0,0 +1,58 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "chisel-operator.serviceAccountName" . }} + labels: + {{- include "chisel-operator.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "chisel-operator.serviceAccountName" . }} + labels: + {{- include "chisel-operator.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: ["apps"] + resources: ["deployments", "deployments/*"] + verbs: ["*"] + - apiGroups: [""] + resources: ["services", "services/status", "services/finalizers"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["chisel-operator.io"] + resources: ["*"] + verbs: ["*"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "create", "update", "patch", "delete"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "chisel-operator.serviceAccountName" . }} + labels: + {{- include "chisel-operator.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ include "chisel-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "chisel-operator.serviceAccountName" . }} + apiGroup: rbac.authorization.k8s.io + + +{{- end }} diff --git a/charts/chisel-operator/chisel-operator/values.yaml b/charts/chisel-operator/chisel-operator/values.yaml new file mode 100644 index 0000000..0bab700 --- /dev/null +++ b/charts/chisel-operator/chisel-operator/values.yaml @@ -0,0 +1,51 @@ +# Default values for chisel-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 # Right now only 1 replica is supported +# LeaderElection and multiple replicas may be supported in the future. +# For now, we recommend running only 1 replica else Chisel Operator may constantly +# recreate resources, wasting your API resources and costing you money. + +image: + repository: ghcr.io/fyralabs/chisel-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + # tag: + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Create CRDs for Chisel Operator +createCrds: true diff --git a/charts/drupal/README.md b/charts/drupal/README.md new file mode 100644 index 0000000..b07acbd --- /dev/null +++ b/charts/drupal/README.md @@ -0,0 +1,3 @@ +## drupal notes + +To initialize drupal with all the modules we need, use the "Initialize Drupal" button in Tilt's UI. Or see the script it executes in ../../scripts/drupal-init.sh \ No newline at end of file diff --git a/charts/drupal/drupal/.helmignore b/charts/drupal/drupal/.helmignore new file mode 100644 index 0000000..207983f --- /dev/null +++ b/charts/drupal/drupal/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# img folder +img/ +# Changelog +CHANGELOG.md diff --git a/charts/drupal/drupal/Chart.lock b/charts/drupal/drupal/Chart.lock new file mode 100644 index 0000000..9e7f677 --- /dev/null +++ b/charts/drupal/drupal/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: mariadb + repository: oci://registry-1.docker.io/bitnamicharts + version: 19.0.7 +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.24.0 +digest: sha256:1a41985df21415bc1a7fdd62b58daa1b60b31f2c2ebda4b9506e099a372b338c +generated: "2024-10-03T11:38:53.545931255Z" diff --git a/charts/drupal/drupal/Chart.yaml b/charts/drupal/drupal/Chart.yaml new file mode 100644 index 0000000..6826be6 --- /dev/null +++ b/charts/drupal/drupal/Chart.yaml @@ -0,0 +1,42 @@ +annotations: + category: CMS + images: | + - name: apache-exporter + image: docker.io/bitnami/apache-exporter:1.0.9-debian-12-r1 + - name: drupal + image: docker.io/bitnami/drupal:11.0.5-debian-12-r1 + - name: os-shell + image: docker.io/bitnami/os-shell:12-debian-12-r31 + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 11.0.5 +dependencies: +- condition: mariadb.enabled + name: mariadb + repository: oci://registry-1.docker.io/bitnamicharts + version: 19.x.x +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: Drupal is one of the most versatile open source content management systems + in the world. It is pre-configured with the Ctools and Views modules, Drush and + Let's Encrypt auto-configuration support. +home: https://bitnami.com +icon: https://bitnami.com/assets/stacks/drupal/img/drupal-stack-220x234.png +keywords: +- drupal +- cms +- blog +- http +- web +- application +- php +maintainers: +- name: Broadcom, Inc. All Rights Reserved. + url: https://github.com/bitnami/charts +name: drupal +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/drupal +version: 20.0.10 diff --git a/charts/drupal/drupal/README.md b/charts/drupal/drupal/README.md new file mode 100644 index 0000000..41108fc --- /dev/null +++ b/charts/drupal/drupal/README.md @@ -0,0 +1,586 @@ + + +# Bitnami package for Drupal + +Drupal is one of the most versatile open source content management systems in the world. It is pre-configured with the Ctools and Views modules, Drush and Let's Encrypt auto-configuration support. + +[Overview of Drupal](http://drupal.org) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/drupal +``` + +Looking to use Drupal in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the commercial edition of the Bitnami catalog. + +## Introduction + +This chart bootstraps a [Drupal](https://github.com/bitnami/containers/tree/main/bitnami/drupal) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +It also packages the [Bitnami MariaDB chart](https://github.com/bitnami/charts/tree/main/bitnami/mariadb) which is required for bootstrapping a MariaDB deployment as a database for the Drupal application. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ +- PV provisioner support in the underlying infrastructure +- ReadWriteMany volumes for deployment scaling + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://REGISTRY_NAME/REPOSITORY_NAME/drupal +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The command deploys Drupal on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Configuration and installation details + +### Resource requests and limits + +Bitnami charts allow setting resource requests and limits for all containers inside the chart deployment. These are inside the `resources` value (check parameter table). Setting requests is essential for production workloads and these should be adapted to your specific use case. + +To make this process easier, the chart contains the `resourcesPreset` values, which automatically sets the `resources` section according to different presets. Check these presets in [the bitnami/common chart](https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15). However, in production workloads using `resourcePreset` is discouraged as it may not fully adapt to your specific needs. Find more information on container resource management in the [official Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +### [Rolling VS Immutable tags](https://docs.vmware.com/en/VMware-Tanzu-Application-Catalog/services/tutorials/GUID-understand-rolling-tags-containers-index.html) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Image + +The `image` parameter allows specifying which image will be pulled for the chart. + +#### Private registry + +If you configure the `image` value to one in a private registry, you will need to [specify an image pull secret](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod). + +1. Manually create image pull secret(s) in the namespace. See [this YAML example reference](https://kubernetes.io/docs/concepts/containers/images/#creating-a-secret-with-a-docker-config). Consult your image registry's documentation about getting the appropriate secret. +2. Note that the `imagePullSecrets` configuration value cannot currently be passed to helm using the `--set` parameter, so you must supply these using a `values.yaml` file, such as: + + ```yaml + imagePullSecrets: + - name: SECRET_NAME + ``` + +3. Install the chart + +### Setting Pod's affinity + +This chart allows you to set your custom affinity using the `affinity` parameter. Find more information about Pod's affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `podAffinityPreset`, `podAntiAffinityPreset`, or `nodeAffinityPreset` parameters. + +## Persistence + +The [Bitnami Drupal](https://github.com/bitnami/containers/tree/main/bitnami/drupal) image stores the Drupal data and configurations at the `/bitnami/drupal` path of the container. + +Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. +See the [Parameters](#parameters) section to configure the PVC or to disable persistence. + +### Existing PersistentVolumeClaim + +1. Create the PersistentVolume +2. Create the PersistentVolumeClaim +3. Install the chart + +```console +helm install my-release --set persistence.existingClaim=PVC_NAME oci://REGISTRY_NAME/REPOSITORY_NAME/drupal +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +### Host path + +#### System compatibility + +- The local filesystem accessibility to a container in a pod with `hostPath` has been tested on OSX/MacOS with xhyve, and Linux with VirtualBox. +- Windows has not been tested with the supported VM drivers. Minikube does however officially support [Mounting Host Folders](https://minikube.sigs.k8s.io/docs/handbook/mount/) per pod. Or you may manually sync your container whenever host files are changed with tools like [docker-sync](https://github.com/EugenMayer/docker-sync) or [docker-bg-sync](https://github.com/cweagans/docker-bg-sync). + +#### Mounting steps + +1. The specified `hostPath` directory must already exist (create one if it does not). +2. Install the chart + + ```console + helm install my-release --set persistence.hostPath=/PATH/TO/HOST/MOUNT oci://REGISTRY_NAME/REPOSITORY_NAME/drupal + ``` + + > Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + + This will mount the `drupal-data` volume into the `hostPath` directory. The site data will be persisted if the mount path contains valid data, else the site data will be initialized at first launch. +3. Because the container cannot control the host machine's directory permissions, you must set the Drupal file directory permissions yourself and disable or clear Drupal cache. See Drupal Core's [INSTALL.txt](https://cgit.drupalcode.org/drupal/tree/core/INSTALL.txt?h=8.3.x#n152) for setting file permissions, and see [Drupal handbook page](https://www.drupal.org/node/2598914) to disable the cache, or [Drush handbook](https://drushcommands.com/drush-8x/cache/cache-rebuild/) to clear cache. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.defaultStorageClass` | Global default StorageClass for Persistent Volume(s) | `""` | +| `global.storageClass` | DEPRECATED: use global.defaultStorageClass instead | `""` | +| `global.compatibility.openshift.adaptSecurityContext` | Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) | `auto` | + +### Common parameters + +| Name | Description | Value | +| ------------------- | ---------------------------------------------------------------------------------------------------------- | ----- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override drupal.fullname template (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override drupal.fullname template | `""` | +| `namespaceOverride` | String to fully override common.names.namespace | `""` | +| `commonAnnotations` | Common annotations to add to all Drupal resources (sub-charts are not considered). Evaluated as a template | `{}` | +| `commonLabels` | Common labels to add to all Drupal resources (sub-charts are not considered). Evaluated as a template | `{}` | +| `extraDeploy` | Array of extra objects to deploy with the release (evaluated as a template). | `[]` | + +### Drupal parameters + +| Name | Description | Value | +| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `image.registry` | Drupal image registry | `REGISTRY_NAME` | +| `image.repository` | Drupal Image name | `REPOSITORY_NAME/drupal` | +| `image.digest` | Drupal image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | Drupal image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `image.debug` | Specify if debug logs should be enabled | `false` | +| `replicaCount` | Number of Drupal Pods to run (requires ReadWriteMany PVC support) | `1` | +| `drupalProfile` | Drupal installation profile | `standard` | +| `drupalSkipInstall` | Skip Drupal installation wizard. Useful for migrations and restoring from SQL dump | `false` | +| `drupalUsername` | User of the application | `user` | +| `drupalPassword` | Application password | `""` | +| `drupalEmail` | Admin email | `user@example.com` | +| `allowEmptyPassword` | Allow DB blank passwords | `true` | +| `command` | Override default container command (useful when using custom images) | `[]` | +| `args` | Override default container args (useful when using custom images) | `[]` | +| `updateStrategy.type` | Update strategy - only really applicable for deployments with RWO PVs attached | `RollingUpdate` | +| `priorityClassName` | Drupal pods' priorityClassName | `""` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `automountServiceAccountToken` | Mount Service Account token in pod | `false` | +| `hostAliases` | Add deployment host aliases | `[]` | +| `extraEnvVars` | Extra environment variables | `[]` | +| `extraEnvVarsCM` | ConfigMap containing extra env vars | `""` | +| `extraEnvVarsSecret` | Secret containing extra env vars (in case of sensitive data) | `""` | +| `extraVolumes` | Array of extra volumes to be added to the deployment (evaluated as template). Requires setting `extraVolumeMounts` | `[]` | +| `extraVolumeMounts` | Array of extra volume mounts to be added to the container (evaluated as template). Normally used with `extraVolumes`. | `[]` | +| `initContainers` | Add additional init containers to the pod (evaluated as a template) | `[]` | +| `pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` | +| `pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `""` | +| `pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `pdb.minAvailable` and `pdb.maxUnavailable` are empty. | `""` | +| `sidecars` | Attach additional containers to the pod (evaluated as a template) | `[]` | +| `tolerations` | Tolerations for pod assignment | `[]` | +| `serviceAccount.create` | Specifies whether a service account should be created | `true` | +| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `""` | +| `serviceAccount.annotations` | Add annotations | `{}` | +| `serviceAccount.automountServiceAccountToken` | Automount API credentials for a service account. | `false` | +| `existingSecret` | Name of a secret with the application password | `""` | +| `smtpHost` | SMTP host | `""` | +| `smtpPort` | SMTP port | `""` | +| `smtpUser` | SMTP user | `""` | +| `smtpPassword` | SMTP password | `""` | +| `smtpProtocol` | SMTP Protocol (options: ssl,tls, nil) | `""` | +| `containerPorts` | Container ports | `{}` | +| `extraContainerPorts` | Optionally specify extra list of additional ports for Drupal container(s) | `[]` | +| `sessionAffinity` | Control where client requests go, to the same pod or round-robin. Values: ClientIP or None | `None` | +| `persistence.enabled` | Enable persistence using PVC | `true` | +| `persistence.storageClass` | PVC Storage Class for Drupal volume | `""` | +| `persistence.accessModes` | PVC Access Mode for Drupal volume | `["ReadWriteOnce"]` | +| `persistence.size` | PVC Storage Request for Drupal volume | `8Gi` | +| `persistence.existingClaim` | A manually managed Persistent Volume Claim | `""` | +| `persistence.hostPath` | If defined, the drupal-data volume will mount to the specified hostPath. | `""` | +| `persistence.annotations` | Persistent Volume Claim annotations | `{}` | +| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `nodeAffinityPreset.key` | Node label key to match Ignored if `affinity` is set. | `""` | +| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | +| `affinity` | Affinity for pod assignment | `{}` | +| `nodeSelector` | Node labels for pod assignment. Evaluated as a template. | `{}` | +| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `micro` | +| `resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `podSecurityContext.enabled` | Enable Drupal pods' Security Context | `true` | +| `podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `podSecurityContext.fsGroup` | Drupal pods' group ID | `1001` | +| `containerSecurityContext.enabled` | Enabled Drupal containers' Security Context | `true` | +| `containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `containerSecurityContext.runAsUser` | Set Drupal containers' Security Context runAsUser | `1001` | +| `containerSecurityContext.runAsGroup` | Set Drupal containers' Security Context runAsGroup | `1001` | +| `containerSecurityContext.runAsNonRoot` | Set Controller container's Security Context runAsNonRoot | `true` | +| `containerSecurityContext.privileged` | Set Drupal container's Security Context privileged | `false` | +| `containerSecurityContext.allowPrivilegeEscalation` | Set Drupal container's Security Context allowPrivilegeEscalation | `false` | +| `containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `containerSecurityContext.readOnlyRootFilesystem` | Set Drupal container's Security Context readOnlyRootFilesystem | `true` | +| `startupProbe.enabled` | Enable startupProbe | `false` | +| `startupProbe.path` | Request path for startupProbe | `/user/login` | +| `startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `600` | +| `startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `startupProbe.failureThreshold` | Failure threshold for startupProbe | `5` | +| `startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `livenessProbe.enabled` | Enable livenessProbe | `true` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `600` | +| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `5` | +| `livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `readinessProbe.enabled` | Enable readinessProbe | `true` | +| `readinessProbe.path` | Request path for readinessProbe | `/user/login` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `30` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `5` | +| `readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `5` | +| `readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `customStartupProbe` | Override default startup probe | `{}` | +| `customLivenessProbe` | Override default liveness probe | `{}` | +| `customReadinessProbe` | Override default readiness probe | `{}` | +| `lifecycleHooks` | LifecycleHook to set additional configuration at startup Evaluated as a template | `{}` | +| `podAnnotations` | Pod annotations | `{}` | +| `podLabels` | Add additional labels to the pod (evaluated as a template) | `{}` | + +### Traffic Exposure Parameters + +| Name | Description | Value | +| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `service.type` | Kubernetes Service type | `LoadBalancer` | +| `service.ports.http` | Service HTTP port | `80` | +| `service.ports.https` | Service HTTPS port | `443` | +| `service.loadBalancerSourceRanges` | Restricts access for LoadBalancer (only with `service.type: LoadBalancer`) | `[]` | +| `service.loadBalancerIP` | loadBalancerIP for the Drupal Service (optional, cloud specific) | `""` | +| `service.nodePorts` | Kubernetes node port | `{}` | +| `service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `service.clusterIP` | %%MAIN_CONTAINER_NAME%% service Cluster IP | `""` | +| `service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `service.annotations` | Additional custom annotations for %%MAIN_CONTAINER_NAME%% service | `{}` | +| `service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `ingress.enabled` | Enable ingress controller resource | `false` | +| `ingress.pathType` | Ingress Path type | `ImplementationSpecific` | +| `ingress.apiVersion` | Override API Version (automatically detected if not set) | `""` | +| `ingress.ingressClassName` | IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) | `""` | +| `ingress.hostname` | Default host for the ingress resource | `drupal.local` | +| `ingress.path` | The Path to Drupal. You may need to set this to '/*' in order to use this | `/` | +| `ingress.annotations` | Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. | `{}` | +| `ingress.tls` | Enable TLS configuration for the hostname defined at ingress.hostname parameter | `false` | +| `ingress.tlsWwwPrefix` | Adds www subdomain to default cert | `false` | +| `ingress.extraHosts` | The list of additional hostnames to be covered with this ingress record. | `[]` | +| `ingress.extraPaths` | Any additional arbitrary paths that may need to be added to the ingress under the main host. | `[]` | +| `ingress.extraTls` | The tls configuration for additional hostnames to be covered with this ingress record. | `[]` | +| `ingress.secrets` | If you're providing your own certificates, please use this to add the certificates as secrets | `[]` | +| `ingress.extraRules` | Additional rules to be covered with this ingress record | `[]` | + +### Database parameters + +| Name | Description | Value | +| ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `mariadb.enabled` | Whether to deploy a mariadb server to satisfy the applications database requirements | `true` | +| `mariadb.architecture` | MariaDB architecture (`standalone` or `replication`) | `standalone` | +| `mariadb.auth.rootPassword` | Password for the MariaDB `root` user | `""` | +| `mariadb.auth.database` | Database name to create | `bitnami_drupal` | +| `mariadb.auth.username` | Database user to create | `bn_drupal` | +| `mariadb.auth.password` | Password for the database | `""` | +| `mariadb.primary.persistence.enabled` | Enable database persistence using PVC | `true` | +| `mariadb.primary.persistence.storageClass` | MariaDB primary persistent volume storage Class | `""` | +| `mariadb.primary.persistence.accessModes` | Database Persistent Volume Access Modes | `["ReadWriteOnce"]` | +| `mariadb.primary.persistence.size` | Database Persistent Volume Size | `8Gi` | +| `mariadb.primary.persistence.hostPath` | Set path in case you want to use local host path volumes (not recommended in production) | `""` | +| `mariadb.primary.persistence.existingClaim` | Name of an existing `PersistentVolumeClaim` for MariaDB primary replicas | `""` | +| `externalDatabase.host` | Host of the existing database | `""` | +| `externalDatabase.port` | Port of the existing database | `3306` | +| `externalDatabase.user` | Existing username in the external db | `bn_drupal` | +| `externalDatabase.password` | Password for the above username. Ignored if existing secret is provided | `""` | +| `externalDatabase.database` | Name of the existing database | `bitnami_drupal` | +| `externalDatabase.existingSecret` | Name of a secret with the database password. (externalDatabase.password will be ignored and picked up from this secret). The secret has to contain the key db-password | `""` | + +### Volume Permissions parameters + +| Name | Description | Value | +| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `volumePermissions.enabled` | Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `REGISTRY_NAME` | +| `volumePermissions.image.repository` | Init container volume-permissions image name | `REPOSITORY_NAME/os-shell` | +| `volumePermissions.image.digest` | Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `volumePermissions.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). | `none` | +| `volumePermissions.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | + +### Metrics parameters + +| Name | Description | Value | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `metrics.enabled` | Start a exporter side-car | `false` | +| `metrics.image.registry` | Apache exporter image registry | `REGISTRY_NAME` | +| `metrics.image.repository` | Apache exporter image repository | `REPOSITORY_NAME/apache-exporter` | +| `metrics.image.digest` | Apache exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `metrics.image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `metrics.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). | `none` | +| `metrics.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `metrics.podAnnotations` | Additional annotations for Metrics exporter pod | `{}` | +| `metrics.service.type` | Drupal exporter service type | `ClusterIP` | +| `metrics.service.ports.metrics` | Drupal exporter service port | `9117` | +| `metrics.service.externalTrafficPolicy` | Drupal exporter service external traffic policy | `Cluster` | +| `metrics.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `metrics.service.loadBalancerIP` | Drupal exporter service Load Balancer IP | `""` | +| `metrics.service.loadBalancerSourceRanges` | Drupal exporter service Load Balancer sources | `[]` | +| `metrics.service.annotations` | Additional custom annotations for Drupal exporter service | `{}` | +| `metrics.serviceMonitor.enabled` | Create ServiceMonitor resource(s) for scraping metrics using PrometheusOperator | `false` | +| `metrics.serviceMonitor.namespace` | The namespace in which the ServiceMonitor will be created | `""` | +| `metrics.serviceMonitor.interval` | The interval at which metrics should be scraped | `30s` | +| `metrics.serviceMonitor.scrapeTimeout` | The timeout after which the scrape is ended | `""` | +| `metrics.serviceMonitor.relabellings` | Metrics RelabelConfigs to apply to samples before scraping. | `[]` | +| `metrics.serviceMonitor.metricRelabelings` | Metrics RelabelConfigs to apply to samples before ingestion. | `[]` | +| `metrics.serviceMonitor.honorLabels` | Specify honorLabels parameter to add the scrape endpoint | `false` | +| `metrics.serviceMonitor.additionalLabels` | Additional labels that can be used so ServiceMonitor resource(s) can be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.enabled` | Create a custom prometheusRule Resource for scraping metrics using PrometheusOperator | `false` | +| `metrics.prometheusRule.namespace` | The namespace in which the prometheusRule will be created | `""` | +| `metrics.prometheusRule.additionalLabels` | Additional labels for the prometheusRule | `{}` | +| `metrics.prometheusRule.rules` | Custom Prometheus rules | `[]` | + +### Certificate injection parameters + +| Name | Description | Value | +| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | +| `certificates.customCertificate.certificateSecret` | Secret containing the certificate and key to add | `""` | +| `certificates.customCertificate.chainSecret.name` | Name of the secret containing the certificate chain | `secret-name` | +| `certificates.customCertificate.chainSecret.key` | Key of the certificate chain file inside the secret | `secret-key` | +| `certificates.customCertificate.certificateLocation` | Location in the container to store the certificate | `/etc/ssl/certs/ssl-cert-snakeoil.pem` | +| `certificates.customCertificate.keyLocation` | Location in the container to store the private key | `/etc/ssl/private/ssl-cert-snakeoil.key` | +| `certificates.customCertificate.chainLocation` | Location in the container to store the certificate chain | `/etc/ssl/certs/mychain.pem` | +| `certificates.customCAs` | Defines a list of secrets to import into the container trust store | `[]` | +| `certificates.command` | Override default container command (useful when using custom images) | `[]` | +| `certificates.args` | Override default container args (useful when using custom images) | `[]` | +| `certificates.extraEnvVars` | Container sidecar extra environment variables (eg proxy) | `[]` | +| `certificates.extraEnvVarsCM` | ConfigMap containing extra env vars | `""` | +| `certificates.extraEnvVarsSecret` | Secret containing extra env vars (in case of sensitive data) | `""` | +| `certificates.image.registry` | Container sidecar registry | `REGISTRY_NAME` | +| `certificates.image.repository` | Container sidecar image | `REPOSITORY_NAME/os-shell` | +| `certificates.image.digest` | Container sidecar image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `certificates.image.pullPolicy` | Container sidecar image pull policy | `IfNotPresent` | +| `certificates.image.pullSecrets` | Container sidecar image pull secrets | `[]` | + +### NetworkPolicy parameters + +| Name | Description | Value | +| --------------------------------------- | --------------------------------------------------------------- | ------ | +| `networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` | +| `networkPolicy.allowExternal` | Don't require server label for connections | `true` | +| `networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` | +| `networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | + +The above parameters map to the env variables defined in [bitnami/drupal](https://github.com/bitnami/containers/tree/main/bitnami/drupal). For more information please refer to the [bitnami/drupal](https://github.com/bitnami/containers/tree/main/bitnami/drupal) image documentation. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set drupalUsername=admin,drupalPassword=password,mariadb.auth.rootPassword=secretpassword \ + oci://REGISTRY_NAME/REPOSITORY_NAME/drupal +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The above command sets the Drupal administrator account username and password to `admin` and `password` respectively. Additionally, it sets the MariaDB `root` user password to `secretpassword`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://REGISTRY_NAME/REPOSITORY_NAME/drupal +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. +> **Tip**: You can use the default [values.yaml](https://github.com/bitnami/charts/tree/main/bitnami/drupal/values.yaml) + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### To 19.0.0 + +This major release bumps the MariaDB version to 11.4. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-11-3-to-mariadb-11-4/) for upgrading from MariaDB 11.3 to 11.4. No major issues are expected during the upgrade. + +### To 18.0.0 + +This major bump changes the following security defaults: + +- `runAsGroup` is changed from `0` to `1001` +- `readOnlyRootFilesystem` is set to `true` +- `resourcesPreset` is changed from `none` to the minimum size working in our test suites (NOTE: `resourcesPreset` is not meant for production usage, but `resources` adapted to your use case). +- `global.compatibility.openshift.adaptSecurityContext` is changed from `disabled` to `auto`. +- The `networkPolicy` section has been normalized amongst all Bitnami charts. Compared to the previous approach, the values section has been simplified (check the Parameters section) and now it set to `enabled=true` by default. Egress traffic is allowed by default and ingress traffic is allowed by all pods but only to the ports set in `containerPorts` and `extraContainerPorts`. + +This could potentially break any customization or init scripts used in your deployment. If this is the case, change the default values to the previous ones. + +Also, this major release bumps the MariaDB chart version to [18.x.x](https://github.com/bitnami/charts/pull/24804); no major issues are expected during the upgrade. + +### To 17.0.0 + +This major release bumps the MariaDB version to 11.2. No major issues are expected during the upgrade. + +### To 16.0.0 + +This major release bumps the MariaDB version to 11.1. No major issues are expected during the upgrade. + +### To 15.0.0 + +This major release bumps the MariaDB version to 11.0. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-10-11-to-mariadb-11-0/) for upgrading from MariaDB 10.11 to 11.0. No major issues are expected during the upgrade. + +### To 14.0.0 + +This major release bumps the MariaDB version to 10.11. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-10-6-to-mariadb-10-11/) for upgrading from MariaDB 10.6 to 10.11. No major issues are expected during the upgrade. + +### To 12.0.0 + +This major release bumps the MariaDB version to 10.6. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-105-to-mariadb-106/) for upgrading from MariaDB 10.5 to 10.6. No major issues are expected during the upgrade. + +### To 11.0.0 + +This major release renames several values in this chart and adds missing features, in order to be inline with the rest of assets in the Bitnami charts repository. + +Affected values: + +- `service.port` was deprecated, we recommend using `service.ports.http` instead. +- `service.httpsPort` was deprecated, we recommend using `service.ports.https` instead. +- `persistence.accessMode` has been deprecated, we recommend using `persistence.accessModes` instead. + +Additionally also updates the MariaDB subchart to it newest major, 10.0.0, which contains similar changes. + +### To 10.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +#### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Move dependency information from the *requirements.yaml* to the *Chart.yaml* +- After running `helm dependency update`, a *Chart.lock* file is generated containing the same structure used in the previous *requirements.lock* +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +#### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +#### Useful links + +- +- +- + +### To 9.0.0 + +MariaDB dependency version was bumped to a new major version that introduces several incompatilibites. Therefore, backwards compatibility is not guaranteed unless an external database is used. Check [MariaDB Upgrading Notes](https://github.com/bitnami/charts/tree/main/bitnami/mariadb#to-800) for more information. + +To upgrade to `9.0.0`, you have two alternatives: + +- Install a new Drupal chart, and migrate your Drupal site using backup/restore tools such as [Drupal Backup and Migrate](https://www.drupal.org/project/backup_migrate). +- Reuse the PVC used to hold the MariaDB data on your previous release. To do so, follow the instructions below (the following example assumes that the release name is `drupal`): + +> NOTE: Please, create a backup of your database before running any of those actions. The steps below would be only valid if your application (e.g. any plugins or custom code) is compatible with MariaDB 10.5.x + +Obtain the credentials and the name of the PVC used to hold the MariaDB data on your current release: + +```console +export DRUPAL_PASSWORD=$(kubectl get secret --namespace default drupal -o jsonpath="{.data.drupal-password}" | base64 -d) +export MARIADB_ROOT_PASSWORD=$(kubectl get secret --namespace default drupal-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 -d) +export MARIADB_PASSWORD=$(kubectl get secret --namespace default drupal-mariadb -o jsonpath="{.data.mariadb-password}" | base64 -d) +export MARIADB_PVC=$(kubectl get pvc -l app=mariadb,component=master,release=drupal -o jsonpath="{.items[0].metadata.name}") +``` + +Upgrade your release (maintaining the version) disabling MariaDB and scaling Drupal replicas to 0: + +```console +helm upgrade drupal oci://REGISTRY_NAME/REPOSITORY_NAME/drupal --set drupalPassword=$DRUPAL_PASSWORD --set replicaCount=0 --set mariadb.enabled=false --version 8.2.1 +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +Finally, upgrade you release to 9.0.0 reusing the existing PVC, and enabling back MariaDB: + +```console +helm upgrade drupal oci://REGISTRY_NAME/REPOSITORY_NAME/drupal --set mariadb.primary.persistence.existingClaim=$MARIADB_PVC --set mariadb.auth.rootPassword=$MARIADB_ROOT_PASSWORD --set mariadb.auth.password=$MARIADB_PASSWORD --set drupalPassword=$DRUPAL_PASSWORD +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +You should see the lines below in MariaDB container logs: + +```console +$ kubectl logs $(kubectl get pods -l app.kubernetes.io/instance=drupal,app.kubernetes.io/name=mariadb,app.kubernetes.io/component=primary -o jsonpath="{.items[0].metadata.name}") +... +mariadb 12:13:24.98 INFO ==> Using persisted data +mariadb 12:13:25.01 INFO ==> Running mysql_upgrade +... +``` + +### To 8.0.0 + +The [Bitnami Drupal](https://github.com/bitnami/containers/tree/main/bitnami/drupal) image was migrated to a "non-root" user approach. Previously the container ran as the `root` user and the Apache daemon was started as the `daemon` user. From now on, both the container and the Apache daemon run as user `1001`. You can revert this behavior by setting the parameters `containerSecurityContext.runAsUser` to `root`. + +Consequences: + +- The HTTP/HTTPS ports exposed by the container are now `8080/8443` instead of `80/443`. +- Backwards compatibility is not guaranteed. + +To upgrade to `8.0.0`, backup Drupal data and the previous MariaDB databases, install a new Drupal chart and import the backups and data, ensuring the `1001` user has the appropriate permissions on the migrated volume. + +This upgrade also adapts the chart to the latest Bitnami good practices. Check the Parameters section for more information. + +### To 6.0.0 + +Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec. + +In the `apiVersion` of the deployment resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage. + +This major version signifies this change. + +### To 2.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to 2.0.0. The following example assumes that the release name is drupal: + +```console +kubectl patch deployment drupal-drupal --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' +kubectl delete statefulset drupal-mariadb --cascade=false +``` + +## License + +Copyright © 2024 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/charts/drupal/drupal/templates/NOTES.txt b/charts/drupal/drupal/templates/NOTES.txt new file mode 100644 index 0000000..95e2c92 --- /dev/null +++ b/charts/drupal/drupal/templates/NOTES.txt @@ -0,0 +1,88 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +{{- if or .Values.mariadb.enabled .Values.externalDatabase.host -}} + +** Please be patient while the chart is being deployed ** + +1. Get the Drupal URL: + +{{- if .Values.ingress.enabled }} + + You should be able to access your new Drupal installation through + + http://{{- .Values.ingress.hostname }}/ + +{{- else if eq .Values.service.type "LoadBalancer" }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ include "common.names.namespace" . }} -w {{ include "common.names.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ include "common.names.namespace" . }} {{ include "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + +{{- $port:=(coalesce .Values.service.ports.http .Values.service.port) | toString }} + echo "Drupal URL: http://$SERVICE_IP{{- if ne $port "80" }}:{{ coalesce .Values.service.ports.http .Values.service.port }}{{ end }}/" + +{{- else if eq .Values.service.type "ClusterIP" }} + + echo "Drupal URL: http://127.0.0.1:8080/" + kubectl port-forward --namespace {{ include "common.names.namespace" . }} svc/{{ include "common.names.fullname" . }} 8080:{{ coalesce .Values.service.ports.http .Values.service.port }} + +{{- end }} + +{{- if eq .Values.service.type "NodePort" }} + + Or running: + + export NODE_PORT=$(kubectl get --namespace {{ include "common.names.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "common.names.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ include "common.names.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo "Drupal URL: http://$NODE_IP:$NODE_PORT/" + +{{- end }} + +2. Get your Drupal login credentials by running: + + echo Username: {{ .Values.drupalUsername }} + echo Password: $(kubectl get secret --namespace {{ include "common.names.namespace" . }} {{ template "drupal.secretName" . }} -o jsonpath="{.data.drupal-password}" | base64 -d) + +{{- else -}} + +######################################################################################## +### ERROR: You did not provide an external database host in your 'helm install' call ### +######################################################################################## + +This deployment will be incomplete until you configure Drupal with a resolvable database +host. To configure Drupal to use and external database host: + +1. Complete your Drupal deployment by running: + + export APP_PASSWORD=$(kubectl get secret --namespace {{ include "common.names.namespace" . }} {{ template "drupal.secretName" . }} -o jsonpath="{.data.drupal-password}" | base64 -d) + + ## PLEASE UPDATE THE EXTERNAL DATABASE CONNECTION PARAMETERS IN THE FOLLOWING COMMAND AS NEEDED ## + + helm upgrade --namespace {{ include "common.names.namespace" . }} {{ .Release.Name }} oci://registry-1.docker.io/bitnamicharts/{{ .Chart.Name }} \ + --set drupalPassword=$APP_PASSWORD,service.type={{ .Values.service.type }},mariadb.enabled=false{{- if not (empty .Values.externalDatabase.user) }},externalDatabase.user={{ .Values.externalDatabase.user }}{{- end }}{{- if not (empty .Values.externalDatabase.password) }},externalDatabase.password={{ .Values.externalDatabase.password }}{{- end }}{{- if not (empty .Values.externalDatabase.database) }},externalDatabase.database={{ .Values.externalDatabase.database }}{{- end }},externalDatabase.host=YOUR_EXTERNAL_DATABASE_HOST{{- if .Values.global }}{{- if .Values.global.imagePullSecrets }},global.imagePullSecrets={{ .Values.global.imagePullSecrets }}{{- end }}{{- end }} + +{{- end }} + +{{- include "common.warnings.rollingTag" .Values.image }} +{{- include "common.warnings.rollingTag" .Values.metrics.image }} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image }} +{{- include "common.warnings.rollingTag" .Values.certificates.image }} + +{{- $passwordValidationErrors := list -}} +{{- if not .Values.existingSecret -}} + {{- $secretName := include "drupal.secretName" . -}} + {{- $requiredDrupalPassword := dict "valueKey" "drupalPassword" "secret" $secretName "field" "drupal-password" "context" $ -}} + {{- $requiredDrupalPasswordError := include "common.validations.values.single.empty" $requiredDrupalPassword -}} + {{- $passwordValidationErrors = append $passwordValidationErrors $requiredDrupalPasswordError -}} +{{- end -}} + +{{- $mariadbSecretName := include "drupal.databaseSecretName" . -}} +{{- $mariadbPasswordValidationErrors := include "common.validations.values.mariadb.passwords" (dict "secret" $mariadbSecretName "subchart" true "context" $) -}} +{{- $passwordValidationErrors = append $passwordValidationErrors $mariadbPasswordValidationErrors -}} + +{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $) -}} +{{- include "common.warnings.resources" (dict "sections" (list "metrics" "" "volumePermissions") "context" $) }} +{{- include "common.warnings.modifiedImages" (dict "images" (list .Values.image .Values.volumePermissions.image .Values.metrics.image .Values.certificates.image) "context" $) }} \ No newline at end of file diff --git a/charts/drupal/drupal/templates/_helpers.tpl b/charts/drupal/drupal/templates/_helpers.tpl new file mode 100644 index 0000000..da01ed6 --- /dev/null +++ b/charts/drupal/drupal/templates/_helpers.tpl @@ -0,0 +1,144 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "drupal.mariadb.fullname" -}} +{{- printf "%s-%s" .Release.Name "mariadb" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the proper certificate image name +*/}} +{{- define "certificates.image" -}} +{{- include "common.images.image" ( dict "imageRoot" .Values.certificates.image "global" .Values.global ) -}} +{{- end -}} + +{{/* +Return the proper Drupal image name +*/}} +{{- define "drupal.image" -}} +{{- include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) -}} +{{- end -}} + +{{/* +Return the proper image name (for the metrics image) +*/}} +{{- define "drupal.metrics.image" -}} +{{- include "common.images.image" (dict "imageRoot" .Values.metrics.image "global" .Values.global) -}} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "drupal.volumePermissions.image" -}} +{{- include "common.images.image" ( dict "imageRoot" .Values.volumePermissions.image "global" .Values.global ) -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "drupal.imagePullSecrets" -}} +{{- include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.metrics.image .Values.volumePermissions.image .Values.certificates.image) "global" .Values.global) -}} +{{- end -}} + +{{/* +Return the proper Storage Class +*/}} +{{- define "drupal.storageClass" -}} +{{- include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) -}} +{{- end -}} + +{{/* +Drupal credential secret name +*/}} +{{- define "drupal.secretName" -}} +{{- coalesce .Values.existingSecret (include "common.names.fullname" .) -}} +{{- end -}} + +{{/* +Return the MariaDB Hostname +*/}} +{{- define "drupal.databaseHost" -}} +{{- if .Values.mariadb.enabled }} + {{- if eq .Values.mariadb.architecture "replication" }} + {{- printf "%s-%s" (include "drupal.mariadb.fullname" .) "primary" | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s" (include "drupal.mariadb.fullname" .) -}} + {{- end -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.host -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MariaDB Port +*/}} +{{- define "drupal.databasePort" -}} +{{- if .Values.mariadb.enabled }} + {{- printf "3306" -}} +{{- else -}} + {{- printf "%d" (.Values.externalDatabase.port | int ) -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MariaDB Database Name +*/}} +{{- define "drupal.databaseName" -}} +{{- if .Values.mariadb.enabled }} + {{- printf "%s" .Values.mariadb.auth.database -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.database -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MariaDB User +*/}} +{{- define "drupal.databaseUser" -}} +{{- if .Values.mariadb.enabled }} + {{- printf "%s" .Values.mariadb.auth.username -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.user -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MariaDB Secret Name +*/}} +{{- define "drupal.databaseSecretName" -}} +{{- if .Values.mariadb.enabled }} + {{- printf "%s" (include "drupal.mariadb.fullname" .) -}} +{{- else if .Values.externalDatabase.existingSecret -}} + {{- printf "%s" .Values.externalDatabase.existingSecret -}} +{{- else -}} + {{- printf "%s-%s" (include "common.names.fullname" .) "externaldb" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the database password key +*/}} +{{- define "drupal.databasePasswordKey" -}} +{{- if .Values.mariadb.enabled -}} +mariadb-password +{{- else -}} +db-password +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "drupal.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/charts/drupal/drupal/templates/deployment.yaml b/charts/drupal/drupal/templates/deployment.yaml new file mode 100644 index 0000000..bb36ad4 --- /dev/null +++ b/charts/drupal/drupal/templates/deployment.yaml @@ -0,0 +1,384 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + {{- if .Values.updateStrategy }} + strategy: {{- toYaml .Values.updateStrategy | nindent 4 }} + {{- end }} + replicas: {{ .Values.replicaCount }} + template: + metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + {{- if or .Values.podAnnotations (and .Values.metrics.enabled .Values.metrics.podAnnotations) }} + annotations: + {{- if .Values.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- end }} + spec: + {{- include "drupal.imagePullSecrets" . | nindent 6 }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + serviceAccountName: {{ include "drupal.serviceAccountName" . }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- if .Values.hostAliases }} + # yamllint disable rule:indentation + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + # yamllint enable rule:indentation + {{- end }} + initContainers: + - name: prepare-base-dir + image: {{ include "drupal.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + command: + - /bin/bash + args: + - -ec + - | + #!/bin/bash + + . /opt/bitnami/scripts/liblog.sh + . /opt/bitnami/scripts/libfs.sh + + info "Copying base dir to empty dir" + # In order to not break the application functionality (such as upgrades or plugins) we need + # to make the base directory writable, so we need to copy it to an empty dir volume + cp -r --preserve=mode /opt/bitnami/drupal /emptydir/app-base-dir + + info "Copying symlinks to stdout/stderr" + # We copy the logs folder because it has symlinks to stdout and stderr + if ! is_dir_empty /opt/bitnami/apache/logs; then + cp -r /opt/bitnami/apache/logs /emptydir/apache-logs-dir + fi + info "Copy operation completed" + volumeMounts: + - name: empty-dir + mountPath: /emptydir + {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }} + - name: volume-permissions + image: {{ include "drupal.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - sh + - -c + - | + mkdir -p "/bitnami/drupal" + chown -R "{{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }}" "/bitnami/drupal" + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.volumePermissions.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: drupal-data + mountPath: /bitnami/drupal + {{- end }} + {{- if .Values.certificates.customCAs }} + - name: certificates + image: {{ template "certificates.image" . }} + imagePullPolicy: {{ default .Values.image.pullPolicy .Values.certificates.image.pullPolicy }} + imagePullSecrets: + {{- range (default .Values.image.pullSecrets .Values.certificates.image.pullSecrets) }} + - name: {{ . }} + {{- end }} + command: + {{- if .Values.certificates.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.certificates.command "context" $) | nindent 12 }} + {{- else if .Values.certificates.customCertificate.certificateSecret }} + - sh + - -c + - install_packages ca-certificates openssl + {{- else }} + - sh + - -c + - install_packages ca-certificates openssl + && openssl req -new -x509 -days 3650 -nodes -sha256 + -subj "/CN=$(hostname)" -addext "subjectAltName = DNS:$(hostname)" + -out /etc/ssl/certs/ssl-cert-snakeoil.pem + -keyout /etc/ssl/private/ssl-cert-snakeoil.key -extensions v3_req + {{- end }} + {{- if .Values.certificates.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.certificates.args "context" $) | nindent 12 }} + {{- end }} + env: {{- include "common.tplvalues.render" (dict "value" .Values.certificates.extraEnvVars "context" $) | nindent 12 }} + envFrom: + {{- if .Values.certificates.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.certificates.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.certificates.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.certificates.extraEnvVarsSecret "context" $) }} + {{- end }} + volumeMounts: + - name: etc-ssl-certs + mountPath: /etc/ssl/certs + readOnly: false + - name: etc-ssl-private + mountPath: /etc/ssl/private + readOnly: false + - name: custom-ca-certificates + mountPath: /usr/local/share/ca-certificates + readOnly: true + {{- end }} + {{- if .Values.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: {{ include "common.names.fullname" . }} + image: {{ template "drupal.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" .Values.image.debug | quote }} + - name: ALLOW_EMPTY_PASSWORD + value: {{ ternary "yes" "no" .Values.allowEmptyPassword | quote }} + - name: APACHE_HTTP_PORT_NUMBER + value: {{ .Values.containerPorts.http | quote }} + - name: APACHE_HTTPS_PORT_NUMBER + value: {{ .Values.containerPorts.https | quote }} + - name: DRUPAL_DATABASE_HOST + value: {{ include "drupal.databaseHost" . | quote }} + - name: DRUPAL_DATABASE_PORT_NUMBER + value: {{ include "drupal.databasePort" . | quote }} + - name: DRUPAL_DATABASE_NAME + value: {{ include "drupal.databaseName" . | quote }} + - name: DRUPAL_DATABASE_USER + value: {{ include "drupal.databaseUser" . | quote }} + - name: DRUPAL_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "drupal.databaseSecretName" . }} + key: {{ include "drupal.databasePasswordKey" . | quote }} + - name: DRUPAL_SKIP_BOOTSTRAP + value: {{ ternary "yes" "no" .Values.drupalSkipInstall | quote }} + - name: DRUPAL_PROFILE + value: {{ .Values.drupalProfile | quote }} + - name: DRUPAL_USERNAME + value: {{ .Values.drupalUsername | quote }} + - name: DRUPAL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "drupal.secretName" . }} + key: drupal-password + - name: DRUPAL_EMAIL + value: {{ .Values.drupalEmail | quote }} + {{- if .Values.smtpHost }} + - name: SMTP_HOST + value: {{ .Values.smtpHost | quote }} + {{- end }} + {{- if .Values.smtpPort }} + - name: SMTP_PORT + value: {{ .Values.smtpPort | quote }} + {{- end }} + {{- if .Values.smtpUser }} + - name: SMTP_USER + value: {{ .Values.smtpUser | quote }} + {{- end }} + {{- if .Values.smtpPassword }} + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "drupal.secretName" . }} + key: smtp-password + {{- end }} + {{- if .Values.smtpProtocol }} + - name: SMTP_PROTOCOL + value: {{ .Values.smtpProtocol | quote }} + {{- end }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- if .Values.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.containerPorts.http }} + - name: https + containerPort: {{ .Values.containerPorts.https }} + {{- if .Values.extraContainerPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraContainerPorts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.startupProbe.enabled }} + startupProbe: + httpGet: + path: {{ .Values.startupProbe.path }} + port: http + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + {{- end }} + {{- if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.livenessProbe.enabled }} + livenessProbe: + tcpSocket: + port: http + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.readinessProbe.path }} + port: http + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- end }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: empty-dir + mountPath: /opt/bitnami/apache/conf + subPath: apache-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/apache/logs + subPath: apache-logs-dir + - name: empty-dir + mountPath: /opt/bitnami/apache/var/run + subPath: apache-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/php/etc + subPath: php-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/php/tmp + subPath: php-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/php/var + subPath: php-var-dir + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/drupal + subPath: app-base-dir + - name: drupal-data + mountPath: /bitnami/drupal + {{- if .Values.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ template "drupal.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + command: [ '/bin/apache_exporter', '--scrape_uri', 'http://status.localhost:{{ .Values.containerPorts.http }}/server-status/?auto' ] + ports: + - name: metrics + containerPort: 9117 + livenessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 15 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 5 + timeoutSeconds: 1 + {{- if .Values.metrics.resourcesPreset }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- else if ne .Values.metrics.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.metrics.resourcesPreset) | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: empty-dir + emptyDir: {} + - name: drupal-data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (printf "%s-drupal" (include "common.names.fullname" .)) }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} diff --git a/charts/drupal/drupal/templates/externaldb-secrets.yaml b/charts/drupal/drupal/templates/externaldb-secrets.yaml new file mode 100644 index 0000000..bfdd266 --- /dev/null +++ b/charts/drupal/drupal/templates/externaldb-secrets.yaml @@ -0,0 +1,19 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and (not .Values.mariadb.enabled) (not .Values.externalDatabase.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-externaldb" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + db-password: {{ default "" .Values.externalDatabase.password | b64enc | quote }} +{{- end }} diff --git a/charts/drupal/drupal/templates/extra-list.yaml b/charts/drupal/drupal/templates/extra-list.yaml new file mode 100644 index 0000000..329f5c6 --- /dev/null +++ b/charts/drupal/drupal/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/drupal/drupal/templates/ingress.yaml b/charts/drupal/drupal/templates/ingress.yaml new file mode 100644 index 0000000..a0a3b8e --- /dev/null +++ b/charts/drupal/drupal/templates/ingress.yaml @@ -0,0 +1,66 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.ingress.enabled }} +apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + annotations: + {{- if .Values.ingress.certManager }} + kubernetes.io/tls-acme: "true" + {{- end }} + {{- if or .Values.ingress.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.ingress.annotations .Values.commonAnnotations ) "context" . ) }} + {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.ingressClassName (eq "true" (include "common.ingress.supportsIngressClassname" .)) }} + ingressClassName: {{ .Values.ingress.ingressClassName | quote }} + {{- end }} + rules: + {{- if .Values.ingress.hostname }} + - host: {{ .Values.ingress.hostname }} + http: + paths: + - path: {{ .Values.ingress.path }} + {{- if eq "true" (include "common.ingress.supportsPathType" .) }} + pathType: {{ .Values.ingress.pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" .) "servicePort" "http" "context" $) | nindent 14 }} + {{- if .Values.ingress.extraPaths }} + {{- toYaml .Values.ingress.extraPaths | nindent 10 }} + {{- end }} + {{- end }} + {{- range (coalesce .Values.ingress.extraHosts .Values.ingress.hosts) }} + - host: {{ .name | quote }} + http: + paths: + - path: {{ default "/" .path }} + {{- if eq "true" (include "common.ingress.supportsPathType" $) }} + pathType: {{ default "ImplementationSpecific" .pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" "http" "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.ingress.extraRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraRules "context" $) | nindent 4 }} + {{- end }} + {{- if or .Values.ingress.tls .Values.ingress.extraTls }} + tls: + {{- if .Values.ingress.tls }} + - hosts: + - {{ .Values.ingress.hostname | quote }} + {{- if and (or (.Values.ingress.tlsWwwPrefix) (eq (index .Values.ingress.annotations "nginx.ingress.kubernetes.io/from-to-www-redirect") "true" )) (not (contains "www." .Values.ingress.hostname)) }} + - {{ printf "www.%s" (tpl .Values.ingress.hostname $) | quote }} + {{- end }} + secretName: {{ printf "%s-tls" .Values.ingress.hostname }} + {{- end }} + {{- if .Values.ingress.extraTls }} + {{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraTls "context" $) | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/drupal/drupal/templates/metrics-svc.yaml b/charts/drupal/drupal/templates/metrics-svc.yaml new file mode 100644 index 0000000..f95e56a --- /dev/null +++ b/charts/drupal/drupal/templates/metrics-svc.yaml @@ -0,0 +1,39 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-metrics" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if or .Values.metrics.service.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.metrics.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.metrics.service.type }} + {{- if eq .Values.metrics.service.type "LoadBalancer" }} + externalTrafficPolicy: {{ .Values.metrics.service.externalTrafficPolicy }} + {{- end }} + {{- if and (eq .Values.metrics.service.type "LoadBalancer") .Values.metrics.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} + {{- end }} + {{- if and (eq .Values.metrics.service.type "LoadBalancer") .Values.metrics.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.metrics.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + ports: + - name: metrics + port: {{ .Values.metrics.service.ports.metrics }} + protocol: TCP + targetPort: metrics + {{- if .Values.metrics.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} +{{- end }} diff --git a/charts/drupal/drupal/templates/networkpolicy.yaml b/charts/drupal/drupal/templates/networkpolicy.yaml new file mode 100644 index 0000000..a0c01ac --- /dev/null +++ b/charts/drupal/drupal/templates/networkpolicy.yaml @@ -0,0 +1,80 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + policyTypes: + - Ingress + - Egress + {{- if .Values.networkPolicy.allowExternalEgress }} + egress: + - {} + {{- else }} + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # Allow outbound connections to MariaDB + - ports: + - port: {{ include "drupal.databasePort" . }} + {{- if .Values.mariadb.enabled }} + to: + - podSelector: + matchLabels: + app.kubernetes.io/name: mariadb + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + {{- if .Values.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} + ingress: + - ports: + - port: {{ .Values.containerPorts.http }} + - port: {{ .Values.containerPorts.https }} + {{- range .Values.extraContainerPorts }} + - port: {{ . }} + {{- end }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/drupal/drupal/templates/pdb.yaml b/charts/drupal/drupal/templates/pdb.yaml new file mode 100644 index 0000000..d28b3ec --- /dev/null +++ b/charts/drupal/drupal/templates/pdb.yaml @@ -0,0 +1,26 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.pdb.minAvailable }} + minAvailable: {{ .Values.pdb.minAvailable }} + {{- end }} + {{- if or .Values.pdb.maxUnavailable (not .Values.pdb.minAvailable) }} + maxUnavailable: {{ .Values.pdb.maxUnavailable | default 1 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" (dict "values" (list .Values.podLabels .Values.commonLabels) "context" .) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} +{{- end }} diff --git a/charts/drupal/drupal/templates/prometheusrule.yaml b/charts/drupal/drupal/templates/prometheusrule.yaml new file mode 100644 index 0000000..7293adb --- /dev/null +++ b/charts/drupal/drupal/templates/prometheusrule.yaml @@ -0,0 +1,23 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.prometheusRule.namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.metrics.prometheusRule.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.prometheusRule.additionalLabels "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + groups: + - name: {{ include "common.names.fullname" . }} + rules: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.rules "context" $ ) | nindent 8 }} +{{- end }} diff --git a/charts/drupal/drupal/templates/pv.yaml b/charts/drupal/drupal/templates/pv.yaml new file mode 100644 index 0000000..95ab4dd --- /dev/null +++ b/charts/drupal/drupal/templates/pv.yaml @@ -0,0 +1,23 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.persistence.enabled .Values.persistence.hostPath (not .Values.persistence.existingClaim) -}} +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ printf "%s-drupal" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + capacity: + storage: {{ .Values.persistence.size | quote }} + hostPath: + path: {{ .Values.persistence.hostPath | quote }} +{{- end -}} diff --git a/charts/drupal/drupal/templates/pvc.yaml b/charts/drupal/drupal/templates/pvc.yaml new file mode 100644 index 0000000..923a535 --- /dev/null +++ b/charts/drupal/drupal/templates/pvc.yaml @@ -0,0 +1,33 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ printf "%s-drupal" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.persistence.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.persistence.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.persistence.hostPath }} + storageClassName: "" + {{- end }} + accessModes: + {{- if not (empty .Values.persistence.accessModes) }} + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + {{- else }} + - {{ .Values.persistence.accessMode | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- include "drupal.storageClass" . | nindent 2 }} +{{- end -}} diff --git a/charts/drupal/drupal/templates/secrets.yaml b/charts/drupal/drupal/templates/secrets.yaml new file mode 100644 index 0000000..3a3e3f0 --- /dev/null +++ b/charts/drupal/drupal/templates/secrets.yaml @@ -0,0 +1,26 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if not .Values.existingSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if .Values.drupalPassword }} + drupal-password: {{ default "" .Values.drupalPassword | b64enc | quote }} + {{- else }} + drupal-password: {{ randAlphaNum 10 | b64enc | quote }} + {{- end }} + {{- if .Values.smtpPassword }} + smtp-password: {{ .Values.smtpPassword | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/charts/drupal/drupal/templates/serviceaccount.yaml b/charts/drupal/drupal/templates/serviceaccount.yaml new file mode 100644 index 0000000..ad0ad4a --- /dev/null +++ b/charts/drupal/drupal/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "drupal.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/charts/drupal/drupal/templates/servicemonitor.yaml b/charts/drupal/drupal/templates/servicemonitor.yaml new file mode 100644 index 0000000..60dd04f --- /dev/null +++ b/charts/drupal/drupal/templates/servicemonitor.yaml @@ -0,0 +1,43 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.serviceMonitor.namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.additionalLabels "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabellings }} + relabelings: {{- toYaml .Values.metrics.serviceMonitor.relabellings | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- toYaml .Values.metrics.serviceMonitor.metricRelabelings | nindent 6 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: metrics +{{- end }} diff --git a/charts/drupal/drupal/templates/svc.yaml b/charts/drupal/drupal/templates/svc.yaml new file mode 100644 index 0000000..20b70ef --- /dev/null +++ b/charts/drupal/drupal/templates/svc.yaml @@ -0,0 +1,57 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.service.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if .Values.service.sessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} + {{- if .Values.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if (and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + ports: + - name: http + port: {{ coalesce .Values.service.ports.http .Values.service.port }} + targetPort: http + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.http)) }} + nodePort: {{ .Values.service.nodePorts.http }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + - name: https + port: {{ coalesce .Values.service.ports.https .Values.service.httpsPort }} + targetPort: https + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.https)) }} + nodePort: {{ .Values.service.nodePorts.https }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} diff --git a/charts/drupal/drupal/templates/tls-secrets.yaml b/charts/drupal/drupal/templates/tls-secrets.yaml new file mode 100644 index 0000000..2b2dfd8 --- /dev/null +++ b/charts/drupal/drupal/templates/tls-secrets.yaml @@ -0,0 +1,22 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + namespace: {{ include "common.names.namespace" $ | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $.Values.commonLabels "context" $ ) | nindent 4 }} + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate | b64enc }} + tls.key: {{ .key | b64enc }} +{{- end }} +{{- end }} diff --git a/charts/drupal/drupal/values.schema.json b/charts/drupal/drupal/values.schema.json new file mode 100644 index 0000000..072fbcd --- /dev/null +++ b/charts/drupal/drupal/values.schema.json @@ -0,0 +1,233 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "drupalUsername": { + "type": "string", + "title": "Username", + "form": true + }, + "drupalPassword": { + "type": "string", + "title": "Password", + "form": true, + "description": "Defaults to a random 10-character alphanumeric string if not set" + }, + "drupalEmail": { + "type": "string", + "title": "Admin email", + "form": true + }, + "persistence": { + "type": "object", + "properties": { + "drupal": { + "type": "object", + "properties": { + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi" + } + } + } + } + }, + "ingress": { + "type": "object", + "form": true, + "title": "Ingress Configuration", + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Use a custom hostname", + "description": "Enable the ingress resource that allows you to access the Drupal installation." + }, + "hostname": { + "type": "string", + "form": true, + "title": "Hostname", + "hidden": { + "value": false, + "path": "ingress/enabled" + } + } + } + }, + "service": { + "type": "object", + "form": true, + "title": "Service Configuration", + "properties": { + "type": { + "type": "string", + "form": true, + "title": "Service Type", + "description": "Allowed values: \"ClusterIP\", \"NodePort\" and \"LoadBalancer\"" + } + } + }, + "mariadb": { + "type": "object", + "title": "MariaDB Details", + "form": true, + "properties": { + "enabled": { + "type": "boolean", + "title": "Use a new MariaDB database hosted in the cluster", + "form": true, + "description": "Whether to deploy a mariadb server to satisfy the applications database requirements. To use an external database switch this off and configure the external database details" + }, + "primary": { + "type": "object", + "properties": { + "persistence": { + "type": "object", + "properties": { + "size": { + "type": "string", + "title": "Volume Size", + "form": true, + "hidden": { + "value": false, + "path": "mariadb/enabled" + }, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi" + } + } + } + } + } + } + }, + "externalDatabase": { + "type": "object", + "title": "External Database Details", + "description": "If MariaDB is disabled. Use this section to specify the external database details", + "form": true, + "hidden": "mariadb/enabled", + "properties": { + "host": { + "type": "string", + "form": true, + "title": "Database Host" + }, + "user": { + "type": "string", + "form": true, + "title": "Database Username" + }, + "password": { + "type": "string", + "form": true, + "title": "Database Password" + }, + "database": { + "type": "string", + "form": true, + "title": "Database Name" + }, + "port": { + "type": "integer", + "form": true, + "title": "Database Port" + } + } + }, + "resources": { + "type": "object", + "title": "Requested Resources", + "description": "Configure resource requests", + "form": true, + "properties": { + "requests": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "form": true, + "render": "slider", + "title": "Memory Request", + "sliderMin": 10, + "sliderMax": 2048, + "sliderUnit": "Mi" + }, + "cpu": { + "type": "string", + "form": true, + "render": "slider", + "title": "CPU Request", + "sliderMin": 10, + "sliderMax": 2000, + "sliderUnit": "m" + } + } + } + } + }, + "metrics": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable Metrics", + "description": "Prometheus Exporter / Metrics", + "form": true + }, + "serviceMonitor": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Create Prometheus Operator ServiceMonitor", + "description": "Create a ServiceMonitor to track metrics using Prometheus Operator", + "form": true, + "hidden": { + "value": false, + "path": "metrics/enabled" + } + } + } + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "drupal": { + "type": "object", + "properties": { + "create": { + "type": "string", + "title": "Specifies whether a service account should be created", + "form": true + }, + "name": { + "type": "string", + "title": "The name of the service account to use", + "form": true + }, + "annotations": { + "type": "string", + "title": "Add annotations", + "form": true + }, + "automountServiceAccountToken": { + "type": "string", + "title": "Automount API credentials for a service account", + "form": true + } + } + } + } + } + } +} diff --git a/charts/drupal/drupal/values.yaml b/charts/drupal/drupal/values.yaml new file mode 100644 index 0000000..554dbc3 --- /dev/null +++ b/charts/drupal/drupal/values.yaml @@ -0,0 +1,982 @@ +# Copyright Broadcom, Inc. All Rights Reserved. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.defaultStorageClass Global default StorageClass for Persistent Volume(s) +## @param global.storageClass DEPRECATED: use global.defaultStorageClass instead +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + defaultStorageClass: "" + storageClass: "" + ## Compatibility adaptations for Kubernetes platforms + ## + compatibility: + ## Compatibility adaptations for Openshift + ## + openshift: + ## @param global.compatibility.openshift.adaptSecurityContext Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) + ## + adaptSecurityContext: auto +## @section Common parameters + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override drupal.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override drupal.fullname template +## +fullnameOverride: "" +## @param namespaceOverride String to fully override common.names.namespace +## +namespaceOverride: "" +## @param commonAnnotations Common annotations to add to all Drupal resources (sub-charts are not considered). Evaluated as a template +## +commonAnnotations: {} +## @param commonLabels Common labels to add to all Drupal resources (sub-charts are not considered). Evaluated as a template +## +commonLabels: {} +## @param extraDeploy Array of extra objects to deploy with the release (evaluated as a template). +## +extraDeploy: [] +## @section Drupal parameters + +## Bitnami Drupal image version +## ref: https://hub.docker.com/r/bitnami/drupal/tags/ +## @param image.registry [default: REGISTRY_NAME] Drupal image registry +## @param image.repository [default: REPOSITORY_NAME/drupal] Drupal Image name +## @skip image.tag Drupal Image tag +## @param image.digest Drupal image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param image.pullPolicy Drupal image pull policy +## @param image.pullSecrets Specify docker-registry secret names as an array +## @param image.debug Specify if debug logs should be enabled +## +image: + registry: docker.io + repository: bitnami/drupal + tag: 11.0.5-debian-12-r1 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Set to true if you would like to see extra information on logs + ## + debug: false +## @param replicaCount Number of Drupal Pods to run (requires ReadWriteMany PVC support) +## +replicaCount: 1 +## @param drupalProfile Drupal installation profile +## ref: https://github.com/bitnami/containers/tree/main/bitnami/drupal#configuration +## +drupalProfile: standard +## @param drupalSkipInstall Skip Drupal installation wizard. Useful for migrations and restoring from SQL dump +## ref: https://github.com/bitnami/containers/tree/main/bitnami/drupal#configuration +## +drupalSkipInstall: false +## @param drupalUsername User of the application +## ref: https://github.com/bitnami/containers/tree/main/bitnami/drupal#configuration +## +drupalUsername: user +## @param drupalPassword Application password +## Defaults to a random 10-character alphanumeric string if not set +## ref: https://github.com/bitnami/containers/tree/main/bitnami/drupal#configuration +## +drupalPassword: "" +## @param drupalEmail Admin email +## ref: https://github.com/bitnami/containers/tree/main/bitnami/drupal#configuration +## +drupalEmail: user@example.com +## @param allowEmptyPassword Allow DB blank passwords +## ref: https://github.com/bitnami/containers/tree/main/bitnami/drupal#environment-variables +## +allowEmptyPassword: true +## @param command Override default container command (useful when using custom images) +## +command: [] +## @param args Override default container args (useful when using custom images) +## +args: [] +## @param updateStrategy.type Update strategy - only really applicable for deployments with RWO PVs attached +## If replicas = 1, an update can get "stuck", as the previous pod remains attached to the +## PV, and the "incoming" pod can never start. Changing the strategy to "Recreate" will +## terminate the single previous pod, so that the new, incoming pod can attach to the PV +## +updateStrategy: + type: RollingUpdate +## @param priorityClassName Drupal pods' priorityClassName +## +priorityClassName: "" +## @param schedulerName Name of the k8s scheduler (other than default) +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param topologySpreadConstraints Topology Spread Constraints for pod assignment +## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## The value is evaluated as a template +## +topologySpreadConstraints: [] +## @param automountServiceAccountToken Mount Service Account token in pod +## +automountServiceAccountToken: false +## @param hostAliases [array] Add deployment host aliases +## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +## +hostAliases: + ## Necessary for apache-exporter to work + ## + - ip: "127.0.0.1" + hostnames: + - "status.localhost" +## @param extraEnvVars Extra environment variables +## For example: +## +extraEnvVars: [] +# - name: BEARER_AUTH +# value: true +## @param extraEnvVarsCM ConfigMap containing extra env vars +## +extraEnvVarsCM: "" +## @param extraEnvVarsSecret Secret containing extra env vars (in case of sensitive data) +## +extraEnvVarsSecret: "" +## @param extraVolumes Array of extra volumes to be added to the deployment (evaluated as template). Requires setting `extraVolumeMounts` +## +extraVolumes: [] +## @param extraVolumeMounts Array of extra volume mounts to be added to the container (evaluated as template). Normally used with `extraVolumes`. +## +extraVolumeMounts: [] +## @param initContainers Add additional init containers to the pod (evaluated as a template) +## +initContainers: [] +## Pod Disruption Budget configuration +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb +## @param pdb.create Enable/disable a Pod Disruption Budget creation +## @param pdb.minAvailable Minimum number/percentage of pods that should remain scheduled +## @param pdb.maxUnavailable Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `pdb.minAvailable` and `pdb.maxUnavailable` are empty. +## +pdb: + create: true + minAvailable: "" + maxUnavailable: "" +## @param sidecars Attach additional containers to the pod (evaluated as a template) +## +sidecars: [] +## @param tolerations Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +serviceAccount: + ## @param serviceAccount.create Specifies whether a service account should be created + ## + create: true + ## @param serviceAccount.name The name of the service account to use. If not set and create is true, a name is generated using the fullname template + ## + name: "" + ## @param serviceAccount.annotations Add annotations + ## + annotations: {} + ## @param serviceAccount.automountServiceAccountToken Automount API credentials for a service account. + ## + automountServiceAccountToken: false +## @param existingSecret Name of a secret with the application password +## +existingSecret: "" +## SMTP mail delivery configuration +## ref: https://github.com/bitnami/containers/tree/main/bitnami/drupal/#smtp-configuration +## @param smtpHost SMTP host +## @param smtpPort SMTP port +## @param smtpUser SMTP user +## @param smtpPassword SMTP password +## @param smtpProtocol SMTP Protocol (options: ssl,tls, nil) +## +smtpHost: "" +smtpPort: "" +smtpUser: "" +smtpPassword: "" +smtpProtocol: "" +## @param containerPorts [object] Container ports +## +containerPorts: + http: 8080 + https: 8443 +## @param extraContainerPorts Optionally specify extra list of additional ports for Drupal container(s) +## e.g: +## extraContainerPorts: +## - name: myservice +## containerPort: 9090 +## +extraContainerPorts: [] +## @param sessionAffinity Control where client requests go, to the same pod or round-robin. Values: ClientIP or None +## ref: https://kubernetes.io/docs/concepts/services-networking/service/ +## +sessionAffinity: "None" +## Enable persistence using Persistent Volume Claims +## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ +## +persistence: + ## @param persistence.enabled Enable persistence using PVC + ## + enabled: true + ## @param persistence.storageClass PVC Storage Class for Drupal volume + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param persistence.accessModes PVC Access Mode for Drupal volume + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + ## + accessModes: + - ReadWriteOnce + ## @param persistence.size PVC Storage Request for Drupal volume + ## + size: 8Gi + ## @param persistence.existingClaim A manually managed Persistent Volume Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + ## + existingClaim: "" + ## @param persistence.hostPath If defined, the drupal-data volume will mount to the specified hostPath. + ## Requires persistence.enabled: true + ## Requires persistence.existingClaim: nil|false + ## Default: nil. + ## + hostPath: "" + ## @param persistence.annotations Persistent Volume Claim annotations + ## + annotations: {} +## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAffinityPreset: "" +## @param podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAntiAffinityPreset: soft +## Node affinity preset +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +## @param nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## @param nodeAffinityPreset.key Node label key to match Ignored if `affinity` is set. +## @param nodeAffinityPreset.values Node label values to match. Ignored if `affinity` is set. +## +nodeAffinityPreset: + type: "" + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] +## @param affinity Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector Node labels for pod assignment. Evaluated as a template. +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ +## +nodeSelector: {} +## Drupal container's resource requests and limits +## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +## We usually recommend not to specify default resources and to leave this as a conscious +## choice for the user. This also increases chances charts run on environments with little +## resources, such as Minikube. If you do want to specify resources, uncomment the following +## lines, adjust them as necessary, and remove the curly braces after 'resources:'. +## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). +## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 +## +resourcesPreset: "micro" +## @param resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) +## Example: +## resources: +## requests: +## cpu: 2 +## memory: 512Mi +## limits: +## cpu: 3 +## memory: 1024Mi +## +resources: {} +## Configure Pods Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +## @param podSecurityContext.enabled Enable Drupal pods' Security Context +## @param podSecurityContext.fsGroupChangePolicy Set filesystem group change policy +## @param podSecurityContext.sysctls Set kernel settings using the sysctl interface +## @param podSecurityContext.supplementalGroups Set filesystem extra groups +## @param podSecurityContext.fsGroup Drupal pods' group ID +## +podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 +## Configure Container Security Context (only main container) +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +## @param containerSecurityContext.enabled Enabled Drupal containers' Security Context +## @param containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container +## @param containerSecurityContext.runAsUser Set Drupal containers' Security Context runAsUser +## @param containerSecurityContext.runAsGroup Set Drupal containers' Security Context runAsGroup +## @param containerSecurityContext.runAsNonRoot Set Controller container's Security Context runAsNonRoot +## @param containerSecurityContext.privileged Set Drupal container's Security Context privileged +## @param containerSecurityContext.allowPrivilegeEscalation Set Drupal container's Security Context allowPrivilegeEscalation +## @param containerSecurityContext.capabilities.drop List of capabilities to be dropped +## @param containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile +## @param containerSecurityContext.readOnlyRootFilesystem Set Drupal container's Security Context readOnlyRootFilesystem +## +containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" +## Configure extra options for startup probe +## Drupal core exposes /user/login to unauthenticated requests, making it a good +## default startup and readiness path. However, that may not always be the +## case. For example, if the image value is overridden to an image containing a +## module that alters that route, or an image that does not auto-install Drupal. +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## @param startupProbe.enabled Enable startupProbe +## @param startupProbe.path Request path for startupProbe +## @param startupProbe.initialDelaySeconds Initial delay seconds for startupProbe +## @param startupProbe.periodSeconds Period seconds for startupProbe +## @param startupProbe.timeoutSeconds Timeout seconds for startupProbe +## @param startupProbe.failureThreshold Failure threshold for startupProbe +## @param startupProbe.successThreshold Success threshold for startupProbe +## +startupProbe: + enabled: false + path: /user/login + initialDelaySeconds: 600 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 5 + successThreshold: 1 +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## @param livenessProbe.enabled Enable livenessProbe +## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe +## @param livenessProbe.periodSeconds Period seconds for livenessProbe +## @param livenessProbe.timeoutSeconds Timeout seconds for livenessProbe +## @param livenessProbe.failureThreshold Failure threshold for livenessProbe +## @param livenessProbe.successThreshold Success threshold for livenessProbe +## +livenessProbe: + enabled: true + initialDelaySeconds: 600 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 5 + successThreshold: 1 +## Configure extra options for readiness probe +## Drupal core exposes /user/login to unauthenticated requests, making it a good +## default startup and readiness path. However, that may not always be the +## case. For example, if the image value is overridden to an image containing a +## module that alters that route, or an image that does not auto-install Drupal. +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## @param readinessProbe.enabled Enable readinessProbe +## @param readinessProbe.path Request path for readinessProbe +## @param readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds Timeout seconds for readinessProbe +## @param readinessProbe.failureThreshold Failure threshold for readinessProbe +## @param readinessProbe.successThreshold Success threshold for readinessProbe +## +readinessProbe: + enabled: true + path: /user/login + initialDelaySeconds: 30 + periodSeconds: 5 + timeoutSeconds: 1 + failureThreshold: 5 + successThreshold: 1 +## @param customStartupProbe Override default startup probe +## +customStartupProbe: {} +## @param customLivenessProbe Override default liveness probe +## +customLivenessProbe: {} +## @param customReadinessProbe Override default readiness probe +## +customReadinessProbe: {} +## @param lifecycleHooks LifecycleHook to set additional configuration at startup Evaluated as a template +## +lifecycleHooks: {} +## @param podAnnotations Pod annotations +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param podLabels Add additional labels to the pod (evaluated as a template) +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @section Traffic Exposure Parameters + +## Kubernetes configuration. For minikube, set this to NodePort, elsewhere use LoadBalancer +## +service: + ## @param service.type Kubernetes Service type + ## + type: LoadBalancer + ## @param service.ports.http Service HTTP port + ## @param service.ports.https Service HTTPS port + ## + ports: + http: 80 + https: 443 + ## @param service.loadBalancerSourceRanges Restricts access for LoadBalancer (only with `service.type: LoadBalancer`) + ## e.g: + ## loadBalancerSourceRanges: + ## - 0.0.0.0/0 + ## + loadBalancerSourceRanges: [] + ## @param service.loadBalancerIP loadBalancerIP for the Drupal Service (optional, cloud specific) + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer + loadBalancerIP: "" + ## @param service.nodePorts [object] Kubernetes node port + ## nodePorts: + ## http: + ## https: + ## + nodePorts: + http: "" + https: "" + ## @param service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.clusterIP %%MAIN_CONTAINER_NAME%% service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param service.annotations Additional custom annotations for %%MAIN_CONTAINER_NAME%% service + ## + annotations: {} + ## @param service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} +## Configure the ingress resource that allows you to access the +## Drupal installation. Set up the URL +## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/ +## +ingress: + ## @param ingress.enabled Enable ingress controller resource + ## + enabled: false + ## DEPRECATED: Use ingress.annotations instead of ingress.certManager + ## certManager: false + ## + + ## @param ingress.pathType Ingress Path type + ## + pathType: ImplementationSpecific + ## @param ingress.apiVersion Override API Version (automatically detected if not set) + ## + apiVersion: "" + ## @param ingress.ingressClassName IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) + ## This is supported in Kubernetes 1.18+ and required if you have more than one IngressClass marked as the default for your cluster . + ## ref: https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/ + ## + ingressClassName: "" + ## @param ingress.hostname Default host for the ingress resource + ## + hostname: drupal.local + ## @param ingress.path The Path to Drupal. You may need to set this to '/*' in order to use this + ## with ALB ingress controllers. + ## + path: / + ## @param ingress.annotations Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. + ## For a full list of possible ingress annotations, please see + ## ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md + ## Use this parameter to set the required annotations for cert-manager, see + ## ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations + ## + ## e.g: + ## annotations: + ## kubernetes.io/ingress.class: nginx + ## cert-manager.io/cluster-issuer: cluster-issuer-name + ## + annotations: {} + ## @param ingress.tls Enable TLS configuration for the hostname defined at ingress.hostname parameter + ## TLS certificates will be retrieved from a TLS secret with name: {{- printf "%s-tls" .Values.ingress.hostname }} + ## You can use the ingress.secrets parameter to create this TLS secret or relay on cert-manager to create it + ## + tls: false + ## @param ingress.tlsWwwPrefix Adds www subdomain to default cert + ## Creates tls host with ingress.hostname: {{ print "www.%s" .Values.ingress.hostname }} + ## Is enabled if "nginx.ingress.kubernetes.io/from-to-www-redirect" is "true" + tlsWwwPrefix: false + ## @param ingress.extraHosts The list of additional hostnames to be covered with this ingress record. + ## Most likely the hostname above will be enough, but in the event more hosts are needed, this is an array + ## extraHosts: + ## - name: drupal.local + ## path: / + extraHosts: [] + ## @param ingress.extraPaths Any additional arbitrary paths that may need to be added to the ingress under the main host. + ## For example: The ALB ingress controller requires a special rule for handling SSL redirection. + ## extraPaths: + ## - path: /* + ## backend: + ## serviceName: ssl-redirect + ## servicePort: use-annotation + extraPaths: [] + ## @param ingress.extraTls The tls configuration for additional hostnames to be covered with this ingress record. + ## see: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + ## extraTls: + ## - hosts: + ## - drupal.local + ## secretName: drupal.local-tls + extraTls: [] + ## @param ingress.secrets If you're providing your own certificates, please use this to add the certificates as secrets + ## key and certificate should start with -----BEGIN CERTIFICATE----- or + ## -----BEGIN RSA PRIVATE KEY----- + ## + ## name should line up with a tlsSecret set further up + ## If you're using cert-manager, this is unneeded, as it will create the secret for you if it is not set + ## + ## It is also possible to create and manage the certificates outside of this helm chart + ## Please see README.md for more information + ## Example: + ## - name: drupal.local-tls + ## key: + ## certificate: + ## + secrets: [] + ## @param ingress.extraRules Additional rules to be covered with this ingress record + ## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules + ## e.g: + ## extraRules: + ## - host: example.local + ## http: + ## path: / + ## backend: + ## service: + ## name: example-svc + ## port: + ## name: http + ## + extraRules: [] +## @section Database parameters + +## MariaDB chart configuration +## https://github.com/bitnami/charts/blob/main/bitnami/mariadb/values.yaml +## +mariadb: + ## @param mariadb.enabled Whether to deploy a mariadb server to satisfy the applications database requirements + ## To use an external database set this to false and configure the externalDatabase parameters + ## + enabled: true + ## @param mariadb.architecture MariaDB architecture (`standalone` or `replication`) + ## + architecture: standalone + ## MariaDB Authentication parameters + ## @param mariadb.auth.rootPassword Password for the MariaDB `root` user + ## @param mariadb.auth.database Database name to create + ## @param mariadb.auth.username Database user to create + ## @param mariadb.auth.password Password for the database + ## + auth: + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mariadb#setting-the-root-password-on-first-run + ## + rootPassword: "" + ## ref: https://github.com/bitnami/containers/blob/main/bitnami/mariadb/README.md#creating-a-database-on-first-run + ## + database: bitnami_drupal + ## ref: https://github.com/bitnami/containers/blob/main/bitnami/mariadb/README.md#creating-a-database-user-on-first-run + ## + username: bn_drupal + password: "" + primary: + ## Enable persistence using Persistent Volume Claims + ## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ + ## @param mariadb.primary.persistence.enabled Enable database persistence using PVC + ## @param mariadb.primary.persistence.storageClass MariaDB primary persistent volume storage Class + ## @param mariadb.primary.persistence.accessModes Database Persistent Volume Access Modes + ## @param mariadb.primary.persistence.size Database Persistent Volume Size + ## @param mariadb.primary.persistence.hostPath Set path in case you want to use local host path volumes (not recommended in production) + ## @param mariadb.primary.persistence.existingClaim Name of an existing `PersistentVolumeClaim` for MariaDB primary replicas + ## + persistence: + enabled: true + ## mariadb data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + accessModes: + - ReadWriteOnce + size: 8Gi + hostPath: "" + existingClaim: "" +## External database configuration +## @param externalDatabase.host Host of the existing database +## @param externalDatabase.port Port of the existing database +## @param externalDatabase.user Existing username in the external db +## @param externalDatabase.password Password for the above username. Ignored if existing secret is provided +## @param externalDatabase.database Name of the existing database +## @param externalDatabase.existingSecret Name of a secret with the database password. (externalDatabase.password will be ignored and picked up from this secret). The secret has to contain the key db-password +## +externalDatabase: + host: "" + port: 3306 + user: bn_drupal + password: "" + database: bitnami_drupal + existingSecret: "" +## @section Volume Permissions parameters + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) + ## + enabled: false + ## @param volumePermissions.image.registry [default: REGISTRY_NAME] Init container volume-permissions image registry + ## @param volumePermissions.image.repository [default: REPOSITORY_NAME/os-shell] Init container volume-permissions image name + ## @skip volumePermissions.image.tag Init container volume-permissions image tag + ## @param volumePermissions.image.digest Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## @param volumePermissions.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 12-debian-12-r31 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Init containers' resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param volumePermissions.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "none" + ## @param volumePermissions.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} +## @section Metrics parameters + +## Prometheus Exporter / Metrics +## +metrics: + ## @param metrics.enabled Start a exporter side-car + ## + enabled: false + ## @param metrics.image.registry [default: REGISTRY_NAME] Apache exporter image registry + ## @param metrics.image.repository [default: REPOSITORY_NAME/apache-exporter] Apache exporter image repository + ## @skip metrics.image.tag Apache exporter image tag + ## @param metrics.image.digest Apache exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param metrics.image.pullPolicy Image pull policy + ## @param metrics.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/apache-exporter + tag: 1.0.9-debian-12-r1 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param metrics.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "none" + ## @param metrics.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## + resources: {} + ## + ## @param metrics.podAnnotations [object] Additional annotations for Metrics exporter pod + ## + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9117" + ## Drupal exporter service parameters + ## + service: + ## @param metrics.service.type Drupal exporter service type + ## + type: ClusterIP + ## @param metrics.service.ports.metrics Drupal exporter service port + ## + ports: + metrics: 9117 + ## @param metrics.service.externalTrafficPolicy Drupal exporter service external traffic policy + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param metrics.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param metrics.service.loadBalancerIP Drupal exporter service Load Balancer IP + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param metrics.service.loadBalancerSourceRanges Drupal exporter service Load Balancer sources + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g. + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param metrics.service.annotations Additional custom annotations for Drupal exporter service + ## + annotations: {} + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator + ## https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + serviceMonitor: + ## @param metrics.serviceMonitor.enabled Create ServiceMonitor resource(s) for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param metrics.serviceMonitor.namespace The namespace in which the ServiceMonitor will be created + ## + namespace: "" + ## @param metrics.serviceMonitor.interval The interval at which metrics should be scraped + ## + interval: 30s + ## @param metrics.serviceMonitor.scrapeTimeout The timeout after which the scrape is ended + ## + scrapeTimeout: "" + ## @param metrics.serviceMonitor.relabellings Metrics RelabelConfigs to apply to samples before scraping. + ## + relabellings: [] + ## @param metrics.serviceMonitor.metricRelabelings Metrics RelabelConfigs to apply to samples before ingestion. + ## + metricRelabelings: [] + ## @param metrics.serviceMonitor.honorLabels Specify honorLabels parameter to add the scrape endpoint + ## + honorLabels: false + ## @param metrics.serviceMonitor.additionalLabels Additional labels that can be used so ServiceMonitor resource(s) can be discovered by Prometheus + ## + additionalLabels: {} + ## Custom PrometheusRule to be defined + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + ## + prometheusRule: + ## @param metrics.prometheusRule.enabled Create a custom prometheusRule Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param metrics.prometheusRule.namespace The namespace in which the prometheusRule will be created + ## + namespace: "" + ## @param metrics.prometheusRule.additionalLabels Additional labels for the prometheusRule + ## + additionalLabels: {} + ## @param metrics.prometheusRule.rules Custom Prometheus rules + ## e.g: + ## rules: + ## - alert: ApacheDown + ## expr: apache_up{service="{{ template "common.names.fullname" . }}-metrics"} == 0 + ## for: 2m + ## labels: + ## severity: error + ## annotations: + ## summary: Drupal instance {{ "{{ $labels.instance }}" }} down + ## description: Drupal instance {{ "{{ $labels.instance }}" }} is down + ## + rules: [] +## @section Certificate injection parameters + +## Add custom certificates and certificate authorities to drupal container +## +certificates: + ## @param certificates.customCertificate.certificateSecret Secret containing the certificate and key to add + ## @param certificates.customCertificate.chainSecret.name Name of the secret containing the certificate chain + ## @param certificates.customCertificate.chainSecret.key Key of the certificate chain file inside the secret + ## @param certificates.customCertificate.certificateLocation Location in the container to store the certificate + ## @param certificates.customCertificate.keyLocation Location in the container to store the private key + ## @param certificates.customCertificate.chainLocation Location in the container to store the certificate chain + ## + customCertificate: + certificateSecret: "" + chainSecret: + name: secret-name + key: secret-key + certificateLocation: /etc/ssl/certs/ssl-cert-snakeoil.pem + keyLocation: /etc/ssl/private/ssl-cert-snakeoil.key + chainLocation: /etc/ssl/certs/mychain.pem + ## @param certificates.customCAs Defines a list of secrets to import into the container trust store + ## + customCAs: [] + ## @param certificates.command Override default container command (useful when using custom images) + ## + command: [] + ## @param certificates.args Override default container args (useful when using custom images) + ## + args: [] + ## @param certificates.extraEnvVars Container sidecar extra environment variables (eg proxy) + ## + extraEnvVars: [] + ## @param certificates.extraEnvVarsCM ConfigMap containing extra env vars + ## + extraEnvVarsCM: "" + ## @param certificates.extraEnvVarsSecret Secret containing extra env vars (in case of sensitive data) + ## + extraEnvVarsSecret: "" + ## @param certificates.image.registry [default: REGISTRY_NAME] Container sidecar registry + ## @param certificates.image.repository [default: REPOSITORY_NAME/os-shell] Container sidecar image + ## @skip certificates.image.tag Container sidecar image tag + ## @param certificates.image.digest Container sidecar image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param certificates.image.pullPolicy Container sidecar image pull policy + ## @param certificates.image.pullSecrets Container sidecar image pull secrets + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 12-debian-12-r31 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images + ## + pullPolicy: IfNotPresent + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] +## @section NetworkPolicy parameters + +## Network Policy configuration +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +## +networkPolicy: + ## @param networkPolicy.enabled Specifies whether a NetworkPolicy should be created + ## + enabled: true + ## @param networkPolicy.allowExternal Don't require server label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## server label will have network access to the ports server is listening + ## on. When true, server will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.allowExternalEgress Allow the pod to access any range of port and all destinations. + ## + allowExternalEgress: true + ## @param networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + extraIngress: [] + ## @param networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} diff --git a/charts/drupal/values-overrides.yaml b/charts/drupal/values-overrides.yaml new file mode 100644 index 0000000..6cc8fd7 --- /dev/null +++ b/charts/drupal/values-overrides.yaml @@ -0,0 +1,15 @@ +# @see https://artifacthub.io/packages/helm/bitnami/drupal?modal=values + +fullnameOverride: drupal +mariadb: + enabled: false +allowEmptyPassword: true +externalDatabase: + host: "mariadb.futureporn.svc.cluster.local" + port: 3306 + user: drupal + database: drupal + existingSecret: externaldb +image: + debug: true + tag: 10.3.6-debian-12-r1 \ No newline at end of file diff --git a/charts/fp/templates-staging/chihaya.yaml b/charts/fp/templates-staging/chihaya.yaml new file mode 100644 index 0000000..0d8ab54 --- /dev/null +++ b/charts/fp/templates-staging/chihaya.yaml @@ -0,0 +1,39 @@ + +# --- +# apiVersion: v1 +# kind: Service +# metadata: +# name: chihaya +# namespace: futureporn +# annotations: +# external-dns.alpha.kubernetes.io/hostname: "{{ .Values.chihaya.hostname }}" +# spec: +# type: LoadBalancer +# selector: +# app: chihaya +# ports: +# - name: http +# port: 80 +# targetPort: 80 + +# --- +# apiVersion: apps/v1 +# kind: Deployment +# metadata: +# name: chihaya +# spec: +# replicas: 1 +# selector: +# matchLabels: +# app: chihaya +# template: +# metadata: +# labels: +# app: chihaya +# spec: +# containers: +# - name: chihaya +# image: "quay.io/jzelinskie/chihaya-git:latest" +# ports: +# - containerPort: 80 + diff --git a/charts/fp/templates/mailbox.yaml b/charts/fp/templates-staging/mailbox.yaml similarity index 100% rename from charts/fp/templates/mailbox.yaml rename to charts/fp/templates-staging/mailbox.yaml diff --git a/charts/fp/templates/chihaya.yaml b/charts/fp/templates/chihaya.yaml deleted file mode 100644 index a5773b4..0000000 --- a/charts/fp/templates/chihaya.yaml +++ /dev/null @@ -1,79 +0,0 @@ - ---- -apiVersion: v1 -kind: Service -metadata: - name: chihaya - namespace: futureporn - annotations: - external-dns.alpha.kubernetes.io/hostname: "{{ .Values.chihaya.hostname }}" -spec: - type: LoadBalancer - selector: - app: chihaya - ports: - - name: http - port: 80 - targetPort: 80 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: chihaya -spec: - replicas: 1 - selector: - matchLabels: - app: chihaya - template: - metadata: - labels: - app: chihaya - spec: - containers: - - name: chihaya - image: "quay.io/jzelinskie/chihaya-git:latest" - ports: - - containerPort: 80 - ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: chihaya-http - namespace: futureporn -spec: - entryPoints: - - web - routes: - - match: Host(`chihaya.fp.sbtp.xyz`) - kind: Rule - middlewares: - - name: redirect - namespace: futureporn - services: - - name: chihaya - port: web - ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: chihaya-https - namespace: futureporn - annotations: - cert-manager.io/cluster-issuer: "{{ .Values.certManager.issuer }}" -spec: - entryPoints: - - websecure - routes: - - match: Host(`chihaya.fp.sbtp.xyz`) - kind: Rule - services: - - name: chihaya - namespace: futureporn - port: web - tls: - secretName: chihaya-tls - diff --git a/charts/fp/templates/chisel.yaml b/charts/fp/templates/chisel.yaml index 0b32666..e6b3a13 100644 --- a/charts/fp/templates/chisel.yaml +++ b/charts/fp/templates/chisel.yaml @@ -1,23 +1,14 @@ {{ if ne .Values.environment "production" }} -## chisel-operator acts on all Services of type LoadBalancer, randomly assigning them to an available ExitNode. -## Thus, we need to create lots of ExitNodes to ensure that -## each services gets an ExitNode - - -{{- $exitNodeCount := 9 }} # Define the number of ExitNodes you need - -{{- range $i := until $exitNodeCount }} --- apiVersion: chisel-operator.io/v1 kind: ExitNode metadata: - name: exit-node-{{ $i }} + name: vault-exit-node namespace: futureporn spec: - host: "155.138.254.201" + host: {{ quote .Values.chisel.exitNode.host }} port: 9090 auth: chisel -{{- end }} {{ end }} \ No newline at end of file diff --git a/charts/fp/templates/build.yaml b/charts/fp/templates/factory.yaml similarity index 74% rename from charts/fp/templates/build.yaml rename to charts/fp/templates/factory.yaml index e1bbf54..a83c21c 100644 --- a/charts/fp/templates/build.yaml +++ b/charts/fp/templates/factory.yaml @@ -3,23 +3,23 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: build + name: factory namespace: futureporn labels: - app.kubernetes.io/name: build + app.kubernetes.io/name: factory spec: - replicas: {{ .Values.build.replicas }} + replicas: {{ .Values.factory.replicas }} selector: matchLabels: - app: build + app: factory template: metadata: labels: - app: build + app: factory spec: containers: - - name: build - image: "{{ .Values.build.imageName }}" + - name: factory + image: "{{ .Values.factory.imageName }}" volumeMounts: - name: capture-worker-cache mountPath: "{{ .Values.capture.cache.dir }}" @@ -34,6 +34,16 @@ spec: secretKeyRef: name: postgrest key: automationUserJwt + - name: PATREON_CREATOR_ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: patreon + key: creatorAccessToken + - name: PATREON_CREATOR_REFRESH_TOKEN + valueFrom: + secretKeyRef: + name: patreon + key: creatorRefreshToken - name: POSTGREST_URL value: "{{ .Values.postgrest.url }}" - name: SCOUT_URL diff --git a/charts/fp/templates/game-2048.yaml b/charts/fp/templates/game-2048.yaml deleted file mode 100644 index 9fe43d5..0000000 --- a/charts/fp/templates/game-2048.yaml +++ /dev/null @@ -1,102 +0,0 @@ - -# --- -# apiVersion: networking.k8s.io/v1 -# kind: Ingress -# metadata: -# name: game-2048 -# namespace: futureporn -# spec: -# ingressClassName: ngrok -# rules: -# - host: "{{ .Values.ngrok.hostname }}" -# http: -# paths: -# - path: / -# pathType: Prefix -# backend: -# service: -# name: game-2048 -# port: -# number: 80 - ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: game-2048-http - namespace: futureporn -spec: - entryPoints: - - web - routes: - - match: Host(`game-2048.fp.sbtp.xyz`) - kind: Rule - middlewares: - - name: redirect - namespace: futureporn - services: - - name: game-2048 - port: 80 - ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: game-2048-https - namespace: futureporn - annotations: - cert-manager.io/cluster-issuer: "{{ .Values.certManager.issuer }}" -spec: - entryPoints: - - websecure - routes: - - match: Host(`game-2048.fp.sbtp.xyz`) - kind: Rule - services: - - name: game-2048 - namespace: futureporn - port: 80 - tls: - secretName: game-2048-tls - - ---- -apiVersion: v1 -kind: Service -metadata: - name: game-2048 - namespace: futureporn - annotations: - external-dns.alpha.kubernetes.io/hostname: "{{ .Values.game2048.hostname }}" -spec: - type: LoadBalancer - selector: - app: game-2048 - ports: - - name: http - port: 80 - targetPort: 80 - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: game-2048 - namespace: futureporn -spec: - replicas: 1 - selector: - matchLabels: - app: game-2048 - template: - metadata: - labels: - app: game-2048 - spec: - containers: - - name: game-2048 - image: alexwhen/docker-2048 - ports: - - name: http - containerPort: 80 - diff --git a/charts/fp/templates/gateway.yaml b/charts/fp/templates/gateway.yaml new file mode 100644 index 0000000..3e0b13b --- /dev/null +++ b/charts/fp/templates/gateway.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: example-gateway + namespace: futureporn +spec: + gatewayClassName: example-class + listeners: + - name: http + protocol: HTTP + port: 80 diff --git a/charts/fp/templates/next.yaml b/charts/fp/templates/next.yaml index bc426c5..78ccb2a 100644 --- a/charts/fp/templates/next.yaml +++ b/charts/fp/templates/next.yaml @@ -1,44 +1,4 @@ ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: next-http - namespace: futureporn -spec: - entryPoints: - - web - routes: - - match: Host(`next.fp.sbtp.xyz`) - kind: Rule - middlewares: - - name: redirect - namespace: futureporn - services: - - name: next - port: web - ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: next-https - namespace: futureporn - annotations: - cert-manager.io/cluster-issuer: "{{ .Values.certManager.issuer }}" -spec: - entryPoints: - - websecure - routes: - - match: Host(`next.fp.sbtp.xyz`) - kind: Rule - services: - - name: next - namespace: futureporn - port: web - tls: - secretName: next-tls - --- apiVersion: v1 @@ -57,6 +17,29 @@ spec: value: 0.0.0.0 - name: NEXT_PUBLIC_UPPY_COMPANION_URL value: "{{ .Values.uppy.url }}" + - name: NEXT_PUBLIC_POSTGREST_URL + value: "{{ .Values.postgrest.url }}" + - name: NEXT_PUBLIC_WEBSITE_DOMAIN + value: {{ printf "https://%s" .Values.next.hostname | quote }} + - name: NEXT_PUBLIC_API_DOMAIN + value: {{ .Values.next.hostname | quote }} + - name: PATREON_CLIENT_ID + valueFrom: + secretKeyRef: + name: patreon + key: clientId + - name: PATREON_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: patreon + key: clientSecret + - name: SUPERTOKENS_API_KEYS + valueFrom: + secretKeyRef: + name: supertokens + key: apiKeys + - name: SUPERTOKENS_URL + value: {{ printf "https://%s" .Values.supertokens.hostname | quote }} ports: - name: web containerPort: 3000 diff --git a/charts/fp/templates/pgadmin4.yaml b/charts/fp/templates/pgadmin4.yaml index c5656dd..4d38fe4 100644 --- a/charts/fp/templates/pgadmin4.yaml +++ b/charts/fp/templates/pgadmin4.yaml @@ -43,7 +43,7 @@ metadata: name: pgadmin4 namespace: futureporn spec: - type: NodePort + type: ClusterIP ports: - port: 5050 targetPort: 80 diff --git a/charts/fp/templates/postgrest.yaml b/charts/fp/templates/postgrest.yaml index 3e907f1..60c71f4 100644 --- a/charts/fp/templates/postgrest.yaml +++ b/charts/fp/templates/postgrest.yaml @@ -1,18 +1,41 @@ + +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: postgrest-httproute + namespace: futureporn +spec: + parentRefs: + - name: example-gateway + hostnames: + - "{{ .Values.postgrest.hostname }}" + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: postgrest + port: {{ .Values.postgrest.port }} + + --- apiVersion: v1 kind: Service metadata: name: postgrest namespace: futureporn + annotations: + external-dns.alpha.kubernetes.io/hostname: "{{ .Values.postgrest.hostname }}" spec: - type: ClusterIP + type: LoadBalancer selector: app: postgrest ports: - - name: web + - name: http port: {{ .Values.postgrest.port }} - targetPort: http - protocol: TCP + targetPort: {{ .Values.postgrest.port }} --- diff --git a/charts/fp/templates/strapi.yaml b/charts/fp/templates/strapi.yaml deleted file mode 100644 index 0016063..0000000 --- a/charts/fp/templates/strapi.yaml +++ /dev/null @@ -1,227 +0,0 @@ - ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: strapi-http - namespace: futureporn -spec: - entryPoints: - - web - routes: - - match: Host(`strapi.fp.sbtp.xyz`) - kind: Rule - middlewares: - - name: redirect - namespace: futureporn - services: - - name: strapi - port: http - ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: strapi-https - namespace: futureporn - annotations: - cert-manager.io/cluster-issuer: "{{ .Values.certManager.issuer }}" -spec: - entryPoints: - - websecure - routes: - - match: Host(`strapi.fp.sbtp.xyz`) - kind: Rule - services: - - name: strapi - namespace: futureporn - port: http - tls: - secretName: strapi-tls - ---- -apiVersion: v1 -kind: Service -metadata: - name: strapi - namespace: futureporn - annotations: - external-dns.alpha.kubernetes.io/hostname: "{{ .Values.strapi.hostname }}" -spec: - type: LoadBalancer - selector: - app: strapi - ports: - - name: http - port: 1339 - targetPort: http - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: strapi - namespace: futureporn - labels: - app.kubernetes.io/name: strapi -spec: - replicas: {{ .Values.strapi.replicas }} - selector: - matchLabels: - app: strapi - template: - metadata: - labels: - app: strapi - spec: - containers: - - name: strapi - readinessProbe: - httpGet: - path: / - port: http - initialDelaySeconds: 5 - periodSeconds: 5 - image: "{{ .Values.strapi.imageName }}" - ports: - - name: http - containerPort: 1339 - env: - - name: NODE_EXTRA_CA_CERTS - value: "{{ .Values.strapi.nodeExtraCaCerts }}" - - name: ADMIN_JWT_SECRET - valueFrom: - secretKeyRef: - name: strapi - key: adminJwtSecret - - name: API_TOKEN_SALT - valueFrom: - secretKeyRef: - name: strapi - key: apiTokenSalt - - name: APP_KEYS - valueFrom: - secretKeyRef: - name: strapi - key: appKeys - - name: DATABASE_URL - valueFrom: - secretKeyRef: - name: strapi - key: databaseUrl - - name: CDN_BUCKET_USC_URL - valueFrom: - secretKeyRef: - name: strapi - key: cdnBucketUscUrl - - name: DATABASE_CLIENT - value: postgres - - name: DATABASE_HOST - value: postgresql.futureporn.svc.cluster.local - - name: DATABASE_NAME - value: futureporn-strapi - - name: JWT_SECRET - valueFrom: - secretKeyRef: - name: strapi - key: jwtSecret - - name: MUX_PLAYBACK_RESTRICTION_ID - valueFrom: - secretKeyRef: - name: strapi - key: muxPlaybackRestrictionId - - name: MUX_SIGNING_KEY_ID - valueFrom: - secretKeyRef: - name: strapi - key: muxSigningKeyId - - name: MUX_SIGNING_KEY_PRIVATE_KEY - valueFrom: - secretKeyRef: - name: strapi - key: muxSigningKeyPrivateKey - - name: NODE_ENV - value: production - - name: S3_USC_BUCKET_APPLICATION_KEY - valueFrom: - secretKeyRef: - name: strapi - key: s3UscBucketApplicationKey - - name: S3_USC_BUCKET_ENDPOINT - valueFrom: - secretKeyRef: - name: strapi - key: s3UscBucketEndpoint - - name: S3_USC_BUCKET_KEY_ID - valueFrom: - secretKeyRef: - name: strapi - key: s3UscBucketKeyId - - name: S3_USC_BUCKET_NAME - valueFrom: - secretKeyRef: - name: strapi - key: s3UscBucketName - - name: S3_USC_BUCKET_REGION - valueFrom: - secretKeyRef: - name: strapi - key: s3UscBucketRegion - - name: SENDGRID_API_KEY - valueFrom: - secretKeyRef: - name: strapi - key: sendgridApiKey - - name: TRANSFER_TOKEN_SALT - valueFrom: - secretKeyRef: - name: strapi - key: transferTokenSalt - - name: STRAPI_URL - value: "{{ .Values.strapi.url }}" - - name: PORT - value: "{{ .Values.strapi.port }}" - resources: - limits: - cpu: 1000m - memory: 2Gi - restartPolicy: Always - - -# --- -# apiVersion: v1 -# kind: PersistentVolumeClaim -# metadata: -# name: strapi -# namespace: futureporn -# annotations: -# meta.helm.sh/release-name: fp -# meta.helm.sh/release-namespace: futureporn -# labels: -# app.kubernetes.io/managed-by: {{ .Values.managedBy }} -# spec: -# accessModes: -# - ReadWriteOnce -# resources: -# requests: -# storage: 100Gi -# storageClassName: {{ .Values.storageClassName }} - - - - - ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: strapi - namespace: futureporn -spec: - secretName: strapi-tls - issuerRef: - name: "{{ .Values.certManager.issuer }}" - kind: ClusterIssuer - dnsNames: - - "{{ .Values.strapi.hostname }}" - diff --git a/charts/fp/templates/supertokens.yaml b/charts/fp/templates/supertokens.yaml new file mode 100644 index 0000000..ceca4b5 --- /dev/null +++ b/charts/fp/templates/supertokens.yaml @@ -0,0 +1,138 @@ + +# --- +# apiVersion: traefik.io/v1alpha1 +# kind: IngressRoute +# metadata: +# name: supertokens-http +# namespace: futureporn +# spec: +# entryPoints: +# - web +# routes: +# - match: Host(`auth.fp.sbtp.xyz`) +# kind: Rule +# middlewares: +# - name: redirect +# namespace: futureporn +# services: +# - name: supertokens +# port: 3567 + +# --- +# apiVersion: traefik.io/v1alpha1 +# kind: IngressRoute +# metadata: +# name: supertokens-https +# namespace: futureporn +# annotations: +# cert-manager.io/cluster-issuer: "{{ .Values.certManager.issuer }}" +# spec: +# entryPoints: +# - websecure +# routes: +# - match: Host(`auth.fp.sbtp.xyz`) +# kind: Rule +# services: +# - name: supertokens +# namespace: futureporn +# port: 3567 +# tls: +# secretName: supertokens-tls + +# --- +# apiVersion: batch/v1 +# kind: Job +# metadata: +# name: supertokens-database-seed +# namespace: futureporn +# spec: +# template: +# spec: +# containers: +# - name: supertokens-database-seed +# image: postgres:latest +# imagePullPolicy: IfNotPresent +# env: +# - name: DB_DATABASE +# value: postgres + +# # valueFrom: +# # secretKeyRef: +# # name: supertokens +# # key: postgresqlUri +# command: +# - /bin/sh +# - -c +# - psql -a -f CREATE DATABASE supertokens; +# restartPolicy: OnFailure + +--- +apiVersion: v1 +kind: Service +metadata: + name: supertokens + namespace: futureporn + annotations: + external-dns.alpha.kubernetes.io/hostname: "{{ .Values.supertokens.hostname }}" +spec: + type: LoadBalancer + selector: + app: supertokens + ports: + - name: http + port: {{ .Values.supertokens.port }} + targetPort: {{ .Values.supertokens.port }} + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: supertokens + namespace: futureporn +spec: + replicas: {{ .Values.supertokens.replicas }} + selector: + matchLabels: + app: supertokens + template: + metadata: + labels: + app: supertokens + spec: + containers: + - name: supertokens + image: registry.supertokens.io/supertokens/supertokens-postgresql + ports: + - name: http + containerPort: {{ .Values.supertokens.port }} + # livenessProbe: + # httpGet: + # path: /hello + # port: http + # failureThreshold: 3 + # initialDelaySeconds: 10 + # periodSeconds: 10 + # readinessProbe: + # httpGet: + # path: /hello + # port: http + # failureThreshold: 3 + # initialDelaySeconds: 10 + # periodSeconds: 10 + # timeoutSeconds: 30 + env: + ## @see https://github.com/supertokens/supertokens-docker-postgresql/blob/master/README.md + - name: DISABLE_TELEMETRY + value: "true" + - name: SUPERTOKENS_PORT + value: "{{ .Values.supertokens.port }}" + - name: POSTGRESQL_CONNECTION_URI + valueFrom: + secretKeyRef: + name: supertokens + key: postgresqlUri + - name: API_KEYS + valueFrom: + secretKeyRef: + name: supertokens + key: apiKeys diff --git a/charts/fp/templates/traefik.yaml b/charts/fp/templates/traefik.yaml index e96f119..f87411a 100644 --- a/charts/fp/templates/traefik.yaml +++ b/charts/fp/templates/traefik.yaml @@ -1,11 +1,115 @@ ---- -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: redirect - namespace: futureporn +# --- +# apiVersion: traefik.io/v1alpha1 +# kind: Middleware +# metadata: +# name: redirect +# namespace: futureporn +# spec: +# redirectScheme: +# scheme: https +# permanent: true + + +# --- +# apiVersion: traefik.io/v1alpha1 +# kind: Middleware +# metadata: +# name: traefik-dashboard-basicauth +# namespace: futureporn + +# spec: +# basicAuth: +# secret: traefik-dashboard-auth + +# --- +# apiVersion: traefik.io/v1alpha1 +# kind: IngressRoute +# metadata: +# name: traefik-dashboard-custom +# namespace: futureporn + +# spec: +# entryPoints: +# - websecure +# - web +# routes: +# - match: PathPrefix(`/board`) +# kind: Rule +# # priority: 2147483647 +# # middlewares: +# # - name: traefik-dashboard-basicauth +# # namespace: traefik +# services: +# - name: dashboard@internal +# kind: TraefikService + +# --- +# apiVersion: traefik.io/v1alpha1 +# kind: IngressRoute +# metadata: +# name: traefik-api-custom +# namespace: futureporn + +# spec: +# entryPoints: +# - websecure +# - web +# routes: +# - match: PathPrefix(`/api`) +# kind: Rule +# # priority: 2147483647 +# # middlewares: +# # - name: traefik-dashboard-basicauth +# # namespace: traefik +# services: +# - name: api@internal +# kind: TraefikService + + +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: whoami-httproute + namespace: futureporn spec: - redirectScheme: - scheme: https - permanent: true + parentRefs: + - name: traefik-gateway + hostnames: + - traefik.futureporn.svc.cluster.local + rules: + - matches: + - path: + type: PathPrefix + value: /whoami + filters: + - type: ResponseHeaderModifier + responseHeaderModifier: + add: + - name: x-cj-was-here + value: "true" + backendRefs: + - name: whoami + port: 8888 + - matches: + - path: + type: PathPrefix + value: /postgrest + backendRefs: + - name: postgrest + port: 9000 + +# --- +# apiVersion: gateway.networking.k8s.io/v1 +# kind: HTTPRoute +# metadata: +# name: whoami-httproute +# namespace: futureporn +# spec: +# parentRefs: +# - name: traefik-gateway +# hostnames: +# - traefik.futureporn.svc.cluster.local +# rules: +# - matches: diff --git a/charts/fp/templates/whoami.yaml b/charts/fp/templates/whoami.yaml index b84b7b6..31a3d7d 100644 --- a/charts/fp/templates/whoami.yaml +++ b/charts/fp/templates/whoami.yaml @@ -3,45 +3,27 @@ {{ if ne .Values.environment "production" }} ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: whoami-http - namespace: futureporn -spec: - entryPoints: - - web - routes: - - match: Host(`whoami.fp.sbtp.xyz`) - kind: Rule - middlewares: - - name: redirect - namespace: futureporn - services: - - name: whoami - port: 80 ---- -apiVersion: traefik.io/v1alpha1 -kind: IngressRoute -metadata: - name: whoami-https - namespace: futureporn - annotations: - cert-manager.io/cluster-issuer: "{{ .Values.certManager.issuer }}" -spec: - entryPoints: - - websecure - routes: - - match: Host(`whoami.fp.sbtp.xyz`) - kind: Rule - services: - - name: whoami - namespace: futureporn - port: 80 - tls: - secretName: whoami-tls +# --- +# apiVersion: gateway.networking.k8s.io/v1 +# kind: HTTPRoute +# metadata: +# name: whoami-httproute +# namespace: futureporn +# spec: +# parentRefs: +# - name: traefik-gateway +# hostnames: +# - traefik.futureporn +# rules: +# - matches: +# - path: +# type: PathPrefix +# value: /whoami +# backendRefs: +# - name: whoami +# port: {{ .Values.whoami.port }} + --- apiVersion: v1 @@ -56,8 +38,8 @@ spec: selector: app: whoami ports: - - port: 80 - targetPort: 80 + - port: {{ .Values.whoami.port }} + targetPort: {{ .Values.whoami.port }} --- @@ -79,8 +61,10 @@ spec: containers: - name: whoami image: containous/whoami + args: + - --port={{ .Values.whoami.port }} ports: - - containerPort: 80 + - containerPort: {{ .Values.whoami.port }} {{ end }} \ No newline at end of file diff --git a/charts/fp/values.yaml b/charts/fp/values.yaml index 224a04d..d2e2d02 100644 --- a/charts/fp/values.yaml +++ b/charts/fp/values.yaml @@ -33,9 +33,9 @@ mailbox: cdnBucketUrl: https://fp-dev.b-cdn.net s3BucketName: fp-dev port: 5000 -build: +factory: replicas: 1 - imageName: fp/build + imageName: fp/factory strapi: replicas: 1 imageName: fp/strapi @@ -79,25 +79,32 @@ scout: imageName: fp/scout replicas: 1 port: 8134 - url: http://scout.futureporn.svc.cluster.local:8134 + url: http://scout.fp.sbtp.xyz postgrest: - url: http://postgrest.futureporn.svc.cluster.local:9000 + hostname: postgrest.fp.sbtp.xyz image: postgrest/postgrest replicas: 1 port: 9000 schemas: api -# postgresql: -# image: postgres:16 -# replicas: 1 -# user: futureporn -# port: 5432 chisel: exitNode: host: "155.138.254.201" port: 9090 game2048: hostname: game-2048.fp.sbtp.xyz +supertokens: + port: 3348 + hostname: supertokens.fp.sbtp.xyz + replicas: 1 +logto: + admin: + port: 3002 + hostname: logto-admin.fp.sbtp.xyz + main: + port: 3001 + hostname: logto.fp.sbtp.xyz whoami: hostname: whoami.fp.sbtp.xyz + port: 8888 migrations: - imageName: fp/migrations \ No newline at end of file + imageName: fp/migrations diff --git a/charts/mariadb/mariadb/.helmignore b/charts/mariadb/mariadb/.helmignore new file mode 100644 index 0000000..207983f --- /dev/null +++ b/charts/mariadb/mariadb/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# img folder +img/ +# Changelog +CHANGELOG.md diff --git a/charts/mariadb/mariadb/Chart.lock b/charts/mariadb/mariadb/Chart.lock new file mode 100644 index 0000000..029083d --- /dev/null +++ b/charts/mariadb/mariadb/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.23.0 +digest: sha256:fbd6439f12ded949c04553b9c52a4c8153a8f2790147d972b314ddcd46921a14 +generated: "2024-09-23T12:24:39.221888112Z" diff --git a/charts/mariadb/mariadb/Chart.yaml b/charts/mariadb/mariadb/Chart.yaml new file mode 100644 index 0000000..4a84e3f --- /dev/null +++ b/charts/mariadb/mariadb/Chart.yaml @@ -0,0 +1,36 @@ +annotations: + category: Database + images: | + - name: mariadb + image: docker.io/bitnami/mariadb:11.4.3-debian-12-r1 + - name: mysqld-exporter + image: docker.io/bitnami/mysqld-exporter:0.15.1-debian-12-r34 + - name: os-shell + image: docker.io/bitnami/os-shell:12-debian-12-r30 + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 11.4.3 +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: MariaDB is an open source, community-developed SQL database server that + is widely in use around the world due to its enterprise features, flexibility, and + collaboration with leading tech firms. +home: https://bitnami.com +icon: https://bitnami.com/assets/stacks/mariadb/img/mariadb-stack-220x234.png +keywords: +- mariadb +- mysql +- database +- sql +- prometheus +maintainers: +- name: Broadcom, Inc. All Rights Reserved. + url: https://github.com/bitnami/charts +name: mariadb +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/mariadb +version: 19.1.0 diff --git a/charts/mariadb/mariadb/README.md b/charts/mariadb/mariadb/README.md new file mode 100644 index 0000000..5eace34 --- /dev/null +++ b/charts/mariadb/mariadb/README.md @@ -0,0 +1,650 @@ + + +# Bitnami package for MariaDB + +MariaDB is an open source, community-developed SQL database server that is widely in use around the world due to its enterprise features, flexibility, and collaboration with leading tech firms. + +[Overview of MariaDB](https://mariadb.org/) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/mariadb +``` + +Looking to use MariaDB in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the commercial edition of the Bitnami catalog. + +## Introduction + +This chart bootstraps a [MariaDB](https://github.com/bitnami/containers/tree/main/bitnami/mariadb) replication cluster deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +MariaDB is developed as open source software and as a relational database it provides an SQL interface for accessing data. The latest versions of MariaDB also include GIS and JSON features. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://REGISTRY_NAME/REPOSITORY_NAME/mariadb +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The command deploys MariaDB on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Configuration and installation details + +### Resource requests and limits + +Bitnami charts allow setting resource requests and limits for all containers inside the chart deployment. These are inside the `resources` value (check parameter table). Setting requests is essential for production workloads and these should be adapted to your specific use case. + +To make this process easier, the chart contains the `resourcesPreset` values, which automatically sets the `resources` section according to different presets. Check these presets in [the bitnami/common chart](https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15). However, in production workloads using `resourcesPreset` is discouraged as it may not fully adapt to your specific needs. Find more information on container resource management in the [official Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +### [Rolling VS Immutable tags](https://docs.vmware.com/en/VMware-Tanzu-Application-Catalog/services/tutorials/GUID-understand-rolling-tags-containers-index.html) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Change MariaDB version + +To modify the MariaDB version used in this chart you can specify a [valid image tag](https://hub.docker.com/r/bitnami/mariadb/tags/) using the `image.tag` parameter. For example, `image.tag=X.Y.Z`. This approach is also applicable to other images like exporters. + +### Initialize a fresh instance + +The [Bitnami MariaDB](https://github.com/bitnami/containers/tree/main/bitnami/mariadb) image allows you to use your custom scripts to initialize a fresh instance. Custom scripts may be specified using the `initdbScripts` parameter. Alternatively, an external ConfigMap may be created with all the initialization scripts and the ConfigMap passed to the chart via the `initdbScriptsConfigMap` parameter. Note that this will override the `initdbScripts` parameter. + +The allowed extensions are `.sh`, `.sql` and `.sql.gz`. + +These scripts are treated differently depending on their extension. While `.sh` scripts are executed on all the nodes, `.sql` and `.sql.gz` scripts are only executed on the primary nodes. This is because `.sh` scripts support conditional tests to identify the type of node they are running on, while such tests are not supported in `.sql` or `.sql.gz` files. + +When using a `.sh` script, you may wish to perform a "one-time" action like creating a database. This can be achieved by adding a condition in the script to ensure that it is executed only on one node, as shown in the example below: + +```yaml +initdbScripts: + my_init_script.sh: | + #!/bin/sh + if [[ $(hostname) == *primary* ]]; then + echo "Primary node" + mysql -P 3306 -uroot -prandompassword -e "create database new_database"; + else + echo "No primary node" + fi +``` + +### Sidecars and Init Containers + +If additional containers are needed in the same pod as MariaDB (such as additional metrics or logging exporters), they can be defined using the `sidecars` parameter. + +```yaml +sidecars: +- name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +If these sidecars export extra ports, extra port definitions can be added using the `service.extraPorts` parameter (where available), as shown in the example below: + +```yaml +service: + extraPorts: + - name: extraPort + port: 11311 + targetPort: 11311 +``` + +> NOTE: This Helm chart already includes sidecar containers for the Prometheus exporters (where applicable). These can be activated by adding the `--enable-metrics=true` parameter at deployment time. The `sidecars` parameter should therefore only be used for any extra sidecar containers. + +If additional init containers are needed in the same pod, they can be defined using the `initContainers` parameter. Here is an example: + +```yaml +initContainers: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +Learn more about [sidecar containers](https://kubernetes.io/docs/concepts/workloads/pods/) and [init containers](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/). + +## Persistence + +The [Bitnami MariaDB](https://github.com/bitnami/containers/tree/main/bitnami/mariadb) image stores the MariaDB data and configurations at the `/bitnami/mariadb` path of the container. + +The chart mounts a [Persistent Volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) volume at this location. The volume is created using dynamic volume provisioning, by default. An existing PersistentVolumeClaim can also be defined. + +If you encounter errors when working with persistent volumes, refer to our [troubleshooting guide for persistent volumes](https://docs.bitnami.com/kubernetes/faq/troubleshooting/troubleshooting-persistence-volumes/). + +### Adjust permissions of persistent volume mountpoint + +As the image run as non-root by default, it is necessary to adjust the ownership of the persistent volume so that the container can write data into it. + +By default, the chart is configured to use Kubernetes Security Context to automatically change the ownership of the volume. However, this feature does not work in all Kubernetes distributions. + +As an alternative, this chart supports using an initContainer to change the ownership of the volume before mounting it in the final destination. You can enable this initContainer by setting `volumePermissions.enabled` to `true`. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| `global.imageRegistry` | Global Docker Image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.defaultStorageClass` | Global default StorageClass for Persistent Volume(s) | `""` | +| `global.storageClass` | DEPRECATED: use global.defaultStorageClass instead | `""` | +| `global.compatibility.openshift.adaptSecurityContext` | Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) | `auto` | + +### Common parameters + +| Name | Description | Value | +| ------------------------- | --------------------------------------------------------------------------------------- | --------------- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override mariadb.fullname | `""` | +| `fullnameOverride` | String to fully override mariadb.fullname | `""` | +| `clusterDomain` | Default Kubernetes cluster domain | `cluster.local` | +| `commonAnnotations` | Common annotations to add to all MariaDB resources (sub-charts are not considered) | `{}` | +| `commonLabels` | Common labels to add to all MariaDB resources (sub-charts are not considered) | `{}` | +| `schedulerName` | Name of the scheduler (other than default) to dispatch pods | `""` | +| `runtimeClassName` | Name of the Runtime Class for all MariaDB pods | `""` | +| `extraDeploy` | Array of extra objects to deploy with the release (evaluated as a template) | `[]` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` | +| `diagnosticMode.command` | Command to override all containers in the deployment | `["sleep"]` | +| `diagnosticMode.args` | Args to override all containers in the deployment | `["infinity"]` | +| `serviceBindings.enabled` | Create secret for service binding (Experimental) | `false` | + +### MariaDB common parameters + +| Name | Description | Value | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | +| `image.registry` | MariaDB image registry | `REGISTRY_NAME` | +| `image.repository` | MariaDB image repository | `REPOSITORY_NAME/mariadb` | +| `image.digest` | MariaDB image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | MariaDB image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `image.debug` | Specify if debug logs should be enabled | `false` | +| `architecture` | MariaDB architecture (`standalone` or `replication`) | `standalone` | +| `auth.rootPassword` | Password for the `root` user. Ignored if existing secret is provided. | `""` | +| `auth.database` | Name for a custom database to create | `my_database` | +| `auth.username` | Name for a custom user to create | `""` | +| `auth.password` | Password for the new user. Ignored if existing secret is provided | `""` | +| `auth.replicationUser` | MariaDB replication user | `replicator` | +| `auth.replicationPassword` | MariaDB replication user password. Ignored if existing secret is provided | `""` | +| `auth.existingSecret` | Use existing secret for password details (`auth.rootPassword`, `auth.password`, `auth.replicationPassword` will be ignored and picked up from this secret). The secret has to contain the keys `mariadb-root-password`, `mariadb-replication-password` and `mariadb-password` | `""` | +| `auth.forcePassword` | Force users to specify required passwords | `false` | +| `auth.usePasswordFiles` | Mount credentials as files instead of using environment variables | `false` | +| `auth.customPasswordFiles` | Use custom password files when `auth.usePasswordFiles` is set to `true`. Define path for keys `root` and `user`, also define `replicator` if `architecture` is set to `replication` | `{}` | +| `initdbScripts` | Dictionary of initdb scripts | `{}` | +| `initdbScriptsConfigMap` | ConfigMap with the initdb scripts (Note: Overrides `initdbScripts`) | `""` | + +### MariaDB Primary parameters + +| Name | Description | Value | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `primary.name` | Name of the primary database (eg primary, master, leader, ...) | `primary` | +| `primary.command` | Override default container command on MariaDB Primary container(s) (useful when using custom images) | `[]` | +| `primary.args` | Override default container args on MariaDB Primary container(s) (useful when using custom images) | `[]` | +| `primary.lifecycleHooks` | for the MariaDB Primary container(s) to automate configuration before or after startup | `{}` | +| `primary.automountServiceAccountToken` | Mount Service Account token in pod | `false` | +| `primary.hostAliases` | Add deployment host aliases | `[]` | +| `primary.containerPorts.mysql` | Container port for mysql | `3306` | +| `primary.configuration` | MariaDB Primary configuration to be injected as ConfigMap | `""` | +| `primary.existingConfigmap` | Name of existing ConfigMap with MariaDB Primary configuration. | `""` | +| `primary.updateStrategy.type` | MariaDB primary statefulset strategy type | `RollingUpdate` | +| `primary.rollingUpdatePartition` | Partition update strategy for Mariadb Primary statefulset | `""` | +| `primary.podAnnotations` | Additional pod annotations for MariaDB primary pods | `{}` | +| `primary.podLabels` | Extra labels for MariaDB primary pods | `{}` | +| `primary.podAffinityPreset` | MariaDB primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.podAntiAffinityPreset` | MariaDB primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `primary.nodeAffinityPreset.type` | MariaDB primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.nodeAffinityPreset.key` | MariaDB primary node label key to match Ignored if `primary.affinity` is set. | `""` | +| `primary.nodeAffinityPreset.values` | MariaDB primary node label values to match. Ignored if `primary.affinity` is set. | `[]` | +| `primary.affinity` | Affinity for MariaDB primary pods assignment | `{}` | +| `primary.nodeSelector` | Node labels for MariaDB primary pods assignment | `{}` | +| `primary.tolerations` | Tolerations for MariaDB primary pods assignment | `[]` | +| `primary.schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `primary.podManagementPolicy` | podManagementPolicy to manage scaling operation of MariaDB primary pods | `""` | +| `primary.topologySpreadConstraints` | Topology Spread Constraints for MariaDB primary pods assignment | `[]` | +| `primary.priorityClassName` | Priority class for MariaDB primary pods assignment | `""` | +| `primary.runtimeClassName` | Runtime Class for MariaDB primary pods | `""` | +| `primary.podSecurityContext.enabled` | Enable security context for MariaDB primary pods | `true` | +| `primary.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `primary.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `primary.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `primary.podSecurityContext.fsGroup` | Group ID for the mounted volumes' filesystem | `1001` | +| `primary.containerSecurityContext.enabled` | MariaDB primary container securityContext | `true` | +| `primary.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `primary.containerSecurityContext.runAsUser` | User ID for the MariaDB primary container | `1001` | +| `primary.containerSecurityContext.runAsGroup` | Group ID for the MariaDB primary container | `1001` | +| `primary.containerSecurityContext.runAsNonRoot` | Set primary container's Security Context runAsNonRoot | `true` | +| `primary.containerSecurityContext.privileged` | Set primary container's Security Context privileged | `false` | +| `primary.containerSecurityContext.allowPrivilegeEscalation` | Set primary container's Security Context allowPrivilegeEscalation | `false` | +| `primary.containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `primary.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `primary.containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `primary.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if primary.resources is set (primary.resources is recommended for production). | `micro` | +| `primary.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `primary.startupProbe.enabled` | Enable startupProbe | `false` | +| `primary.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `120` | +| `primary.startupProbe.periodSeconds` | Period seconds for startupProbe | `15` | +| `primary.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `primary.startupProbe.failureThreshold` | Failure threshold for startupProbe | `10` | +| `primary.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `primary.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `primary.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `120` | +| `primary.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `primary.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `primary.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `primary.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `primary.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `primary.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `30` | +| `primary.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `primary.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `primary.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `primary.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `primary.customStartupProbe` | Override default startup probe for MariaDB primary containers | `{}` | +| `primary.customLivenessProbe` | Override default liveness probe for MariaDB primary containers | `{}` | +| `primary.customReadinessProbe` | Override default readiness probe for MariaDB primary containers | `{}` | +| `primary.startupWaitOptions` | Override default builtin startup wait check options for MariaDB primary containers | `{}` | +| `primary.extraFlags` | MariaDB primary additional command line flags | `""` | +| `primary.extraEnvVars` | Extra environment variables to be set on MariaDB primary containers | `[]` | +| `primary.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for MariaDB primary containers | `""` | +| `primary.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for MariaDB primary containers | `""` | +| `primary.persistence.enabled` | Enable persistence on MariaDB primary replicas using a `PersistentVolumeClaim`. If false, use emptyDir | `true` | +| `primary.persistence.existingClaim` | Name of an existing `PersistentVolumeClaim` for MariaDB primary replicas | `""` | +| `primary.persistence.subPath` | Subdirectory of the volume to mount at | `""` | +| `primary.persistence.storageClass` | MariaDB primary persistent volume storage Class | `""` | +| `primary.persistence.labels` | Labels for the PVC | `{}` | +| `primary.persistence.annotations` | MariaDB primary persistent volume claim annotations | `{}` | +| `primary.persistence.accessModes` | MariaDB primary persistent volume access Modes | `["ReadWriteOnce"]` | +| `primary.persistence.size` | MariaDB primary persistent volume size | `8Gi` | +| `primary.persistence.selector` | Selector to match an existing Persistent Volume | `{}` | +| `primary.extraVolumes` | Optionally specify extra list of additional volumes to the MariaDB Primary pod(s) | `[]` | +| `primary.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the MariaDB Primary container(s) | `[]` | +| `primary.initContainers` | Add additional init containers for the MariaDB Primary pod(s) | `[]` | +| `primary.sidecars` | Add additional sidecar containers for the MariaDB Primary pod(s) | `[]` | +| `primary.service.type` | MariaDB Primary Kubernetes service type | `ClusterIP` | +| `primary.service.ports.mysql` | MariaDB Primary Kubernetes service port for MariaDB | `3306` | +| `primary.service.ports.metrics` | MariaDB Primary Kubernetes service port for metrics | `9104` | +| `primary.service.nodePorts.mysql` | MariaDB Primary Kubernetes service node port | `""` | +| `primary.service.clusterIP` | MariaDB Primary Kubernetes service clusterIP IP | `""` | +| `primary.service.loadBalancerIP` | MariaDB Primary loadBalancerIP if service type is `LoadBalancer` | `""` | +| `primary.service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `primary.service.loadBalancerSourceRanges` | Address that are allowed when MariaDB Primary service is LoadBalancer | `[]` | +| `primary.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `primary.service.annotations` | Provide any additional annotations which may be required | `{}` | +| `primary.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `primary.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `primary.pdb.create` | Enable/disable a Pod Disruption Budget creation for MariaDB primary pods | `true` | +| `primary.pdb.minAvailable` | Minimum number/percentage of MariaDB primary pods that must still be available after the eviction | `""` | +| `primary.pdb.maxUnavailable` | Maximum number/percentage of MariaDB primary pods that can be unavailable after the eviction. Defaults to `1` if both `primary.pdb.minAvailable` and `primary.pdb.maxUnavailable` are empty. | `""` | +| `primary.revisionHistoryLimit` | Maximum number of revisions that will be maintained in the StatefulSet | `10` | + +### MariaDB Secondary parameters + +| Name | Description | Value | +| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `secondary.name` | Name of the secondary database (eg secondary, slave, ...) | `secondary` | +| `secondary.replicaCount` | Number of MariaDB secondary replicas | `1` | +| `secondary.command` | Override default container command on MariaDB Secondary container(s) (useful when using custom images) | `[]` | +| `secondary.args` | Override default container args on MariaDB Secondary container(s) (useful when using custom images) | `[]` | +| `secondary.lifecycleHooks` | for the MariaDB Secondary container(s) to automate configuration before or after startup | `{}` | +| `secondary.automountServiceAccountToken` | Mount Service Account token in pod | `false` | +| `secondary.hostAliases` | Add deployment host aliases | `[]` | +| `secondary.containerPorts.mysql` | Container port for mysql | `3306` | +| `secondary.configuration` | MariaDB Secondary configuration to be injected as ConfigMap | `""` | +| `secondary.existingConfigmap` | Name of existing ConfigMap with MariaDB Secondary configuration. | `""` | +| `secondary.updateStrategy.type` | MariaDB secondary statefulset strategy type | `RollingUpdate` | +| `secondary.rollingUpdatePartition` | Partition update strategy for Mariadb Secondary statefulset | `""` | +| `secondary.podAnnotations` | Additional pod annotations for MariaDB secondary pods | `{}` | +| `secondary.podLabels` | Extra labels for MariaDB secondary pods | `{}` | +| `secondary.podAffinityPreset` | MariaDB secondary pod affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `secondary.podAntiAffinityPreset` | MariaDB secondary pod anti-affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `secondary.nodeAffinityPreset.type` | MariaDB secondary node affinity preset type. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `secondary.nodeAffinityPreset.key` | MariaDB secondary node label key to match Ignored if `secondary.affinity` is set. | `""` | +| `secondary.nodeAffinityPreset.values` | MariaDB secondary node label values to match. Ignored if `secondary.affinity` is set. | `[]` | +| `secondary.affinity` | Affinity for MariaDB secondary pods assignment | `{}` | +| `secondary.nodeSelector` | Node labels for MariaDB secondary pods assignment | `{}` | +| `secondary.tolerations` | Tolerations for MariaDB secondary pods assignment | `[]` | +| `secondary.topologySpreadConstraints` | Topology Spread Constraints for MariaDB secondary pods assignment | `[]` | +| `secondary.priorityClassName` | Priority class for MariaDB secondary pods assignment | `""` | +| `secondary.runtimeClassName` | Runtime Class for MariaDB secondary pods | `""` | +| `secondary.schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `secondary.podManagementPolicy` | podManagementPolicy to manage scaling operation of MariaDB secondary pods | `""` | +| `secondary.podSecurityContext.enabled` | Enable security context for MariaDB secondary pods | `true` | +| `secondary.podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `secondary.podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `secondary.podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `secondary.podSecurityContext.fsGroup` | Group ID for the mounted volumes' filesystem | `1001` | +| `secondary.containerSecurityContext.enabled` | MariaDB secondary container securityContext | `true` | +| `secondary.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `secondary.containerSecurityContext.runAsUser` | User ID for the MariaDB secondary container | `1001` | +| `secondary.containerSecurityContext.runAsGroup` | Group ID for the MariaDB secondary container | `1001` | +| `secondary.containerSecurityContext.runAsNonRoot` | Set secondary container's Security Context runAsNonRoot | `true` | +| `secondary.containerSecurityContext.privileged` | Set secondary container's Security Context privileged | `false` | +| `secondary.containerSecurityContext.allowPrivilegeEscalation` | Set secondary container's Security Context allowPrivilegeEscalation | `false` | +| `secondary.containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `secondary.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `secondary.containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `secondary.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if secondary.resources is set (secondary.resources is recommended for production). | `micro` | +| `secondary.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `secondary.startupProbe.enabled` | Enable startupProbe | `false` | +| `secondary.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `120` | +| `secondary.startupProbe.periodSeconds` | Period seconds for startupProbe | `15` | +| `secondary.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `secondary.startupProbe.failureThreshold` | Failure threshold for startupProbe | `10` | +| `secondary.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `secondary.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `secondary.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `120` | +| `secondary.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `secondary.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `secondary.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `secondary.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `secondary.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `secondary.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `30` | +| `secondary.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `secondary.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `secondary.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `secondary.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `secondary.customStartupProbe` | Override default startup probe for MariaDB secondary containers | `{}` | +| `secondary.customLivenessProbe` | Override default liveness probe for MariaDB secondary containers | `{}` | +| `secondary.customReadinessProbe` | Override default readiness probe for MariaDB secondary containers | `{}` | +| `secondary.startupWaitOptions` | Override default builtin startup wait check options for MariaDB secondary containers | `{}` | +| `secondary.extraFlags` | MariaDB secondary additional command line flags | `""` | +| `secondary.extraEnvVars` | Extra environment variables to be set on MariaDB secondary containers | `[]` | +| `secondary.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for MariaDB secondary containers | `""` | +| `secondary.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for MariaDB secondary containers | `""` | +| `secondary.persistence.enabled` | Enable persistence on MariaDB secondary replicas using a `PersistentVolumeClaim` | `true` | +| `secondary.persistence.subPath` | Subdirectory of the volume to mount at | `""` | +| `secondary.persistence.storageClass` | MariaDB secondary persistent volume storage Class | `""` | +| `secondary.persistence.labels` | Labels for the PVC | `{}` | +| `secondary.persistence.annotations` | MariaDB secondary persistent volume claim annotations | `{}` | +| `secondary.persistence.accessModes` | MariaDB secondary persistent volume access Modes | `["ReadWriteOnce"]` | +| `secondary.persistence.size` | MariaDB secondary persistent volume size | `8Gi` | +| `secondary.persistence.selector` | Selector to match an existing Persistent Volume | `{}` | +| `secondary.extraVolumes` | Optionally specify extra list of additional volumes to the MariaDB secondary pod(s) | `[]` | +| `secondary.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the MariaDB secondary container(s) | `[]` | +| `secondary.initContainers` | Add additional init containers for the MariaDB secondary pod(s) | `[]` | +| `secondary.sidecars` | Add additional sidecar containers for the MariaDB secondary pod(s) | `[]` | +| `secondary.service.type` | MariaDB secondary Kubernetes service type | `ClusterIP` | +| `secondary.service.ports.mysql` | MariaDB secondary Kubernetes service port for MariaDB | `3306` | +| `secondary.service.ports.metrics` | MariaDB secondary Kubernetes service port for metrics | `9104` | +| `secondary.service.nodePorts.mysql` | MariaDB secondary Kubernetes service node port | `""` | +| `secondary.service.clusterIP` | MariaDB secondary Kubernetes service clusterIP IP | `""` | +| `secondary.service.loadBalancerIP` | MariaDB secondary loadBalancerIP if service type is `LoadBalancer` | `""` | +| `secondary.service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `secondary.service.loadBalancerSourceRanges` | Address that are allowed when MariaDB secondary service is LoadBalancer | `[]` | +| `secondary.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `secondary.service.annotations` | Provide any additional annotations which may be required | `{}` | +| `secondary.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `secondary.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `secondary.pdb.create` | Enable/disable a Pod Disruption Budget creation for MariaDB secondary pods | `true` | +| `secondary.pdb.minAvailable` | Minimum number/percentage of MariaDB secondary pods that should remain scheduled | `""` | +| `secondary.pdb.maxUnavailable` | Maximum number/percentage of MariaDB secondary pods that may be made unavailable. Defaults to `1` if both `secondary.pdb.minAvailable` and `secondary.pdb.maxUnavailable` are empty. | `""` | +| `secondary.revisionHistoryLimit` | Maximum number of revisions that will be maintained in the StatefulSet | `10` | + +### RBAC parameters + +| Name | Description | Value | +| --------------------------------------------- | -------------------------------------------------------------- | ------- | +| `serviceAccount.create` | Enable the creation of a ServiceAccount for MariaDB pods | `true` | +| `serviceAccount.name` | Name of the created ServiceAccount | `""` | +| `serviceAccount.annotations` | Annotations for MariaDB Service Account | `{}` | +| `serviceAccount.automountServiceAccountToken` | Automount service account token for the server service account | `false` | +| `rbac.create` | Whether to create and use RBAC resources or not | `false` | + +### Volume Permissions parameters + +| Name | Description | Value | +| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| `volumePermissions.enabled` | Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `REGISTRY_NAME` | +| `volumePermissions.image.repository` | Init container volume-permissions image repository | `REPOSITORY_NAME/os-shell` | +| `volumePermissions.image.digest` | Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `volumePermissions.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). | `nano` | +| `volumePermissions.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | + +### Metrics parameters + +| Name | Description | Value | +| ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `metrics.enabled` | Start a side-car prometheus exporter | `false` | +| `metrics.image.registry` | Exporter image registry | `REGISTRY_NAME` | +| `metrics.image.repository` | Exporter image repository | `REPOSITORY_NAME/mysqld-exporter` | +| `metrics.image.digest` | Exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `metrics.image.pullPolicy` | Exporter image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `metrics.annotations` | Annotations for the Exporter pod | `{}` | +| `metrics.extraArgs` | Extra args to be passed to mysqld_exporter | `{}` | +| `metrics.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the MariaDB metrics container(s) | `{}` | +| `metrics.containerPorts.http` | Container port for http | `9104` | +| `metrics.containerSecurityContext.enabled` | Enable security context for MariaDB metrics container | `false` | +| `metrics.containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `{}` | +| `metrics.containerSecurityContext.runAsUser` | User ID for the MariaDB metrics container | `1001` | +| `metrics.containerSecurityContext.runAsGroup` | Group ID for the MariaDB metrics container | `1001` | +| `metrics.containerSecurityContext.runAsNonRoot` | Set metrics container's Security Context runAsNonRoot | `true` | +| `metrics.containerSecurityContext.privileged` | Set metrics container's Security Context privileged | `false` | +| `metrics.containerSecurityContext.allowPrivilegeEscalation` | Set metrics container's Security Context allowPrivilegeEscalation | `false` | +| `metrics.containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `metrics.containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `metrics.containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `metrics.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). | `nano` | +| `metrics.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `metrics.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `metrics.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `120` | +| `metrics.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `metrics.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `metrics.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `metrics.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `metrics.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `metrics.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `30` | +| `metrics.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `metrics.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `metrics.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `metrics.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `metrics.serviceMonitor.enabled` | Create ServiceMonitor Resource for scraping metrics using PrometheusOperator | `false` | +| `metrics.serviceMonitor.namespace` | Namespace which Prometheus is running in | `""` | +| `metrics.serviceMonitor.jobLabel` | The name of the label on the target service to use as the job name in prometheus. | `""` | +| `metrics.serviceMonitor.interval` | Interval at which metrics should be scraped | `30s` | +| `metrics.serviceMonitor.scrapeTimeout` | Specify the timeout after which the scrape is ended | `""` | +| `metrics.serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping | `[]` | +| `metrics.serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion | `[]` | +| `metrics.serviceMonitor.honorLabels` | honorLabels chooses the metric's labels on collisions with target labels | `false` | +| `metrics.serviceMonitor.selector` | ServiceMonitor selector labels | `{}` | +| `metrics.serviceMonitor.labels` | Extra labels for the ServiceMonitor | `{}` | +| `metrics.prometheusRule.enabled` | if `true`, creates a Prometheus Operator PrometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) | `false` | +| `metrics.prometheusRule.namespace` | Namespace for the PrometheusRule Resource (defaults to the Release Namespace) | `""` | +| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so PrometheusRule will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.rules` | Prometheus Rule definitions | `[]` | + +### NetworkPolicy parameters + +| Name | Description | Value | +| --------------------------------------- | --------------------------------------------------------------- | ------ | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources | `true` | +| `networkPolicy.allowExternal` | The Policy model to apply | `true` | +| `networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` | +| `networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | + +The above parameters map to the env variables defined in [bitnami/mariadb](https://github.com/bitnami/containers/tree/main/bitnami/mariadb). For more information please refer to the [bitnami/mariadb](https://github.com/bitnami/containers/tree/main/bitnami/mariadb) image documentation. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set auth.rootPassword=secretpassword,auth.database=app_database \ + oci://REGISTRY_NAME/REPOSITORY_NAME/mariadb +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The above command sets the MariaDB `root` account password to `secretpassword`. Additionally it creates a database named `my_database`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://REGISTRY_NAME/REPOSITORY_NAME/mariadb +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. +> **Tip**: You can use the default [values.yaml](https://github.com/bitnami/charts/tree/main/bitnami/mariadb/values.yaml) + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +It's necessary to set the `auth.rootPassword` parameter when upgrading for readiness/liveness probes to work properly. When you install this chart for the first time, some notes will be displayed providing the credentials you must use under the 'Administrator credentials' section. Please note down the password and run the command below to upgrade your chart: + +```console +helm upgrade my-release oci://REGISTRY_NAME/REPOSITORY_NAME/mariadb --set auth.rootPassword=[ROOT_PASSWORD] +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +| Note: you need to substitute the placeholder _[ROOT_PASSWORD]_ with the value obtained in the installation notes. + +### To 17.0.0 + +This major bump changes the following security defaults: + +- `runAsGroup` is changed from `0` to `1001` +- `readOnlyRootFilesystem` is set to `true` +- `resourcesPreset` is changed from `none` to the minimum size working in our test suites (NOTE: `resourcesPreset` is not meant for production usage, but `resources` adapted to your use case). +- `global.compatibility.openshift.adaptSecurityContext` is changed from `disabled` to `auto`. + +This could potentially break any customization or init scripts used in your deployment. If this is the case, change the default values to the previous ones. + +### To 16.0.0 + +This section enables NetworkPolicies by default to increase security of the application. It also adapts the values in the `networkPolicy` section to the current Bitnami standards. The removed sections are `networkPolicy.metrics.*`, `networkPolicy.ingressRules.*` and `networkPolicy.egressRules.*`. Check the Parameters table for the new structure. + +### To 14.0.0 + +This major release bumps the MariaDB version to 11.1. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-between-minor-versions-on-linux/) for upgrading from MariaDB 11.0 to 11.1. No major issues are expected during the upgrade. + +### To 13.0.0 + +This major release bumps the MariaDB version to 11.0. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-10-11-to-mariadb-11-0/) for upgrading from MariaDB 10.11 to 11.0. No major issues are expected during the upgrade. + +### To 11.0.0 + +This major release bumps default MariaDB branch to 10.6. Follow the [official instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-105-to-mariadb-106/) from upgrading between 10.5 and 10.6. + +No major issues are expected during the upgrade. + +### To 10.0.0 + +This major release renames several values in this chart and adds missing features, in order to be inline with the rest of assets in the Bitnami charts repository. + +Affected values: + +- `primary.service.port` was deprecated, we recommend using `primary.service.ports.mysql` instead. +- `primary.service.nodePort` was deprecated, we recommend using `primary.service.nodePorts.mysql` instead. +- `secondary.service.port` was deprecated, we recommend using `secondary.service.ports.mysql` instead. +- `secondary.service.nodePort` was deprecated, we recommend using `secondary.service.nodePorts.mysql` instead. +- `metrics.serviceMonitor.additionalLabels` was deprecated, we recommend using `metrics.serviceMonitor.selector` instead. +- `primary.pdb.enabled` renamed as `primary.pdb.create`. +- `secondary.pdb.enabled` renamed as `secondary.pdb.create`. +- `primary.updateStrategy` changed from String type (previously default to 'rollingUpdate') to Object type, allowing users to configure other updateStrategy parameters, similar to other charts. +- Removed value `primary.rollingUpdatePartition`, now configured using `primary.updateStrategy` setting `primary.updateStrategy.rollingUpdate.partition`. +- `secondary.updateStrategy` changed from String type (previously default to 'rollingUpdate') to Object type, allowing users to configure other updateStrategy parameters, similar to other charts. +- Removed value `secondary.rollingUpdatePartition`, now configured using `secondary.updateStrategy` setting `secondary.updateStrategy.rollingUpdate.partition`. +- `metrics.serviceMonitor.relabellings`, previously used to configure ServiceMonitor metricRelabelings, has been replaced with the value `metrics.serviceMonitor.metricRelabelings`, and new value `metrics.serviceMonitor.relabelings` can be used to set ServiceMonitor relabelings parameter + +### To 9.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +### To 8.0.0 + +- Several parameters were renamed or disappeared in favor of new ones on this major version: + - The terms _master_ and _slave_ have been replaced by the terms _primary_ and _secondary_. Therefore, parameters prefixed with `master` or `slave` are now prefixed with `primary` or `secondary`, respectively. + - `securityContext.*` is deprecated in favor of `primary.podSecurityContext`, `primary.containerSecurityContext`, `secondary.podSecurityContext`, and `secondary.containerSecurityContext`. + - Credentials parameter are reorganized under the `auth` parameter. + - `replication.enabled` parameter is deprecated in favor of `architecture` parameter that accepts two values: `standalone` and `replication`. +- The default MariaDB version was updated from 10.3 to 10.5. According to the official documentation, upgrading from 10.3 should be painless. However, there are some things that have changed which could affect an upgrade: + - [Incompatible changes upgrading from MariaDB 10.3 to MariaDB 10.4](https://mariadb.com/kb/en/upgrading-from-mariadb-103-to-mariadb-104/#incompatible-changes-between-103-and-104). + - [Incompatible changes upgrading from MariaDB 10.4 to MariaDB 10.5](https://mariadb.com/kb/en/upgrading-from-mariadb-104-to-mariadb-105/#incompatible-changes-between-104-and-105). +- Chart labels were adapted to follow the [Helm charts standard labels](https://helm.sh/docs/chart_best_practices/labels/#standard-labels). +- This version also introduces `bitnami/common`, a [library chart](https://helm.sh/docs/topics/library_charts/#helm) as a dependency. More documentation about this new utility could be found [here](https://github.com/bitnami/charts/tree/main/bitnami/common#bitnami-common-library-chart). Please, make sure that you have updated the chart dependencies before executing any upgrade. + +Consequences: + +Backwards compatibility is not guaranteed. To upgrade to `8.0.0`, install a new release of the MariaDB chart, and migrate the data from your previous release. You have 2 alternatives to do so: + +- Create a backup of the database, and restore it on the new release using tools such as [mysqldump](https://mariadb.com/kb/en/mysqldump/). +- Reuse the PVC used to hold the master data on your previous release. To do so, use the `primary.persistence.existingClaim` parameter. The following example assumes that the release name is `mariadb`: + +```console +helm install mariadb oci://REGISTRY_NAME/REPOSITORY_NAME/mariadb --set auth.rootPassword=[ROOT_PASSWORD] --set primary.persistence.existingClaim=[EXISTING_PVC] +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +| Note: you need to substitute the placeholder _[EXISTING_PVC]_ with the name of the PVC used on your previous release, and _[ROOT_PASSWORD]_ with the root password used in your previous release. + +### To 7.0.0 + +Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec. + +In the `apiVersion` of the statefulset resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage. + +This major version bump signifies this change. + +### To 6.0.0 + +MariaDB version was updated from 10.1 to 10.3, there are no changes in the chart itself. According to the official documentation, upgrading from 10.1 should be painless. However, there are some things that have changed which could affect an upgrade: + +- [Incompatible changes upgrading from MariaDB 10.1 to MariaDB 10.2](https://mariadb.com/kb/en/library/upgrading-from-mariadb-101-to-mariadb-102//#incompatible-changes-between-101-and-102) +- [Incompatible changes upgrading from MariaDB 10.2 to MariaDB 10.3](https://mariadb.com/kb/en/library/upgrading-from-mariadb-102-to-mariadb-103/#incompatible-changes-between-102-and-103) + +### To 5.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to 5.0.0. The following example assumes that the release name is mariadb: + +```console +kubectl delete statefulset opencart-mariadb --cascade=false +``` + +## License + +Copyright © 2024 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/charts/mariadb/mariadb/templates/NOTES.txt b/charts/mariadb/mariadb/templates/NOTES.txt new file mode 100644 index 0000000..c5e1110 --- /dev/null +++ b/charts/mariadb/mariadb/templates/NOTES.txt @@ -0,0 +1,77 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.diagnosticMode.enabled }} +The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with: + + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }} + +Get the list of pods by executing: + + kubectl get pods --namespace {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Access the pod you want to debug by executing + + kubectl exec --namespace {{ .Release.Namespace }} -ti -- bash + +In order to replicate the container startup scripts execute this command: + + /opt/bitnami/scripts/mariadb/entrypoint.sh /opt/bitnami/scripts/mariadb/run.sh + +{{- else }} + +Tip: + + Watch the deployment status using the command: kubectl get pods -w --namespace {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Services: + + echo Primary: {{ include "mariadb.primary.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ coalesce .Values.primary.service.ports.mysql .Values.primary.service.port }} +{{- if eq .Values.architecture "replication" }} + echo Secondary: {{ include "mariadb.secondary.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ coalesce .Values.secondary.service.ports.mysql .Values.secondary.service.port }} +{{- end }} + +Administrator credentials: + + Username: root + Password : $(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "mariadb.secretName" . }} -o jsonpath="{.data.mariadb-root-password}" | base64 -d) + +To connect to your database: + + 1. Run a pod that you can use as a client: + + kubectl run {{ include "common.names.fullname" . }}-client --rm --tty -i --restart='Never' --image {{ template "mariadb.image" . }} --namespace {{ .Release.Namespace }} --command -- bash + + 2. To connect to primary service (read/write): + + mysql -h {{ include "mariadb.primary.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} -uroot -p {{ .Values.auth.database }} + +{{- if eq .Values.architecture "replication" }} + + 3. To connect to secondary service (read-only): + + mysql -h {{ include "mariadb.secondary.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} -uroot -p {{ .Values.auth.database }} +{{- end }} + +To upgrade this helm chart: + + 1. Obtain the password as described on the 'Administrator credentials' section and set the 'auth.rootPassword' parameter as shown below: + + ROOT_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "mariadb.secretName" . }} -o jsonpath="{.data.mariadb-root-password}" | base64 -d) + helm upgrade --namespace {{ .Release.Namespace }} {{ .Release.Name }} oci://registry-1.docker.io/bitnamicharts/mariadb --set auth.rootPassword=$ROOT_PASSWORD + +{{- include "common.warnings.rollingTag" .Values.image }} +{{- include "common.warnings.rollingTag" .Values.metrics.image }} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image }} +{{- include "mariadb.validateValues" . }} +{{- if not .Values.auth.customPasswordFiles -}} + {{- $passwordValidationErrors := include "common.validations.values.mariadb.passwords" (dict "secret" (include "common.names.fullname" .) "context" $) -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $passwordValidationErrors) "context" $) -}} +{{- end }} +{{- end }} +{{- include "common.warnings.resources" (dict "sections" (list "metrics" "primary" "secondary" "volumePermissions") "context" $) }} +{{- include "common.warnings.modifiedImages" (dict "images" (list .Values.image .Values.volumePermissions.image .Values.metrics.image) "context" $) }} \ No newline at end of file diff --git a/charts/mariadb/mariadb/templates/_helpers.tpl b/charts/mariadb/mariadb/templates/_helpers.tpl new file mode 100644 index 0000000..e871624 --- /dev/null +++ b/charts/mariadb/mariadb/templates/_helpers.tpl @@ -0,0 +1,164 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{- define "mariadb.primary.fullname" -}} +{{- if eq .Values.architecture "replication" }} +{{- printf "%s-%s" (include "common.names.fullname" .) .Values.primary.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- include "common.names.fullname" . -}} +{{- end -}} +{{- end -}} + +{{- define "mariadb.secondary.fullname" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) .Values.secondary.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the proper MariaDB image name +*/}} +{{- define "mariadb.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper metrics image name +*/}} +{{- define "mariadb.metrics.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.metrics.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "mariadb.volumePermissions.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.volumePermissions.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "mariadb.imagePullSecrets" -}} +{{ include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.metrics.image .Values.volumePermissions.image) "global" .Values.global) }} +{{- end -}} + +{{ template "mariadb.initdbScriptsCM" . }} +{{/* +Get the initialization scripts ConfigMap name. +*/}} +{{- define "mariadb.initdbScriptsCM" -}} +{{- if .Values.initdbScriptsConfigMap -}} +{{- printf "%s" (tpl .Values.initdbScriptsConfigMap $) -}} +{{- else -}} +{{- printf "%s-init-scripts" (include "mariadb.primary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "mariadb.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the configmap with the MariaDB Primary configuration +*/}} +{{- define "mariadb.primary.configmapName" -}} +{{- if .Values.primary.existingConfigmap -}} + {{- printf "%s" (tpl .Values.primary.existingConfigmap $) -}} +{{- else -}} + {{- printf "%s" (include "mariadb.primary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for MariaDB Secondary +*/}} +{{- define "mariadb.primary.createConfigmap" -}} +{{- if and .Values.primary.configuration (not .Values.primary.existingConfigmap) }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Return the configmap with the MariaDB Primary configuration +*/}} +{{- define "mariadb.secondary.configmapName" -}} +{{- if .Values.secondary.existingConfigmap -}} + {{- printf "%s" (tpl .Values.secondary.existingConfigmap $) -}} +{{- else -}} + {{- printf "%s" (include "mariadb.secondary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for MariaDB Secondary +*/}} +{{- define "mariadb.secondary.createConfigmap" -}} +{{- if and (eq .Values.architecture "replication") .Values.secondary.configuration (not .Values.secondary.existingConfigmap) }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Return the secret with MariaDB credentials +*/}} +{{- define "mariadb.secretName" -}} + {{- if .Values.auth.existingSecret -}} + {{- printf "%s" (tpl .Values.auth.existingSecret $) -}} + {{- else -}} + {{- printf "%s" (include "common.names.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{/* +Return true if a secret object should be created for MariaDB +*/}} +{{- define "mariadb.createSecret" -}} +{{- if not (or .Values.auth.existingSecret .Values.auth.customPasswordFiles) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "mariadb.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "mariadb.validateValues.architecture" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* Validate values of MariaDB - must provide a valid architecture */}} +{{- define "mariadb.validateValues.architecture" -}} +{{- if and (ne .Values.architecture "standalone") (ne .Values.architecture "replication") -}} +mariadb: architecture + Invalid architecture selected. Valid values are "standalone" and + "replication". Please set a valid architecture (--set architecture="xxxx") +{{- end -}} +{{- end -}} + +{{/* +Get existing password to access MariaDB +*/}} +{{- define "mariadb.secret.existPassword" -}} +{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "mariadb.secretName" .)).data -}} +{{- if hasKey $secret "mariadb-password" }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/charts/mariadb/mariadb/templates/extra-list.yaml b/charts/mariadb/mariadb/templates/extra-list.yaml new file mode 100644 index 0000000..329f5c6 --- /dev/null +++ b/charts/mariadb/mariadb/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/mariadb/mariadb/templates/networkpolicy.yaml b/charts/mariadb/mariadb/templates/networkpolicy.yaml new file mode 100644 index 0000000..c7f6053 --- /dev/null +++ b/charts/mariadb/mariadb/templates/networkpolicy.yaml @@ -0,0 +1,76 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 6 }} + policyTypes: + - Ingress + - Egress + {{- if .Values.networkPolicy.allowExternalEgress }} + egress: + - {} + {{- else }} + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # Allow connection to other cluster pods + - ports: + - port: {{ .Values.primary.containerPorts.mysql }} + - port: {{ .Values.secondary.containerPorts.mysql }} + to: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} + {{- if .Values.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.rts.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} + ingress: + - ports: + - port: {{ .Values.primary.containerPorts.mysql }} + - port: {{ .Values.secondary.containerPorts.mysql }} + {{- if .Values.metrics.enabled }} + - port: {{ .Values.metrics.containerPorts.http }} + {{- end }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/mariadb/mariadb/templates/primary/configmap.yaml b/charts/mariadb/mariadb/templates/primary/configmap.yaml new file mode 100644 index 0000000..37136a9 --- /dev/null +++ b/charts/mariadb/mariadb/templates/primary/configmap.yaml @@ -0,0 +1,20 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if (include "mariadb.primary.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "mariadb.primary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + my.cnf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.configuration "context" $ ) | nindent 4 }} +{{- end -}} diff --git a/charts/mariadb/mariadb/templates/primary/initialization-configmap.yaml b/charts/mariadb/mariadb/templates/primary/initialization-configmap.yaml new file mode 100644 index 0000000..eab9863 --- /dev/null +++ b/charts/mariadb/mariadb/templates/primary/initialization-configmap.yaml @@ -0,0 +1,19 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.initdbScripts (not .Values.initdbScriptsConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-init-scripts" (include "mariadb.primary.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: +{{- include "common.tplvalues.render" (dict "value" .Values.initdbScripts "context" .) | nindent 2 }} +{{ end }} diff --git a/charts/mariadb/mariadb/templates/primary/pdb.yaml b/charts/mariadb/mariadb/templates/primary/pdb.yaml new file mode 100644 index 0000000..5f4f652 --- /dev/null +++ b/charts/mariadb/mariadb/templates/primary/pdb.yaml @@ -0,0 +1,28 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.primary.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "mariadb.primary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.primary.pdb.minAvailable }} + minAvailable: {{ .Values.primary.pdb.minAvailable }} + {{- end }} + {{- if or .Values.primary.pdb.maxUnavailable (not .Values.primary.pdb.minAvailable) }} + maxUnavailable: {{ .Values.primary.pdb.maxUnavailable | default 1 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.primary.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: primary +{{- end }} diff --git a/charts/mariadb/mariadb/templates/primary/statefulset.yaml b/charts/mariadb/mariadb/templates/primary/statefulset.yaml new file mode 100644 index 0000000..9b66234 --- /dev/null +++ b/charts/mariadb/mariadb/templates/primary/statefulset.yaml @@ -0,0 +1,443 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "mariadb.primary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: 1 + revisionHistoryLimit: {{ .Values.primary.revisionHistoryLimit }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.primary.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: primary + serviceName: {{ include "mariadb.primary.fullname" . }} + {{- if .Values.primary.updateStrategy }} + updateStrategy: {{- toYaml .Values.primary.updateStrategy | nindent 4 }} + {{- end }} + template: + metadata: + annotations: + {{- if (include "mariadb.primary.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/primary/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.primary.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.podAnnotations "context" $) | nindent 8 }} + {{- end }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + app.kubernetes.io/component: primary + spec: + {{- include "mariadb.imagePullSecrets" . | nindent 6 }} + automountServiceAccountToken: {{ .Values.primary.automountServiceAccountToken }} + {{- if .Values.primary.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.primary.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if or .Values.primary.schedulerName .Values.schedulerName }} + schedulerName: {{ (coalesce .Values.primary.schedulerName .Values.schedulerName) | quote }} + {{- end }} + serviceAccountName: {{ template "mariadb.serviceAccountName" . }} + {{- if .Values.primary.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.primary.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAffinityPreset "component" "primary" "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAntiAffinityPreset "component" "primary" "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.primary.nodeAffinityPreset.type "key" .Values.primary.nodeAffinityPreset.key "values" .Values.primary.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.primary.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.primary.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.primary.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.schedulerName }} + schedulerName: {{ .Values.primary.schedulerName }} + {{- end }} + {{- if .Values.primary.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.primary.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.priorityClassName }} + priorityClassName: {{ .Values.primary.priorityClassName | quote }} + {{- else if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- if .Values.primary.runtimeClassName }} + runtimeClassName: {{ .Values.primary.runtimeClassName | quote }} + {{- else if .Values.runtimeClassName }} + runtimeClassName: {{ .Values.runtimeClassName | quote }} + {{- end }} + {{- if .Values.primary.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.primary.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + initContainers: + - name: preserve-logs-symlinks + image: {{ include "mariadb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.primary.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.primary.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.primary.resources }} + resources: {{ toYaml .Values.primary.resources | nindent 12 }} + {{- else if ne .Values.primary.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.primary.resourcesPreset) | nindent 12 }} + {{- end }} + command: + - /bin/bash + args: + - -ec + - | + #!/bin/bash + + . /opt/bitnami/scripts/libfs.sh + # We copy the logs folder because it has symlinks to stdout and stderr + if ! is_dir_empty /opt/bitnami/mariadb/logs; then + cp -r /opt/bitnami/mariadb/logs /emptydir/app-logs-dir + fi + volumeMounts: + - name: empty-dir + mountPath: /emptydir + {{- if and .Values.primary.podSecurityContext.enabled .Values.volumePermissions.enabled .Values.primary.persistence.enabled }} + - name: volume-permissions + image: {{ include "mariadb.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + chown -R {{ .Values.primary.containerSecurityContext.runAsUser }}:{{ .Values.primary.podSecurityContext.fsGroup }} /bitnami/mariadb + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.volumePermissions.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mariadb + {{- if .Values.primary.persistence.subPath }} + subPath: {{ .Values.primary.persistence.subPath }} + {{- end }} + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + {{- end }} + {{- if .Values.primary.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: mariadb + image: {{ include "mariadb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.primary.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.primary.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.primary.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.primary.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.primary.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.primary.args "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.primary.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.primary.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MARIADB_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mariadb/secrets/mariadb-root-password" .Values.auth.customPasswordFiles.root }} + {{- else }} + - name: MARIADB_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.secretName" . }} + key: mariadb-root-password + {{- end }} + {{- if not (empty .Values.auth.username) }} + - name: MARIADB_USER + value: {{ .Values.auth.username | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MARIADB_PASSWORD_FILE + value: {{ default "/opt/bitnami/mariadb/secrets/mariadb-password" .Values.auth.customPasswordFiles.user }} + {{- else }} + - name: MARIADB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.secretName" . }} + key: mariadb-password + {{- end }} + {{- end }} + - name: MARIADB_DATABASE + value: {{ .Values.auth.database | quote }} + {{- if eq .Values.architecture "replication" }} + - name: MARIADB_REPLICATION_MODE + value: "master" + - name: MARIADB_REPLICATION_USER + value: {{ .Values.auth.replicationUser | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MARIADB_REPLICATION_PASSWORD_FILE + value: {{ default "/opt/bitnami/mariadb/secrets/mariadb-replication-password" .Values.auth.customPasswordFiles.replicator }} + {{- else }} + - name: MARIADB_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.secretName" . }} + key: mariadb-replication-password + {{- end }} + {{- end }} + {{- if .Values.primary.extraFlags }} + - name: MARIADB_EXTRA_FLAGS + value: "{{ .Values.primary.extraFlags }}" + {{- end }} + {{- if .Values.primary.startupWaitOptions }} + - name: MARIADB_STARTUP_WAIT_RETRIES + value: "{{ .Values.primary.startupWaitOptions.retries | default 300 }}" + - name: MARIADB_STARTUP_WAIT_SLEEP_TIME + value: "{{ .Values.primary.startupWaitOptions.sleepTime | default 2 }}" + {{- end }} + {{- if .Values.primary.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if or .Values.primary.extraEnvVarsCM .Values.primary.extraEnvVarsSecret }} + envFrom: + {{- if .Values.primary.extraEnvVarsCM }} + - configMapRef: + name: {{ .Values.primary.extraEnvVarsCM }} + {{- end }} + {{- if .Values.primary.extraEnvVarsSecret }} + - secretRef: + name: {{ .Values.primary.extraEnvVarsSecret }} + {{- end }} + {{- end }} + ports: + - name: mysql + containerPort: {{ .Values.primary.containerPorts.mysql }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.primary.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.startupProbe.enabled }} + startupProbe: {{- omit .Values.primary.startupProbe "enabled" | toYaml | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_ROOT_PASSWORD_FILE") + fi + mariadb-admin ping -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.primary.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.livenessProbe.enabled }} + livenessProbe: {{- omit .Values.primary.livenessProbe "enabled" | toYaml | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_ROOT_PASSWORD_FILE") + fi + mariadb-admin status -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.primary.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.readinessProbe.enabled }} + readinessProbe: {{- omit .Values.primary.readinessProbe "enabled" | toYaml | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_ROOT_PASSWORD_FILE") + fi + mariadb-admin ping -uroot -p"${password_aux}" + {{- end }} + {{- end }} + {{- if .Values.primary.resources }} + resources: {{ toYaml .Values.primary.resources | nindent 12 }} + {{- else if ne .Values.primary.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.primary.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mariadb + {{- if .Values.primary.persistence.subPath }} + subPath: {{ .Values.primary.persistence.subPath }} + {{- end }} + {{- if or .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + mountPath: /docker-entrypoint-initdb.d + {{- end }} + {{- if or .Values.primary.configuration .Values.primary.existingConfigmap }} + - name: config + mountPath: /opt/bitnami/mariadb/conf/my.cnf + subPath: my.cnf + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mariadb-credentials + mountPath: /opt/bitnami/mariadb/secrets/ + {{- end }} + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/mariadb/conf + subPath: app-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/mariadb/tmp + subPath: app-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/mariadb/logs + subPath: app-logs-dir + {{- if .Values.primary.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ include "mariadb.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.metrics.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + env: + {{- if .Values.auth.usePasswordFiles }} + - name: MARIADB_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysqld-exporter/secrets/mariadb-root-password" .Values.auth.customPasswordFiles.root }} + {{- else }} + - name: MARIADB_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.secretName" . }} + key: mariadb-root-password + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else }} + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_ROOT_PASSWORD_FILE") + fi + MYSQLD_EXPORTER_PASSWORD=${password_aux} /bin/mysqld_exporter --mysqld.address=localhost:{{ .Values.primary.containerPorts.mysql }} --mysqld.username=root --web.listen-address=:{{ .Values.metrics.containerPorts.http }} {{- range .Values.metrics.extraArgs.primary }} {{ . }} {{- end }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.metrics.containerPorts.http }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.metrics.livenessProbe.enabled }} + livenessProbe: {{- omit .Values.metrics.livenessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- if .Values.metrics.readinessProbe.enabled }} + readinessProbe: {{- omit .Values.metrics.readinessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- end }} + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- else if ne .Values.metrics.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.metrics.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mariadb-credentials + mountPath: /opt/bitnami/mysqld-exporter/secrets/ + {{- end }} + {{- if .Values.metrics.extraVolumeMounts.primary }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.extraVolumeMounts.primary "context" $) | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.primary.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: empty-dir + emptyDir: {} + {{- if or .Values.primary.configuration .Values.primary.existingConfigmap }} + - name: config + configMap: + name: {{ include "mariadb.primary.configmapName" . }} + {{- end }} + {{- if or .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + configMap: + name: {{ template "mariadb.initdbScriptsCM" . }} + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mariadb-credentials + secret: + secretName: {{ template "mariadb.secretName" . }} + items: + - key: mariadb-root-password + path: mariadb-root-password + - key: mariadb-password + path: mariadb-password + {{- if eq .Values.architecture "replication" }} + - key: mariadb-replication-password + path: mariadb-replication-password + {{- end }} + {{- end }} + {{- if .Values.primary.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraVolumes "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.primary.persistence.enabled .Values.primary.persistence.existingClaim }} + - name: data + persistentVolumeClaim: + claimName: {{ tpl .Values.primary.persistence.existingClaim . }} + {{- else if not .Values.primary.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if and .Values.primary.persistence.enabled (not .Values.primary.persistence.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + {{- $claimLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.primary.persistence.labels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.matchLabels" ( dict "customLabels" $claimLabels "context" $ ) | nindent 10 }} + app.kubernetes.io/component: primary + {{- if .Values.primary.persistence.annotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.primary.persistence.annotations "context" $ ) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.primary.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.primary.persistence.size | quote }} + {{ include "common.storage.class" (dict "persistence" .Values.primary.persistence "global" .Values.global) }} + {{- if .Values.primary.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.primary.persistence.selector "context" $) | nindent 10 }} + {{- end -}} + {{- end }} diff --git a/charts/mariadb/mariadb/templates/primary/svc.yaml b/charts/mariadb/mariadb/templates/primary/svc.yaml new file mode 100644 index 0000000..b0fc974 --- /dev/null +++ b/charts/mariadb/mariadb/templates/primary/svc.yaml @@ -0,0 +1,62 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mariadb.primary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: primary + annotations: + {{- if or .Values.primary.service.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.primary.service.annotations .Values.commonAnnotations ) "context" . ) }} + {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.primary.service.type }} + {{- if and .Values.primary.service.clusterIP (eq .Values.primary.service.type "ClusterIP") }} + clusterIP: {{ .Values.primary.service.clusterIP }} + {{- end }} + {{- if and .Values.primary.service.externalTrafficPolicy (or (eq .Values.primary.service.type "LoadBalancer") (eq .Values.primary.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.primary.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.primary.service.type "LoadBalancer") .Values.primary.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.primary.service.loadBalancerSourceRanges | nindent 4 }} + {{ end }} + {{- if (and (eq .Values.primary.service.type "LoadBalancer") (not (empty .Values.primary.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.primary.service.loadBalancerIP }} + {{- end }} + {{- if .Values.primary.service.sessionAffinity }} + sessionAffinity: {{ .Values.primary.service.sessionAffinity }} + {{- end }} + {{- if .Values.primary.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: mysql + port: {{ coalesce .Values.primary.service.ports.mysql .Values.primary.service.port }} + protocol: TCP + targetPort: mysql + {{- if (and (or (eq .Values.primary.service.type "NodePort") (eq .Values.primary.service.type "LoadBalancer")) (coalesce .Values.primary.service.nodePorts.mysql .Values.primary.service.nodePort)) }} + nodePort: {{ coalesce .Values.primary.service.nodePorts.mysql .Values.primary.service.nodePort }} + {{- else if eq .Values.primary.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if and .Values.metrics.enabled (gt (.Values.primary.service.ports.metrics | int) 0) }} + - name: metrics + port: {{ .Values.primary.service.ports.metrics }} + protocol: TCP + targetPort: metrics + {{- end }} + {{- if .Values.primary.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.primary.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: primary diff --git a/charts/mariadb/mariadb/templates/prometheusrules.yaml b/charts/mariadb/mariadb/templates/prometheusrules.yaml new file mode 100644 index 0000000..d24f0e2 --- /dev/null +++ b/charts/mariadb/mariadb/templates/prometheusrules.yaml @@ -0,0 +1,24 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.prometheusRule.namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.metrics.prometheusRule.additionalLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.additionalLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + groups: + - name: {{ include "common.names.fullname" . }} + rules: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.rules "context" $ ) | nindent 6 }} +{{- end }} diff --git a/charts/mariadb/mariadb/templates/role.yaml b/charts/mariadb/mariadb/templates/role.yaml new file mode 100644 index 0000000..4102e66 --- /dev/null +++ b/charts/mariadb/mariadb/templates/role.yaml @@ -0,0 +1,23 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - endpoints + verbs: + - get +{{- end }} diff --git a/charts/mariadb/mariadb/templates/rolebinding.yaml b/charts/mariadb/mariadb/templates/rolebinding.yaml new file mode 100644 index 0000000..08d8b3d --- /dev/null +++ b/charts/mariadb/mariadb/templates/rolebinding.yaml @@ -0,0 +1,23 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +kind: RoleBinding +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ include "mariadb.serviceAccountName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "common.names.fullname" . -}} +{{- end }} diff --git a/charts/mariadb/mariadb/templates/secondary/configmap.yaml b/charts/mariadb/mariadb/templates/secondary/configmap.yaml new file mode 100644 index 0000000..770173f --- /dev/null +++ b/charts/mariadb/mariadb/templates/secondary/configmap.yaml @@ -0,0 +1,20 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if (include "mariadb.secondary.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "mariadb.secondary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + my.cnf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.secondary.configuration "context" $ ) | nindent 4 }} +{{- end -}} diff --git a/charts/mariadb/mariadb/templates/secondary/pdb.yaml b/charts/mariadb/mariadb/templates/secondary/pdb.yaml new file mode 100644 index 0000000..1e6b2c6 --- /dev/null +++ b/charts/mariadb/mariadb/templates/secondary/pdb.yaml @@ -0,0 +1,28 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and (eq .Values.architecture "replication") .Values.secondary.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "mariadb.secondary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.secondary.pdb.minAvailable }} + minAvailable: {{ .Values.secondary.pdb.minAvailable }} + {{- end }} + {{- if or .Values.secondary.pdb.maxUnavailable (not .Values.secondary.pdb.minAvailable) }} + maxUnavailable: {{ .Values.secondary.pdb.maxUnavailable | default 1 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.secondary.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: secondary +{{- end }} diff --git a/charts/mariadb/mariadb/templates/secondary/statefulset.yaml b/charts/mariadb/mariadb/templates/secondary/statefulset.yaml new file mode 100644 index 0000000..b8560c4 --- /dev/null +++ b/charts/mariadb/mariadb/templates/secondary/statefulset.yaml @@ -0,0 +1,414 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if eq .Values.architecture "replication" }} +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "mariadb.secondary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.secondary.replicaCount }} + revisionHistoryLimit: {{ .Values.secondary.revisionHistoryLimit }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.secondary.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: secondary + serviceName: {{ include "mariadb.secondary.fullname" . }} + podManagementPolicy: {{ .Values.secondary.podManagementPolicy }} + {{- if .Values.secondary.updateStrategy }} + updateStrategy: {{- toYaml .Values.secondary.updateStrategy | nindent 4 }} + {{- end }} + template: + metadata: + annotations: + {{- if (include "mariadb.secondary.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/secondary/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.secondary.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.podAnnotations "context" $) | nindent 8 }} + {{- end }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + app.kubernetes.io/component: secondary + spec: + {{- include "mariadb.imagePullSecrets" . | nindent 6 }} + {{- if or .Values.secondary.schedulerName .Values.schedulerName }} + schedulerName: {{ (coalesce .Values.secondary.schedulerName .Values.schedulerName) | quote }} + {{- end }} + serviceAccountName: {{ template "mariadb.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.secondary.automountServiceAccountToken }} + {{- if .Values.secondary.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.secondary.podAffinityPreset "component" "secondary" "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.secondary.podAntiAffinityPreset "component" "secondary" "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.secondary.nodeAffinityPreset.type "key" .Values.secondary.nodeAffinityPreset.key "values" .Values.secondary.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.secondary.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.priorityClassName }} + priorityClassName: {{ .Values.secondary.priorityClassName | quote }} + {{- else if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- if .Values.secondary.runtimeClassName }} + runtimeClassName: {{ .Values.secondary.runtimeClassName | quote }} + {{- else if .Values.runtimeClassName }} + runtimeClassName: {{ .Values.runtimeClassName | quote }} + {{- end }} + {{- if .Values.secondary.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.secondary.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + initContainers: + - name: preserve-logs-symlinks + image: {{ include "mariadb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.secondary.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.primary.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.secondary.resources }} + resources: {{ toYaml .Values.secondary.resources | nindent 12 }} + {{- else if ne .Values.secondary.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.secondary.resourcesPreset) | nindent 12 }} + {{- end }} + command: + - /bin/bash + args: + - -ec + - | + #!/bin/bash + + . /opt/bitnami/scripts/libfs.sh + # We copy the logs folder because it has symlinks to stdout and stderr + if ! is_dir_empty /opt/bitnami/mariadb/logs; then + cp -r /opt/bitnami/mariadb/logs /emptydir/app-logs-dir + fi + volumeMounts: + - name: empty-dir + mountPath: /emptydir + {{- if and .Values.secondary.podSecurityContext.enabled .Values.volumePermissions.enabled .Values.secondary.persistence.enabled }} + - name: volume-permissions + image: {{ include "mariadb.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + chown -R {{ .Values.secondary.containerSecurityContext.runAsUser }}:{{ .Values.secondary.podSecurityContext.fsGroup }} /bitnami/mariadb + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- else if ne .Values.volumePermissions.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.volumePermissions.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mariadb + {{- if .Values.secondary.persistence.subPath }} + subPath: {{ .Values.secondary.persistence.subPath }} + {{- end }} + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + {{- end }} + {{- if .Values.secondary.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: mariadb + image: {{ include "mariadb.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.secondary.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.secondary.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.secondary.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.secondary.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.args "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.secondary.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: MARIADB_REPLICATION_MODE + value: "slave" + - name: MARIADB_MASTER_HOST + value: {{ include "mariadb.primary.fullname" . }} + - name: MARIADB_MASTER_PORT_NUMBER + value: {{ coalesce .Values.primary.service.ports.mysql .Values.primary.service.port | quote }} + - name: MARIADB_MASTER_ROOT_USER + value: "root" + {{- if .Values.auth.usePasswordFiles }} + - name: MARIADB_MASTER_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mariadb/secrets/mariadb-root-password" .Values.auth.customPasswordFiles.root }} + {{- else }} + - name: MARIADB_MASTER_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.secretName" . }} + key: mariadb-root-password + {{- end }} + - name: MARIADB_REPLICATION_USER + value: {{ .Values.auth.replicationUser | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MARIADB_REPLICATION_PASSWORD_FILE + value: {{ default "/opt/bitnami/mariadb/secrets/mariadb-replication-password" .Values.auth.customPasswordFiles.replicator }} + {{- else }} + - name: MARIADB_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.secretName" . }} + key: mariadb-replication-password + {{- end }} + {{- if .Values.secondary.extraFlags }} + - name: MARIADB_EXTRA_FLAGS + value: "{{ .Values.secondary.extraFlags }}" + {{- end }} + {{- if .Values.secondary.startupWaitOptions }} + - name: MARIADB_STARTUP_WAIT_RETRIES + value: "{{ .Values.secondary.startupWaitOptions.retries | default 300 }}" + - name: MARIADB_STARTUP_WAIT_SLEEP_TIME + value: "{{ .Values.secondary.startupWaitOptions.sleepTime | default 2 }}" + {{- end }} + {{- if .Values.secondary.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if or .Values.secondary.extraEnvVarsCM .Values.secondary.extraEnvVarsSecret }} + envFrom: + {{- if .Values.secondary.extraEnvVarsCM }} + - configMapRef: + name: {{ .Values.secondary.extraEnvVarsCM }} + {{- end }} + {{- if .Values.secondary.extraEnvVarsSecret }} + - secretRef: + name: {{ .Values.secondary.extraEnvVarsSecret }} + {{- end }} + {{- end }} + ports: + - name: mysql + containerPort: {{ .Values.secondary.containerPorts.mysql }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.secondary.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.secondary.startupProbe.enabled }} + startupProbe: {{- omit .Values.secondary.startupProbe "enabled" | toYaml | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_MASTER_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_MASTER_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_MASTER_ROOT_PASSWORD_FILE") + fi + mariadb-admin ping -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.secondary.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.secondary.livenessProbe.enabled }} + livenessProbe: {{- omit .Values.secondary.livenessProbe "enabled" | toYaml | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_MASTER_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_MASTER_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_MASTER_ROOT_PASSWORD_FILE") + fi + mariadb-admin status -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.secondary.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.secondary.readinessProbe.enabled }} + readinessProbe: {{- omit .Values.secondary.readinessProbe "enabled" | toYaml | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_MASTER_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_MASTER_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_MASTER_ROOT_PASSWORD_FILE") + fi + mariadb-admin ping -uroot -p"${password_aux}" + {{- end }} + {{- end }} + {{- if .Values.secondary.resources }} + resources: {{ toYaml .Values.secondary.resources | nindent 12 }} + {{- else if ne .Values.secondary.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.secondary.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mariadb + {{- if .Values.secondary.persistence.subPath }} + subPath: {{ .Values.secondary.persistence.subPath }} + {{- end }} + {{- if or .Values.secondary.configuration .Values.secondary.existingConfigmap }} + - name: config + mountPath: /opt/bitnami/mariadb/conf/my.cnf + subPath: my.cnf + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mariadb-credentials + mountPath: /opt/bitnami/mariadb/secrets/ + {{- end }} + {{- if .Values.secondary.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/mariadb/conf + subPath: app-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/mariadb/tmp + subPath: app-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/mariadb/logs + subPath: app-logs-dir + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ include "mariadb.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.metrics.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + env: + {{- if .Values.auth.usePasswordFiles }} + - name: MARIADB_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysqld-exporter/secrets/mariadb-root-password" .Values.auth.customPasswordFiles.root }} + {{- else }} + - name: MARIADB_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mariadb.secretName" . }} + key: mariadb-root-password + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else }} + command: + - /bin/bash + - -ec + - | + password_aux="${MARIADB_ROOT_PASSWORD:-}" + if [[ -f "${MARIADB_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MARIADB_ROOT_PASSWORD_FILE") + fi + MYSQLD_EXPORTER_PASSWORD=${password_aux} /bin/mysqld_exporter --mysqld.address=localhost:{{ .Values.secondary.containerPorts.mysql }} --mysqld.username=root --web.listen-address=:{{ .Values.metrics.containerPorts.http }} {{- range .Values.metrics.extraArgs.primary }} {{ . }} {{- end }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.metrics.containerPorts.http }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.metrics.livenessProbe.enabled }} + livenessProbe: {{- omit .Values.metrics.livenessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- if .Values.metrics.readinessProbe.enabled }} + readinessProbe: {{- omit .Values.metrics.readinessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- end }} + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- else if ne .Values.metrics.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.metrics.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mariadb-credentials + mountPath: /opt/bitnami/mysqld-exporter/secrets/ + {{- end }} + - name: empty-dir + mountPath: /tmp + subPath: app-tmp-dir + {{- if .Values.metrics.extraVolumeMounts.secondary }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.extraVolumeMounts.secondary "context" $) | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.secondary.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if or .Values.secondary.configuration .Values.secondary.existingConfigmap }} + - name: config + configMap: + name: {{ include "mariadb.secondary.configmapName" . }} + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mariadb-credentials + secret: + secretName: {{ template "mariadb.secretName" . }} + items: + - key: mariadb-root-password + path: mariadb-root-password + - key: mariadb-replication-password + path: mariadb-replication-password + {{- end }} + - name: empty-dir + emptyDir: {} + {{- if .Values.secondary.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.extraVolumes "context" $) | nindent 8 }} + {{- end }} + {{- if not .Values.secondary.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: data + {{- $claimLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.secondary.persistence.labels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.matchLabels" ( dict "customLabels" $claimLabels "context" $ ) | nindent 10 }} + app.kubernetes.io/component: secondary + {{- if .Values.secondary.persistence.annotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.secondary.persistence.annotations "context" $ ) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.secondary.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.secondary.persistence.size | quote }} + {{ include "common.storage.class" (dict "persistence" .Values.secondary.persistence "global" .Values.global) }} + {{- if .Values.secondary.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.persistence.selector "context" $) | nindent 10 }} + {{- end -}} + {{- end }} +{{- end }} diff --git a/charts/mariadb/mariadb/templates/secondary/svc.yaml b/charts/mariadb/mariadb/templates/secondary/svc.yaml new file mode 100644 index 0000000..cd6f1d1 --- /dev/null +++ b/charts/mariadb/mariadb/templates/secondary/svc.yaml @@ -0,0 +1,64 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if eq .Values.architecture "replication" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mariadb.secondary.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: secondary + annotations: + {{- if or .Values.secondary.service.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.secondary.service.annotations .Values.commonAnnotations ) "context" . ) }} + {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.secondary.service.type }} + {{- if and .Values.secondary.service.clusterIP (eq .Values.secondary.service.type "ClusterIP") }} + clusterIP: {{ .Values.secondary.service.clusterIP }} + {{- end }} + {{- if and .Values.secondary.service.externalTrafficPolicy (or (eq .Values.secondary.service.type "LoadBalancer") (eq .Values.secondary.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.secondary.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.secondary.service.type "LoadBalancer") .Values.secondary.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.secondary.service.loadBalancerSourceRanges | nindent 4 }} + {{ end }} + {{- if and (eq .Values.secondary.service.type "LoadBalancer") (not (empty .Values.secondary.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.secondary.service.loadBalancerIP }} + {{- end }} + {{- if .Values.secondary.service.sessionAffinity }} + sessionAffinity: {{ .Values.secondary.service.sessionAffinity }} + {{- end }} + {{- if .Values.secondary.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: mysql + port: {{ coalesce .Values.secondary.service.ports.mysql .Values.secondary.service.port }} + protocol: TCP + targetPort: mysql + {{- if (and (or (eq .Values.secondary.service.type "NodePort") (eq .Values.secondary.service.type "LoadBalancer")) (coalesce .Values.secondary.service.nodePorts.mysql .Values.secondary.service.nodePort)) }} + nodePort: {{ coalesce .Values.secondary.service.nodePorts.mysql .Values.secondary.service.nodePort }} + {{- else if eq .Values.secondary.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if and .Values.metrics.enabled (gt (.Values.secondary.service.ports.metrics | int) 0) }} + - name: metrics + port: {{ .Values.secondary.service.ports.metrics }} + protocol: TCP + targetPort: metrics + {{- end }} + {{- if .Values.secondary.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.secondary.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: secondary +{{- end }} diff --git a/charts/mariadb/mariadb/templates/secrets.yaml b/charts/mariadb/mariadb/templates/secrets.yaml new file mode 100644 index 0000000..9551ee2 --- /dev/null +++ b/charts/mariadb/mariadb/templates/secrets.yaml @@ -0,0 +1,98 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- $host := include "mariadb.primary.fullname" . }} +{{- $port := print .Values.primary.service.ports.mysql }} +{{- $rootPassword := include "common.secrets.passwords.manage" ( dict "secret" ( include "mariadb.secretName" . ) "key" "mariadb-root-password" "providedValues" ( list "auth.rootPassword" ) "context" $ ) | trimAll "\"" | b64dec }} +{{- $password := .Values.auth.password }} +{{- if and .Values.auth.username ( include "mariadb.secret.existPassword" . ) }} +{{- $password = include "common.secrets.passwords.manage" ( dict "secret" ( include "mariadb.secretName" . ) "key" "mariadb-password" "providedValues" ( list "auth.password" ) "context" $ ) | trimAll "\"" | b64dec }} +{{- else if ( and .Values.auth.username ( not .Values.auth.forcePassword ) ( empty .Values.auth.password ) ) }} +{{- $password = randAlphaNum 10 }} +{{- end }} +{{- if eq ( include "mariadb.createSecret" . ) "true" }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if ( not .Values.auth.forcePassword ) }} + mariadb-root-password: {{ print $rootPassword | b64enc | quote }} + {{- else }} + mariadb-root-password: {{ required "A MariaDB Root Password is required!" .Values.auth.rootPassword | b64enc | quote }} + {{- end }} + {{- if .Values.auth.username }} + {{- if ( not .Values.auth.forcePassword ) }} + mariadb-password: {{ print $password | b64enc | quote }} + {{- else }} + mariadb-password: {{ required "A MariaDB Database Password is required!" $password | b64enc | quote }} + {{- end }} + {{- end }} + {{- if eq .Values.architecture "replication" }} + {{- if ( not .Values.auth.forcePassword ) }} + mariadb-replication-password: {{ include "common.secrets.passwords.manage" ( dict "secret" ( include "common.names.fullname" . ) "key" "mariadb-replication-password" "providedValues" ( list "auth.replicationPassword" ) "context" $ ) }} + {{- else }} + mariadb-replication-password: {{ required "A MariaDB Replication Password is required!" .Values.auth.replicationPassword | b64enc | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- if .Values.serviceBindings.enabled }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }}-svcbind-root + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: servicebinding.io/mysql +data: + provider: {{ print "bitnami" | b64enc | quote }} + type: {{ print "mysql" | b64enc | quote }} + host: {{ print $host | b64enc | quote }} + port: {{ print $port | b64enc | quote }} + username: {{ print "root" | b64enc | quote }} + password: {{ print $rootPassword | b64enc | quote }} + uri: {{ printf "mysql://root:%s@%s:%s" $rootPassword $host $port | b64enc | quote }} + +{{- if .Values.auth.username }} +{{- $database := .Values.auth.database }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }}-svcbind-custom-user + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: servicebinding.io/mysql +data: + provider: {{ print "bitnami" | b64enc | quote }} + type: {{ print "mysql" | b64enc | quote }} + host: {{ print $host | b64enc | quote }} + port: {{ print $port | b64enc | quote }} + username: {{ print .Values.auth.username | b64enc | quote }} + {{- if $database }} + database: {{ print $database | b64enc | quote }} + {{- end }} + {{- if and .Values.auth.forcePassword ( empty $password ) }} + password: {{ required "A MariaDB Database Password is required!" $password | b64enc | quote }} + {{- else }} + password: {{ print $password | b64enc | quote }} + {{- end }} + uri: {{ printf "mysql://%s:%s@%s:%s/%s" .Values.auth.username $password $host $port $database | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/charts/mariadb/mariadb/templates/serviceaccount.yaml b/charts/mariadb/mariadb/templates/serviceaccount.yaml new file mode 100644 index 0000000..411decf --- /dev/null +++ b/charts/mariadb/mariadb/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "mariadb.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/charts/mariadb/mariadb/templates/servicemonitor.yaml b/charts/mariadb/mariadb/templates/servicemonitor.yaml new file mode 100644 index 0000000..046189d --- /dev/null +++ b/charts/mariadb/mariadb/templates/servicemonitor.yaml @@ -0,0 +1,44 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.serviceMonitor.namespace | quote }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.metrics.serviceMonitor.labels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.metrics.serviceMonitor.jobLabel | quote }} + endpoints: + - port: metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 6 }} + {{- if .Values.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/mariadb/mariadb/values.schema.json b/charts/mariadb/mariadb/values.schema.json new file mode 100644 index 0000000..500c4eb --- /dev/null +++ b/charts/mariadb/mariadb/values.schema.json @@ -0,0 +1,176 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "architecture": { + "type": "string", + "title": "MariaDB architecture", + "form": true, + "description": "Allowed values: `standalone` or `replication`" + }, + "auth": { + "type": "object", + "title": "Authentication configuration", + "form": true, + "properties": { + "rootPassword": { + "type": "string", + "title": "MariaDB root password", + "form": true, + "description": "Defaults to a random 10-character alphanumeric string if not set" + }, + "database": { + "type": "string", + "title": "MariaDB custom database", + "description": "Name of the custom database to be created during the 1st initialization of MariaDB", + "form": true + }, + "username": { + "type": "string", + "title": "MariaDB custom user", + "description": "Name of the custom user to be created during the 1st initialization of MariaDB. This user only has permissions on the MariaDB custom database", + "form": true + }, + "password": { + "type": "string", + "title": "Password for MariaDB custom user", + "description": "Defaults to a random 10-character alphanumeric string if not set", + "form": true, + "hidden": { + "value": false, + "path": "usePassword" + } + }, + "replicationUser": { + "type": "string", + "title": "MariaDB replication user", + "description": "Name of user used to manage replication.", + "form": true, + "hidden": { + "value": "standalone", + "path": "architecture" + } + }, + "replicationPassword": { + "type": "string", + "title": "Password for MariaDB replication user", + "description": "Defaults to a random 10-character alphanumeric string if not set", + "form": true, + "hidden": { + "value": "standalone", + "path": "architecture" + } + } + } + }, + "primary": { + "type": "object", + "title": "Primary replicas settings", + "form": true, + "properties": { + "persistence": { + "type": "object", + "title": "Persistence for primary replicas", + "form": true, + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable persistence", + "description": "Enable persistence using Persistent Volume Claims" + }, + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi", + "hidden": { + "value": false, + "path": "persistence/enabled" + } + } + } + } + } + }, + "secondary": { + "type": "object", + "title": "Secondary replicas settings", + "form": true, + "hidden": { + "value": false, + "path": "replication/enabled" + }, + "properties": { + "persistence": { + "type": "object", + "title": "Persistence for secondary replicas", + "form": true, + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable persistence", + "description": "Enable persistence using Persistent Volume Claims" + }, + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi", + "hidden": { + "value": false, + "path": "persistence/enabled" + } + } + } + } + } + }, + "volumePermissions": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable Init Containers", + "description": "Use an init container to set required folder permissions on the data volume before mounting it in the final destination" + } + } + }, + "metrics": { + "type": "object", + "form": true, + "title": "Prometheus metrics details", + "properties": { + "enabled": { + "type": "boolean", + "title": "Create Prometheus metrics exporter", + "description": "Create a side-car container to expose Prometheus metrics", + "form": true + }, + "serviceMonitor": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Create Prometheus Operator ServiceMonitor", + "description": "Create a ServiceMonitor to track metrics using Prometheus Operator", + "form": true, + "hidden": { + "value": false, + "path": "metrics/enabled" + } + } + } + } + } + } + } +} diff --git a/charts/mariadb/mariadb/values.yaml b/charts/mariadb/mariadb/values.yaml new file mode 100644 index 0000000..c6c7e31 --- /dev/null +++ b/charts/mariadb/mariadb/values.yaml @@ -0,0 +1,1373 @@ +# Copyright Broadcom, Inc. All Rights Reserved. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass +## + +## @param global.imageRegistry Global Docker Image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.defaultStorageClass Global default StorageClass for Persistent Volume(s) +## @param global.storageClass DEPRECATED: use global.defaultStorageClass instead +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + defaultStorageClass: "" + storageClass: "" + ## Compatibility adaptations for Kubernetes platforms + ## + compatibility: + ## Compatibility adaptations for Openshift + ## + openshift: + ## @param global.compatibility.openshift.adaptSecurityContext Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) + ## + adaptSecurityContext: auto +## @section Common parameters +## + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override mariadb.fullname +## +nameOverride: "" +## @param fullnameOverride String to fully override mariadb.fullname +## +fullnameOverride: "" +## @param clusterDomain Default Kubernetes cluster domain +## +clusterDomain: cluster.local +## @param commonAnnotations Common annotations to add to all MariaDB resources (sub-charts are not considered) +## +commonAnnotations: {} +## @param commonLabels Common labels to add to all MariaDB resources (sub-charts are not considered) +## +commonLabels: {} +## @param schedulerName Name of the scheduler (other than default) to dispatch pods +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param runtimeClassName Name of the Runtime Class for all MariaDB pods +## ref: https://kubernetes.io/docs/concepts/containers/runtime-class/ +## +runtimeClassName: "" +## @param extraDeploy Array of extra objects to deploy with the release (evaluated as a template) +## +extraDeploy: [] +## Enable diagnostic mode in the deployment +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers in the deployment + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers in the deployment + ## + args: + - infinity +## @param serviceBindings.enabled Create secret for service binding (Experimental) +## Ref: https://servicebinding.io/service-provider/ +## +serviceBindings: + enabled: false +## @section MariaDB common parameters +## + +## Bitnami MariaDB image +## ref: https://hub.docker.com/r/bitnami/mariadb/tags/ +## @param image.registry [default: REGISTRY_NAME] MariaDB image registry +## @param image.repository [default: REPOSITORY_NAME/mariadb] MariaDB image repository +## @skip image.tag MariaDB image tag (immutable tags are recommended) +## @param image.digest MariaDB image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param image.pullPolicy MariaDB image pull policy +## @param image.pullSecrets Specify docker-registry secret names as an array +## @param image.debug Specify if debug logs should be enabled +## +image: + registry: docker.io + repository: bitnami/mariadb + tag: 11.4.3-debian-12-r1 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/concepts/containers/images/#pre-pulled-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets (secrets must be manually created in the namespace) + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Set to true if you would like to see extra information on logs + ## It turns BASH and/or NAMI debugging in the image + ## + debug: false +## @param architecture MariaDB architecture (`standalone` or `replication`) +## +architecture: standalone +## MariaDB Authentication parameters +## +auth: + ## @param auth.rootPassword Password for the `root` user. Ignored if existing secret is provided. + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mariadb#setting-the-root-password-on-first-run + ## + rootPassword: "" + ## @param auth.database Name for a custom database to create + ## ref: https://github.com/bitnami/containers/blob/main/bitnami/mariadb/README.md#creating-a-database-on-first-run + ## + database: my_database + ## @param auth.username Name for a custom user to create + ## ref: https://github.com/bitnami/containers/blob/main/bitnami/mariadb/README.md#creating-a-database-user-on-first-run + ## + username: "" + ## @param auth.password Password for the new user. Ignored if existing secret is provided + ## + password: "" + ## @param auth.replicationUser MariaDB replication user + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mariadb#setting-up-a-replication-cluster + ## + replicationUser: replicator + ## @param auth.replicationPassword MariaDB replication user password. Ignored if existing secret is provided + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mariadb#setting-up-a-replication-cluster + ## + replicationPassword: "" + ## @param auth.existingSecret Use existing secret for password details (`auth.rootPassword`, `auth.password`, `auth.replicationPassword` will be ignored and picked up from this secret). The secret has to contain the keys `mariadb-root-password`, `mariadb-replication-password` and `mariadb-password` + ## + existingSecret: "" + ## @param auth.forcePassword Force users to specify required passwords + ## + forcePassword: false + ## @param auth.usePasswordFiles Mount credentials as files instead of using environment variables + ## + usePasswordFiles: false + ## @param auth.customPasswordFiles Use custom password files when `auth.usePasswordFiles` is set to `true`. Define path for keys `root` and `user`, also define `replicator` if `architecture` is set to `replication` + ## Example: + ## customPasswordFiles: + ## root: /vault/secrets/mariadb-root + ## user: /vault/secrets/mariadb-user + ## replicator: /vault/secrets/mariadb-replicator + ## + customPasswordFiles: {} +## @param initdbScripts Dictionary of initdb scripts +## Specify dictionary of scripts to be run at first boot +## Example: +## initdbScripts: +## my_init_script.sh: | +## #!/bin/bash +## echo "Do something." +## +initdbScripts: {} +## @param initdbScriptsConfigMap ConfigMap with the initdb scripts (Note: Overrides `initdbScripts`) +## +initdbScriptsConfigMap: "" +## @section MariaDB Primary parameters +## + +## Mariadb Primary parameters +## +primary: + ## @param primary.name Name of the primary database (eg primary, master, leader, ...) + ## + name: primary + ## @param primary.command Override default container command on MariaDB Primary container(s) (useful when using custom images) + ## + command: [] + ## @param primary.args Override default container args on MariaDB Primary container(s) (useful when using custom images) + ## + args: [] + ## @param primary.lifecycleHooks for the MariaDB Primary container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param primary.automountServiceAccountToken Mount Service Account token in pod + ## + automountServiceAccountToken: false + ## @param primary.hostAliases Add deployment host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param primary.containerPorts.mysql Container port for mysql + ## + containerPorts: + mysql: 3306 + ## @param primary.configuration [string] MariaDB Primary configuration to be injected as ConfigMap + ## ref: https://mysql.com/kb/en/mysql/configuring-mysql-with-mycnf/#example-of-configuration-file + ## + configuration: |- + [mysqld] + skip-name-resolve + explicit_defaults_for_timestamp + basedir=/opt/bitnami/mariadb + datadir=/bitnami/mariadb/data + plugin_dir=/opt/bitnami/mariadb/plugin + port={{ .Values.primary.containerPorts.mysql }} + socket=/opt/bitnami/mariadb/tmp/mysql.sock + tmpdir=/opt/bitnami/mariadb/tmp + max_allowed_packet=16M + bind-address=* + pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid + log-error=/opt/bitnami/mariadb/logs/mysqld.log + character-set-server=UTF8 + collation-server=utf8_general_ci + slow_query_log=0 + long_query_time=10.0 + binlog_expire_logs_seconds=2592000 + + [client] + port=3306 + socket=/opt/bitnami/mariadb/tmp/mysql.sock + default-character-set=UTF8 + plugin_dir=/opt/bitnami/mariadb/plugin + + [manager] + port=3306 + socket=/opt/bitnami/mariadb/tmp/mysql.sock + pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid + ## @param primary.existingConfigmap Name of existing ConfigMap with MariaDB Primary configuration. + ## NOTE: When it's set the 'configuration' parameter is ignored + ## + existingConfigmap: "" + ## @param primary.updateStrategy.type MariaDB primary statefulset strategy type + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + ## StrategyType + ## Can be set to RollingUpdate or OnDelete + ## + type: RollingUpdate + ## @param primary.rollingUpdatePartition Partition update strategy for Mariadb Primary statefulset + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + ## + rollingUpdatePartition: "" + ## @param primary.podAnnotations Additional pod annotations for MariaDB primary pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param primary.podLabels Extra labels for MariaDB primary pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + ## + podLabels: {} + ## @param primary.podAffinityPreset MariaDB primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param primary.podAntiAffinityPreset MariaDB primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## Mariadb Primary node affinity preset + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param primary.nodeAffinityPreset.type MariaDB primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param primary.nodeAffinityPreset.key MariaDB primary node label key to match Ignored if `primary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param primary.nodeAffinityPreset.values MariaDB primary node label values to match. Ignored if `primary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param primary.affinity Affinity for MariaDB primary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param primary.nodeSelector Node labels for MariaDB primary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: {} + ## @param primary.tolerations Tolerations for MariaDB primary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param primary.schedulerName Name of the k8s scheduler (other than default) + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + ## @param primary.podManagementPolicy podManagementPolicy to manage scaling operation of MariaDB primary pods + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies + ## + podManagementPolicy: "" + ## @param primary.topologySpreadConstraints Topology Spread Constraints for MariaDB primary pods assignment + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## E.g. + ## topologySpreadConstraints: + ## - maxSkew: 1 + ## topologyKey: topology.kubernetes.io/zone + ## whenUnsatisfiable: DoNotSchedule + ## + topologySpreadConstraints: [] + ## @param primary.priorityClassName Priority class for MariaDB primary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + ## + priorityClassName: "" + ## @param primary.runtimeClassName Runtime Class for MariaDB primary pods + ## Ref: https://kubernetes.io/docs/concepts/containers/runtime-class/ + ## + runtimeClassName: "" + ## MariaDB primary Pod security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param primary.podSecurityContext.enabled Enable security context for MariaDB primary pods + ## @param primary.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy + ## @param primary.podSecurityContext.sysctls Set kernel settings using the sysctl interface + ## @param primary.podSecurityContext.supplementalGroups Set filesystem extra groups + ## @param primary.podSecurityContext.fsGroup Group ID for the mounted volumes' filesystem + ## + podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 + ## MariaDB primary container security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param primary.containerSecurityContext.enabled MariaDB primary container securityContext + ## @param primary.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param primary.containerSecurityContext.runAsUser User ID for the MariaDB primary container + ## @param primary.containerSecurityContext.runAsGroup Group ID for the MariaDB primary container + ## @param primary.containerSecurityContext.runAsNonRoot Set primary container's Security Context runAsNonRoot + ## @param primary.containerSecurityContext.privileged Set primary container's Security Context privileged + ## @param primary.containerSecurityContext.allowPrivilegeEscalation Set primary container's Security Context allowPrivilegeEscalation + ## @param primary.containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem + ## @param primary.containerSecurityContext.capabilities.drop List of capabilities to be dropped + ## @param primary.containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile + ## + containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## MariaDB primary container's resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param primary.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if primary.resources is set (primary.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "micro" + ## @param primary.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## Configure extra options for MariaDB primary containers' liveness, readiness and startup probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## @param primary.startupProbe.enabled Enable startupProbe + ## @param primary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param primary.startupProbe.periodSeconds Period seconds for startupProbe + ## @param primary.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param primary.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param primary.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + initialDelaySeconds: 120 + periodSeconds: 15 + timeoutSeconds: 5 + failureThreshold: 10 + successThreshold: 1 + ## Configure extra options for liveness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param primary.livenessProbe.enabled Enable livenessProbe + ## @param primary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param primary.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param primary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param primary.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param primary.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## @param primary.readinessProbe.enabled Enable readinessProbe + ## @param primary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param primary.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param primary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param primary.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param primary.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## @param primary.customStartupProbe Override default startup probe for MariaDB primary containers + ## + customStartupProbe: {} + ## @param primary.customLivenessProbe Override default liveness probe for MariaDB primary containers + ## + customLivenessProbe: {} + ## @param primary.customReadinessProbe Override default readiness probe for MariaDB primary containers + ## + customReadinessProbe: {} + ## @param primary.startupWaitOptions Override default builtin startup wait check options for MariaDB primary containers + ## `bitnami/mariadb` Docker image has built-in startup check mechanism, + ## which periodically checks if MariaDB service has started up and stops it + ## if all checks have failed after X tries. Use these to control these checks. + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mariadb/pull/240 + ## Example (with default options): + ## startupWaitOptions: + ## retries: 300 + ## waitTime: 2 + ## + startupWaitOptions: {} + ## @param primary.extraFlags MariaDB primary additional command line flags + ## Can be used to specify command line flags, for example: + ## E.g. + ## extraFlags: "--max-connect-errors=1000 --max_connections=155" + ## + extraFlags: "" + ## @param primary.extraEnvVars Extra environment variables to be set on MariaDB primary containers + ## E.g. + ## extraEnvVars: + ## - name: TZ + ## value: "Europe/Paris" + ## + extraEnvVars: [] + ## @param primary.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for MariaDB primary containers + ## + extraEnvVarsCM: "" + ## @param primary.extraEnvVarsSecret Name of existing Secret containing extra env vars for MariaDB primary containers + ## + extraEnvVarsSecret: "" + ## Enable persistence using Persistent Volume Claims + ## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ + ## + persistence: + ## @param primary.persistence.enabled Enable persistence on MariaDB primary replicas using a `PersistentVolumeClaim`. If false, use emptyDir + ## + enabled: true + ## @param primary.persistence.existingClaim Name of an existing `PersistentVolumeClaim` for MariaDB primary replicas + ## NOTE: When it's set the rest of persistence parameters are ignored + ## + existingClaim: "" + ## @param primary.persistence.subPath Subdirectory of the volume to mount at + ## + subPath: "" + ## @param primary.persistence.storageClass MariaDB primary persistent volume storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param primary.persistence.labels Labels for the PVC + ## + labels: {} + ## @param primary.persistence.annotations MariaDB primary persistent volume claim annotations + ## + annotations: {} + ## @param primary.persistence.accessModes MariaDB primary persistent volume access Modes + ## + accessModes: + - ReadWriteOnce + ## @param primary.persistence.size MariaDB primary persistent volume size + ## + size: 8Gi + ## @param primary.persistence.selector Selector to match an existing Persistent Volume + ## selector: + ## matchLabels: + ## app: my-app + ## + selector: {} + ## @param primary.extraVolumes Optionally specify extra list of additional volumes to the MariaDB Primary pod(s) + ## + extraVolumes: [] + ## @param primary.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the MariaDB Primary container(s) + ## + extraVolumeMounts: [] + ## @param primary.initContainers Add additional init containers for the MariaDB Primary pod(s) + ## + initContainers: [] + ## @param primary.sidecars Add additional sidecar containers for the MariaDB Primary pod(s) + ## + sidecars: [] + ## MariaDB Primary Service parameters + ## + service: + ## @param primary.service.type MariaDB Primary Kubernetes service type + ## + type: ClusterIP + ports: + ## @param primary.service.ports.mysql MariaDB Primary Kubernetes service port for MariaDB + ## + mysql: 3306 + ## @param primary.service.ports.metrics MariaDB Primary Kubernetes service port for metrics + ## + metrics: 9104 + ## @param primary.service.nodePorts.mysql MariaDB Primary Kubernetes service node port + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + mysql: "" + ## @param primary.service.clusterIP MariaDB Primary Kubernetes service clusterIP IP + ## + clusterIP: "" + ## @param primary.service.loadBalancerIP MariaDB Primary loadBalancerIP if service type is `LoadBalancer` + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param primary.service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param primary.service.loadBalancerSourceRanges Address that are allowed when MariaDB Primary service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## E.g. + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param primary.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param primary.service.annotations Provide any additional annotations which may be required + ## + annotations: {} + ## @param primary.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param primary.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## MariaDB primary Pod Disruption Budget configuration + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + ## + pdb: + ## @param primary.pdb.create Enable/disable a Pod Disruption Budget creation for MariaDB primary pods + ## + create: true + ## @param primary.pdb.minAvailable Minimum number/percentage of MariaDB primary pods that must still be available after the eviction + ## + minAvailable: "" + ## @param primary.pdb.maxUnavailable Maximum number/percentage of MariaDB primary pods that can be unavailable after the eviction. Defaults to `1` if both `primary.pdb.minAvailable` and `primary.pdb.maxUnavailable` are empty. + ## + maxUnavailable: "" + ## @param primary.revisionHistoryLimit Maximum number of revisions that will be maintained in the StatefulSet + ## + revisionHistoryLimit: 10 +## @section MariaDB Secondary parameters +## + +## Mariadb Secondary parameters +## +secondary: + ## @param secondary.name Name of the secondary database (eg secondary, slave, ...) + ## + name: secondary + ## @param secondary.replicaCount Number of MariaDB secondary replicas + ## + replicaCount: 1 + ## @param secondary.command Override default container command on MariaDB Secondary container(s) (useful when using custom images) + ## + command: [] + ## @param secondary.args Override default container args on MariaDB Secondary container(s) (useful when using custom images) + ## + args: [] + ## @param secondary.lifecycleHooks for the MariaDB Secondary container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param secondary.automountServiceAccountToken Mount Service Account token in pod + ## + automountServiceAccountToken: false + ## @param secondary.hostAliases Add deployment host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param secondary.containerPorts.mysql Container port for mysql + ## + containerPorts: + mysql: 3306 + ## @param secondary.configuration [string] MariaDB Secondary configuration to be injected as ConfigMap + ## ref: https://mysql.com/kb/en/mysql/configuring-mysql-with-mycnf/#example-of-configuration-file + ## + configuration: |- + [mysqld] + skip-name-resolve + explicit_defaults_for_timestamp + basedir=/opt/bitnami/mariadb + datadir=/bitnami/mariadb/data + port={{ .Values.secondary.containerPorts.mysql }} + socket=/opt/bitnami/mariadb/tmp/mysql.sock + tmpdir=/opt/bitnami/mariadb/tmp + max_allowed_packet=16M + bind-address=0.0.0.0 + pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid + log-error=/opt/bitnami/mariadb/logs/mysqld.log + character-set-server=UTF8 + collation-server=utf8_general_ci + slow_query_log=0 + long_query_time=10.0 + binlog_expire_logs_seconds=2592000 + + [client] + port=3306 + socket=/opt/bitnami/mariadb/tmp/mysql.sock + default-character-set=UTF8 + + [manager] + port=3306 + socket=/opt/bitnami/mariadb/tmp/mysql.sock + pid-file=/opt/bitnami/mariadb/tmp/mysqld.pid + ## @param secondary.existingConfigmap Name of existing ConfigMap with MariaDB Secondary configuration. + ## NOTE: When it's set the 'configuration' parameter is ignored + ## + existingConfigmap: "" + ## @param secondary.updateStrategy.type MariaDB secondary statefulset strategy type + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + ## StrategyType + ## Can be set to RollingUpdate or OnDelete + ## + type: RollingUpdate + ## @param secondary.rollingUpdatePartition Partition update strategy for Mariadb Secondary statefulset + ## https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions + ## + rollingUpdatePartition: "" + ## @param secondary.podAnnotations Additional pod annotations for MariaDB secondary pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param secondary.podLabels Extra labels for MariaDB secondary pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + ## + podLabels: {} + ## @param secondary.podAffinityPreset MariaDB secondary pod affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param secondary.podAntiAffinityPreset MariaDB secondary pod anti-affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## Mariadb Secondary node affinity preset + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param secondary.nodeAffinityPreset.type MariaDB secondary node affinity preset type. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param secondary.nodeAffinityPreset.key MariaDB secondary node label key to match Ignored if `secondary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param secondary.nodeAffinityPreset.values MariaDB secondary node label values to match. Ignored if `secondary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param secondary.affinity Affinity for MariaDB secondary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param secondary.nodeSelector Node labels for MariaDB secondary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: {} + ## @param secondary.tolerations Tolerations for MariaDB secondary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param secondary.topologySpreadConstraints Topology Spread Constraints for MariaDB secondary pods assignment + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## E.g. + ## topologySpreadConstraints: + ## - maxSkew: 1 + ## topologyKey: topology.kubernetes.io/zone + ## whenUnsatisfiable: DoNotSchedule + ## + topologySpreadConstraints: [] + ## @param secondary.priorityClassName Priority class for MariaDB secondary pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + ## + priorityClassName: "" + ## @param secondary.runtimeClassName Runtime Class for MariaDB secondary pods + ## Ref: https://kubernetes.io/docs/concepts/containers/runtime-class/ + ## + runtimeClassName: "" + ## @param secondary.schedulerName Name of the k8s scheduler (other than default) + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + ## @param secondary.podManagementPolicy podManagementPolicy to manage scaling operation of MariaDB secondary pods + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies + ## + podManagementPolicy: "" + ## MariaDB secondary Pod security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param secondary.podSecurityContext.enabled Enable security context for MariaDB secondary pods + ## @param secondary.podSecurityContext.fsGroupChangePolicy Set filesystem group change policy + ## @param secondary.podSecurityContext.sysctls Set kernel settings using the sysctl interface + ## @param secondary.podSecurityContext.supplementalGroups Set filesystem extra groups + ## @param secondary.podSecurityContext.fsGroup Group ID for the mounted volumes' filesystem + ## + podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 + ## MariaDB secondary container security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param secondary.containerSecurityContext.enabled MariaDB secondary container securityContext + ## @param secondary.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param secondary.containerSecurityContext.runAsUser User ID for the MariaDB secondary container + ## @param secondary.containerSecurityContext.runAsGroup Group ID for the MariaDB secondary container + ## @param secondary.containerSecurityContext.runAsNonRoot Set secondary container's Security Context runAsNonRoot + ## @param secondary.containerSecurityContext.privileged Set secondary container's Security Context privileged + ## @param secondary.containerSecurityContext.allowPrivilegeEscalation Set secondary container's Security Context allowPrivilegeEscalation + ## @param secondary.containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem + ## @param secondary.containerSecurityContext.capabilities.drop List of capabilities to be dropped + ## @param secondary.containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile + ## + containerSecurityContext: + enabled: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## MariaDB secondary container's resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param secondary.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if secondary.resources is set (secondary.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "micro" + ## @param secondary.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## Configure extra options for MariaDB Secondary containers' liveness, readiness and startup probes + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes) + ## @param secondary.startupProbe.enabled Enable startupProbe + ## @param secondary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param secondary.startupProbe.periodSeconds Period seconds for startupProbe + ## @param secondary.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param secondary.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param secondary.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: false + initialDelaySeconds: 120 + periodSeconds: 15 + timeoutSeconds: 5 + failureThreshold: 10 + successThreshold: 1 + ## Configure extra options for liveness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param secondary.livenessProbe.enabled Enable livenessProbe + ## @param secondary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param secondary.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param secondary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param secondary.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param secondary.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## @param secondary.readinessProbe.enabled Enable readinessProbe + ## @param secondary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param secondary.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param secondary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param secondary.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param secondary.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## @param secondary.customStartupProbe Override default startup probe for MariaDB secondary containers + ## + customStartupProbe: {} + ## @param secondary.customLivenessProbe Override default liveness probe for MariaDB secondary containers + ## + customLivenessProbe: {} + ## @param secondary.customReadinessProbe Override default readiness probe for MariaDB secondary containers + ## + customReadinessProbe: {} + ## @param secondary.startupWaitOptions Override default builtin startup wait check options for MariaDB secondary containers + ## `bitnami/mariadb` Docker image has built-in startup check mechanism, + ## which periodically checks if MariaDB service has started up and stops it + ## if all checks have failed after X tries. Use these to control these checks. + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mariadb/pull/240 + ## Example (with default options): + ## startupWaitOptions: + ## retries: 300 + ## waitTime: 2 + ## + startupWaitOptions: {} + ## @param secondary.extraFlags MariaDB secondary additional command line flags + ## Can be used to specify command line flags, for example: + ## E.g. + ## extraFlags: "--max-connect-errors=1000 --max_connections=155" + ## + extraFlags: "" + ## @param secondary.extraEnvVars Extra environment variables to be set on MariaDB secondary containers + ## E.g. + ## extraEnvVars: + ## - name: TZ + ## value: "Europe/Paris" + ## + extraEnvVars: [] + ## @param secondary.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for MariaDB secondary containers + ## + extraEnvVarsCM: "" + ## @param secondary.extraEnvVarsSecret Name of existing Secret containing extra env vars for MariaDB secondary containers + ## + extraEnvVarsSecret: "" + ## Enable persistence using Persistent Volume Claims + ## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ + ## + persistence: + ## @param secondary.persistence.enabled Enable persistence on MariaDB secondary replicas using a `PersistentVolumeClaim` + ## + enabled: true + ## @param secondary.persistence.subPath Subdirectory of the volume to mount at + ## + subPath: "" + ## @param secondary.persistence.storageClass MariaDB secondary persistent volume storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param secondary.persistence.labels Labels for the PVC + ## + labels: {} + ## @param secondary.persistence.annotations MariaDB secondary persistent volume claim annotations + ## + annotations: {} + ## @param secondary.persistence.accessModes MariaDB secondary persistent volume access Modes + ## + accessModes: + - ReadWriteOnce + ## @param secondary.persistence.size MariaDB secondary persistent volume size + ## + size: 8Gi + ## @param secondary.persistence.selector Selector to match an existing Persistent Volume + ## selector: + ## matchLabels: + ## app: my-app + ## + selector: {} + ## @param secondary.extraVolumes Optionally specify extra list of additional volumes to the MariaDB secondary pod(s) + ## + extraVolumes: [] + ## @param secondary.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the MariaDB secondary container(s) + ## + extraVolumeMounts: [] + ## @param secondary.initContainers Add additional init containers for the MariaDB secondary pod(s) + ## + initContainers: [] + ## @param secondary.sidecars Add additional sidecar containers for the MariaDB secondary pod(s) + ## + sidecars: [] + ## MariaDB Secondary Service parameters + ## + service: + ## @param secondary.service.type MariaDB secondary Kubernetes service type + ## + type: ClusterIP + ports: + ## @param secondary.service.ports.mysql MariaDB secondary Kubernetes service port for MariaDB + ## + mysql: 3306 + ## @param secondary.service.ports.metrics MariaDB secondary Kubernetes service port for metrics + ## + metrics: 9104 + ## @param secondary.service.nodePorts.mysql MariaDB secondary Kubernetes service node port + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + mysql: "" + ## @param secondary.service.clusterIP MariaDB secondary Kubernetes service clusterIP IP + ## e.g: + ## clusterIP: None + ## + clusterIP: "" + ## @param secondary.service.loadBalancerIP MariaDB secondary loadBalancerIP if service type is `LoadBalancer` + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param secondary.service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param secondary.service.loadBalancerSourceRanges Address that are allowed when MariaDB secondary service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## E.g. + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param secondary.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param secondary.service.annotations Provide any additional annotations which may be required + ## + annotations: {} + ## @param secondary.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param secondary.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## MariaDB secondary Pod Disruption Budget configuration + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + ## + pdb: + ## @param secondary.pdb.create Enable/disable a Pod Disruption Budget creation for MariaDB secondary pods + ## + create: true + ## @param secondary.pdb.minAvailable Minimum number/percentage of MariaDB secondary pods that should remain scheduled + ## + minAvailable: "" + ## @param secondary.pdb.maxUnavailable Maximum number/percentage of MariaDB secondary pods that may be made unavailable. Defaults to `1` if both `secondary.pdb.minAvailable` and `secondary.pdb.maxUnavailable` are empty. + ## + maxUnavailable: "" + ## @param secondary.revisionHistoryLimit Maximum number of revisions that will be maintained in the StatefulSet + ## + revisionHistoryLimit: 10 +## @section RBAC parameters +## + +## MariaDB pods ServiceAccount +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## +serviceAccount: + ## @param serviceAccount.create Enable the creation of a ServiceAccount for MariaDB pods + ## + create: true + ## @param serviceAccount.name Name of the created ServiceAccount + ## If not set and create is true, a name is generated using the mariadb.fullname template + ## + name: "" + ## @param serviceAccount.annotations Annotations for MariaDB Service Account + ## + annotations: {} + ## @param serviceAccount.automountServiceAccountToken Automount service account token for the server service account + ## + automountServiceAccountToken: false +## Role Based Access +## ref: https://kubernetes.io/docs/admin/authorization/rbac/ +## +rbac: + ## @param rbac.create Whether to create and use RBAC resources or not + ## + create: false +## @section Volume Permissions parameters +## + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` + ## + enabled: false + ## @param volumePermissions.image.registry [default: REGISTRY_NAME] Init container volume-permissions image registry + ## @param volumePermissions.image.repository [default: REPOSITORY_NAME/os-shell] Init container volume-permissions image repository + ## @skip volumePermissions.image.tag Init container volume-permissions image tag (immutable tags are recommended) + ## @param volumePermissions.image.digest Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## @param volumePermissions.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 12-debian-12-r30 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets (secrets must be manually created in the namespace) + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param volumePermissions.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if volumePermissions.resources is set (volumePermissions.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param volumePermissions.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} +## @section Metrics parameters +## + +## Mysqld Prometheus exporter parameters +## +metrics: + ## @param metrics.enabled Start a side-car prometheus exporter + ## + enabled: false + ## @param metrics.image.registry [default: REGISTRY_NAME] Exporter image registry + ## @param metrics.image.repository [default: REPOSITORY_NAME/mysqld-exporter] Exporter image repository + ## @skip metrics.image.tag Exporter image tag (immutable tags are recommended) + ## @param metrics.image.digest Exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param metrics.image.pullPolicy Exporter image pull policy + ## @param metrics.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/mysqld-exporter + tag: 0.15.1-debian-12-r34 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets (secrets must be manually created in the namespace) + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param metrics.annotations [object] Annotations for the Exporter pod + ## + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9104" + ## @param metrics.extraArgs [object] Extra args to be passed to mysqld_exporter + ## ref: https://github.com/prometheus/mysqld_exporter/ + ## E.g. + ## - --collect.auto_increment.columns + ## - --collect.binlog_size + ## - --collect.engine_innodb_status + ## - --collect.engine_tokudb_status + ## - --collect.global_status + ## - --collect.global_variables + ## - --collect.info_schema.clientstats + ## - --collect.info_schema.innodb_metrics + ## - --collect.info_schema.innodb_tablespaces + ## - --collect.info_schema.innodb_cmp + ## - --collect.info_schema.innodb_cmpmem + ## - --collect.info_schema.processlist + ## - --collect.info_schema.processlist.min_time + ## - --collect.info_schema.query_response_time + ## - --collect.info_schema.tables + ## - --collect.info_schema.tables.databases + ## - --collect.info_schema.tablestats + ## - --collect.info_schema.userstats + ## - --collect.perf_schema.eventsstatements + ## - --collect.perf_schema.eventsstatements.digest_text_limit + ## - --collect.perf_schema.eventsstatements.limit + ## - --collect.perf_schema.eventsstatements.timelimit + ## - --collect.perf_schema.eventswaits + ## - --collect.perf_schema.file_events + ## - --collect.perf_schema.file_instances + ## - --collect.perf_schema.indexiowaits + ## - --collect.perf_schema.tableiowaits + ## - --collect.perf_schema.tablelocks + ## - --collect.perf_schema.replication_group_member_stats + ## - --collect.slave_status + ## - --collect.slave_hosts + ## - --collect.heartbeat + ## - --collect.heartbeat.database + ## - --collect.heartbeat.table + ## + extraArgs: + primary: [] + secondary: [] + ## @param metrics.extraVolumeMounts [object] Optionally specify extra list of additional volumeMounts for the MariaDB metrics container(s) + ## + extraVolumeMounts: + primary: [] + secondary: [] + ## @param metrics.containerPorts.http Container port for http + ## + containerPorts: + http: 9104 + ## MariaDB metrics container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param metrics.containerSecurityContext.enabled Enable security context for MariaDB metrics container + ## @param metrics.containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container + ## @param metrics.containerSecurityContext.runAsUser User ID for the MariaDB metrics container + ## @param metrics.containerSecurityContext.runAsGroup Group ID for the MariaDB metrics container + ## @param metrics.containerSecurityContext.runAsNonRoot Set metrics container's Security Context runAsNonRoot + ## @param metrics.containerSecurityContext.privileged Set metrics container's Security Context privileged + ## @param metrics.containerSecurityContext.allowPrivilegeEscalation Set metrics container's Security Context allowPrivilegeEscalation + ## @param metrics.containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem + ## @param metrics.containerSecurityContext.capabilities.drop List of capabilities to be dropped + ## @param metrics.containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile + ## Example: + ## containerSecurityContext: + ## enabled: true + ## capabilities: + ## drop: ["NET_RAW"] + ## readOnlyRootFilesystem: true + ## + containerSecurityContext: + enabled: false + privileged: false + runAsNonRoot: true + seLinuxOptions: {} + runAsUser: 1001 + runAsGroup: 1001 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" + ## Mysqld Prometheus exporter resource requests and limits + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## We usually recommend not to specify default resources and to leave this as a conscious + ## choice for the user. This also increases chances charts run on environments with little + ## resources, such as Minikube. If you do want to specify resources, uncomment the following + ## lines, adjust them as necessary, and remove the curly braces after 'resources:'. + ## @param metrics.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param metrics.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## + resources: {} + ## Configure extra options for liveness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param metrics.livenessProbe.enabled Enable livenessProbe + ## @param metrics.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param metrics.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param metrics.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param metrics.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param metrics.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + ## Configure extra options for readiness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param metrics.readinessProbe.enabled Enable readinessProbe + ## @param metrics.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param metrics.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param metrics.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param metrics.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param metrics.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator + ## + serviceMonitor: + ## @param metrics.serviceMonitor.enabled Create ServiceMonitor Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param metrics.serviceMonitor.namespace Namespace which Prometheus is running in + ## + namespace: "" + ## @param metrics.serviceMonitor.jobLabel The name of the label on the target service to use as the job name in prometheus. + ## + jobLabel: "" + ## @param metrics.serviceMonitor.interval Interval at which metrics should be scraped + ## + interval: 30s + ## @param metrics.serviceMonitor.scrapeTimeout Specify the timeout after which the scrape is ended + ## e.g: + ## scrapeTimeout: 30s + ## + scrapeTimeout: "" + ## @param metrics.serviceMonitor.relabelings RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + ## + relabelings: [] + ## @param metrics.serviceMonitor.metricRelabelings MetricRelabelConfigs to apply to samples before ingestion + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + ## @param metrics.serviceMonitor.honorLabels honorLabels chooses the metric's labels on collisions with target labels + ## + honorLabels: false + ## @param metrics.serviceMonitor.selector ServiceMonitor selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + ## + ## selector: + ## prometheus: my-prometheus + ## + selector: {} + ## @param metrics.serviceMonitor.labels Extra labels for the ServiceMonitor + ## + labels: {} + ## Prometheus Operator PrometheusRule configuration + ## + prometheusRule: + ## @param metrics.prometheusRule.enabled if `true`, creates a Prometheus Operator PrometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) + ## + enabled: false + ## @param metrics.prometheusRule.namespace Namespace for the PrometheusRule Resource (defaults to the Release Namespace) + ## + namespace: "" + ## @param metrics.prometheusRule.additionalLabels Additional labels that can be used so PrometheusRule will be discovered by Prometheus + ## + additionalLabels: {} + ## @param metrics.prometheusRule.rules Prometheus Rule definitions + ## - alert: MariaDB-Down + ## expr: absent(up{job="mariadb"} == 1) + ## for: 5m + ## labels: + ## severity: warning + ## service: mariadb + ## annotations: + ## message: 'MariaDB instance {{ `{{` }} $labels.instance {{ `}}` }} is down' + ## summary: MariaDB instance is down + ## + rules: [] +## @section NetworkPolicy parameters +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +## +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources + ## + enabled: true + ## @param networkPolicy.allowExternal The Policy model to apply + ## When set to false, only pods with the correct client label will have network access to the ports MariaDB is + ## listening on. When true, MariaDB will accept connections from any source (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.allowExternalEgress Allow the pod to access any range of port and all destinations. + ## + allowExternalEgress: true + ## @param networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraIngress: [] + ## @param networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} diff --git a/charts/mariadb/values-overrides.yaml b/charts/mariadb/values-overrides.yaml new file mode 100644 index 0000000..8bc0914 --- /dev/null +++ b/charts/mariadb/values-overrides.yaml @@ -0,0 +1,8 @@ +# @see https://artifacthub.io/packages/helm/bitnami/mariadb?modal=values +fullnameOverride: mariadb +# architecture: replication +architecture: standalone +auth: + username: drupal + database: drupal + existingSecret: mariadb \ No newline at end of file diff --git a/charts/phpmyadmin/phpmyadmin/.helmignore b/charts/phpmyadmin/phpmyadmin/.helmignore new file mode 100644 index 0000000..207983f --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# img folder +img/ +# Changelog +CHANGELOG.md diff --git a/charts/phpmyadmin/phpmyadmin/Chart.lock b/charts/phpmyadmin/phpmyadmin/Chart.lock new file mode 100644 index 0000000..109d91c --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: mariadb + repository: oci://registry-1.docker.io/bitnamicharts + version: 19.0.6 +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.23.0 +digest: sha256:8626b452b34cfdd615a5e97ad13de70344e5fd14ee39db107795e20d5006b3c8 +generated: "2024-09-19T09:40:39.92295583Z" diff --git a/charts/phpmyadmin/phpmyadmin/Chart.yaml b/charts/phpmyadmin/phpmyadmin/Chart.yaml new file mode 100644 index 0000000..e5933f4 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/Chart.yaml @@ -0,0 +1,38 @@ +annotations: + category: Infrastructure + images: | + - name: apache-exporter + image: docker.io/bitnami/apache-exporter:1.0.8-debian-12-r9 + - name: phpmyadmin + image: docker.io/bitnami/phpmyadmin:5.2.1-debian-12-r42 + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 5.2.1 +dependencies: +- condition: db.bundleTestDB + name: mariadb + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - phpmyadmin-database + version: 19.x.x +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: phpMyAdmin is a free software tool written in PHP, intended to handle + the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations + on MySQL and MariaDB. +home: https://bitnami.com +icon: https://bitnami.com/assets/stacks/phpmyadmin/img/phpmyadmin-stack-220x234.png +keywords: +- mariadb +- mysql +- phpmyadmin +maintainers: +- name: Broadcom, Inc. All Rights Reserved. + url: https://github.com/bitnami/charts +name: phpmyadmin +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/phpmyadmin +version: 17.0.7 diff --git a/charts/phpmyadmin/phpmyadmin/README.md b/charts/phpmyadmin/phpmyadmin/README.md new file mode 100644 index 0000000..97bc819 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/README.md @@ -0,0 +1,588 @@ + + +# Bitnami package for phpMyAdmin + +phpMyAdmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. phpMyAdmin supports a wide range of operations on MySQL and MariaDB. + +[Overview of phpMyAdmin](https://www.phpmyadmin.net/) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/phpmyadmin +``` + +Looking to use phpMyAdmin in production? Try [VMware Tanzu Application Catalog](https://bitnami.com/enterprise), the commercial edition of the Bitnami catalog. + +## Introduction + +This chart bootstraps a [phpMyAdmin](https://github.com/bitnami/containers/tree/main/bitnami/phpmyadmin) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +As a portable web application written primarily in PHP, phpMyAdmin has become one of the most popular MySQL administration tools, especially for web hosting services. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.23+ +- Helm 3.8.0+ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://REGISTRY_NAME/REPOSITORY_NAME/phpmyadmin +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The command deploys phpMyAdmin on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Configuration and installation details + +### Resource requests and limits + +Bitnami charts allow setting resource requests and limits for all containers inside the chart deployment. These are inside the `resources` value (check parameter table). Setting requests is essential for production workloads and these should be adapted to your specific use case. + +To make this process easier, the chart contains the `resourcesPreset` values, which automatically sets the `resources` section according to different presets. Check these presets in [the bitnami/common chart](https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15). However, in production workloads using `resourcePreset` is discouraged as it may not fully adapt to your specific needs. Find more information on container resource management in the [official Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). + +### [Rolling VS Immutable tags](https://docs.vmware.com/en/VMware-Tanzu-Application-Catalog/services/tutorials/GUID-understand-rolling-tags-containers-index.html) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Ingress + +This chart provides support for Ingress resources. If you have an ingress controller installed on your cluster, such as [nginx-ingress-controller](https://github.com/bitnami/charts/tree/main/bitnami/nginx-ingress-controller) or [contour](https://github.com/bitnami/charts/tree/main/bitnami/contour) you can utilize the ingress controller to serve your application. + +To enable ingress integration, please set `ingress.enabled` to `true`. + +#### Hosts + +Most likely you will only want to have one hostname that maps to this phpMyAdmin installation. If that's your case, the property `ingress.hostname` will set it. However, it is possible to have more than one host. To facilitate this, the `ingress.extraHosts` object can be specified as an array. You can also use `ingress.extraTLS` to add the TLS configuration for extra hosts. + +For each host indicated at `ingress.extraHosts`, please indicate a `name`, `path`, and any `annotations` that you may want the ingress controller to know about. + +For annotations, please see [this document](https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md). Not all annotations are supported by all ingress controllers, but this document does a good job of indicating which annotation is supported by many popular ingress controllers. + +### TLS Secrets + +This chart will facilitate the creation of TLS secrets for use with the ingress controller, however, this is not required. There are some common use cases: + +- Helm generates and manages certificate secrets (default). +- User generates certificates and helm manages secrets. +- User generates and manages certificates separately. +- An additional tool (like [cert-manager](https://github.com/jetstack/cert-manager/)) manages the secrets for the application. + +In the second case, a certificate and a key are needed. We would expect them to look like this: + +- certificate files should look like (and there can be more than one certificate if there is a certificate chain) + + ```console + -----BEGIN CERTIFICATE----- + MIID6TCCAtGgAwIBAgIJAIaCwivkeB5EMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV + ... + jScrvkiBO65F46KioCL9h5tDvomdU1aqpI/CBzhvZn1c0ZTf87tGQR8NK7v7 + -----END CERTIFICATE----- + ``` + +- keys should look like: + + ```console + -----BEGIN RSA PRIVATE KEY----- + MIIEogIBAAKCAQEAvLYcyu8f3skuRyUgeeNpeDvYBCDcgq+LsWap6zbX5f8oLqp4 + ... + wrj2wDbCDCFmfqnSJ+dKI3vFLlEz44sAV8jX/kd4Y6ZTQhlLbYc= + -----END RSA PRIVATE KEY----- + ``` + +If you are going to generate certificates yourself and want helm to manage the secret, please copy these values into the `certificate` and `key` values for a given `ingress.secrets` entry. + +If you want to manage TLS secrets outside of Helm, please know that you can create a TLS secret and pass its name via the parameter `ingress.existingSecretName`. + +To make use of cert-manager, you need to add the the `cert-manager.io/cluster-issuer:` annotation to the ingress object via `ingress.annotations`. + +### Adding extra environment variables + +In case you want to add extra environment variables (useful for advanced operations like custom init scripts), you can use the `extraEnvVars` property. + +```yaml +extraEnvVars: + - name: LOG_LEVEL + value: DEBUG +``` + +Alternatively, you can use a ConfigMap or a Secret with the environment variables. To do so, use the `extraEnvVarsCM` or the `extraEnvVarsSecret` values. + +### Sidecars and Init Containers + +If you have a need for additional containers to run within the same pod as the PhpMyAdmin app (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. + +```yaml +sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +Similarly, you can add extra init containers using the `initContainers` parameter. + +```yaml +initContainers: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +### Deploying extra resources + +There are cases where you may want to deploy extra objects, such a ConfigMap containing your app's configuration or some extra deployment with a micro service used by your app. For covering this case, the chart allows adding the full specification of other objects using the `extraDeploy` parameter. + +### Setting Pod's affinity + +This chart allows you to set your custom affinity using the `XXX.affinity` parameter(s). Find more information about Pod's affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `podAffinityPreset`, `XpodAntiAffinityPreset`, or `nodeAffinityPreset` parameters. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.defaultStorageClass` | Global default StorageClass for Persistent Volume(s) | `""` | +| `global.compatibility.openshift.adaptSecurityContext` | Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) | `disabled` | + +### Common parameters + +| Name | Description | Value | +| ------------------- | -------------------------------------------------------------------------------------------- | --------------- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override common.names.fullname template (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override common.names.fullname template | `""` | +| `commonLabels` | Add labels to all the deployed resources | `{}` | +| `commonAnnotations` | Add annotations to all the deployed resources | `{}` | +| `clusterDomain` | Kubernetes Cluster Domain | `cluster.local` | +| `extraDeploy` | Array of extra objects to deploy with the release | `[]` | + +### phpMyAdmin parameters + +| Name | Description | Value | +| -------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------- | +| `image.registry` | phpMyAdmin image registry | `REGISTRY_NAME` | +| `image.repository` | phpMyAdmin image repository | `REPOSITORY_NAME/phpmyadmin` | +| `image.digest` | phpMyAdmin image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `image.debug` | Enable phpmyadmin image debug mode | `false` | +| `command` | Override default container command (useful when using custom images) | `[]` | +| `args` | Override default container args (useful when using custom images) | `[]` | +| `lifecycleHooks` | for the phpmyadmin container(s) to automate configuration before or after startup | `{}` | +| `extraEnvVars` | Extra environment variables to be set on PhpMyAdmin container | `[]` | +| `extraEnvVarsCM` | Name of a existing ConfigMap containing extra env vars | `""` | +| `extraEnvVarsSecret` | Name of a existing Secret containing extra env vars | `""` | + +### phpMyAdmin deployment parameters + +| Name | Description | Value | +| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | +| `automountServiceAccountToken` | Mount Service Account token in pod | `false` | +| `hostAliases` | Deployment pod host aliases | `[]` | +| `containerPorts.http` | HTTP port to expose at container level | `8080` | +| `containerPorts.https` | HTTPS port to expose at container level | `8443` | +| `extraContainerPorts` | Optionally specify extra list of additional ports for phpMyAdmin container(s) | `[]` | +| `updateStrategy.type` | Strategy to use to update Pods | `RollingUpdate` | +| `podSecurityContext.enabled` | Enable phpMyAdmin pods' Security Context | `true` | +| `podSecurityContext.fsGroupChangePolicy` | Set filesystem group change policy | `Always` | +| `podSecurityContext.sysctls` | Set kernel settings using the sysctl interface | `[]` | +| `podSecurityContext.supplementalGroups` | Set filesystem extra groups | `[]` | +| `podSecurityContext.fsGroup` | User ID for the container | `1001` | +| `containerSecurityContext.enabled` | Enabled containers' Security Context | `true` | +| `containerSecurityContext.seLinuxOptions` | Set SELinux options in container | `nil` | +| `containerSecurityContext.runAsUser` | Set containers' Security Context runAsUser | `1001` | +| `containerSecurityContext.runAsGroup` | Set containers' Security Context runAsGroup | `1001` | +| `containerSecurityContext.runAsNonRoot` | Set container's Security Context runAsNonRoot | `true` | +| `containerSecurityContext.privileged` | Set container's Security Context privileged | `false` | +| `containerSecurityContext.readOnlyRootFilesystem` | Set container's Security Context readOnlyRootFilesystem | `true` | +| `containerSecurityContext.allowPrivilegeEscalation` | Set container's Security Context allowPrivilegeEscalation | `false` | +| `containerSecurityContext.capabilities.drop` | List of capabilities to be dropped | `["ALL"]` | +| `containerSecurityContext.seccompProfile.type` | Set container's Security Context seccomp profile | `RuntimeDefault` | +| `replicas` | Number of replicas | `1` | +| `resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). | `micro` | +| `resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `startupProbe.enabled` | Enable startupProbe | `false` | +| `startupProbe.httpGet.path` | Request path for startupProbe | `/` | +| `startupProbe.httpGet.port` | Port for startupProbe | `http` | +| `startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `30` | +| `startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `30` | +| `startupProbe.failureThreshold` | Failure threshold for startupProbe | `6` | +| `startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `livenessProbe.enabled` | Enable livenessProbe | `true` | +| `livenessProbe.tcpSocket.port` | Port for livenessProbe | `http` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `30` | +| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `30` | +| `livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` | +| `livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `readinessProbe.enabled` | Enable readinessProbe | `true` | +| `readinessProbe.httpGet.path` | Request path for readinessProbe | `/` | +| `readinessProbe.httpGet.port` | Port for readinessProbe | `http` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `30` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `30` | +| `readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` | +| `readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `customStartupProbe` | Override default startup probe | `{}` | +| `customLivenessProbe` | Override default liveness probe | `{}` | +| `customReadinessProbe` | Override default readiness probe | `{}` | +| `podLabels` | Extra labels for PhpMyAdmin pods | `{}` | +| `podAnnotations` | Annotations for PhpMyAdmin pods | `{}` | +| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `nodeAffinityPreset.key` | Node label key to match. Ignored if `affinity` is set. | `""` | +| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | +| `affinity` | Affinity for pod assignment. Evaluated as a template. | `{}` | +| `nodeSelector` | Node labels for pod assignment. Evaluated as a template. | `{}` | +| `tolerations` | Tolerations for pod assignment. Evaluated as a template. | `[]` | +| `priorityClassName` | phpmyadmin pods' priorityClassName | `""` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `extraVolumes` | Optionally specify extra list of additional volumes for PhpMyAdmin pods | `[]` | +| `extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for PhpMyAdmin container(s) | `[]` | +| `initContainers` | Add init containers to the PhpMyAdmin pods | `[]` | +| `pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` | +| `pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `""` | +| `pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `pdb.minAvailable` and `pdb.maxUnavailable` are empty. | `""` | +| `sidecars` | Add sidecar containers to the PhpMyAdmin pods | `[]` | + +### Traffic Exposure parameters + +| Name | Description | Value | +| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `service.type` | Kubernetes Service type | `ClusterIP` | +| `service.ports.http` | Service HTTP port | `80` | +| `service.ports.https` | Service HTTPS port | `443` | +| `service.nodePorts.http` | Kubernetes http node port | `""` | +| `service.nodePorts.https` | Kubernetes https node port | `""` | +| `service.clusterIP` | PhpMyAdmin service clusterIP IP | `""` | +| `service.loadBalancerIP` | Load balancer IP for the phpMyAdmin Service (optional, cloud specific) | `""` | +| `service.loadBalancerSourceRanges` | Addresses that are allowed when service is LoadBalancer | `[]` | +| `service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `service.annotations` | Provide any additional annotations that may be required for the PhpMyAdmin service | `{}` | +| `service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `ingress.enabled` | Set to true to enable ingress record generation | `false` | +| `ingress.apiVersion` | Force Ingress API version (automatically detected if not set) | `""` | +| `ingress.hostname` | When the ingress is enabled, a host pointing to this will be created | `phpmyadmin.local` | +| `ingress.pathType` | Ingress path type | `ImplementationSpecific` | +| `ingress.path` | Default path for the ingress record | `/` | +| `ingress.extraPaths` | An array with additional arbitrary paths that may need to be added to the ingress under the main host | `[]` | +| `ingress.annotations` | Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. | `{}` | +| `ingress.tls` | Enable TLS configuration for the hostname defined at `ingress.hostname` parameter | `false` | +| `ingress.extraHosts` | The list of additional hostnames to be covered with this ingress record. | `[]` | +| `ingress.extraTls` | The tls configuration for additional hostnames to be covered with this ingress record. | `[]` | +| `ingress.secrets` | If you're providing your own certificates and want to manage the secret via helm, | `[]` | +| `ingress.existingSecretName` | If you're providing your own certificate and want to manage the secret yourself, | `""` | +| `ingress.ingressClassName` | IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) | `""` | +| `ingress.extraRules` | Additional rules to be covered with this ingress record | `[]` | + +### Database parameters + +| Name | Description | Value | +| -------------------------- | ----------------------------------------------------------------- | ------- | +| `db.allowArbitraryServer` | Enable connection to arbitrary MySQL server | `true` | +| `db.port` | Database port to use to connect | `3306` | +| `db.chartName` | Database suffix if included in the same release | `""` | +| `db.host` | Database Hostname. Ignored when `db.chartName` is set. | `""` | +| `db.bundleTestDB` | Deploy a MariaDB instance for testing purposes | `false` | +| `db.enableSsl` | Enable SSL for the connection between phpMyAdmin and the database | `false` | +| `db.ssl.clientKey` | Client key file when using SSL | `""` | +| `db.ssl.clientCertificate` | Client certificate file when using SSL | `""` | +| `db.ssl.caCertificate` | CA file when using SSL | `""` | +| `db.ssl.ciphers` | List of allowable ciphers for connections when using SSL | `[]` | +| `db.ssl.verify` | Enable SSL certificate validation | `true` | +| `mariadb` | MariaDB chart configuration | `{}` | + +### Other Parameters + +| Name | Description | Value | +| --------------------------------------------- | ---------------------------------------------------------------------- | ------- | +| `serviceAccount.create` | Enable creation of ServiceAccount for PhpMyAdmin pod | `true` | +| `serviceAccount.name` | The name of the ServiceAccount to use. | `""` | +| `serviceAccount.automountServiceAccountToken` | Allows auto mount of ServiceAccountToken on the serviceAccount created | `false` | +| `serviceAccount.annotations` | Additional custom annotations for the ServiceAccount | `{}` | + +### Metrics parameters + +| Name | Description | Value | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | +| `metrics.enabled` | Start a side-car prometheus exporter | `false` | +| `metrics.image.registry` | Apache exporter image registry | `REGISTRY_NAME` | +| `metrics.image.repository` | Apache exporter image repository | `REPOSITORY_NAME/apache-exporter` | +| `metrics.image.digest` | Apache exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `metrics.image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `metrics.resourcesPreset` | Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). | `nano` | +| `metrics.resources` | Set container requests and limits for different resources like CPU or memory (essential for production workloads) | `{}` | +| `metrics.service.type` | Prometheus metrics service type | `ClusterIP` | +| `metrics.service.port` | Prometheus metrics service port | `9117` | +| `metrics.service.annotations` | Annotations for Prometheus metrics service | `{}` | +| `metrics.service.clusterIP` | phpmyadmin service Cluster IP | `""` | +| `metrics.service.loadBalancerIP` | Load Balancer IP if the Prometheus metrics server type is `LoadBalancer` | `""` | +| `metrics.service.loadBalancerSourceRanges` | phpmyadmin service Load Balancer sources | `[]` | +| `metrics.service.externalTrafficPolicy` | phpmyadmin service external traffic policy | `Cluster` | +| `metrics.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `metrics.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `metrics.serviceMonitor.enabled` | Create ServiceMonitor Resource for scraping metrics using PrometheusOperator | `false` | +| `metrics.serviceMonitor.namespace` | Specify the namespace in which the serviceMonitor resource will be created | `""` | +| `metrics.serviceMonitor.jobLabel` | The name of the label on the target service to use as the job name in prometheus. | `""` | +| `metrics.serviceMonitor.interval` | Specify the interval at which metrics should be scraped | `30s` | +| `metrics.serviceMonitor.scrapeTimeout` | Specify the timeout after which the scrape is ended | `""` | +| `metrics.serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping | `[]` | +| `metrics.serviceMonitor.metricRelabelings` | Specify Metric Relabelings to add to the scrape endpoint | `[]` | +| `metrics.serviceMonitor.labels` | Extra labels for the ServiceMonitor | `{}` | +| `metrics.serviceMonitor.honorLabels` | Specify honorLabels parameter to add the scrape endpoint | `false` | +| `metrics.serviceMonitor.selector` | ServiceMonitor selector labels | `{}` | + +### NetworkPolicy parameters + +| Name | Description | Value | +| --------------------------------------- | --------------------------------------------------------------- | ------ | +| `networkPolicy.enabled` | Specifies whether a NetworkPolicy should be created | `true` | +| `networkPolicy.allowExternal` | Don't require server label for connections | `true` | +| `networkPolicy.allowExternalEgress` | Allow the pod to access any range of port and all destinations. | `true` | +| `networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | + +For more information please refer to the [bitnami/phpmyadmin](https://github.com/bitnami/containers/tree/main/bitnami/phpmyadmin) image documentation. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set db.host=mymariadb,db.port=3306 oci://REGISTRY_NAME/REPOSITORY_NAME/phpmyadmin +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +The above command sets the phpMyAdmin to connect to a database in `mymariadb` host and `3306` port respectively. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://REGISTRY_NAME/REPOSITORY_NAME/phpmyadmin +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. +> **Tip**: You can use the default [values.yaml](https://github.com/bitnami/charts/tree/main/bitnami/phpmyadmin/values.yaml) + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### To 17.0.0 + +This major release bumps the MariaDB version to 11.4. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-11-3-to-mariadb-11-4/) for upgrading from MariaDB 11.3 to 11.4. No major issues are expected during the upgrade. + +### To 16.0.0 + +This major bump changes the following security defaults: + +- `runAsGroup` is changed from `0` to `1001` +- `readOnlyRootFilesystem` is set to `true` +- `resourcesPreset` is changed from `none` to the minimum size working in our test suites (NOTE: `resourcesPreset` is not meant for production usage, but `resources` adapted to your use case). +- `global.compatibility.openshift.adaptSecurityContext` is changed from `disabled` to `auto`. +- The `networkPolicy` section has been normalized amongst all Bitnami charts. Compared to the previous approach, the values section has been simplified (check the Parameters section) and now it set to `enabled=true` by default. Egress traffic is allowed by default and ingress traffic is allowed by all pods but only to the ports set in `containerPorts` and `extraContainerPorts`. + +This could potentially break any customization or init scripts used in your deployment. If this is the case, change the default values to the previous ones. + +### To 15.0.0 + +This major release bumps the MariaDB chart version to [18.x.x](https://github.com/bitnami/charts/pull/24804); no major issues are expected during the upgrade. + +### To 14.0.0 + +This major release bumps the MariaDB version to 11.2. No major issues are expected during the upgrade. + +### To 13.0.0 + +This major release bumps the MariaDB version to 11.1. No major issues are expected during the upgrade. + +### To 12.0.0 + +This major release bumps the MariaDB version to 11.0. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-10-11-to-mariadb-11-0/) for upgrading from MariaDB 10.11 to 11.0. No major issues are expected during the upgrade. + +### To 11.0.0 + +This major release bumps the MariaDB version to 10.11. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-10-6-to-mariadb-10-11/) for upgrading from MariaDB 10.6 to 10.11. No major issues are expected during the upgrade. + +### To 10.0.0 + +This major release bumps the MariaDB version to 10.6. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-105-to-mariadb-106/) for upgrading from MariaDB 10.5 to 10.6. No major issues are expected during the upgrade. + +### To 9.0.0 + +This major release renames several values in this chart and adds missing features, in order to be inline with the rest of assets in the Bitnami charts repository. + +Affected values: + +- `service.port` was deprecated. We recommend using `service.ports.http` instead. +- `service.httpsPort` was deprecated. We recommend using `service.ports.https` instead. +- `metrics.serviceMonitor.additionalLabels` renamed as `metrics.serviceMonitor.labels` + +Additionally updates the MariaDB subchart to it newest major, 10.0.0, which contains similar changes. Check [MariaDB Upgrading Notes](https://github.com/bitnami/charts/tree/main/bitnami/mariadb#to-1000) for more information. + +### To 8.0.0 + +- Chart labels were adapted to follow the [Helm charts standard labels](https://helm.sh/docs/chart_best_practices/labels/#standard-labels). + +Consequences: + +- Backwards compatibility is not guaranteed. However, you can easily workaround this issue by removing PhpMyAdmin deployment before upgrading (the following example assumes that the release name is `phpmyadmin`): + +```console +export MARIADB_ROOT_PASSWORD=$(kubectl get secret --namespace default phpmyadmin-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 -d) +export MARIADB_PASSWORD=$(kubectl get secret --namespace default phpmyadmin-mariadb -o jsonpath="{.data.mariadb-password}" | base64 -d) +kubectl delete deployments.apps phpmyadmin +helm upgrade phpmyadmin oci://REGISTRY_NAME/REPOSITORY_NAME/phpmyadmin --set mariadb.auth.rootPassword=$MARIADB_ROOT_PASSWORD,mariadb.auth.password=$MARIADB_PASSWORD +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +### To 7.0.0 + +In this major there were two main changes introduced: + +1. Adaptation to Helm v2 EOL +2. Updated MariaDB dependency version + +Please read the update notes carefully. + +#### 1. Adaptation to Helm v2 EOL + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +##### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Move dependency information from the *requirements.yaml* to the *Chart.yaml* +- After running `helm dependency update`, a *Chart.lock* file is generated containing the same structure used in the previous *requirements.lock* +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +##### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +##### Useful links + +- +- +- + +#### 2. Updated MariaDB dependency version + +In this major the MariaDB dependency version was also bumped to a new major version that introduces several incompatilibites. Therefore, backwards compatibility is not guaranteed unless an external database is used. Check [MariaDB Upgrading Notes](https://github.com/bitnami/charts/tree/main/bitnami/mariadb#to-800) for more information. + +To upgrade to `7.0.0`, it should be done reusing the PVCs used to hold both the MariaDB and phpMyAdmin data on your previous release. To do so, follow the instructions below (the following example assumes that the release name is `phpmyadmin` and that `db.bundleTestDB=true` when the chart was first installed): + +> NOTE: Please, create a backup of your database before running any of those actions. The steps below would be only valid if your application (e.g. any plugins or custom code) is compatible with MariaDB 10.5.x + +Obtain the credentials and the names of the PVCs used to hold both the MariaDB and phpMyAdmin data on your current release: + +```console +export MARIADB_ROOT_PASSWORD=$(kubectl get secret --namespace default phpmyadmin-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 -d) +export MARIADB_PASSWORD=$(kubectl get secret --namespace default phpmyadmin-mariadb -o jsonpath="{.data.mariadb-password}" | base64 -d) +export MARIADB_PVC=$(kubectl get pvc -l app=mariadb,component=master,release=phpmyadmin -o jsonpath="{.items[0].metadata.name}") +``` + +Delete the phpMyAdmin deployment and delete the MariaDB statefulsets: + +```console + kubectl delete deployments.apps phpmyadmin + + kubectl delete statefulsets.apps phpmyadmin-mariadb-master + + kubectl delete statefulsets.apps phpmyadmin-mariadb-slave + +``` + +Now the upgrade works: + +```console +helm upgrade phpmyadmin oci://REGISTRY_NAME/REPOSITORY_NAME/phpmyadmin --set mariadb.primary.persistence.existingClaim=$MARIADB_PVC --set mariadb.auth.rootPassword=$MARIADB_ROOT_PASSWORD --set mariadb.auth.password=$MARIADB_PASSWORD --set db.bundleTestDB=true +``` + +> Note: You need to substitute the placeholders `REGISTRY_NAME` and `REPOSITORY_NAME` with a reference to your Helm chart registry and repository. For example, in the case of Bitnami, you need to use `REGISTRY_NAME=registry-1.docker.io` and `REPOSITORY_NAME=bitnamicharts`. + +Finally, you should see the lines below in MariaDB container logs: + +```console +$ kubectl logs $(kubectl get pods -l app.kubernetes.io/instance=phpmyadmin,app.kubernetes.io/name=mariadb,app.kubernetes.io/component=primary -o jsonpath="{.items[0].metadata.name}") +... +mariadb 12:13:24.98 INFO ==> Using persisted data +mariadb 12:13:25.01 INFO ==> Running mysql_upgrade +... +``` + +### To 6.0.0 + +The [Bitnami phpMyAdmin](https://github.com/bitnami/containers/tree/main/bitnami/phpmyadmin) image was migrated to a "non-root" user approach. Previously the container ran as the `root` user and the Apache daemon was started as the `daemon` user. From now on, both the container and the Apache daemon run as user `1001`. You can revert this behavior by setting the parameters `containerSecurityContext.runAsUser` to `root`. +Chart labels and Ingress configuration were also adapted to follow the Helm charts best practices. + +Consequences: + +- The HTTP/HTTPS ports exposed by the container are now `8080/8443` instead of `80/443`. +- No writing permissions will be granted on `config.inc.php` by default. +- Backwards compatibility is not guaranteed. + +To upgrade to `6.0.0`, backup your previous MariaDB databases, install a new phpMyAdmin chart and import the MariaDB backups. + +This version also introduces `bitnami/common`, a [library chart](https://helm.sh/docs/topics/library_charts/#helm) as a dependency. More documentation about this new utility could be found [here](https://github.com/bitnami/charts/tree/main/bitnami/common#bitnami-common-library-chart). Please, make sure that you have updated the chart dependencies before executing any upgrade. + +### To 1.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to `1.0.0`. The following example assumes that the release name is `phpmyadmin`: + +```console +kubectl patch deployment phpmyadmin-phpmyadmin --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' +``` + +## License + +Copyright © 2024 Broadcom. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/charts/phpmyadmin/phpmyadmin/templates/NOTES.txt b/charts/phpmyadmin/phpmyadmin/templates/NOTES.txt new file mode 100644 index 0000000..5a42dd9 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/NOTES.txt @@ -0,0 +1,69 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +1. Get the application URL by running these commands: + +{{- if .Values.ingress.enabled }} + + You should be able to access your new phpMyAdmin installation through + + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .Values.ingress.hostname }}/ + +{{- else if eq .Values.service.type "LoadBalancer" }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ include "common.names.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + {{- $port:=( coalesce .Values.service.ports.http .Values.service.port) | toString }} + echo "phpMyAdmin URL: http://$SERVICE_IP{{- if ne $port "80" }}:{{coalesce .Values.service.ports.http .Values.service.port }}{{ end }}/" + +{{- else if contains "NodePort" .Values.service.type }} + + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "common.names.fullname" . }}' + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo "phpMyAdmin URL: http://$NODE_IP:$NODE_PORT" + +{{- else if contains "ClusterIP" .Values.service.type }} + + echo "phpMyAdmin URL: http://127.0.0.1:{{coalesce .Values.service.ports.http .Values.service.port }}" + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "common.names.fullname" . }} {{coalesce .Values.service.ports.http .Values.service.port }}:{{coalesce .Values.service.ports.http .Values.service.port }} + +{{- end }} + +2. How to log in +{{- if or (.Values.db.chartName) (.Values.db.host) }} + +phpMyAdmin has been configured to connect to a database in {{ if .Values.db.chartName }}{{ template "phpmyadmin.dbfullname" . }}{{ else }}{{ .Values.db.host }}{{ end }} +{{- if .Values.db.port }}with port {{ .Values.db.port }} {{ end }} +Please login using a database username and password. +{{- else if .Values.db.bundleTestDB }} +For testing purposes, phpMyAdmin has been configured to point to a test MariaDB +instance. Please login using the following credentials: + + Username: root + Password : $(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "phpmyadmin.mariadb.fullname" . }} -o jsonpath="{.data.mariadb-root-password}" | base64 -d) + +{{- else }} +phpMyAdmin has not been configure to point to a specific database. Please provide the db host, +username and password at log in or upgrade the release with a specific database: + +$ helm upgrade {{ .Release.Name }} oci://registry-1.docker.io/bitnamicharts/phpmyadmin --set db.host=mydb + +{{- end }} + +{{- include "phpmyadmin.validateValues" . -}} +{{- include "phpmyadmin.checkRollingTags" . -}} + +{{- $passwordValidationErrors := list -}} +{{- if .Values.mariadb.enabled }} + {{- $mariadbSecretName := include "magento.databaseSecretName" . -}} + {{- $mariadbPasswordValidationErrors := include "common.validations.values.mariadb.passwords" (dict "secret" $mariadbSecretName "subchart" true "context" $) -}} + {{- $passwordValidationErrors = append $passwordValidationErrors $mariadbPasswordValidationErrors -}} +{{- end }} +{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $) -}} +{{- include "common.warnings.resources" (dict "sections" (list "metrics" "") "context" $) }} +{{- include "common.warnings.modifiedImages" (dict "images" (list .Values.image .Values.metrics.image) "context" $) }} \ No newline at end of file diff --git a/charts/phpmyadmin/phpmyadmin/templates/_helpers.tpl b/charts/phpmyadmin/phpmyadmin/templates/_helpers.tpl new file mode 100644 index 0000000..064a7bc --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/_helpers.tpl @@ -0,0 +1,86 @@ +{{/* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the proper PHPMyAdmin image name +*/}} +{{- define "phpmyadmin.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name (for the metrics image) +*/}} +{{- define "phpmyadmin.metrics.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.metrics.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "phpmyadmin.imagePullSecrets" -}} +{{- include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.metrics.image) "global" .Values.global) -}} +{{- end -}} + +{{/* + Create the name of the service account to use + */}} +{{- define "phpmyadmin.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "phpmyadmin.mariadb.fullname" -}} +{{- printf "%s-%s" .Release.Name "mariadb" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fully qualified database name if the database is part of the same release than phpmyadmin. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "phpmyadmin.dbfullname" -}} +{{- printf "%s-%s" .Release.Name .Values.db.chartName | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "phpmyadmin.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "phpmyadmin.validateValues.db.ssl" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* Validate values of phpMyAdmin - must provide a valid database ssl configuration */}} +{{- define "phpmyadmin.validateValues.db.ssl" -}} +{{- if and .Values.db.enableSsl (empty .Values.db.ssl.clientKey) (empty .Values.db.ssl.clientCertificate) (empty .Values.db.ssl.caCertificate) -}} +phpMyAdmin: db.ssl + Invalid database ssl configuration. You enabled SSL for the connection + between phpMyAdmin and the database but no key/certificates were provided + (--set db.ssl.clientKey="xxxx", --set db.ssl.clientCertificate="yyyy") +{{- end -}} +{{- end -}} + +{{/* +Check if there are rolling tags in the images +*/}} +{{- define "phpmyadmin.checkRollingTags" -}} +{{- include "common.warnings.rollingTag" .Values.image }} +{{- include "common.warnings.rollingTag" .Values.metrics.image }} +{{- end -}} diff --git a/charts/phpmyadmin/phpmyadmin/templates/certs.yaml b/charts/phpmyadmin/phpmyadmin/templates/certs.yaml new file mode 100644 index 0000000..6fb29a5 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/certs.yaml @@ -0,0 +1,27 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.db.enableSsl }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-certs" (include "common.names.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if not (empty .Values.db.ssl.clientKey) }} + server_key.pem: {{ .Values.db.ssl.clientKey | b64enc | quote }} + {{- end }} + {{- if not (empty .Values.db.ssl.clientCertificate) }} + server_certificate.pem: {{ .Values.db.ssl.clientCertificate | b64enc | quote }} + {{- end }} + {{- if not (empty .Values.db.ssl.caCertificate) }} + ca_certificate.pem: {{ .Values.db.ssl.caCertificate | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/deployment.yaml b/charts/phpmyadmin/phpmyadmin/templates/deployment.yaml new file mode 100644 index 0000000..ba88865 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/deployment.yaml @@ -0,0 +1,306 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + replicas: {{ .Values.replicas }} + strategy: {{- include "common.tplvalues.render" (dict "value" .Values.updateStrategy "context" $ ) | nindent 4 }} + template: + metadata: + labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }} + {{- if or .Values.podAnnotations (and .Values.metrics.enabled .Values.metrics.podAnnotations) }} + annotations: + {{- if .Values.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- end }} + spec: + {{- include "phpmyadmin.imagePullSecrets" . | nindent 6 }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- if .Values.hostAliases }} + # yamllint disable rule:indentation + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + # yamllint enable rule:indentation + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "customLabels" $podLabels "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.podSecurityContext "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ template "phpmyadmin.serviceAccountName" . }} + {{- end }} + initContainers: + - name: prepare-base-dir + image: {{ include "phpmyadmin.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + command: + - /bin/bash + args: + - -ec + - | + #!/bin/bash + + . /opt/bitnami/scripts/liblog.sh + . /opt/bitnami/scripts/libfs.sh + + info "Copying base dir to empty dir" + # In order to not break the application functionality (such as upgrades or plugins) we need + # to make the base directory writable, so we need to copy it to an empty dir volume + cp -r --preserve=mode /opt/bitnami/phpmyadmin /emptydir/app-base-dir + + info "Copying symlinks to stdout/stderr" + # We copy the logs folder because it has symlinks to stdout and stderr + if ! is_dir_empty /opt/bitnami/apache/logs; then + cp -r /opt/bitnami/apache/logs /emptydir/apache-logs-dir + fi + info "Copying php var directory" + # PhpMyAdmin will fail to start if the php var folder is not populated + if ! is_dir_empty /opt/bitnami/php/var; then + cp -r /opt/bitnami/php/var /emptydir/php-var-dir + fi + info "Copy operation completed" + volumeMounts: + - name: empty-dir + mountPath: /emptydir + {{- if .Values.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: {{ template "phpmyadmin.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" .Values.image.debug | quote }} + - name: DATABASE_PORT_NUMBER + value: {{ .Values.db.port | quote }} + {{- if .Values.db.chartName }} + - name: DATABASE_HOST + value: {{ (include "phpmyadmin.dbfullname" .) | quote }} + {{- else if .Values.db.bundleTestDB }} + - name: DATABASE_HOST + value: {{ (include "phpmyadmin.mariadb.fullname" .) | quote }} + {{- else }} + - name: DATABASE_HOST + value: {{ .Values.db.host | quote }} + {{- end }} + {{- if and (not .Values.db.chartName) (not .Values.db.host) }} + - name: PHPMYADMIN_ALLOW_NO_PASSWORD + value: "true" + - name: PHPMYADMIN_ALLOW_ARBITRARY_SERVER + value: {{ .Values.db.allowArbitraryServer | quote }} + {{- else }} + - name: PHPMYADMIN_ALLOW_NO_PASSWORD + value: "false" + {{- end }} + - name: DATABASE_ENABLE_SSL + value: {{ ternary "yes" "no" .Values.db.enableSsl | quote }} + {{- if .Values.db.enableSsl }} + {{- if not (empty .Values.db.ssl.clientKey) }} + - name: DATABASE_SSL_KEY + value: "/db_certs/server_key.pem" + {{- end }} + {{- if not (empty .Values.db.ssl.clientCertificate) }} + - name: DATABASE_SSL_CERT + value: "/db_certs/server_certificate.pem" + {{- end }} + {{- if not (empty .Values.db.ssl.caCertificate) }} + - name: DATABASE_SSL_CA + value: "/db_certs/ca_certificate.pem" + {{- end }} + {{- if .Values.db.ssl.ciphers }} + - name: DATABASE_SSL_CIPHERS + values: {{ .Values.db.ssl.ciphers | quote }} + {{- end }} + - name: DATABASE_SSL_VERIFY + value: {{ ternary "yes" "no" .Values.db.ssl.verify | quote }} + {{- end }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if or .Values.extraEnvVarsCM .Values.extraEnvVarsSecret }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.containerPorts.http }} + protocol: TCP + - name: https + containerPort: {{ .Values.containerPorts.https }} + protocol: TCP + {{- if .Values.extraContainerPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraContainerPorts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.startupProbe "enabled") "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.livenessProbe "enabled") "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.readinessProbe "enabled") "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- else if ne .Values.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: empty-dir + mountPath: /opt/bitnami/apache/conf + subPath: apache-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/apache/logs + subPath: apache-logs-dir + - name: empty-dir + mountPath: /opt/bitnami/apache/var/run + subPath: apache-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/php/etc + subPath: php-conf-dir + - name: empty-dir + mountPath: /opt/bitnami/php/tmp + subPath: php-tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/php/var + subPath: php-var-dir + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + - name: empty-dir + mountPath: /opt/bitnami/phpmyadmin + subPath: app-base-dir + {{- if .Values.db.enableSsl }} + - name: ssl-certs + mountPath: /db_certs + {{- end }} + {{- if .Values.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ template "phpmyadmin.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + command: ['/bin/apache_exporter', '--scrape_uri', 'http://status.localhost:8080/server-status/?auto'] + ports: + - name: metrics + containerPort: 9117 + livenessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 15 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 5 + timeoutSeconds: 1 + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- else if ne .Values.metrics.resourcesPreset "none" }} + resources: {{- include "common.resources.preset" (dict "type" .Values.metrics.resourcesPreset) | nindent 12 }} + {{- end }} + volumeMounts: + - name: empty-dir + mountPath: /tmp + subPath: tmp-dir + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: empty-dir + emptyDir: {} + {{- if .Values.db.enableSsl }} + - name: ssl-certs + secret: + secretName: {{ printf "%s-certs" (include "common.names.fullname" .) }} + items: + {{- if not (empty .Values.db.ssl.clientKey) }} + - key: server_key.pem + path: server_key.pem + {{- end }} + {{- if not (empty .Values.db.ssl.clientCertificate) }} + - key: server_certificate.pem + path: server_certificate.pem + {{- end }} + {{- if not (empty .Values.db.ssl.caCertificate) }} + - key: ca_certificate.pem + path: ca_certificate.pem + {{- end }} + {{- end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/extra-list.yaml b/charts/phpmyadmin/phpmyadmin/templates/extra-list.yaml new file mode 100644 index 0000000..329f5c6 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/ingress.yaml b/charts/phpmyadmin/phpmyadmin/templates/ingress.yaml new file mode 100644 index 0000000..278b7e9 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/ingress.yaml @@ -0,0 +1,65 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.ingress.enabled }} +apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.ingress.annotations .Values.commonAnnotations .Values.ingress.certManager }} + annotations: + {{- if .Values.ingress.certManager }} + kubernetes.io/tls-acme: "true" + {{- end }} + {{- if or .Values.ingress.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.ingress.annotations .Values.commonAnnotations ) "context" . ) }} + {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if and .Values.ingress.ingressClassName (eq "true" (include "common.ingress.supportsIngressClassname" .)) }} + ingressClassName: {{ .Values.ingress.ingressClassName | quote }} + {{- end }} + rules: + {{- if .Values.ingress.hostname }} + - host: {{ .Values.ingress.hostname }} + http: + paths: + {{- if .Values.ingress.extraPaths }} + {{- toYaml .Values.ingress.extraPaths | nindent 10 }} + {{- end }} + - path: {{ .Values.ingress.path }} + {{- if eq "true" (include "common.ingress.supportsPathType" .) }} + pathType: {{ .Values.ingress.pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" .) "servicePort" "http" "context" $) | nindent 14 }} + {{- end }} + {{- range .Values.ingress.extraHosts }} + - host: {{ .name | quote }} + http: + paths: + - path: {{ default "/" .path }} + {{- if eq "true" (include "common.ingress.supportsPathType" $) }} + pathType: {{ default "ImplementationSpecific" .pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" "http" "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.ingress.extraRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraRules "context" $) | nindent 4 }} + {{- end }} + {{- if or .Values.ingress.tls .Values.ingress.extraTls }} + tls: + {{- if .Values.ingress.tls }} + - hosts: + - {{ .Values.ingress.hostname }} + secretName: {{ .Values.ingress.existingSecretName | default (printf "%s-tls" .Values.ingress.hostname) }} + {{- end }} + {{- if .Values.ingress.extraTls }} + {{- include "common.tplvalues.render" ( dict "value" .Values.ingress.extraTls "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/metrics-svc.yaml b/charts/phpmyadmin/phpmyadmin/templates/metrics-svc.yaml new file mode 100644 index 0000000..dbd012c --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/metrics-svc.yaml @@ -0,0 +1,45 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-metrics" (include "common.names.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if or .Values.metrics.service.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.metrics.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.metrics.service.type }} + {{- if and .Values.metrics.service.clusterIP (eq .Values.metrics.service.type "ClusterIP") }} + clusterIP: {{ .Values.metrics.service.clusterIP }} + {{- end }} + {{- if (or (eq .Values.metrics.service.type "LoadBalancer") (eq .Values.metrics.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.metrics.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if eq .Values.metrics.service.type "LoadBalancer" }} + loadBalancerSourceRanges: {{ .Values.metrics.service.loadBalancerSourceRanges }} + {{- end }} + {{- if (and (eq .Values.metrics.service.type "LoadBalancer") (not (empty .Values.metrics.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} + {{- end }} + {{- if .Values.metrics.service.sessionAffinity }} + sessionAffinity: {{ .Values.metrics.service.sessionAffinity }} + {{- end }} + {{- if .Values.metrics.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.metrics.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - port: {{ .Values.metrics.service.port }} + targetPort: metrics + protocol: TCP + name: metrics + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/networkpolicy.yaml b/charts/phpmyadmin/phpmyadmin/templates/networkpolicy.yaml new file mode 100644 index 0000000..cc38767 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/networkpolicy.yaml @@ -0,0 +1,80 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} + policyTypes: + - Ingress + - Egress + {{- if .Values.networkPolicy.allowExternalEgress }} + egress: + - {} + {{- else }} + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # Allow outbound connections to MariaDB + - ports: + - port: {{ .Values.db.port }} + {{- if .Values.db.bundleTestDB }} + to: + - podSelector: + matchLabels: + app.kubernetes.io/name: mariadb + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + {{- if .Values.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} + ingress: + - ports: + - port: {{ .Values.containerPorts.http }} + - port: {{ .Values.containerPorts.https }} + {{- range .Values.extraContainerPorts }} + - port: {{ . }} + {{- end }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 14 }} + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/pdb.yaml b/charts/phpmyadmin/phpmyadmin/templates/pdb.yaml new file mode 100644 index 0000000..b17ff44 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/pdb.yaml @@ -0,0 +1,26 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.pdb.minAvailable }} + minAvailable: {{ .Values.pdb.minAvailable }} + {{- end }} + {{- if or .Values.pdb.maxUnavailable ( not .Values.pdb.minAvailable ) }} + maxUnavailable: {{ .Values.pdb.maxUnavailable | default 1 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/service.yaml b/charts/phpmyadmin/phpmyadmin/templates/service.yaml new file mode 100644 index 0000000..a447a80 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/service.yaml @@ -0,0 +1,59 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.service.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.service.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + {{- if (and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if .Values.service.sessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} + {{- if .Values.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: http + port: {{ coalesce .Values.service.ports.http .Values.service.port }} + protocol: TCP + targetPort: http + {{- if (and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.http))) }} + nodePort: {{ .Values.service.nodePorts.http }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + - name: https + port: {{ coalesce .Values.service.ports.https .Values.service.httpsPort }} + protocol: TCP + targetPort: https + {{- if (and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.https))) }} + nodePort: {{ .Values.service.nodePorts.https }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.podLabels .Values.commonLabels ) "context" . ) }} + selector: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 4 }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/serviceaccount.yaml b/charts/phpmyadmin/phpmyadmin/templates/serviceaccount.yaml new file mode 100644 index 0000000..65ee3fc --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "phpmyadmin.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }} + {{- $annotations := include "common.tplvalues.merge" ( dict "values" ( list .Values.serviceAccount.annotations .Values.commonAnnotations ) "context" . ) }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $annotations "context" $) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/servicemonitor.yaml b/charts/phpmyadmin/phpmyadmin/templates/servicemonitor.yaml new file mode 100644 index 0000000..f287d34 --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/servicemonitor.yaml @@ -0,0 +1,46 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.serviceMonitor.namespace }} + {{- $labels := include "common.tplvalues.merge" ( dict "values" ( list .Values.metrics.serviceMonitor.labels .Values.commonLabels ) "context" . ) }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $labels "context" $ ) | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.metrics.serviceMonitor.jobLabel | quote }} + endpoints: + - port: metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + selector: + matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 6 }} + app.kubernetes.io/component: metrics + {{- if .Values.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/templates/tls-secrets.yaml b/charts/phpmyadmin/phpmyadmin/templates/tls-secrets.yaml new file mode 100644 index 0000000..bb0a81e --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/templates/tls-secrets.yaml @@ -0,0 +1,43 @@ +{{- /* +Copyright Broadcom, Inc. All Rights Reserved. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.ingress.enabled (not .Values.ingress.existingSecretName) }} +{{- if .Values.ingress.secrets }} +{{- range .Values.ingress.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + namespace: {{ $.Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" $.Values.commonLabels "context" $ ) | nindent 4 }} + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate | b64enc }} + tls.key: {{ .key | b64enc }} +--- +{{- end }} +{{- else if and .Values.ingress.tls (and (not (hasKey .Values.ingress.annotations "cert-manager.io/cluster-issuer")) (not .Values.ingress.certManager)) }} +{{- $secretName := printf "%s-tls" .Values.ingress.hostname }} +{{- $ca := genCA "phpmyadmin-ca" 365 }} +{{- $cert := genSignedCert .Values.ingress.hostname nil (list .Values.ingress.hostname) 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.crt" "defaultValue" $cert.Cert "context" $) }} + tls.key: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.key" "defaultValue" $cert.Key "context" $) }} + ca.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" $ca.Cert "context" $) }} +{{- end }} +{{- end }} diff --git a/charts/phpmyadmin/phpmyadmin/values.yaml b/charts/phpmyadmin/phpmyadmin/values.yaml new file mode 100644 index 0000000..883192e --- /dev/null +++ b/charts/phpmyadmin/phpmyadmin/values.yaml @@ -0,0 +1,803 @@ +# Copyright Broadcom, Inc. All Rights Reserved. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.defaultStorageClass Global default StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + defaultStorageClass: "" + ## Compatibility adaptations for Kubernetes platforms + ## + compatibility: + ## Compatibility adaptations for Openshift + ## + openshift: + ## @param global.compatibility.openshift.adaptSecurityContext Adapt the securityContext sections of the deployment to make them compatible with Openshift restricted-v2 SCC: remove runAsUser, runAsGroup and fsGroup and let the platform use their allowed default IDs. Possible values: auto (apply if the detected running cluster is Openshift), force (perform the adaptation always), disabled (do not perform adaptation) + ## + adaptSecurityContext: disabled +## @section Common parameters + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override common.names.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: "" +## @param commonLabels Add labels to all the deployed resources +## +commonLabels: {} +## @param commonAnnotations Add annotations to all the deployed resources +## +commonAnnotations: {} +## @param clusterDomain Kubernetes Cluster Domain +## +clusterDomain: cluster.local +## @param extraDeploy Array of extra objects to deploy with the release +## +extraDeploy: [] +## @section phpMyAdmin parameters + +## Bitnami PhpMyAdmin image version +## ref: https://hub.docker.com/r/bitnami/phpmyadmin/tags/ +## @param image.registry [default: REGISTRY_NAME] phpMyAdmin image registry +## @param image.repository [default: REPOSITORY_NAME/phpmyadmin] phpMyAdmin image repository +## @skip image.tag phpMyAdmin image tag (immutable tags are recommended) +## @param image.digest phpMyAdmin image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param image.pullPolicy Image pull policy +## @param image.pullSecrets Specify docker-registry secret names as an array +## @param image.debug Enable phpmyadmin image debug mode +## +image: + registry: docker.io + repository: bitnami/phpmyadmin + tag: 5.2.1-debian-12-r42 + digest: "" + ## Specify a imagePullPolicy + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Enable debug mode + ## + debug: false +## @param command Override default container command (useful when using custom images) +## +command: [] +## @param args Override default container args (useful when using custom images) +## +args: [] +## @param lifecycleHooks for the phpmyadmin container(s) to automate configuration before or after startup +## +lifecycleHooks: {} +## @param extraEnvVars Extra environment variables to be set on PhpMyAdmin container +## For example: +## extraEnvVars: +## - name: PHP_UPLOAD_MAX_FILESIZE +## value: "80M" +## +extraEnvVars: [] +## @param extraEnvVarsCM Name of a existing ConfigMap containing extra env vars +## +extraEnvVarsCM: "" +## @param extraEnvVarsSecret Name of a existing Secret containing extra env vars +## +extraEnvVarsSecret: "" +## @section phpMyAdmin deployment parameters + +## @param automountServiceAccountToken Mount Service Account token in pod +## +automountServiceAccountToken: false +## @param hostAliases [array] Deployment pod host aliases +## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +## +hostAliases: + ## Necessary for apache-exporter to work + ## + - ip: "127.0.0.1" + hostnames: + - "status.localhost" +## phpMyAdmin container ports to open +## @param containerPorts.http HTTP port to expose at container level +## @param containerPorts.https HTTPS port to expose at container level +## +containerPorts: + http: 8080 + https: 8443 +## @param extraContainerPorts Optionally specify extra list of additional ports for phpMyAdmin container(s) +## e.g: +## extraContainerPorts: +## - name: myservice +## containerPort: 9090 +## +extraContainerPorts: [] +## @param updateStrategy.type Strategy to use to update Pods +## +updateStrategy: + ## StrategyType + ## Can be set to RollingUpdate or OnDelete + ## + type: RollingUpdate +## phpMyAdmin pods' Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +## @param podSecurityContext.enabled Enable phpMyAdmin pods' Security Context +## @param podSecurityContext.fsGroupChangePolicy Set filesystem group change policy +## @param podSecurityContext.sysctls Set kernel settings using the sysctl interface +## @param podSecurityContext.supplementalGroups Set filesystem extra groups +## @param podSecurityContext.fsGroup User ID for the container +## +podSecurityContext: + enabled: true + fsGroupChangePolicy: Always + sysctls: [] + supplementalGroups: [] + fsGroup: 1001 +## phpMyAdmin containers' Security Context (only main container) +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +## @param containerSecurityContext.enabled Enabled containers' Security Context +## @param containerSecurityContext.seLinuxOptions [object,nullable] Set SELinux options in container +## @param containerSecurityContext.runAsUser Set containers' Security Context runAsUser +## @param containerSecurityContext.runAsGroup Set containers' Security Context runAsGroup +## @param containerSecurityContext.runAsNonRoot Set container's Security Context runAsNonRoot +## @param containerSecurityContext.privileged Set container's Security Context privileged +## @param containerSecurityContext.readOnlyRootFilesystem Set container's Security Context readOnlyRootFilesystem +## @param containerSecurityContext.allowPrivilegeEscalation Set container's Security Context allowPrivilegeEscalation +## @param containerSecurityContext.capabilities.drop List of capabilities to be dropped +## @param containerSecurityContext.seccompProfile.type Set container's Security Context seccomp profile +## +containerSecurityContext: + enabled: true + seLinuxOptions: null + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + privileged: false + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + seccompProfile: + type: "RuntimeDefault" +## phpMyAdmin number of pod replicas +## @param replicas Number of replicas +replicas: 1 +## phpMyAdmin containers' resource requests and limits +## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +## We usually recommend not to specify default resources and to leave this as a conscious +## choice for the user. This also increases chances charts run on environments with little +## resources, such as Minikube. If you do want to specify resources, uncomment the following +## lines, adjust them as necessary, and remove the curly braces after 'resources:'. +## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production). +## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 +## +resourcesPreset: "micro" +## @param resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) +## Example: +## resources: +## requests: +## cpu: 2 +## memory: 512Mi +## limits: +## cpu: 3 +## memory: 1024Mi +## +resources: {} +## phpMyAdmin containers' startup probe. Evaluated as a template. +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes +## @param startupProbe.enabled Enable startupProbe +## @param startupProbe.httpGet.path Request path for startupProbe +## @param startupProbe.httpGet.port Port for startupProbe +## @param startupProbe.initialDelaySeconds Initial delay seconds for startupProbe +## @param startupProbe.periodSeconds Period seconds for startupProbe +## @param startupProbe.timeoutSeconds Timeout seconds for startupProbe +## @param startupProbe.failureThreshold Failure threshold for startupProbe +## @param startupProbe.successThreshold Success threshold for startupProbe +## +startupProbe: + enabled: false + initialDelaySeconds: 30 + timeoutSeconds: 30 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + httpGet: + path: / + port: http +## phpMyAdmin containers' liveness probe. Evaluated as a template. +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes +## @param livenessProbe.enabled Enable livenessProbe +## @param livenessProbe.tcpSocket.port Port for livenessProbe +## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe +## @param livenessProbe.periodSeconds Period seconds for livenessProbe +## @param livenessProbe.timeoutSeconds Timeout seconds for livenessProbe +## @param livenessProbe.failureThreshold Failure threshold for livenessProbe +## @param livenessProbe.successThreshold Success threshold for livenessProbe +## +livenessProbe: + enabled: true + initialDelaySeconds: 30 + timeoutSeconds: 30 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + tcpSocket: + port: http +## phpMyAdmin containers' readiness probes. Evaluated as a template. +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes +## @param readinessProbe.enabled Enable readinessProbe +## @param readinessProbe.httpGet.path Request path for readinessProbe +## @param readinessProbe.httpGet.port Port for readinessProbe +## @param readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds Timeout seconds for readinessProbe +## @param readinessProbe.failureThreshold Failure threshold for readinessProbe +## @param readinessProbe.successThreshold Success threshold for readinessProbe +## +readinessProbe: + enabled: true + initialDelaySeconds: 30 + timeoutSeconds: 30 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + httpGet: + path: / + port: http +## @param customStartupProbe Override default startup probe +## +customStartupProbe: {} +## @param customLivenessProbe Override default liveness probe +## +customLivenessProbe: {} +## @param customReadinessProbe Override default readiness probe +## +customReadinessProbe: {} +## @param podLabels Extra labels for PhpMyAdmin pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @param podAnnotations Annotations for PhpMyAdmin pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAffinityPreset: "" +## @param podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAntiAffinityPreset: soft +## Node affinity preset +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +## +nodeAffinityPreset: + ## @param nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param nodeAffinityPreset.key Node label key to match. Ignored if `affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param nodeAffinityPreset.values Node label values to match. Ignored if `affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] +## @param affinity Affinity for pod assignment. Evaluated as a template. +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector Node labels for pod assignment. Evaluated as a template. +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ +## +nodeSelector: {} +## @param tolerations Tolerations for pod assignment. Evaluated as a template. +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +## @param priorityClassName phpmyadmin pods' priorityClassName +## +priorityClassName: "" +## @param schedulerName Name of the k8s scheduler (other than default) +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param topologySpreadConstraints Topology Spread Constraints for pod assignment +## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## The value is evaluated as a template +## +topologySpreadConstraints: [] +## @param extraVolumes Optionally specify extra list of additional volumes for PhpMyAdmin pods +## +extraVolumes: [] +## @param extraVolumeMounts Optionally specify extra list of additional volumeMounts for PhpMyAdmin container(s) +## +extraVolumeMounts: [] +## @param initContainers Add init containers to the PhpMyAdmin pods +## Example: +## initContainers: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +initContainers: [] +## Pod Disruption Budget configuration +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb +## @param pdb.create Enable/disable a Pod Disruption Budget creation +## @param pdb.minAvailable Minimum number/percentage of pods that should remain scheduled +## @param pdb.maxUnavailable Maximum number/percentage of pods that may be made unavailable. Defaults to `1` if both `pdb.minAvailable` and `pdb.maxUnavailable` are empty. +## +pdb: + create: true + minAvailable: "" + maxUnavailable: "" +## @param sidecars Add sidecar containers to the PhpMyAdmin pods +## Example: +## sidecars: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +sidecars: [] +## @section Traffic Exposure parameters + +## Service configuration +## +service: + ## @param service.type Kubernetes Service type + ## + type: ClusterIP + ## @param service.ports.http Service HTTP port + ## @param service.ports.https Service HTTPS port + ## + ports: + http: 80 + https: 443 + ## Specify the nodePort values for the LoadBalancer and NodePort service types + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## @param service.nodePorts.http Kubernetes http node port + ## @param service.nodePorts.https Kubernetes https node port + ## + nodePorts: + http: "" + https: "" + ## @param service.clusterIP PhpMyAdmin service clusterIP IP + ## e.g: + ## clusterIP: None + ## + clusterIP: "" + ## @param service.loadBalancerIP Load balancer IP for the phpMyAdmin Service (optional, cloud specific) + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer + ## + loadBalancerIP: "" + ## @param service.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## Example: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param service.annotations Provide any additional annotations that may be required for the PhpMyAdmin service + ## + annotations: {} + ## @param service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} +## Ingress configuration +## +ingress: + ## @param ingress.enabled Set to true to enable ingress record generation + ## + enabled: false + ## @param ingress.apiVersion Force Ingress API version (automatically detected if not set) + ## + apiVersion: "" + ## DEPRECATED: Use ingress.annotations instead of ingress.certManager + ## certManager: false + ## + + ## @param ingress.hostname When the ingress is enabled, a host pointing to this will be created + ## + hostname: phpmyadmin.local + ## @param ingress.pathType Ingress path type + ## + pathType: ImplementationSpecific + ## @param ingress.path Default path for the ingress record + ## NOTE: You may need to set this to '/*' in order to use this with ALB ingress controllers + ## + path: / + ## @param ingress.extraPaths An array with additional arbitrary paths that may need to be added to the ingress under the main host + ## e.g: + ## extraPaths: + ## - path: /* + ## backend: + ## serviceName: ssl-redirect + ## servicePort: use-annotation + ## + extraPaths: [] + ## @param ingress.annotations Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. + ## For a full list of possible ingress annotations, please see + ## ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md + ## Use this parameter to set the required annotations for cert-manager, see + ## ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations + ## + ## e.g: + ## annotations: + ## kubernetes.io/ingress.class: nginx + ## cert-manager.io/cluster-issuer: cluster-issuer-name + ## + annotations: {} + ## @param ingress.tls Enable TLS configuration for the hostname defined at `ingress.hostname` parameter + ## TLS certificates will be retrieved from a TLS secret with name: {{- printf "%s-tls" .Values.ingress.hostname }} + ## You can use the ingress.secrets parameter to create this TLS secret, relay on cert-manager to create it, or + ## let the chart create self-signed certificates for you + ## + tls: false + ## @param ingress.extraHosts The list of additional hostnames to be covered with this ingress record. + ## Most likely the hostname above will be enough, but in the event more hosts are needed, this is an array + ## Example: + ## extraHosts: + ## - name: phpmyadmin.local + ## path: / + ## + extraHosts: [] + ## @param ingress.extraTls The tls configuration for additional hostnames to be covered with this ingress record. + ## see: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + ## Example: + ## extraTls: + ## - hosts: + ## - phpmyadmin.local + ## secretName: phpmyadmin.local-tls + ## + extraTls: [] + ## @param ingress.secrets If you're providing your own certificates and want to manage the secret via helm, + ## please use this to add the certificates as secrets key and certificate should start with + ## -----BEGIN CERTIFICATE----- or -----BEGIN RSA PRIVATE KEY----- + ## name should line up with a secretName set further up + ## + ## If it is not set and you're using cert-manager, this is unneeded, as it will create the secret for you + ## If it is not set and you're NOT using cert-manager either, self-signed certificates will be created + ## It is also possible to create and manage the certificates outside of this helm chart + ## Please see README.md for more information + ## + ## Example + ## secrets: + ## - name: phpmyadmin.local-tls + ## key: "" + ## certificate: "" + ## + secrets: [] + ## @param ingress.existingSecretName If you're providing your own certificate and want to manage the secret yourself, + ## please provide the name of the secret with this parameter. This secret will then be used for tls termination. + ## It has higher priority than the cert-manager or the generation of the certificate from the chart. + ## + ## Example: + ## existingSecretName: "byo-phpmyadmin-tls" + ## + existingSecretName: "" + ## @param ingress.ingressClassName IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) + ## This is supported in Kubernetes 1.18+ and required if you have more than one IngressClass marked as the default for your cluster . + ## ref: https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/ + ## + ingressClassName: "" + ## @param ingress.extraRules Additional rules to be covered with this ingress record + ## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules + ## e.g: + ## extraRules: + ## - host: phpmyadmin.local + ## http: + ## path: / + ## backend: + ## service: + ## name: phpmyadmin-svc + ## port: + ## name: http + ## + extraRules: [] +## @section Database parameters + +## Database configuration +## +db: + ## @param db.allowArbitraryServer Enable connection to arbitrary MySQL server + ## If you do not want the user to be able to specify an arbitrary MySQL server at login time, set this to false + ## + allowArbitraryServer: true + ## @param db.port Database port to use to connect + ## + port: 3306 + ## @param db.chartName Database suffix if included in the same release + ## If you are deploying phpMyAdmin as part of a release and the database is part + ## of the release, you can pass a suffix that will be used to find the database + ## in releasename-dbSuffix. Please note that this setting precedes db.host + ## e.g: + ## chartName: mariadb + ## + chartName: "" + ## @param db.host Database Hostname. Ignored when `db.chartName` is set. + ## e.g: + ## host: foo + ## + host: "" + ## @param db.bundleTestDB Deploy a MariaDB instance for testing purposes + ## + bundleTestDB: false + ## @param db.enableSsl Enable SSL for the connection between phpMyAdmin and the database + ## + enableSsl: false + ssl: + ## @param db.ssl.clientKey Client key file when using SSL + ## + clientKey: "" + ## @param db.ssl.clientCertificate Client certificate file when using SSL + ## + clientCertificate: "" + ## @param db.ssl.caCertificate CA file when using SSL + ## + caCertificate: "" + ## @param db.ssl.ciphers List of allowable ciphers for connections when using SSL + ## + ciphers: [] + ## @param db.ssl.verify Enable SSL certificate validation + ## + verify: true +## @param mariadb MariaDB chart configuration +## https://github.com/bitnami/charts/blob/main/bitnami/mariadb/values.yaml +## +mariadb: {} +## @section Other Parameters + +## Service account for PhpMyAdmin to use. +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## +serviceAccount: + ## @param serviceAccount.create Enable creation of ServiceAccount for PhpMyAdmin pod + ## + create: true + ## @param serviceAccount.name The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the common.names.fullname template + ## + name: "" + ## @param serviceAccount.automountServiceAccountToken Allows auto mount of ServiceAccountToken on the serviceAccount created + ## Can be set to false if pods using this serviceAccount do not need to use K8s API + ## + automountServiceAccountToken: false + ## @param serviceAccount.annotations Additional custom annotations for the ServiceAccount + ## + annotations: {} +## @section Metrics parameters + +## Prometheus Exporter / Metrics +## +metrics: + ## @param metrics.enabled Start a side-car prometheus exporter + ## + enabled: false + ## @param metrics.image.registry [default: REGISTRY_NAME] Apache exporter image registry + ## @param metrics.image.repository [default: REPOSITORY_NAME/apache-exporter] Apache exporter image repository + ## @skip metrics.image.tag Apache exporter image tag (immutable tags are recommended) + ## @param metrics.image.digest Apache exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param metrics.image.pullPolicy Image pull policy + ## @param metrics.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/apache-exporter + tag: 1.0.8-debian-12-r9 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param metrics.resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if metrics.resources is set (metrics.resources is recommended for production). + ## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15 + ## + resourcesPreset: "nano" + ## @param metrics.resources Set container requests and limits for different resources like CPU or memory (essential for production workloads) + ## Example: + ## resources: + ## requests: + ## cpu: 2 + ## memory: 512Mi + ## limits: + ## cpu: 3 + ## memory: 1024Mi + ## ref: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ + ## + resources: {} + ## Prometheus Exporter service configuration + ## + service: + ## @param metrics.service.type Prometheus metrics service type + ## + type: ClusterIP + ## @param metrics.service.port Prometheus metrics service port + ## + port: 9117 + ## @param metrics.service.annotations [object] Annotations for Prometheus metrics service + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.metrics.service.port }}" + ## @param metrics.service.clusterIP phpmyadmin service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param metrics.service.loadBalancerIP Load Balancer IP if the Prometheus metrics server type is `LoadBalancer` + ## Use serviceLoadBalancerIP to request a specific static IP, otherwise leave blank + ## + loadBalancerIP: "" + ## @param metrics.service.loadBalancerSourceRanges phpmyadmin service Load Balancer sources + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param metrics.service.externalTrafficPolicy phpmyadmin service external traffic policy + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param metrics.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param metrics.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator + ## https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + serviceMonitor: + ## @param metrics.serviceMonitor.enabled Create ServiceMonitor Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param metrics.serviceMonitor.namespace Specify the namespace in which the serviceMonitor resource will be created + ## + namespace: "" + ## @param metrics.serviceMonitor.jobLabel The name of the label on the target service to use as the job name in prometheus. + ## + jobLabel: "" + ## @param metrics.serviceMonitor.interval Specify the interval at which metrics should be scraped + ## + interval: 30s + ## @param metrics.serviceMonitor.scrapeTimeout Specify the timeout after which the scrape is ended + ## e.g: + ## scrapeTimeout: 30s + ## + scrapeTimeout: "" + ## @param metrics.serviceMonitor.relabelings RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + ## + relabelings: [] + ## @param metrics.serviceMonitor.metricRelabelings Specify Metric Relabelings to add to the scrape endpoint + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + ## @param metrics.serviceMonitor.labels Extra labels for the ServiceMonitor + ## + labels: {} + ## @param metrics.serviceMonitor.honorLabels Specify honorLabels parameter to add the scrape endpoint + ## + honorLabels: false + ## @param metrics.serviceMonitor.selector ServiceMonitor selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + ## + ## selector: + ## prometheus: my-prometheus + ## + selector: {} +## @section NetworkPolicy parameters + +## Network Policy configuration +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +## +networkPolicy: + ## @param networkPolicy.enabled Specifies whether a NetworkPolicy should be created + ## + enabled: true + ## @param networkPolicy.allowExternal Don't require server label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## server label will have network access to the ports server is listening + ## on. When true, server will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.allowExternalEgress Allow the pod to access any range of port and all destinations. + ## + allowExternalEgress: true + ## @param networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + extraIngress: [] + ## @param networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} diff --git a/charts/phpmyadmin/values-overrides.yaml b/charts/phpmyadmin/values-overrides.yaml new file mode 100644 index 0000000..f6f6b59 --- /dev/null +++ b/charts/phpmyadmin/values-overrides.yaml @@ -0,0 +1,6 @@ +fullnameOverride: phpmyadmin +db: + allowArbitraryServer: false + port: 3306 + host: "mariadb.futureporn.svc.cluster.local" + bundleTestDB: false \ No newline at end of file diff --git a/charts/traefik/traefik/Changelog.md b/charts/traefik/traefik/Changelog.md index 4adf400..be5ee51 100644 --- a/charts/traefik/traefik/Changelog.md +++ b/charts/traefik/traefik/Changelog.md @@ -1,5 +1,1375 @@ # Change Log +## 33.0.0 ![AppVersion: v3.2.0](https://img.shields.io/static/v1?label=AppVersion&message=v3.2.0&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-10-30 + +* fix: 🐛 http3 with internal service +* fix: use correct children indentation for logs.access.filters +* fix(schema): :bug: targetPort can also be a string +* fix(certificateResolvers)!: :boom: :bug: use same syntax in Chart and in Traefik +* fix(Traefik)!: :boom: set 8080 as default port for `traefik` entrypoint +* fix(Traefik Hub): RBAC for distributedAcme +* fix(Kubernetes Ingress)!: :boom: :sparkles: enable publishedService by default +* fix(Gateway API): :bug: add missing required RBAC for v3.2 with experimental Channel +* fix(Env Variables)!: allow extending env without overwrite +* feat(deps): update traefik docker tag to v3.2.0 +* feat(deps): update traefik docker tag to v3.1.6 +* feat(Traefik): ✨ support Gateway API statusAddress +* feat(Traefik Proxy): CRDs for v3.2+ +* feat(Gateway API): :sparkles: standard install CRD v1.2.0 +* feat(Gateway API): :sparkles: add infrastructure in the values +* chore: allow TRACE log level +* chore(release): 🚀 publish v33.0.0 +* Update topology spread constraints comments + +**Upgrade Notes** + +There are multiple breaking changes in this release: + +1. The default port of `traefik` entrypoint has changed from `9000` to `8080`, just like the Traefik Proxy default port + * You _may_ have to update probes accordingly (or set this port back to 9000) +2. `publishedService` is enabled by default on Ingress provider + * You _can_ disable it, if needed +3. The `POD_NAME` and `POD_NAMESPACE` environment variables are now set by default, without values. + * It is no longer necessary to add them in values and so, it can be removed from user values. +4. In _values_, **certResolvers** specific syntax has been reworked to align with Traefik Proxy syntax. + * PR [#1214](https://github.com/traefik/traefik-helm-chart/pull/1214) contains a complete before / after example on how to update _values_ +5. Traefik Proxy 3.2 supports Gateway API v1.2 + * The CRDs of this version comes with Gateway API CRD v1.2 of standard channel. + * The CRDs needs to be updated, as documented in the README. + * It is recommended to check that other software using Gateway API on your cluster are compatible + +:information_source: A separate helm chart, just for CRDs, is being considered for a future release. See PR [#1123](https://github.com/traefik/traefik-helm-chart/pull/1223) + +### Default value changes + +```diff +diff --git a/traefik/values.yaml b/traefik/values.yaml +index 73371f3..be89b00 100644 +--- a/traefik/values.yaml ++++ b/traefik/values.yaml +@@ -95,7 +95,7 @@ deployment: + # postStart: + # httpGet: + # path: /ping +- # port: 9000 ++ # port: 8080 + # host: localhost + # scheme: HTTP + # -- Set a runtimeClassName on pod +@@ -138,6 +138,8 @@ gateway: + namespace: "" + # -- Additional gateway annotations (e.g. for cert-manager.io/issuer) + annotations: {} ++ # -- [Infrastructure](https://kubernetes.io/blog/2023/11/28/gateway-api-ga/#gateway-infrastructure-labels) ++ infrastructure: {} + # -- Define listeners + listeners: + web: +@@ -283,10 +285,11 @@ providers: # @schema additionalProperties: false + namespaces: [] + # IP used for Kubernetes Ingress endpoints + publishedService: +- enabled: false +- # Published Kubernetes Service to copy status from. Format: namespace/servicename +- # By default this Traefik service +- # pathOverride: "" ++ # -- Enable [publishedService](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#publishedservice) ++ enabled: true ++ # -- Override path of Kubernetes Service used to copy status from. Format: namespace/servicename. ++ # Default to Service deployed with this Chart. ++ pathOverride: "" + # -- Defines whether to use Native Kubernetes load-balancing mode by default. + nativeLBByDefault: false + +@@ -300,6 +303,15 @@ providers: # @schema additionalProperties: false + namespaces: [] + # -- A label selector can be defined to filter on specific GatewayClass objects only. + labelselector: "" ++ statusAddress: ++ # -- This IP will get copied to the Gateway status.addresses, and currently only supports one IP value (IPv4 or IPv6). ++ ip: "" ++ # -- This Hostname will get copied to the Gateway status.addresses. ++ hostname: "" ++ # -- The Kubernetes service to copy status addresses from. When using third parties tools like External-DNS, this option can be used to copy the service loadbalancer.status (containing the service's endpoints IPs) to the gateways. Default to Service of this Chart. ++ service: ++ name: "{{ (include \"traefik.fullname\" .) }}" ++ namespace: "{{ .Release.Namespace }}" + + file: + # -- Create a file provider +@@ -335,8 +347,8 @@ logs: + # -- Set [logs format](https://doc.traefik.io/traefik/observability/logs/#format) + format: # @schema enum:["common", "json", null]; type:[string, null]; default: "common" + # By default, the level is set to INFO. +- # -- Alternative logging levels are DEBUG, PANIC, FATAL, ERROR, WARN, and INFO. +- level: "INFO" # @schema enum:[INFO,WARN,ERROR,FATAL,PANIC,DEBUG]; default: "INFO" ++ # -- Alternative logging levels are TRACE, DEBUG, INFO, WARN, ERROR, FATAL, and PANIC. ++ level: "INFO" # @schema enum:[TRACE,DEBUG,INFO,WARN,ERROR,FATAL,PANIC]; default: "INFO" + # -- To write the logs into a log file, use the filePath option. + filePath: "" + # -- When set to true and format is common, it disables the colorized output. +@@ -350,10 +362,13 @@ logs: + # -- Set [bufferingSize](https://doc.traefik.io/traefik/observability/access-logs/#bufferingsize) + bufferingSize: # @schema type:[integer, null] + # -- Set [filtering](https://docs.traefik.io/observability/access-logs/#filtering) +- filters: {} +- statuscodes: "" +- retryattempts: false +- minduration: "" ++ filters: # @schema additionalProperties: false ++ # -- Set statusCodes, to limit the access logs to requests with a status codes in the specified range ++ statuscodes: "" ++ # -- Set retryAttempts, to keep the access logs when at least one retry has happened ++ retryattempts: false ++ # -- Set minDuration, to keep access logs when requests take longer than the specified duration ++ minduration: "" + # -- Enables accessLogs for internal resources. Default: false. + addInternals: false + fields: +@@ -566,24 +581,16 @@ additionalArguments: [] + # - "--providers.kubernetesingress.ingressclass=traefik-internal" + # - "--log.level=DEBUG" + +-# -- Environment variables to be passed to Traefik's binary ++# -- Additional Environment variables to be passed to Traefik's binary + # @default -- See _values.yaml_ +-env: +-- name: POD_NAME +- valueFrom: +- fieldRef: +- fieldPath: metadata.name +-- name: POD_NAMESPACE +- valueFrom: +- fieldRef: +- fieldPath: metadata.namespace ++env: [] + + # -- Environment variables to be passed to Traefik's binary from configMaps or secrets + envFrom: [] + + ports: + traefik: +- port: 9000 ++ port: 8080 + # -- Use hostPort if set. + hostPort: # @schema type:[integer, null]; minimum:0 + # -- Use hostIP if set. If not set, Kubernetes will default to 0.0.0.0, which +@@ -601,7 +608,7 @@ ports: + expose: + default: false + # -- The exposed port for this service +- exposedPort: 9000 ++ exposedPort: 8080 + # -- The port protocol (TCP/UDP) + protocol: TCP + web: +@@ -614,7 +621,7 @@ ports: + default: true + exposedPort: 80 + ## -- Different target traefik port on the cluster, useful for IP type LB +- targetPort: # @schema type:[integer, null]; minimum:0 ++ targetPort: # @schema type:[string, integer, null]; minimum:0 + # The port protocol (TCP/UDP) + protocol: TCP + # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) +@@ -653,7 +660,7 @@ ports: + default: true + exposedPort: 443 + ## -- Different target traefik port on the cluster, useful for IP type LB +- targetPort: # @schema type:[integer, null]; minimum:0 ++ targetPort: # @schema type:[string, integer, null]; minimum:0 + ## -- The port protocol (TCP/UDP) + protocol: TCP + # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) +@@ -780,8 +787,8 @@ autoscaling: + + persistence: + # -- Enable persistence using Persistent Volume Claims +- # ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +- # It can be used to store TLS certificates, see `storage` in certResolvers ++ # ref: http://kubernetes.io/docs/user-guide/persistent-volumes/. ++ # It can be used to store TLS certificates along with `certificatesResolvers..acme.storage` option + enabled: false + name: data + existingClaim: "" +@@ -797,7 +804,7 @@ persistence: + # -- Certificates resolvers configuration. + # Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers + # See EXAMPLES.md for more details. +-certResolvers: {} ++certificatesResolvers: {} + + # -- If hostNetwork is true, runs traefik in the host network namespace + # To prevent unschedulabel pods due to port collisions, if hostNetwork=true +@@ -860,7 +867,7 @@ topologySpreadConstraints: [] + # on nodes where no other traefik pods are scheduled. + # - labelSelector: + # matchLabels: +-# app: '{{ template "traefik.name" . }}' ++# app.kubernetes.io/name: '{{ template "traefik.name" . }}' + # maxSkew: 1 + # topologyKey: kubernetes.io/hostname + # whenUnsatisfiable: DoNotSchedule +``` + +## 32.1.0 ![AppVersion: v3.1.5](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.5&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-10-04 + +* fix: :bug: set disableIngressClassLookup until 3.1.4 +* feat(deps): update traefik docker tag to v3.1.5 +* feat(Traefik Proxy): update rbac following v3.2 migration guide +* chore(release): 🚀 publish v32.1.0 + +### Default value changes + +```diff +diff --git a/traefik/values.yaml b/traefik/values.yaml +index f36a9dd..73371f3 100644 +--- a/traefik/values.yaml ++++ b/traefik/values.yaml +@@ -809,9 +809,9 @@ hostNetwork: false + rbac: # @schema additionalProperties: false + enabled: true + # When set to true: +- # 1. Use `Role` and `RoleBinding` instead of `ClusterRole` and `ClusterRoleBinding`. +- # 2. Set `disableIngressClassLookup` on Kubernetes Ingress providers with Traefik Proxy v3 until v3.1.1 +- # 3. Set `disableClusterScopeResources` on Kubernetes Ingress and CRD providers with Traefik Proxy v3.1.2+ ++ # 1. It switches respectively the use of `ClusterRole` and `ClusterRoleBinding` to `Role` and `RoleBinding`. ++ # 2. It adds `disableIngressClassLookup` on Kubernetes Ingress with Traefik Proxy v3 until v3.1.4 ++ # 3. It adds `disableClusterScopeResources` on Ingress and CRD (Kubernetes) providers with Traefik Proxy v3.1.2+ + # **NOTE**: `IngressClass`, `NodePortLB` and **Gateway** provider cannot be used with namespaced RBAC. + # See [upstream documentation](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#disableclusterscoperesources) for more details. + namespaced: false + +## 32.0.0 ![AppVersion: v3.1.4](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.4&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-09-27 + +* chore(release): :rocket: publish 32.0.0 +* fix: replace `CLF` with `common` in `values.yaml` +* feat(Traefik Hub): add APIPlans and APIBundles CRDs + +### Default value changes + +```diff +diff --git a/traefik/values.yaml b/traefik/values.yaml +index 51dec67..f36a9dd 100644 +index d5173dc..f36a9dd 100644 +--- a/traefik/values.yaml ++++ b/traefik/values.yaml +@@ -345,7 +345,7 @@ logs: + # -- To enable access logs + enabled: false + # -- Set [access log format](https://doc.traefik.io/traefik/observability/access-logs/#format) +- format: # @schema enum:["CLF", "json", null]; type:[string, null]; default: "CLF" ++ format: # @schema enum:["common", "json", null]; type:[string, null]; default: "common" + # filePath: "/var/log/traefik/access.log + # -- Set [bufferingSize](https://doc.traefik.io/traefik/observability/access-logs/#bufferingsize) + bufferingSize: # @schema type:[integer, null] +@@ -911,35 +911,34 @@ hub: + # -- Certificate of the WebHook admission server. Default: "hub-agent-cert". + secretName: "" + +- ratelimit: +- redis: +- # -- Enable Redis Cluster. Default: true. +- cluster: # @schema type:[boolean, null] +- # -- Database used to store information. Default: "0". +- database: # @schema type:[string, null] +- # -- Endpoints of the Redis instances to connect to. Default: "". +- endpoints: "" +- # -- The username to use when connecting to Redis endpoints. Default: "". ++ redis: ++ # -- Enable Redis Cluster. Default: true. ++ cluster: # @schema type:[boolean, null] ++ # -- Database used to store information. Default: "0". ++ database: # @schema type:[string, null] ++ # -- Endpoints of the Redis instances to connect to. Default: "". ++ endpoints: "" ++ # -- The username to use when connecting to Redis endpoints. Default: "". ++ username: "" ++ # -- The password to use when connecting to Redis endpoints. Default: "". ++ password: "" ++ sentinel: ++ # -- Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". ++ masterset: "" ++ # -- Username to use for sentinel authentication (can be different from endpoint username). Default: "". + username: "" +- # -- The password to use when connecting to Redis endpoints. Default: "". ++ # -- Password to use for sentinel authentication (can be different from endpoint password). Default: "". + password: "" +- sentinel: +- # -- Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". +- masterset: "" +- # -- Username to use for sentinel authentication (can be different from endpoint username). Default: "". +- username: "" +- # -- Password to use for sentinel authentication (can be different from endpoint password). Default: "". +- password: "" +- # -- Timeout applied on connection with redis. Default: "0s". +- timeout: "" +- tls: +- # -- Path to the certificate authority used for the secured connection. +- ca: "" +- # -- Path to the public certificate used for the secure connection. +- cert: "" +- # -- Path to the private key used for the secure connection. +- key: "" +- # -- When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. +- insecureSkipVerify: false ++ # -- Timeout applied on connection with redis. Default: "0s". ++ timeout: "" ++ tls: ++ # -- Path to the certificate authority used for the secured connection. ++ ca: "" ++ # -- Path to the public certificate used for the secure connection. ++ cert: "" ++ # -- Path to the private key used for the secure connection. ++ key: "" ++ # -- When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. ++ insecureSkipVerify: false + # Enable export of errors logs to the platform. Default: true. + sendlogs: # @schema type:[boolean, null] +``` + +## 32.0.0-rc1 ![AppVersion: v3.1.4](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.4&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-09-20 + +* feat(Traefik Hub): add APIPlans and APIBundles CRDs +* chore(release): 🚀 publish 32.0.0-rc1 + +### Default value changes + +```diff +diff --git a/traefik/values.yaml b/traefik/values.yaml +index d5173dc..51dec67 100644 +--- a/traefik/values.yaml ++++ b/traefik/values.yaml +@@ -911,35 +911,34 @@ hub: + # -- Certificate of the WebHook admission server. Default: "hub-agent-cert". + secretName: "" + +- ratelimit: +- redis: +- # -- Enable Redis Cluster. Default: true. +- cluster: # @schema type:[boolean, null] +- # -- Database used to store information. Default: "0". +- database: # @schema type:[string, null] +- # -- Endpoints of the Redis instances to connect to. Default: "". +- endpoints: "" +- # -- The username to use when connecting to Redis endpoints. Default: "". ++ redis: ++ # -- Enable Redis Cluster. Default: true. ++ cluster: # @schema type:[boolean, null] ++ # -- Database used to store information. Default: "0". ++ database: # @schema type:[string, null] ++ # -- Endpoints of the Redis instances to connect to. Default: "". ++ endpoints: "" ++ # -- The username to use when connecting to Redis endpoints. Default: "". ++ username: "" ++ # -- The password to use when connecting to Redis endpoints. Default: "". ++ password: "" ++ sentinel: ++ # -- Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". ++ masterset: "" ++ # -- Username to use for sentinel authentication (can be different from endpoint username). Default: "". + username: "" +- # -- The password to use when connecting to Redis endpoints. Default: "". ++ # -- Password to use for sentinel authentication (can be different from endpoint password). Default: "". + password: "" +- sentinel: +- # -- Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". +- masterset: "" +- # -- Username to use for sentinel authentication (can be different from endpoint username). Default: "". +- username: "" +- # -- Password to use for sentinel authentication (can be different from endpoint password). Default: "". +- password: "" +- # -- Timeout applied on connection with redis. Default: "0s". +- timeout: "" +- tls: +- # -- Path to the certificate authority used for the secured connection. +- ca: "" +- # -- Path to the public certificate used for the secure connection. +- cert: "" +- # -- Path to the private key used for the secure connection. +- key: "" +- # -- When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. +- insecureSkipVerify: false ++ # -- Timeout applied on connection with redis. Default: "0s". ++ timeout: "" ++ tls: ++ # -- Path to the certificate authority used for the secured connection. ++ ca: "" ++ # -- Path to the public certificate used for the secure connection. ++ cert: "" ++ # -- Path to the private key used for the secure connection. ++ key: "" ++ # -- When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. ++ insecureSkipVerify: false + # Enable export of errors logs to the platform. Default: true. + sendlogs: # @schema type:[boolean, null] +``` + +## 31.1.1 ![AppVersion: v3.1.4](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.4&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-09-20 + +* fix: 🐛 updateStrategy behavior +* feat(deps): update traefik docker tag to v3.1.4 +* chore(release): 🚀 publish v31.1.1 + +## 31.1.0 ![AppVersion: v3.1.3](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.3&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-09-18 + +* fix: 🐛 update CRD to v3.1 +* feat: ✨ input validation using schema +* feat: ✨ add AllowACMEByPass and improve schema/doc on ports values +* feat: add new webhooks and removes unnecessary ones +* feat(deps): update traefik docker tag to v3.1.3 +* chore(release): 🚀 publish v31.1.0 + +### Default value changes + +```diff +diff --git a/traefik/values.yaml b/traefik/values.yaml +index 2232d9e..1b9d0fd 100644 +--- a/traefik/values.yaml ++++ b/traefik/values.yaml +@@ -2,13 +2,13 @@ + # This is a YAML-formatted file. + # Declare variables to be passed into templates + +-image: ++image: # @schema additionalProperties: false + # -- Traefik image host registry + registry: docker.io + # -- Traefik image repository + repository: traefik + # -- defaults to appVersion +- tag: ++ tag: # @schema type:[string, null] + # -- Traefik image pull policy + pullPolicy: IfNotPresent + +@@ -23,27 +23,27 @@ deployment: + # -- Number of pods of the deployment (only applies when kind == Deployment) + replicas: 1 + # -- Number of old history to retain to allow rollback (If not set, default Kubernetes value is set to 10) +- # revisionHistoryLimit: 1 ++ revisionHistoryLimit: # @schema type:[integer, null];minimum:0 + # -- Amount of time (in seconds) before Kubernetes will send the SIGKILL signal if Traefik does not shut down + terminationGracePeriodSeconds: 60 + # -- The minimum number of seconds Traefik needs to be up and running before the DaemonSet/Deployment controller considers it available + minReadySeconds: 0 +- ## Override the liveness/readiness port. This is useful to integrate traefik ++ ## -- Override the liveness/readiness port. This is useful to integrate traefik + ## with an external Load Balancer that performs healthchecks. + ## Default: ports.traefik.port +- # healthchecksPort: 9000 +- ## Override the liveness/readiness host. Useful for getting ping to respond on non-default entryPoint. ++ healthchecksPort: # @schema type:[integer, null];minimum:0 ++ ## -- Override the liveness/readiness host. Useful for getting ping to respond on non-default entryPoint. + ## Default: ports.traefik.hostIP if set, otherwise Pod IP +- # healthchecksHost: localhost +- ## Override the liveness/readiness scheme. Useful for getting ping to ++ healthchecksHost: "" ++ ## -- Override the liveness/readiness scheme. Useful for getting ping to + ## respond on websecure entryPoint. +- # healthchecksScheme: HTTPS +- ## Override the readiness path. ++ healthchecksScheme: # @schema enum:[HTTP, HTTPS, null]; type:[string, null]; default: HTTP ++ ## -- Override the readiness path. + ## Default: /ping +- # readinessPath: /ping +- # Override the liveness path. ++ readinessPath: "" ++ # -- Override the liveness path. + # Default: /ping +- # livenessPath: /ping ++ livenessPath: "" + # -- Additional deployment annotations (e.g. for jaeger-operator sidecar injection) + annotations: {} + # -- Additional deployment labels (e.g. for filtering deployment by custom labels) +@@ -80,7 +80,7 @@ deployment: + # -- Use process namespace sharing + shareProcessNamespace: false + # -- Custom pod DNS policy. Apply if `hostNetwork: true` +- # dnsPolicy: ClusterFirstWithHostNet ++ dnsPolicy: "" + # -- Custom pod [DNS config](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#poddnsconfig-v1-core) + dnsConfig: {} + # -- Custom [host aliases](https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/) +@@ -99,24 +99,24 @@ deployment: + # host: localhost + # scheme: HTTP + # -- Set a runtimeClassName on pod +- runtimeClassName: ++ runtimeClassName: "" + + # -- [Pod Disruption Budget](https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/pod-disruption-budget-v1/) +-podDisruptionBudget: +- enabled: +- maxUnavailable: +- minAvailable: ++podDisruptionBudget: # @schema additionalProperties: false ++ enabled: false ++ maxUnavailable: # @schema type:[string, integer, null];minimum:0 ++ minAvailable: # @schema type:[string, integer, null];minimum:0 + + # -- Create a default IngressClass for Traefik +-ingressClass: ++ingressClass: # @schema additionalProperties: false + enabled: true + isDefaultClass: true +- # name: my-custom-class ++ name: "" + +-core: ++core: # @schema additionalProperties: false + # -- Can be used to use globally v2 router syntax + # See https://doc.traefik.io/traefik/v3.0/migration/v2-to-v3/#new-v3-syntax-notable-changes +- defaultRuleSyntax: ++ defaultRuleSyntax: "" + + # Traefik experimental features + experimental: +@@ -133,11 +133,11 @@ gateway: + # -- When providers.kubernetesGateway.enabled, deploy a default gateway + enabled: true + # -- Set a custom name to gateway +- name: ++ name: "" + # -- By default, Gateway is created in the same `Namespace` than Traefik. +- namespace: ++ namespace: "" + # -- Additional gateway annotations (e.g. for cert-manager.io/issuer) +- annotations: ++ annotations: {} + # -- Define listeners + listeners: + web: +@@ -145,11 +145,11 @@ gateway: + # The port must match a port declared in ports section. + port: 8000 + # -- Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) +- hostname: ++ hostname: "" + # Specify expected protocol on this listener. See [ProtocolType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ProtocolType) + protocol: HTTP + # -- Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces +- namespacePolicy: ++ namespacePolicy: # @schema type:[string, null] + # websecure listener is disabled by default because certificateRefs needs to be added, + # or you may specify TLS protocol with Passthrough mode and add "--providers.kubernetesGateway.experimentalChannel=true" in additionalArguments section. + # websecure: +@@ -167,13 +167,13 @@ gateway: + # # -- TLS behavior for the TLS session initiated by the client. See [TLSModeType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.TLSModeType). + # mode: + +-gatewayClass: ++gatewayClass: # @schema additionalProperties: false + # -- When providers.kubernetesGateway.enabled and gateway.enabled, deploy a default gatewayClass + enabled: true + # -- Set a custom name to GatewayClass +- name: ++ name: "" + # -- Additional gatewayClass labels (e.g. for filtering gateway objects by custom labels) +- labels: ++ labels: {} + + ingressRoute: + dashboard: +@@ -218,14 +218,14 @@ ingressRoute: + # -- TLS options (e.g. secret containing certificate) + tls: {} + +-updateStrategy: ++updateStrategy: # @schema additionalProperties: false + # -- Customize updateStrategy: RollingUpdate or OnDelete + type: RollingUpdate + rollingUpdate: +- maxUnavailable: 0 +- maxSurge: 1 ++ maxUnavailable: 0 # @schema type:[integer, string, null] ++ maxSurge: 1 # @schema type:[integer, string, null] + +-readinessProbe: ++readinessProbe: # @schema additionalProperties: false + # -- The number of consecutive failures allowed before considering the probe as failed. + failureThreshold: 1 + # -- The number of seconds to wait before starting the first probe. +@@ -236,7 +236,7 @@ readinessProbe: + successThreshold: 1 + # -- The number of seconds to wait for a probe response before considering it as failed. + timeoutSeconds: 2 +-livenessProbe: ++livenessProbe: # @schema additionalProperties: false + # -- The number of consecutive failures allowed before considering the probe as failed. + failureThreshold: 3 + # -- The number of seconds to wait before starting the first probe. +@@ -249,9 +249,9 @@ livenessProbe: + timeoutSeconds: 2 + + # -- Define [Startup Probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-startup-probes) +-startupProbe: ++startupProbe: {} + +-providers: ++providers: # @schema additionalProperties: false + kubernetesCRD: + # -- Load Kubernetes IngressRoute provider + enabled: true +@@ -262,12 +262,12 @@ providers: + # -- Allows to return 503 when there is no endpoints available + allowEmptyServices: true + # -- When the parameter is set, only resources containing an annotation with the same value are processed. Otherwise, resources missing the annotation, having an empty value, or the value traefik are processed. It will also set required annotation on Dashboard and Healthcheck IngressRoute when enabled. +- ingressClass: ++ ingressClass: "" + # labelSelector: environment=production,method=traefik + # -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. + namespaces: [] + # -- Defines whether to use Native Kubernetes load-balancing mode by default. +- nativeLBByDefault: ++ nativeLBByDefault: false + + kubernetesIngress: + # -- Load Kubernetes Ingress provider +@@ -277,7 +277,7 @@ providers: + # -- Allows to return 503 when there is no endpoints available + allowEmptyServices: true + # -- When ingressClass is set, only Ingresses containing an annotation with the same value are processed. Otherwise, Ingresses missing the annotation, having an empty value, or the value traefik are processed. +- ingressClass: ++ ingressClass: # @schema type:[string, null] + # labelSelector: environment=production,method=traefik + # -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. + namespaces: [] +@@ -288,7 +288,7 @@ providers: + # By default this Traefik service + # pathOverride: "" + # -- Defines whether to use Native Kubernetes load-balancing mode by default. +- nativeLBByDefault: ++ nativeLBByDefault: false + + kubernetesGateway: + # -- Enable Traefik Gateway provider for Gateway API +@@ -299,7 +299,7 @@ providers: + # -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. + namespaces: [] + # -- A label selector can be defined to filter on specific GatewayClass objects only. +- labelselector: ++ labelselector: "" + + file: + # -- Create a file provider +@@ -307,7 +307,7 @@ providers: + # -- Allows Traefik to automatically watch for file changes + watch: true + # -- File content (YAML format, go template supported) (see https://doc.traefik.io/traefik/providers/file/) +- content: ++ content: "" + + # -- Add volumes to the traefik pod. The volume name will be passed to tpl. + # This can be used to mount a cert pair or a configmap that holds a config.toml file. +@@ -333,90 +333,88 @@ additionalVolumeMounts: [] + logs: + general: + # -- Set [logs format](https://doc.traefik.io/traefik/observability/logs/#format) +- # @default common +- format: ++ format: # @schema enum:["common", "json", null]; type:[string, null]; default: "common" + # By default, the level is set to INFO. + # -- Alternative logging levels are DEBUG, PANIC, FATAL, ERROR, WARN, and INFO. +- level: INFO +- # +- # filePath: "/var/log/traefik/traefik.log +- # noColor: true ++ level: "INFO" # @schema enum:[INFO,WARN,ERROR,FATAL,PANIC,DEBUG]; default: "INFO" ++ # -- To write the logs into a log file, use the filePath option. ++ filePath: "" ++ # -- When set to true and format is common, it disables the colorized output. ++ noColor: false + access: + # -- To enable access logs + enabled: false + # -- Set [access log format](https://doc.traefik.io/traefik/observability/access-logs/#format) +- format: ++ format: # @schema enum:["CLF", "json", null]; type:[string, null]; default: "CLF" + # filePath: "/var/log/traefik/access.log + # -- Set [bufferingSize](https://doc.traefik.io/traefik/observability/access-logs/#bufferingsize) +- bufferingSize: ++ bufferingSize: # @schema type:[integer, null] + # -- Set [filtering](https://docs.traefik.io/observability/access-logs/#filtering) + filters: {} +- # statuscodes: "200,300-302" +- # retryattempts: true +- # minduration: 10ms ++ statuscodes: "" ++ retryattempts: false ++ minduration: "" + # -- Enables accessLogs for internal resources. Default: false. +- addInternals: ++ addInternals: false + fields: + general: +- # -- Available modes: keep, drop, redact. +- defaultmode: keep ++ # -- Set default mode for fields.names ++ defaultmode: keep # @schema enum:[keep, drop, redact]; default: keep + # -- Names of the fields to limit. + names: {} +- ## Examples: +- # ClientUsername: drop + # -- [Limit logged fields or headers](https://doc.traefik.io/traefik/observability/access-logs/#limiting-the-fieldsincluding-headers) + headers: +- # -- Available modes: keep, drop, redact. +- defaultmode: drop ++ # -- Set default mode for fields.headers ++ defaultmode: drop # @schema enum:[keep, drop, redact]; default: drop + names: {} + + metrics: + ## -- Enable metrics for internal resources. Default: false +- addInternals: ++ addInternals: false + + ## -- Prometheus is enabled by default. + ## -- It can be disabled by setting "prometheus: null" + prometheus: + # -- Entry point used to expose metrics. + entryPoint: metrics +- ## Enable metrics on entry points. Default=true +- # addEntryPointsLabels: false +- ## Enable metrics on routers. Default=false +- # addRoutersLabels: true +- ## Enable metrics on services. Default=true +- # addServicesLabels: false ++ ## Enable metrics on entry points. Default: true ++ addEntryPointsLabels: # @schema type:[boolean, null] ++ ## Enable metrics on routers. Default: false ++ addRoutersLabels: # @schema type:[boolean, null] ++ ## Enable metrics on services. Default: true ++ addServicesLabels: # @schema type:[boolean, null] + ## Buckets for latency metrics. Default="0.1,0.3,1.2,5.0" +- # buckets: "0.5,1.0,2.5" ++ buckets: "" + ## When manualRouting is true, it disables the default internal router in + ## order to allow creating a custom router for prometheus@internal service. +- # manualRouting: true ++ manualRouting: false + service: + # -- Create a dedicated metrics service to use with ServiceMonitor +- enabled: +- labels: +- annotations: ++ enabled: false ++ labels: {} ++ annotations: {} + # -- When set to true, it won't check if Prometheus Operator CRDs are deployed +- disableAPICheck: ++ disableAPICheck: # @schema type:[boolean, null] + serviceMonitor: + # -- Enable optional CR for Prometheus Operator. See EXAMPLES.md for more details. + enabled: false +- metricRelabelings: +- relabelings: +- jobLabel: +- interval: +- honorLabels: +- scrapeTimeout: +- honorTimestamps: +- enableHttp2: +- followRedirects: +- additionalLabels: +- namespace: +- namespaceSelector: ++ metricRelabelings: [] ++ relabelings: [] ++ jobLabel: "" ++ interval: "" ++ honorLabels: false ++ scrapeTimeout: "" ++ honorTimestamps: false ++ enableHttp2: false ++ followRedirects: false ++ additionalLabels: {} ++ namespace: "" ++ namespaceSelector: {} + prometheusRule: + # -- Enable optional CR for Prometheus Operator. See EXAMPLES.md for more details. + enabled: false +- additionalLabels: +- namespace: ++ additionalLabels: {} ++ namespace: "" + + # datadog: + # ## Address instructs exporter to send metrics to datadog-agent at this address. +@@ -469,55 +467,55 @@ metrics: + # -- Set to true in order to enable the OpenTelemetry metrics + enabled: false + # -- Enable metrics on entry points. Default: true +- addEntryPointsLabels: ++ addEntryPointsLabels: # @schema type:[boolean, null] + # -- Enable metrics on routers. Default: false +- addRoutersLabels: ++ addRoutersLabels: # @schema type:[boolean, null] + # -- Enable metrics on services. Default: true +- addServicesLabels: ++ addServicesLabels: # @schema type:[boolean, null] + # -- Explicit boundaries for Histogram data points. Default: [.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10] +- explicitBoundaries: ++ explicitBoundaries: [] + # -- Interval at which metrics are sent to the OpenTelemetry Collector. Default: 10s +- pushInterval: ++ pushInterval: "" + http: + # -- Set to true in order to send metrics to the OpenTelemetry Collector using HTTP. + enabled: false + # -- Format: ://:. Default: http://localhost:4318/v1/metrics +- endpoint: ++ endpoint: "" + # -- Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. +- headers: ++ headers: {} + ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. + tls: + # -- The path to the certificate authority, it defaults to the system bundle. +- ca: ++ ca: "" + # -- The path to the public certificate. When using this option, setting the key option is required. +- cert: ++ cert: "" + # -- The path to the private key. When using this option, setting the cert option is required. +- key: ++ key: "" + # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. +- insecureSkipVerify: ++ insecureSkipVerify: # @schema type:[boolean, null] + grpc: + # -- Set to true in order to send metrics to the OpenTelemetry Collector using gRPC + enabled: false + # -- Format: ://:. Default: http://localhost:4318/v1/metrics +- endpoint: ++ endpoint: "" + # -- Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. +- insecure: ++ insecure: false + ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. + tls: + # -- The path to the certificate authority, it defaults to the system bundle. +- ca: ++ ca: "" + # -- The path to the public certificate. When using this option, setting the key option is required. +- cert: ++ cert: "" + # -- The path to the private key. When using this option, setting the cert option is required. +- key: ++ key: "" + # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. +- insecureSkipVerify: ++ insecureSkipVerify: false + + ## Tracing + # -- https://doc.traefik.io/traefik/observability/tracing/overview/ +-tracing: ++tracing: # @schema additionalProperties: false + # -- Enables tracing for internal resources. Default: false. +- addInternals: ++ addInternals: false + otlp: + # -- See https://doc.traefik.io/traefik/v3.0/observability/tracing/opentelemetry/ + enabled: false +@@ -525,36 +523,36 @@ tracing: + # -- Set to true in order to send metrics to the OpenTelemetry Collector using HTTP. + enabled: false + # -- Format: ://:. Default: http://localhost:4318/v1/metrics +- endpoint: ++ endpoint: "" + # -- Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. +- headers: ++ headers: {} + ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. + tls: + # -- The path to the certificate authority, it defaults to the system bundle. +- ca: ++ ca: "" + # -- The path to the public certificate. When using this option, setting the key option is required. +- cert: ++ cert: "" + # -- The path to the private key. When using this option, setting the cert option is required. +- key: ++ key: "" + # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. +- insecureSkipVerify: ++ insecureSkipVerify: false + grpc: + # -- Set to true in order to send metrics to the OpenTelemetry Collector using gRPC + enabled: false + # -- Format: ://:. Default: http://localhost:4318/v1/metrics +- endpoint: ++ endpoint: "" + # -- Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. +- insecure: ++ insecure: false + ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. + tls: + # -- The path to the certificate authority, it defaults to the system bundle. +- ca: ++ ca: "" + # -- The path to the public certificate. When using this option, setting the key option is required. +- cert: ++ cert: "" + # -- The path to the private key. When using this option, setting the cert option is required. +- key: ++ key: "" + # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. +- insecureSkipVerify: ++ insecureSkipVerify: false + + # -- Global command arguments to be passed to all traefik's pods + globalArguments: +@@ -587,13 +585,12 @@ ports: + traefik: + port: 9000 + # -- Use hostPort if set. +- # hostPort: 9000 +- # ++ hostPort: # @schema type:[integer, null]; minimum:0 + # -- Use hostIP if set. If not set, Kubernetes will default to 0.0.0.0, which + # means it's listening on all your interfaces and all your IPs. You may want + # to set this value if you need traefik to listen on specific interface + # only. +- # hostIP: 192.168.100.10 ++ hostIP: # @schema type:[string, null] + + # Defines whether the port is exposed if service.type is LoadBalancer or + # NodePort. +@@ -617,112 +614,93 @@ ports: + default: true + exposedPort: 80 + ## -- Different target traefik port on the cluster, useful for IP type LB +- # targetPort: 80 ++ targetPort: # @schema type:[integer, null]; minimum:0 + # The port protocol (TCP/UDP) + protocol: TCP +- # -- Use nodeport if set. This is useful if you have configured Traefik in a +- # LoadBalancer. +- # nodePort: 32080 ++ # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) ++ nodePort: # @schema type:[integer, null]; minimum:0 + # Port Redirections + # Added in 2.2, you can make permanent redirects via entrypoints. + # https://docs.traefik.io/routing/entrypoints/#redirection +- # redirectTo: +- # port: websecure +- # (Optional) +- # priority: 10 +- # permanent: true +- # +- # -- Trust forwarded headers information (X-Forwarded-*). +- # forwardedHeaders: +- # trustedIPs: [] +- # insecure: false +- # +- # -- Enable the Proxy Protocol header parsing for the entry point +- # proxyProtocol: +- # trustedIPs: [] +- # insecure: false +- # ++ redirectTo: {} ++ forwardedHeaders: ++ # -- Trust forwarded headers information (X-Forwarded-*). ++ trustedIPs: [] ++ insecure: false ++ proxyProtocol: ++ # -- Enable the Proxy Protocol header parsing for the entry point ++ trustedIPs: [] ++ insecure: false + # -- Set transport settings for the entrypoint; see also + # https://doc.traefik.io/traefik/routing/entrypoints/#transport + transport: + respondingTimeouts: +- readTimeout: +- writeTimeout: +- idleTimeout: ++ readTimeout: # @schema type:[string, integer, null] ++ writeTimeout: # @schema type:[string, integer, null] ++ idleTimeout: # @schema type:[string, integer, null] + lifeCycle: +- requestAcceptGraceTimeout: +- graceTimeOut: +- keepAliveMaxRequests: +- keepAliveMaxTime: ++ requestAcceptGraceTimeout: # @schema type:[string, integer, null] ++ graceTimeOut: # @schema type:[string, integer, null] ++ keepAliveMaxRequests: # @schema type:[integer, null]; minimum:0 ++ keepAliveMaxTime: # @schema type:[string, integer, null] + websecure: + ## -- Enable this entrypoint as a default entrypoint. When a service doesn't explicitly set an entrypoint it will only use this entrypoint. + # asDefault: true + port: 8443 +- # hostPort: 8443 +- # containerPort: 8443 ++ hostPort: # @schema type:[integer, null]; minimum:0 ++ containerPort: # @schema type:[integer, null]; minimum:0 + expose: + default: true + exposedPort: 443 + ## -- Different target traefik port on the cluster, useful for IP type LB +- # targetPort: 80 ++ targetPort: # @schema type:[integer, null]; minimum:0 + ## -- The port protocol (TCP/UDP) + protocol: TCP +- # nodePort: 32443 +- ## -- Specify an application protocol. This may be used as a hint for a Layer 7 load balancer. +- # appProtocol: https +- # +- ## -- Enable HTTP/3 on the entrypoint +- ## Enabling it will also enable http3 experimental feature +- ## https://doc.traefik.io/traefik/routing/entrypoints/#http3 +- ## There are known limitations when trying to listen on same ports for +- ## TCP & UDP (Http3). There is a workaround in this chart using dual Service. +- ## https://github.com/kubernetes/kubernetes/issues/47249#issuecomment-587960741 ++ # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) ++ nodePort: # @schema type:[integer, null]; minimum:0 ++ # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol) ++ appProtocol: # @schema type:[string, null] ++ # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#allowacmebypass) ++ allowACMEByPass: false + http3: ++ ## -- Enable HTTP/3 on the entrypoint ++ ## Enabling it will also enable http3 experimental feature ++ ## https://doc.traefik.io/traefik/routing/entrypoints/#http3 ++ ## There are known limitations when trying to listen on same ports for ++ ## TCP & UDP (Http3). There is a workaround in this chart using dual Service. ++ ## https://github.com/kubernetes/kubernetes/issues/47249#issuecomment-587960741 + enabled: false +- # advertisedPort: 4443 +- # +- # -- Trust forwarded headers information (X-Forwarded-*). +- # forwardedHeaders: +- # trustedIPs: [] +- # insecure: false +- # +- # -- Enable the Proxy Protocol header parsing for the entry point +- # proxyProtocol: +- # trustedIPs: [] +- # insecure: false +- # +- # -- Set transport settings for the entrypoint; see also +- # https://doc.traefik.io/traefik/routing/entrypoints/#transport ++ advertisedPort: # @schema type:[integer, null]; minimum:0 ++ forwardedHeaders: ++ # -- Trust forwarded headers information (X-Forwarded-*). ++ trustedIPs: [] ++ insecure: false ++ proxyProtocol: ++ # -- Enable the Proxy Protocol header parsing for the entry point ++ trustedIPs: [] ++ insecure: false ++ # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#transport) + transport: + respondingTimeouts: +- readTimeout: +- writeTimeout: +- idleTimeout: ++ readTimeout: # @schema type:[string, integer, null] ++ writeTimeout: # @schema type:[string, integer, null] ++ idleTimeout: # @schema type:[string, integer, null] + lifeCycle: +- requestAcceptGraceTimeout: +- graceTimeOut: +- keepAliveMaxRequests: +- keepAliveMaxTime: +- # +- ## Set TLS at the entrypoint +- ## https://doc.traefik.io/traefik/routing/entrypoints/#tls ++ requestAcceptGraceTimeout: # @schema type:[string, integer, null] ++ graceTimeOut: # @schema type:[string, integer, null] ++ keepAliveMaxRequests: # @schema type:[integer, null]; minimum:0 ++ keepAliveMaxTime: # @schema type:[string, integer, null] ++ # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#tls) + tls: + enabled: true +- # this is the name of a TLSOption definition + options: "" + certResolver: "" + domains: [] +- # - main: example.com +- # sans: +- # - foo.example.com +- # - bar.example.com +- # + # -- One can apply Middlewares on an entrypoint + # https://doc.traefik.io/traefik/middlewares/overview/ + # https://doc.traefik.io/traefik/routing/entrypoints/#middlewares + # -- /!\ It introduces here a link between your static configuration and your dynamic configuration /!\ + # It follows the provider naming convention: https://doc.traefik.io/traefik/providers/overview/#provider-namespace +- # middlewares: + # - namespace-name1@kubernetescrd + # - namespace-name2@kubernetescrd + middlewares: [] +@@ -730,10 +708,6 @@ ports: + # -- When using hostNetwork, use another port to avoid conflict with node exporter: + # https://github.com/prometheus/prometheus/wiki/Default-port-allocations + port: 9100 +- # hostPort: 9100 +- # Defines whether the port is exposed if service.type is LoadBalancer or +- # NodePort. +- # + # -- You may not want to expose the metrics port on production deployments. + # If you want to access it from outside your cluster, + # use `kubectl port-forward` or create a secure ingress +@@ -810,15 +784,15 @@ persistence: + # It can be used to store TLS certificates, see `storage` in certResolvers + enabled: false + name: data +- # existingClaim: "" ++ existingClaim: "" + accessMode: ReadWriteOnce + size: 128Mi +- # storageClass: "" +- # volumeName: "" ++ storageClass: "" ++ volumeName: "" + path: /data + annotations: {} + # -- Only mount a subpath of the Volume into the pod +- # subPath: "" ++ subPath: "" + + # -- Certificates resolvers configuration. + # Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers +@@ -832,7 +806,7 @@ certResolvers: {} + hostNetwork: false + + # -- Whether Role Based Access Control objects like roles and rolebindings should be created +-rbac: ++rbac: # @schema additionalProperties: false + enabled: true + # When set to true: + # 1. Use `Role` and `RoleBinding` instead of `ClusterRole` and `ClusterRoleBinding`. +@@ -843,7 +817,7 @@ rbac: + namespaced: false + # Enable user-facing roles + # https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles +- # aggregateTo: [ "admin" ] ++ aggregateTo: [] + # List of Kubernetes secrets that are accessible for Traefik. If empty, then access is granted to every secret. + secretResourceNames: [] + +@@ -852,7 +826,7 @@ podSecurityPolicy: + enabled: false + + # -- The service account the pods will use to interact with the Kubernetes API +-serviceAccount: ++serviceAccount: # @schema additionalProperties: false + # If set, an existing service account is used + # If not set, a service account is created automatically using the fullname template + name: "" +@@ -918,54 +892,54 @@ extraObjects: [] + + # -- This field override the default Release Namespace for Helm. + # It will not affect optional CRDs such as `ServiceMonitor` and `PrometheusRules` +-namespaceOverride: ++namespaceOverride: "" + + ## -- This field override the default app.kubernetes.io/instance label for all Objects. +-instanceLabelOverride: ++instanceLabelOverride: "" + + # Traefik Hub configuration. See https://doc.traefik.io/traefik-hub/ + hub: + # -- Name of `Secret` with key 'token' set to a valid license token. + # It enables API Gateway. +- token: ++ token: "" + apimanagement: + # -- Set to true in order to enable API Management. Requires a valid license token. +- enabled: ++ enabled: false + admission: + # -- WebHook admission server listen address. Default: "0.0.0.0:9943". +- listenAddr: ++ listenAddr: "" + # -- Certificate of the WebHook admission server. Default: "hub-agent-cert". +- secretName: ++ secretName: "" + + ratelimit: + redis: + # -- Enable Redis Cluster. Default: true. +- cluster: ++ cluster: # @schema type:[boolean, null] + # -- Database used to store information. Default: "0". +- database: ++ database: # @schema type:[string, null] + # -- Endpoints of the Redis instances to connect to. Default: "". +- endpoints: ++ endpoints: "" + # -- The username to use when connecting to Redis endpoints. Default: "". +- username: ++ username: "" + # -- The password to use when connecting to Redis endpoints. Default: "". +- password: ++ password: "" + sentinel: + # -- Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". +- masterset: ++ masterset: "" + # -- Username to use for sentinel authentication (can be different from endpoint username). Default: "". +- username: ++ username: "" + # -- Password to use for sentinel authentication (can be different from endpoint password). Default: "". +- password: ++ password: "" + # -- Timeout applied on connection with redis. Default: "0s". +- timeout: ++ timeout: "" + tls: + # -- Path to the certificate authority used for the secured connection. +- ca: ++ ca: "" + # -- Path to the public certificate used for the secure connection. +- cert: ++ cert: "" + # -- Path to the private key used for the secure connection. +- key: ++ key: "" + # -- When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. +- insecureSkipVerify: ++ insecureSkipVerify: false + # Enable export of errors logs to the platform. Default: true. +- sendlogs: ++ sendlogs: # @schema type:[boolean, null] +``` + +## 31.0.0 ![AppVersion: v3.1.2](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.2&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-09-03 + +* fix(Traefik Hub): update CRDs to v1.5.0 +* fix(HTTP3): split udp and tcp Service when service.single is false +* fix!: 🐛 set allowEmptyServices to true by default +* feat(Traefik Hub): update CRDs to v1.7.0 +* chore(release): 🚀 publish v31.0.0 + +### Default value changes + +```diff +diff --git a/traefik/values.yaml b/traefik/values.yaml +index 78eeacf..2232d9e 100644 +--- a/traefik/values.yaml ++++ b/traefik/values.yaml +@@ -260,7 +260,7 @@ providers: + # -- Allows to reference ExternalName services in IngressRoute + allowExternalNameServices: false + # -- Allows to return 503 when there is no endpoints available +- allowEmptyServices: false ++ allowEmptyServices: true + # -- When the parameter is set, only resources containing an annotation with the same value are processed. Otherwise, resources missing the annotation, having an empty value, or the value traefik are processed. It will also set required annotation on Dashboard and Healthcheck IngressRoute when enabled. + ingressClass: + # labelSelector: environment=production,method=traefik +@@ -275,7 +275,7 @@ providers: + # -- Allows to reference ExternalName services in Ingress + allowExternalNameServices: false + # -- Allows to return 503 when there is no endpoints available +- allowEmptyServices: false ++ allowEmptyServices: true + # -- When ingressClass is set, only Ingresses containing an annotation with the same value are processed. Otherwise, Ingresses missing the annotation, having an empty value, or the value traefik are processed. + ingressClass: + # labelSelector: environment=production,method=traefik +``` + +## 30.1.0 ![AppVersion: v3.1.2](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.2&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) + +**Release date:** 2024-08-14 + +* fix: disable default HTTPS listener for gateway +* fix(Gateway API): wildcard support in hostname +* fix(Gateway API): use Standard channel by default +* feat: ✨ rework namespaced RBAC with `disableClusterScopeResources` +* chore(release): 🚀 publish v30.1.0 +* chore(deps): update traefik docker tag to v3.1.2 +* chore(deps): update traefik docker tag to v3.1.1 + +### Default value changes + +```diff +diff --git a/traefik/values.yaml b/traefik/values.yaml +index 83b6d98..78eeacf 100644 +--- a/traefik/values.yaml ++++ b/traefik/values.yaml +@@ -150,20 +150,22 @@ gateway: + protocol: HTTP + # -- Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces + namespacePolicy: +- websecure: +- # -- Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. +- # The port must match a port declared in ports section. +- port: 8443 +- # -- Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) +- hostname: +- # Specify expected protocol on this listener See [ProtocolType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ProtocolType) +- protocol: HTTPS +- # -- Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces) +- namespacePolicy: +- # -- Add certificates for TLS or HTTPS protocols. See [GatewayTLSConfig](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.GatewayTLSConfig) +- certificateRefs: +- # -- TLS behavior for the TLS session initiated by the client. See [TLSModeType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.TLSModeType). +- mode: ++ # websecure listener is disabled by default because certificateRefs needs to be added, ++ # or you may specify TLS protocol with Passthrough mode and add "--providers.kubernetesGateway.experimentalChannel=true" in additionalArguments section. ++ # websecure: ++ # # -- Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. ++ # # The port must match a port declared in ports section. ++ # port: 8443 ++ # # -- Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) ++ # hostname: ++ # # Specify expected protocol on this listener See [ProtocolType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ProtocolType) ++ # protocol: HTTPS ++ # # -- Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces) ++ # namespacePolicy: ++ # # -- Add certificates for TLS or HTTPS protocols. See [GatewayTLSConfig](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.GatewayTLSConfig) ++ # certificateRefs: ++ # # -- TLS behavior for the TLS session initiated by the client. See [TLSModeType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.TLSModeType). ++ # mode: + + gatewayClass: + # -- When providers.kubernetesGateway.enabled and gateway.enabled, deploy a default gatewayClass +@@ -279,10 +281,6 @@ providers: + # labelSelector: environment=production,method=traefik + # -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. + namespaces: [] +- # - "default" +- # Disable cluster IngressClass Lookup - Requires Traefik V3. +- # When combined with rbac.namespaced: true, ClusterRole will not be created and ingresses must use kubernetes.io/ingress.class annotation instead of spec.ingressClassName. +- disableIngressClassLookup: false + # IP used for Kubernetes Ingress endpoints + publishedService: + enabled: false +@@ -836,9 +834,12 @@ hostNetwork: false + # -- Whether Role Based Access Control objects like roles and rolebindings should be created + rbac: + enabled: true +- # If set to false, installs ClusterRole and ClusterRoleBinding so Traefik can be used across namespaces. +- # If set to true, installs Role and RoleBinding instead of ClusterRole/ClusterRoleBinding. Providers will only watch target namespace. +- # When combined with providers.kubernetesIngress.disableIngressClassLookup: true and Traefik V3, ClusterRole to watch IngressClass is also disabled. ++ # When set to true: ++ # 1. Use `Role` and `RoleBinding` instead of `ClusterRole` and `ClusterRoleBinding`. ++ # 2. Set `disableIngressClassLookup` on Kubernetes Ingress providers with Traefik Proxy v3 until v3.1.1 ++ # 3. Set `disableClusterScopeResources` on Kubernetes Ingress and CRD providers with Traefik Proxy v3.1.2+ ++ # **NOTE**: `IngressClass`, `NodePortLB` and **Gateway** provider cannot be used with namespaced RBAC. ++ # See [upstream documentation](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#disableclusterscoperesources) for more details. + namespaced: false + # Enable user-facing roles + # https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles +``` + ## 30.0.2 ![AppVersion: v3.1.0](https://img.shields.io/static/v1?label=AppVersion&message=v3.1.0&color=success&logo=) ![Kubernetes: >=1.22.0-0](https://img.shields.io/static/v1?label=Kubernetes&message=%3E%3D1.22.0-0&color=informational&logo=kubernetes) ![Helm: v3](https://img.shields.io/static/v1?label=Helm&message=v3&color=informational&logo=helm) **Release date:** 2024-07-30 diff --git a/charts/traefik/traefik/Chart.yaml b/charts/traefik/traefik/Chart.yaml index 63145f7..0d1220a 100644 --- a/charts/traefik/traefik/Chart.yaml +++ b/charts/traefik/traefik/Chart.yaml @@ -1,8 +1,20 @@ annotations: - artifacthub.io/changes: "- \"fix(Traefik Hub): missing RBACs for Traefik Hub\"\n- - \"chore(release): \U0001F680 publish v30.0.2\"\n" + artifacthub.io/changes: "- \"fix: \U0001F41B http3 with internal service\"\n- \"fix: + use correct children indentation for logs.access.filters\"\n- \"fix(schema): :bug: + targetPort can also be a string\"\n- \"fix(certificateResolvers)!: :boom: :bug: + use same syntax in Chart and in Traefik\"\n- \"fix(Traefik)!: :boom: set 8080 + as default port for `traefik` entrypoint\"\n- \"fix(Traefik Hub): RBAC for distributedAcme\"\n- + \"fix(Kubernetes Ingress)!: :boom: :sparkles: enable publishedService by default\"\n- + \"fix(Gateway API): :bug: add missing required RBAC for v3.2 with experimental + Channel\"\n- \"fix(Env Variables)!: allow extending env without overwrite\"\n- + \"feat(deps): update traefik docker tag to v3.2.0\"\n- \"feat(deps): update traefik + docker tag to v3.1.6\"\n- \"feat(Traefik): ✨ support Gateway API statusAddress\"\n- + \"feat(Traefik Proxy): CRDs for v3.2+\"\n- \"feat(Gateway API): :sparkles: standard + install CRD v1.2.0\"\n- \"feat(Gateway API): :sparkles: add infrastructure in + the values\"\n- \"chore: allow TRACE log level\"\n- \"chore(release): \U0001F680 + publish v33.0.0\"\n- \"Update topology spread constraints comments\"\n" apiVersion: v2 -appVersion: v3.1.0 +appVersion: v3.2.0 description: A Traefik based Kubernetes ingress controller home: https://traefik.io/ icon: https://raw.githubusercontent.com/traefik/traefik/v2.3/docs/content/assets/img/traefik.logo.png @@ -24,4 +36,4 @@ sources: - https://github.com/traefik/traefik - https://github.com/traefik/traefik-helm-chart type: application -version: 30.0.2 +version: 33.0.0 diff --git a/charts/traefik/traefik/EXAMPLES.md b/charts/traefik/traefik/EXAMPLES.md index ee98168..6c70f5a 100644 --- a/charts/traefik/traefik/EXAMPLES.md +++ b/charts/traefik/traefik/EXAMPLES.md @@ -97,10 +97,10 @@ ingressRoute: The traefik admin port can be forwarded locally: ```bash -kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000 +kubectl port-forward $(kubectl get pods --selector "app.kubernetes.io/name=traefik" --output=name) 8080:8080 ``` -This command makes the dashboard accessible on the url: http://127.0.0.1:9000/dashboard/ +This command makes the dashboard accessible on the url: http://127.0.0.1:8080/dashboard/ # Publish and protect Traefik Dashboard with basic Auth @@ -173,7 +173,7 @@ extraObjects: ports: - port: 8080 name: traefik - targetPort: 9000 + targetPort: 8080 protocol: TCP - apiVersion: v1 @@ -305,7 +305,7 @@ extraObjects: config: type: HTTP httpHealthCheck: - port: 9000 + port: 8080 requestPath: /ping targetRef: group: "" @@ -331,14 +331,15 @@ Here is a more complete example, using also native Let's encrypt feature of Trae persistence: enabled: true size: 128Mi -certResolvers: +certificatesResolvers: letsencrypt: - email: "{{ letsencrypt_email }}" - #caServer: https://acme-v02.api.letsencrypt.org/directory # Production server - caServer: https://acme-staging-v02.api.letsencrypt.org/directory # Staging server - dnsChallenge: - provider: azuredns - storage: /data/acme.json + acme: + email: "{{ letsencrypt_email }}" + #caServer: https://acme-v02.api.letsencrypt.org/directory # Production server + caServer: https://acme-staging-v02.api.letsencrypt.org/directory # Staging server + dnsChallenge: + provider: azuredns + storage: /data/acme.json env: - name: AZURE_CLIENT_ID value: "{{ azure_dns_challenge_application_id }}" @@ -416,6 +417,17 @@ ports: enabled: true ``` +You can also create two `Service`, one for TCP and one for UDP: + +```yaml +ports: + websecure: + http3: + enabled: true +service: + single: false +``` + # Use PROXY protocol on Digital Ocean PROXY protocol is a protocol for sending client connection information, such as origin IP addresses and port numbers, to the final backend server, rather than discarding it at the load balancer. @@ -480,7 +492,7 @@ See [#396](https://github.com/traefik/traefik-helm-chart/issues/396) for more de Once the provider is ready, it can be used in an `IngressRoute`: ```yaml -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: [...] @@ -491,6 +503,8 @@ spec: certResolver: letsencrypt ``` +:information_source: Change `apiVersion` to `traefik.containo.us/v1alpha1` for charts prior to v28.0.0 + See [the list of supported providers](https://doc.traefik.io/traefik/https/acme/#providers) for others. ## Example with CloudFlare @@ -516,11 +530,12 @@ stringData: persistence: enabled: true storageClass: xxx -certResolvers: +certificatesResolvers: letsencrypt: - dnsChallenge: - provider: cloudflare - storage: /data/acme.json + acme: + dnsChallenge: + provider: cloudflare + storage: /data/acme.json env: - name: CF_DNS_API_TOKEN valueFrom: @@ -540,6 +555,9 @@ podSecurityContext: fsGroupChangePolicy: "OnRootMismatch" ``` +>[!NOTE] +> With [Traefik Hub](https://traefik.io/traefik-hub/), certificates can be stored as a `Secret` on Kubernetes with `distributedAcme` resolver. + # Provide default certificate with cert-manager and CloudFlare DNS Setup: @@ -683,7 +701,7 @@ spec: app.kubernetes.io/name: traefik app.kubernetes.io/instance: traefik-traefik ports: - - port: 9000 + - port: 8080 name: "traefik" targetPort: traefik protocol: TCP @@ -822,8 +840,6 @@ metrics: One can use the new stable kubernetes gateway API provider setting the following _values_: ```yaml -image: - tag: v3.1.0-rc3 providers: kubernetesGateway: enabled: true @@ -891,6 +907,8 @@ Once it's applied, whoami should be accessible on http://whoami.docker.localhost +:information_source: In this example, `Deployment` and `HTTPRoute` should be deployed in the same namespace as the Traefik Gateway: Chart namespace. + # Use Kubernetes Gateway API with cert-manager One can use the new stable kubernetes gateway API provider with automatic TLS certificates delivery (with cert-manager) setting the following _values_: @@ -906,6 +924,8 @@ gateway: listeners: websecure: hostname: whoami.docker.localhost + port: 8443 + protocol: HTTPS certificateRefs: - name: whoami-tls ``` diff --git a/charts/traefik/traefik/Guidelines.md b/charts/traefik/traefik/Guidelines.md index 19937d4..3b72a40 100644 --- a/charts/traefik/traefik/Guidelines.md +++ b/charts/traefik/traefik/Guidelines.md @@ -4,77 +4,19 @@ This document outlines the guidelines for developing, managing and extending the This Helm Chart is documented using field description from comments with [helm-docs](https://github.com/norwoodj/helm-docs). -Optionality -All non-critical features (Features not mandatory to starting Traefik) in the helm chart must be optional. All non-critical features should be disabled (commented out) in the values.yaml file. All optional non-critical features should be disabled (commented out) in the values.yaml file, and have a comment # (Optional) in the line above. This allows minimal configuration, and ease of extension. +It comes with a JSON schema generated from values with [helm schema](https://github.com/losisin/helm-values-schema-json) plugin. ## Feature Example ```yaml -image: - # -- Traefik image host registry - registry: docker.io +logs: + general: + # -- Set [logs format](https://doc.traefik.io/traefik/observability/logs/#format) + format: # @schema enum:["common", "json", null]; type:[string, null]; default: "common" ``` -This feature is expected and therefore is defined clearly in the values.yaml file. - -## Optional Feature Example - -```yaml -# storage: -# controlNode: -# type: emptyDir -``` - -This feature is optional, non-critical, and therefore is commented out by default in the values.yaml file. - -To allow this, template blocks that use this need to recursively test for existence of values before using them: - -```yaml -{{- if .Values.storage}} - {{- if .Values.storage.controlNode }} - //code - {{ .Values.storage.controlNode.type }} - {{- end }} -{{- end }} -``` - -The non-critical feature defaults should be populated so that they can be enabled by simply uncommenting the section in the values.yaml file. - -## Optional Non-Critical Feature Example - -```yaml -# storage: -# controlNode: -# type: emptyDir -# # (Optional) -# # volume: 1Gi -``` - -The volume option is clearly optional, and non-critical. It is commented out (apart from the storage section comment block), and is also preceded by a comment of # (Optional) in the preceding line. This facilitates configuration, when the storage section is uncommented, the optional features are still disabled by default. - -Similar to non-critical features, these options need to be tested for existence before use in the template. - -Note -There can be optional values in critical features. These should just be added as an uncommented non-critical feature: - -```yaml -image: - name: traefik - tag: 2.0.0 - # (Optional) - # pullPolicy: IfNotPresent -``` - -Also, the first value under the primary value key does not require an optional comment: - -```yaml -# ports: -# http: 80 -# # (Optional) -# # https: 443 -``` - -This is because if the main subkey is not defined, the entirety of the feature is optional. +Documention is on the first comment, starting with `# --` +Specific instructions for schema, when needed, are done with the inline comment starting with `# @schema`. ## Whitespace diff --git a/charts/traefik/traefik/VALUES.md b/charts/traefik/traefik/VALUES.md index 1ca3baf..aa3d014 100644 --- a/charts/traefik/traefik/VALUES.md +++ b/charts/traefik/traefik/VALUES.md @@ -1,6 +1,6 @@ # traefik -![Version: 30.0.2](https://img.shields.io/badge/Version-30.0.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v3.1.0](https://img.shields.io/badge/AppVersion-v3.1.0-informational?style=flat-square) +![Version: 33.0.0](https://img.shields.io/badge/Version-33.0.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v3.2.0](https://img.shields.io/badge/AppVersion-v3.2.0-informational?style=flat-square) A Traefik based Kubernetes ingress controller @@ -32,73 +32,76 @@ Kubernetes: `>=1.22.0-0` | additionalVolumeMounts | list | `[]` | Additional volumeMounts to add to the Traefik container | | affinity | object | `{}` | on nodes where no other traefik pods are scheduled. It should be used when hostNetwork: true to prevent port conflicts | | autoscaling.enabled | bool | `false` | Create HorizontalPodAutoscaler object. See EXAMPLES.md for more details. | -| certResolvers | object | `{}` | Certificates resolvers configuration. Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers See EXAMPLES.md for more details. | +| certificatesResolvers | object | `{}` | Certificates resolvers configuration. Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers See EXAMPLES.md for more details. | | commonLabels | object | `{}` | Add additional label to all resources | -| core.defaultRuleSyntax | string | `nil` | Can be used to use globally v2 router syntax See https://doc.traefik.io/traefik/v3.0/migration/v2-to-v3/#new-v3-syntax-notable-changes | +| core.defaultRuleSyntax | string | `""` | Can be used to use globally v2 router syntax See https://doc.traefik.io/traefik/v3.0/migration/v2-to-v3/#new-v3-syntax-notable-changes | | deployment.additionalContainers | list | `[]` | Additional containers (e.g. for metric offloading sidecars) | | deployment.additionalVolumes | list | `[]` | Additional volumes available for use with initContainers and additionalContainers | | deployment.annotations | object | `{}` | Additional deployment annotations (e.g. for jaeger-operator sidecar injection) | | deployment.dnsConfig | object | `{}` | Custom pod [DNS config](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#poddnsconfig-v1-core) | +| deployment.dnsPolicy | string | `""` | Custom pod DNS policy. Apply if `hostNetwork: true` | | deployment.enabled | bool | `true` | Enable deployment | +| deployment.healthchecksHost | string | `""` | | +| deployment.healthchecksPort | string | `nil` | | +| deployment.healthchecksScheme | string | `nil` | | | deployment.hostAliases | list | `[]` | Custom [host aliases](https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/) | | deployment.imagePullSecrets | list | `[]` | Pull secret for fetching traefik container image | | deployment.initContainers | list | `[]` | Additional initContainers (e.g. for setting file permission as shown below) | | deployment.kind | string | `"Deployment"` | Deployment or DaemonSet | | deployment.labels | object | `{}` | Additional deployment labels (e.g. for filtering deployment by custom labels) | | deployment.lifecycle | object | `{}` | Pod lifecycle actions | +| deployment.livenessPath | string | `""` | Override the liveness path. Default: /ping | | deployment.minReadySeconds | int | `0` | The minimum number of seconds Traefik needs to be up and running before the DaemonSet/Deployment controller considers it available | | deployment.podAnnotations | object | `{}` | Additional pod annotations (e.g. for mesh injection or prometheus scraping) It supports templating. One can set it with values like traefik/name: '{{ template "traefik.name" . }}' | | deployment.podLabels | object | `{}` | Additional Pod labels (e.g. for filtering Pod by custom labels) | +| deployment.readinessPath | string | `""` | | | deployment.replicas | int | `1` | Number of pods of the deployment (only applies when kind == Deployment) | -| deployment.runtimeClassName | string | `nil` | Set a runtimeClassName on pod | +| deployment.revisionHistoryLimit | string | `nil` | Number of old history to retain to allow rollback (If not set, default Kubernetes value is set to 10) | +| deployment.runtimeClassName | string | `""` | Set a runtimeClassName on pod | | deployment.shareProcessNamespace | bool | `false` | Use process namespace sharing | | deployment.terminationGracePeriodSeconds | int | `60` | Amount of time (in seconds) before Kubernetes will send the SIGKILL signal if Traefik does not shut down | -| env | list | See _values.yaml_ | Environment variables to be passed to Traefik's binary | +| env | list | See _values.yaml_ | Additional Environment variables to be passed to Traefik's binary | | envFrom | list | `[]` | Environment variables to be passed to Traefik's binary from configMaps or secrets | | experimental.kubernetesGateway.enabled | bool | `false` | Enable traefik experimental GatewayClass CRD | | experimental.plugins | object | `{}` | Enable traefik experimental plugins | | extraObjects | list | `[]` | Extra objects to deploy (value evaluated as a template) In some cases, it can avoid the need for additional, extended or adhoc deployments. See #595 for more details and traefik/tests/values/extra.yaml for example. | -| gateway.annotations | string | `nil` | Additional gateway annotations (e.g. for cert-manager.io/issuer) | +| gateway.annotations | object | `{}` | Additional gateway annotations (e.g. for cert-manager.io/issuer) | | gateway.enabled | bool | `true` | When providers.kubernetesGateway.enabled, deploy a default gateway | -| gateway.listeners | object | `{"web":{"hostname":null,"namespacePolicy":null,"port":8000,"protocol":"HTTP"},"websecure":{"certificateRefs":null,"hostname":null,"mode":null,"namespacePolicy":null,"port":8443,"protocol":"HTTPS"}}` | Define listeners | -| gateway.listeners.web.hostname | string | `nil` | Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) | +| gateway.infrastructure | object | `{}` | [Infrastructure](https://kubernetes.io/blog/2023/11/28/gateway-api-ga/#gateway-infrastructure-labels) | +| gateway.listeners | object | `{"web":{"hostname":"","namespacePolicy":null,"port":8000,"protocol":"HTTP"}}` | Define listeners | +| gateway.listeners.web.hostname | string | `""` | Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) | | gateway.listeners.web.namespacePolicy | string | `nil` | Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces | | gateway.listeners.web.port | int | `8000` | Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. The port must match a port declared in ports section. | -| gateway.listeners.websecure.certificateRefs | string | `nil` | Add certificates for TLS or HTTPS protocols. See [GatewayTLSConfig](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.GatewayTLSConfig) | -| gateway.listeners.websecure.hostname | string | `nil` | Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) | -| gateway.listeners.websecure.mode | string | `nil` | TLS behavior for the TLS session initiated by the client. See [TLSModeType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.TLSModeType). | -| gateway.listeners.websecure.namespacePolicy | string | `nil` | Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces) | -| gateway.listeners.websecure.port | int | `8443` | Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. The port must match a port declared in ports section. | -| gateway.name | string | `nil` | Set a custom name to gateway | -| gateway.namespace | string | `nil` | By default, Gateway is created in the same `Namespace` than Traefik. | +| gateway.name | string | `""` | Set a custom name to gateway | +| gateway.namespace | string | `""` | By default, Gateway is created in the same `Namespace` than Traefik. | | gatewayClass.enabled | bool | `true` | When providers.kubernetesGateway.enabled and gateway.enabled, deploy a default gatewayClass | -| gatewayClass.labels | string | `nil` | Additional gatewayClass labels (e.g. for filtering gateway objects by custom labels) | -| gatewayClass.name | string | `nil` | Set a custom name to GatewayClass | +| gatewayClass.labels | object | `{}` | Additional gatewayClass labels (e.g. for filtering gateway objects by custom labels) | +| gatewayClass.name | string | `""` | Set a custom name to GatewayClass | | globalArguments | list | `["--global.checknewversion","--global.sendanonymoususage"]` | Global command arguments to be passed to all traefik's pods | | hostNetwork | bool | `false` | If hostNetwork is true, runs traefik in the host network namespace To prevent unschedulabel pods due to port collisions, if hostNetwork=true and replicas>1, a pod anti-affinity is recommended and will be set if the affinity is left as default. | -| hub.apimanagement.admission.listenAddr | string | `nil` | WebHook admission server listen address. Default: "0.0.0.0:9943". | -| hub.apimanagement.admission.secretName | string | `nil` | Certificate of the WebHook admission server. Default: "hub-agent-cert". | -| hub.apimanagement.enabled | string | `nil` | Set to true in order to enable API Management. Requires a valid license token. | -| hub.ratelimit.redis.cluster | string | `nil` | Enable Redis Cluster. Default: true. | -| hub.ratelimit.redis.database | string | `nil` | Database used to store information. Default: "0". | -| hub.ratelimit.redis.endpoints | string | `nil` | Endpoints of the Redis instances to connect to. Default: "". | -| hub.ratelimit.redis.password | string | `nil` | The password to use when connecting to Redis endpoints. Default: "". | -| hub.ratelimit.redis.sentinel.masterset | string | `nil` | Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". | -| hub.ratelimit.redis.sentinel.password | string | `nil` | Password to use for sentinel authentication (can be different from endpoint password). Default: "". | -| hub.ratelimit.redis.sentinel.username | string | `nil` | Username to use for sentinel authentication (can be different from endpoint username). Default: "". | -| hub.ratelimit.redis.timeout | string | `nil` | Timeout applied on connection with redis. Default: "0s". | -| hub.ratelimit.redis.tls.ca | string | `nil` | Path to the certificate authority used for the secured connection. | -| hub.ratelimit.redis.tls.cert | string | `nil` | Path to the public certificate used for the secure connection. | -| hub.ratelimit.redis.tls.insecureSkipVerify | string | `nil` | When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. | -| hub.ratelimit.redis.tls.key | string | `nil` | Path to the private key used for the secure connection. | -| hub.ratelimit.redis.username | string | `nil` | The username to use when connecting to Redis endpoints. Default: "". | +| hub.apimanagement.admission.listenAddr | string | `""` | WebHook admission server listen address. Default: "0.0.0.0:9943". | +| hub.apimanagement.admission.secretName | string | `""` | Certificate of the WebHook admission server. Default: "hub-agent-cert". | +| hub.apimanagement.enabled | bool | `false` | Set to true in order to enable API Management. Requires a valid license token. | +| hub.redis.cluster | string | `nil` | Enable Redis Cluster. Default: true. | +| hub.redis.database | string | `nil` | Database used to store information. Default: "0". | +| hub.redis.endpoints | string | `""` | Endpoints of the Redis instances to connect to. Default: "". | +| hub.redis.password | string | `""` | The password to use when connecting to Redis endpoints. Default: "". | +| hub.redis.sentinel.masterset | string | `""` | Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". | +| hub.redis.sentinel.password | string | `""` | Password to use for sentinel authentication (can be different from endpoint password). Default: "". | +| hub.redis.sentinel.username | string | `""` | Username to use for sentinel authentication (can be different from endpoint username). Default: "". | +| hub.redis.timeout | string | `""` | Timeout applied on connection with redis. Default: "0s". | +| hub.redis.tls.ca | string | `""` | Path to the certificate authority used for the secured connection. | +| hub.redis.tls.cert | string | `""` | Path to the public certificate used for the secure connection. | +| hub.redis.tls.insecureSkipVerify | bool | `false` | When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. | +| hub.redis.tls.key | string | `""` | Path to the private key used for the secure connection. | +| hub.redis.username | string | `""` | The username to use when connecting to Redis endpoints. Default: "". | | hub.sendlogs | string | `nil` | | -| hub.token | string | `nil` | Name of `Secret` with key 'token' set to a valid license token. It enables API Gateway. | +| hub.token | string | `""` | Name of `Secret` with key 'token' set to a valid license token. It enables API Gateway. | | image.pullPolicy | string | `"IfNotPresent"` | Traefik image pull policy | | image.registry | string | `"docker.io"` | Traefik image host registry | | image.repository | string | `"traefik"` | Traefik image repository | | image.tag | string | `nil` | defaults to appVersion | -| ingressClass | object | `{"enabled":true,"isDefaultClass":true}` | Create a default IngressClass for Traefik | +| ingressClass | object | `{"enabled":true,"isDefaultClass":true,"name":""}` | Create a default IngressClass for Traefik | | ingressRoute.dashboard.annotations | object | `{}` | Additional ingressRoute annotations (e.g. for kubernetes.io/ingress.class) | | ingressRoute.dashboard.enabled | bool | `false` | Create an IngressRoute for the dashboard | | ingressRoute.dashboard.entryPoints | list | `["traefik"]` | Specify the allowed entrypoints to use for the dashboard ingress route, (e.g. traefik, web, websecure). By default, it's using traefik entrypoint, which is not exposed. /!\ Do not expose your dashboard without any protection over the internet /!\ | @@ -115,74 +118,88 @@ Kubernetes: `>=1.22.0-0` | ingressRoute.healthcheck.middlewares | list | `[]` | Additional ingressRoute middlewares (e.g. for authentication) | | ingressRoute.healthcheck.services | list | `[{"kind":"TraefikService","name":"ping@internal"}]` | The internal service used for the healthcheck ingressRoute | | ingressRoute.healthcheck.tls | object | `{}` | TLS options (e.g. secret containing certificate) | -| instanceLabelOverride | string | `nil` | | +| instanceLabelOverride | string | `""` | | | livenessProbe.failureThreshold | int | `3` | The number of consecutive failures allowed before considering the probe as failed. | | livenessProbe.initialDelaySeconds | int | `2` | The number of seconds to wait before starting the first probe. | | livenessProbe.periodSeconds | int | `10` | The number of seconds to wait between consecutive probes. | | livenessProbe.successThreshold | int | `1` | The minimum consecutive successes required to consider the probe successful. | | livenessProbe.timeoutSeconds | int | `2` | The number of seconds to wait for a probe response before considering it as failed. | -| logs.access.addInternals | string | `nil` | Enables accessLogs for internal resources. Default: false. | +| logs.access.addInternals | bool | `false` | Enables accessLogs for internal resources. Default: false. | | logs.access.bufferingSize | string | `nil` | Set [bufferingSize](https://doc.traefik.io/traefik/observability/access-logs/#bufferingsize) | | logs.access.enabled | bool | `false` | To enable access logs | -| logs.access.fields.general.defaultmode | string | `"keep"` | Available modes: keep, drop, redact. | +| logs.access.fields.general.defaultmode | string | `"keep"` | Set default mode for fields.names | | logs.access.fields.general.names | object | `{}` | Names of the fields to limit. | | logs.access.fields.headers | object | `{"defaultmode":"drop","names":{}}` | [Limit logged fields or headers](https://doc.traefik.io/traefik/observability/access-logs/#limiting-the-fieldsincluding-headers) | -| logs.access.fields.headers.defaultmode | string | `"drop"` | Available modes: keep, drop, redact. | -| logs.access.filters | object | `{}` | Set [filtering](https://docs.traefik.io/observability/access-logs/#filtering) | +| logs.access.fields.headers.defaultmode | string | `"drop"` | Set default mode for fields.headers | +| logs.access.filters | object | `{"minduration":"","retryattempts":false,"statuscodes":""}` | Set [filtering](https://docs.traefik.io/observability/access-logs/#filtering) | +| logs.access.filters.minduration | string | `""` | Set minDuration, to keep access logs when requests take longer than the specified duration | +| logs.access.filters.retryattempts | bool | `false` | Set retryAttempts, to keep the access logs when at least one retry has happened | +| logs.access.filters.statuscodes | string | `""` | Set statusCodes, to limit the access logs to requests with a status codes in the specified range | | logs.access.format | string | `nil` | Set [access log format](https://doc.traefik.io/traefik/observability/access-logs/#format) | -| logs.general.format | string | `nil` | Set [logs format](https://doc.traefik.io/traefik/observability/logs/#format) @default common | -| logs.general.level | string | `"INFO"` | Alternative logging levels are DEBUG, PANIC, FATAL, ERROR, WARN, and INFO. | -| metrics.addInternals | string | `nil` | | +| logs.general.filePath | string | `""` | To write the logs into a log file, use the filePath option. | +| logs.general.format | string | `nil` | Set [logs format](https://doc.traefik.io/traefik/observability/logs/#format) | +| logs.general.level | string | `"INFO"` | Alternative logging levels are TRACE, DEBUG, INFO, WARN, ERROR, FATAL, and PANIC. | +| logs.general.noColor | bool | `false` | When set to true and format is common, it disables the colorized output. | +| metrics.addInternals | bool | `false` | | | metrics.otlp.addEntryPointsLabels | string | `nil` | Enable metrics on entry points. Default: true | | metrics.otlp.addRoutersLabels | string | `nil` | Enable metrics on routers. Default: false | | metrics.otlp.addServicesLabels | string | `nil` | Enable metrics on services. Default: true | | metrics.otlp.enabled | bool | `false` | Set to true in order to enable the OpenTelemetry metrics | -| metrics.otlp.explicitBoundaries | string | `nil` | Explicit boundaries for Histogram data points. Default: [.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10] | +| metrics.otlp.explicitBoundaries | list | `[]` | Explicit boundaries for Histogram data points. Default: [.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10] | | metrics.otlp.grpc.enabled | bool | `false` | Set to true in order to send metrics to the OpenTelemetry Collector using gRPC | -| metrics.otlp.grpc.endpoint | string | `nil` | Format: ://:. Default: http://localhost:4318/v1/metrics | -| metrics.otlp.grpc.insecure | string | `nil` | Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. | -| metrics.otlp.grpc.tls.ca | string | `nil` | The path to the certificate authority, it defaults to the system bundle. | -| metrics.otlp.grpc.tls.cert | string | `nil` | The path to the public certificate. When using this option, setting the key option is required. | -| metrics.otlp.grpc.tls.insecureSkipVerify | string | `nil` | When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. | -| metrics.otlp.grpc.tls.key | string | `nil` | The path to the private key. When using this option, setting the cert option is required. | +| metrics.otlp.grpc.endpoint | string | `""` | Format: ://:. Default: http://localhost:4318/v1/metrics | +| metrics.otlp.grpc.insecure | bool | `false` | Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. | +| metrics.otlp.grpc.tls.ca | string | `""` | The path to the certificate authority, it defaults to the system bundle. | +| metrics.otlp.grpc.tls.cert | string | `""` | The path to the public certificate. When using this option, setting the key option is required. | +| metrics.otlp.grpc.tls.insecureSkipVerify | bool | `false` | When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. | +| metrics.otlp.grpc.tls.key | string | `""` | The path to the private key. When using this option, setting the cert option is required. | | metrics.otlp.http.enabled | bool | `false` | Set to true in order to send metrics to the OpenTelemetry Collector using HTTP. | -| metrics.otlp.http.endpoint | string | `nil` | Format: ://:. Default: http://localhost:4318/v1/metrics | -| metrics.otlp.http.headers | string | `nil` | Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. | -| metrics.otlp.http.tls.ca | string | `nil` | The path to the certificate authority, it defaults to the system bundle. | -| metrics.otlp.http.tls.cert | string | `nil` | The path to the public certificate. When using this option, setting the key option is required. | +| metrics.otlp.http.endpoint | string | `""` | Format: ://:. Default: http://localhost:4318/v1/metrics | +| metrics.otlp.http.headers | object | `{}` | Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. | +| metrics.otlp.http.tls.ca | string | `""` | The path to the certificate authority, it defaults to the system bundle. | +| metrics.otlp.http.tls.cert | string | `""` | The path to the public certificate. When using this option, setting the key option is required. | | metrics.otlp.http.tls.insecureSkipVerify | string | `nil` | When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. | -| metrics.otlp.http.tls.key | string | `nil` | The path to the private key. When using this option, setting the cert option is required. | -| metrics.otlp.pushInterval | string | `nil` | Interval at which metrics are sent to the OpenTelemetry Collector. Default: 10s | +| metrics.otlp.http.tls.key | string | `""` | The path to the private key. When using this option, setting the cert option is required. | +| metrics.otlp.pushInterval | string | `""` | Interval at which metrics are sent to the OpenTelemetry Collector. Default: 10s | +| metrics.prometheus.addEntryPointsLabels | string | `nil` | | +| metrics.prometheus.addRoutersLabels | string | `nil` | | +| metrics.prometheus.addServicesLabels | string | `nil` | | +| metrics.prometheus.buckets | string | `""` | | | metrics.prometheus.disableAPICheck | string | `nil` | When set to true, it won't check if Prometheus Operator CRDs are deployed | | metrics.prometheus.entryPoint | string | `"metrics"` | Entry point used to expose metrics. | -| metrics.prometheus.prometheusRule.additionalLabels | string | `nil` | | +| metrics.prometheus.manualRouting | bool | `false` | | +| metrics.prometheus.prometheusRule.additionalLabels | object | `{}` | | | metrics.prometheus.prometheusRule.enabled | bool | `false` | Enable optional CR for Prometheus Operator. See EXAMPLES.md for more details. | -| metrics.prometheus.prometheusRule.namespace | string | `nil` | | -| metrics.prometheus.service.annotations | string | `nil` | | -| metrics.prometheus.service.enabled | string | `nil` | Create a dedicated metrics service to use with ServiceMonitor | -| metrics.prometheus.service.labels | string | `nil` | | -| metrics.prometheus.serviceMonitor.additionalLabels | string | `nil` | | -| metrics.prometheus.serviceMonitor.enableHttp2 | string | `nil` | | +| metrics.prometheus.prometheusRule.namespace | string | `""` | | +| metrics.prometheus.service.annotations | object | `{}` | | +| metrics.prometheus.service.enabled | bool | `false` | Create a dedicated metrics service to use with ServiceMonitor | +| metrics.prometheus.service.labels | object | `{}` | | +| metrics.prometheus.serviceMonitor.additionalLabels | object | `{}` | | +| metrics.prometheus.serviceMonitor.enableHttp2 | bool | `false` | | | metrics.prometheus.serviceMonitor.enabled | bool | `false` | Enable optional CR for Prometheus Operator. See EXAMPLES.md for more details. | -| metrics.prometheus.serviceMonitor.followRedirects | string | `nil` | | -| metrics.prometheus.serviceMonitor.honorLabels | string | `nil` | | -| metrics.prometheus.serviceMonitor.honorTimestamps | string | `nil` | | -| metrics.prometheus.serviceMonitor.interval | string | `nil` | | -| metrics.prometheus.serviceMonitor.jobLabel | string | `nil` | | -| metrics.prometheus.serviceMonitor.metricRelabelings | string | `nil` | | -| metrics.prometheus.serviceMonitor.namespace | string | `nil` | | -| metrics.prometheus.serviceMonitor.namespaceSelector | string | `nil` | | -| metrics.prometheus.serviceMonitor.relabelings | string | `nil` | | -| metrics.prometheus.serviceMonitor.scrapeTimeout | string | `nil` | | -| namespaceOverride | string | `nil` | This field override the default Release Namespace for Helm. It will not affect optional CRDs such as `ServiceMonitor` and `PrometheusRules` | +| metrics.prometheus.serviceMonitor.followRedirects | bool | `false` | | +| metrics.prometheus.serviceMonitor.honorLabels | bool | `false` | | +| metrics.prometheus.serviceMonitor.honorTimestamps | bool | `false` | | +| metrics.prometheus.serviceMonitor.interval | string | `""` | | +| metrics.prometheus.serviceMonitor.jobLabel | string | `""` | | +| metrics.prometheus.serviceMonitor.metricRelabelings | list | `[]` | | +| metrics.prometheus.serviceMonitor.namespace | string | `""` | | +| metrics.prometheus.serviceMonitor.namespaceSelector | object | `{}` | | +| metrics.prometheus.serviceMonitor.relabelings | list | `[]` | | +| metrics.prometheus.serviceMonitor.scrapeTimeout | string | `""` | | +| namespaceOverride | string | `""` | This field override the default Release Namespace for Helm. It will not affect optional CRDs such as `ServiceMonitor` and `PrometheusRules` | | nodeSelector | object | `{}` | nodeSelector is the simplest recommended form of node selection constraint. | | persistence.accessMode | string | `"ReadWriteOnce"` | | | persistence.annotations | object | `{}` | | -| persistence.enabled | bool | `false` | Enable persistence using Persistent Volume Claims ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ It can be used to store TLS certificates, see `storage` in certResolvers | +| persistence.enabled | bool | `false` | Enable persistence using Persistent Volume Claims ref: http://kubernetes.io/docs/user-guide/persistent-volumes/. It can be used to store TLS certificates along with `certificatesResolvers..acme.storage` option | +| persistence.existingClaim | string | `""` | | | persistence.name | string | `"data"` | | | persistence.path | string | `"/data"` | | | persistence.size | string | `"128Mi"` | | -| podDisruptionBudget | object | `{"enabled":null,"maxUnavailable":null,"minAvailable":null}` | [Pod Disruption Budget](https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/pod-disruption-budget-v1/) | +| persistence.storageClass | string | `""` | | +| persistence.subPath | string | `""` | Only mount a subpath of the Volume into the pod | +| persistence.volumeName | string | `""` | | +| podDisruptionBudget | object | `{"enabled":false,"maxUnavailable":null,"minAvailable":null}` | [Pod Disruption Budget](https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/pod-disruption-budget-v1/) | | podSecurityContext | object | See _values.yaml_ | [Pod Security Context](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) | | podSecurityPolicy | object | `{"enabled":false}` | Enable to create a PodSecurityPolicy and assign it to the Service Account via RoleBinding or ClusterRoleBinding | | ports.metrics.expose | object | `{"default":false}` | You may not want to expose the metrics port on production deployments. If you want to access it from outside your cluster, use `kubectl port-forward` or create a secure ingress | @@ -190,49 +207,69 @@ Kubernetes: `>=1.22.0-0` | ports.metrics.port | int | `9100` | When using hostNetwork, use another port to avoid conflict with node exporter: https://github.com/prometheus/prometheus/wiki/Default-port-allocations | | ports.metrics.protocol | string | `"TCP"` | The port protocol (TCP/UDP) | | ports.traefik.expose | object | `{"default":false}` | You SHOULD NOT expose the traefik port on production deployments. If you want to access it from outside your cluster, use `kubectl port-forward` or create a secure ingress | -| ports.traefik.exposedPort | int | `9000` | The exposed port for this service | -| ports.traefik.port | int | `9000` | | +| ports.traefik.exposedPort | int | `8080` | The exposed port for this service | +| ports.traefik.hostIP | string | `nil` | Use hostIP if set. If not set, Kubernetes will default to 0.0.0.0, which means it's listening on all your interfaces and all your IPs. You may want to set this value if you need traefik to listen on specific interface only. | +| ports.traefik.hostPort | string | `nil` | Use hostPort if set. | +| ports.traefik.port | int | `8080` | | | ports.traefik.protocol | string | `"TCP"` | The port protocol (TCP/UDP) | | ports.web.expose.default | bool | `true` | | | ports.web.exposedPort | int | `80` | | +| ports.web.forwardedHeaders.insecure | bool | `false` | | +| ports.web.forwardedHeaders.trustedIPs | list | `[]` | Trust forwarded headers information (X-Forwarded-*). | +| ports.web.nodePort | string | `nil` | See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) | | ports.web.port | int | `8000` | | | ports.web.protocol | string | `"TCP"` | | +| ports.web.proxyProtocol.insecure | bool | `false` | | +| ports.web.proxyProtocol.trustedIPs | list | `[]` | Enable the Proxy Protocol header parsing for the entry point | +| ports.web.redirectTo | object | `{}` | | +| ports.web.targetPort | string | `nil` | | | ports.web.transport | object | `{"keepAliveMaxRequests":null,"keepAliveMaxTime":null,"lifeCycle":{"graceTimeOut":null,"requestAcceptGraceTimeout":null},"respondingTimeouts":{"idleTimeout":null,"readTimeout":null,"writeTimeout":null}}` | Set transport settings for the entrypoint; see also https://doc.traefik.io/traefik/routing/entrypoints/#transport | +| ports.websecure.allowACMEByPass | bool | `false` | See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#allowacmebypass) | +| ports.websecure.appProtocol | string | `nil` | See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol) | +| ports.websecure.containerPort | string | `nil` | | | ports.websecure.expose.default | bool | `true` | | | ports.websecure.exposedPort | int | `443` | | +| ports.websecure.forwardedHeaders.insecure | bool | `false` | | +| ports.websecure.forwardedHeaders.trustedIPs | list | `[]` | Trust forwarded headers information (X-Forwarded-*). | +| ports.websecure.hostPort | string | `nil` | | +| ports.websecure.http3.advertisedPort | string | `nil` | | | ports.websecure.http3.enabled | bool | `false` | | -| ports.websecure.middlewares | list | `[]` | /!\ It introduces here a link between your static configuration and your dynamic configuration /!\ It follows the provider naming convention: https://doc.traefik.io/traefik/providers/overview/#provider-namespace middlewares: - namespace-name1@kubernetescrd - namespace-name2@kubernetescrd | +| ports.websecure.middlewares | list | `[]` | /!\ It introduces here a link between your static configuration and your dynamic configuration /!\ It follows the provider naming convention: https://doc.traefik.io/traefik/providers/overview/#provider-namespace - namespace-name1@kubernetescrd - namespace-name2@kubernetescrd | +| ports.websecure.nodePort | string | `nil` | See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) | | ports.websecure.port | int | `8443` | | | ports.websecure.protocol | string | `"TCP"` | | -| ports.websecure.tls.certResolver | string | `""` | | -| ports.websecure.tls.domains | list | `[]` | | -| ports.websecure.tls.enabled | bool | `true` | | -| ports.websecure.tls.options | string | `""` | | -| ports.websecure.transport | object | `{"keepAliveMaxRequests":null,"keepAliveMaxTime":null,"lifeCycle":{"graceTimeOut":null,"requestAcceptGraceTimeout":null},"respondingTimeouts":{"idleTimeout":null,"readTimeout":null,"writeTimeout":null}}` | Set transport settings for the entrypoint; see also https://doc.traefik.io/traefik/routing/entrypoints/#transport | +| ports.websecure.proxyProtocol.insecure | bool | `false` | | +| ports.websecure.proxyProtocol.trustedIPs | list | `[]` | Enable the Proxy Protocol header parsing for the entry point | +| ports.websecure.targetPort | string | `nil` | | +| ports.websecure.tls | object | `{"certResolver":"","domains":[],"enabled":true,"options":""}` | See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#tls) | +| ports.websecure.transport | object | `{"keepAliveMaxRequests":null,"keepAliveMaxTime":null,"lifeCycle":{"graceTimeOut":null,"requestAcceptGraceTimeout":null},"respondingTimeouts":{"idleTimeout":null,"readTimeout":null,"writeTimeout":null}}` | See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#transport) | | priorityClassName | string | `""` | [Pod Priority and Preemption](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/) | -| providers.file.content | string | `nil` | File content (YAML format, go template supported) (see https://doc.traefik.io/traefik/providers/file/) | +| providers.file.content | string | `""` | File content (YAML format, go template supported) (see https://doc.traefik.io/traefik/providers/file/) | | providers.file.enabled | bool | `false` | Create a file provider | | providers.file.watch | bool | `true` | Allows Traefik to automatically watch for file changes | | providers.kubernetesCRD.allowCrossNamespace | bool | `false` | Allows IngressRoute to reference resources in namespace other than theirs | -| providers.kubernetesCRD.allowEmptyServices | bool | `false` | Allows to return 503 when there is no endpoints available | +| providers.kubernetesCRD.allowEmptyServices | bool | `true` | Allows to return 503 when there is no endpoints available | | providers.kubernetesCRD.allowExternalNameServices | bool | `false` | Allows to reference ExternalName services in IngressRoute | | providers.kubernetesCRD.enabled | bool | `true` | Load Kubernetes IngressRoute provider | -| providers.kubernetesCRD.ingressClass | string | `nil` | When the parameter is set, only resources containing an annotation with the same value are processed. Otherwise, resources missing the annotation, having an empty value, or the value traefik are processed. It will also set required annotation on Dashboard and Healthcheck IngressRoute when enabled. | +| providers.kubernetesCRD.ingressClass | string | `""` | When the parameter is set, only resources containing an annotation with the same value are processed. Otherwise, resources missing the annotation, having an empty value, or the value traefik are processed. It will also set required annotation on Dashboard and Healthcheck IngressRoute when enabled. | | providers.kubernetesCRD.namespaces | list | `[]` | Array of namespaces to watch. If left empty, Traefik watches all namespaces. | -| providers.kubernetesCRD.nativeLBByDefault | string | `nil` | Defines whether to use Native Kubernetes load-balancing mode by default. | +| providers.kubernetesCRD.nativeLBByDefault | bool | `false` | Defines whether to use Native Kubernetes load-balancing mode by default. | | providers.kubernetesGateway.enabled | bool | `false` | Enable Traefik Gateway provider for Gateway API | | providers.kubernetesGateway.experimentalChannel | bool | `false` | Toggles support for the Experimental Channel resources (Gateway API release channels documentation). This option currently enables support for TCPRoute and TLSRoute. | -| providers.kubernetesGateway.labelselector | string | `nil` | A label selector can be defined to filter on specific GatewayClass objects only. | +| providers.kubernetesGateway.labelselector | string | `""` | A label selector can be defined to filter on specific GatewayClass objects only. | | providers.kubernetesGateway.namespaces | list | `[]` | Array of namespaces to watch. If left empty, Traefik watches all namespaces. | -| providers.kubernetesIngress.allowEmptyServices | bool | `false` | Allows to return 503 when there is no endpoints available | +| providers.kubernetesGateway.statusAddress.hostname | string | `""` | This Hostname will get copied to the Gateway status.addresses. | +| providers.kubernetesGateway.statusAddress.ip | string | `""` | This IP will get copied to the Gateway status.addresses, and currently only supports one IP value (IPv4 or IPv6). | +| providers.kubernetesGateway.statusAddress.service | object | `{"name":"{{ (include \"traefik.fullname\" .) }}","namespace":"{{ .Release.Namespace }}"}` | The Kubernetes service to copy status addresses from. When using third parties tools like External-DNS, this option can be used to copy the service loadbalancer.status (containing the service's endpoints IPs) to the gateways. Default to Service of this Chart. | +| providers.kubernetesIngress.allowEmptyServices | bool | `true` | Allows to return 503 when there is no endpoints available | | providers.kubernetesIngress.allowExternalNameServices | bool | `false` | Allows to reference ExternalName services in Ingress | -| providers.kubernetesIngress.disableIngressClassLookup | bool | `false` | | | providers.kubernetesIngress.enabled | bool | `true` | Load Kubernetes Ingress provider | | providers.kubernetesIngress.ingressClass | string | `nil` | When ingressClass is set, only Ingresses containing an annotation with the same value are processed. Otherwise, Ingresses missing the annotation, having an empty value, or the value traefik are processed. | | providers.kubernetesIngress.namespaces | list | `[]` | Array of namespaces to watch. If left empty, Traefik watches all namespaces. | -| providers.kubernetesIngress.nativeLBByDefault | string | `nil` | Defines whether to use Native Kubernetes load-balancing mode by default. | -| providers.kubernetesIngress.publishedService.enabled | bool | `false` | | -| rbac | object | `{"enabled":true,"namespaced":false,"secretResourceNames":[]}` | Whether Role Based Access Control objects like roles and rolebindings should be created | +| providers.kubernetesIngress.nativeLBByDefault | bool | `false` | Defines whether to use Native Kubernetes load-balancing mode by default. | +| providers.kubernetesIngress.publishedService.enabled | bool | `true` | Enable [publishedService](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#publishedservice) | +| providers.kubernetesIngress.publishedService.pathOverride | string | `""` | Override path of Kubernetes Service used to copy status from. Format: namespace/servicename. Default to Service deployed with this Chart. | +| rbac | object | `{"aggregateTo":[],"enabled":true,"namespaced":false,"secretResourceNames":[]}` | Whether Role Based Access Control objects like roles and rolebindings should be created | | readinessProbe.failureThreshold | int | `1` | The number of consecutive failures allowed before considering the probe as failed. | | readinessProbe.initialDelaySeconds | int | `2` | The number of seconds to wait before starting the first probe. | | readinessProbe.periodSeconds | int | `10` | The number of seconds to wait between consecutive probes. | @@ -253,31 +290,31 @@ Kubernetes: `>=1.22.0-0` | service.type | string | `"LoadBalancer"` | | | serviceAccount | object | `{"name":""}` | The service account the pods will use to interact with the Kubernetes API | | serviceAccountAnnotations | object | `{}` | Additional serviceAccount annotations (e.g. for oidc authentication) | -| startupProbe | string | `nil` | Define [Startup Probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-startup-probes) | +| startupProbe | object | `{}` | Define [Startup Probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-startup-probes) | | tlsOptions | object | `{}` | TLS Options are created as [TLSOption CRDs](https://doc.traefik.io/traefik/https/tls/#tls-options) When using `labelSelector`, you'll need to set labels on tlsOption accordingly. See EXAMPLE.md for details. | | tlsStore | object | `{}` | TLS Store are created as [TLSStore CRDs](https://doc.traefik.io/traefik/https/tls/#default-certificate). This is useful if you want to set a default certificate. See EXAMPLE.md for details. | | tolerations | list | `[]` | Tolerations allow the scheduler to schedule pods with matching taints. | | topologySpreadConstraints | list | `[]` | You can use topology spread constraints to control how Pods are spread across your cluster among failure-domains. | -| tracing | object | `{"addInternals":null,"otlp":{"enabled":false,"grpc":{"enabled":false,"endpoint":null,"insecure":null,"tls":{"ca":null,"cert":null,"insecureSkipVerify":null,"key":null}},"http":{"enabled":false,"endpoint":null,"headers":null,"tls":{"ca":null,"cert":null,"insecureSkipVerify":null,"key":null}}}}` | https://doc.traefik.io/traefik/observability/tracing/overview/ | -| tracing.addInternals | string | `nil` | Enables tracing for internal resources. Default: false. | +| tracing | object | `{"addInternals":false,"otlp":{"enabled":false,"grpc":{"enabled":false,"endpoint":"","insecure":false,"tls":{"ca":"","cert":"","insecureSkipVerify":false,"key":""}},"http":{"enabled":false,"endpoint":"","headers":{},"tls":{"ca":"","cert":"","insecureSkipVerify":false,"key":""}}}}` | https://doc.traefik.io/traefik/observability/tracing/overview/ | +| tracing.addInternals | bool | `false` | Enables tracing for internal resources. Default: false. | | tracing.otlp.enabled | bool | `false` | See https://doc.traefik.io/traefik/v3.0/observability/tracing/opentelemetry/ | | tracing.otlp.grpc.enabled | bool | `false` | Set to true in order to send metrics to the OpenTelemetry Collector using gRPC | -| tracing.otlp.grpc.endpoint | string | `nil` | Format: ://:. Default: http://localhost:4318/v1/metrics | -| tracing.otlp.grpc.insecure | string | `nil` | Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. | -| tracing.otlp.grpc.tls.ca | string | `nil` | The path to the certificate authority, it defaults to the system bundle. | -| tracing.otlp.grpc.tls.cert | string | `nil` | The path to the public certificate. When using this option, setting the key option is required. | -| tracing.otlp.grpc.tls.insecureSkipVerify | string | `nil` | When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. | -| tracing.otlp.grpc.tls.key | string | `nil` | The path to the private key. When using this option, setting the cert option is required. | +| tracing.otlp.grpc.endpoint | string | `""` | Format: ://:. Default: http://localhost:4318/v1/metrics | +| tracing.otlp.grpc.insecure | bool | `false` | Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. | +| tracing.otlp.grpc.tls.ca | string | `""` | The path to the certificate authority, it defaults to the system bundle. | +| tracing.otlp.grpc.tls.cert | string | `""` | The path to the public certificate. When using this option, setting the key option is required. | +| tracing.otlp.grpc.tls.insecureSkipVerify | bool | `false` | When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. | +| tracing.otlp.grpc.tls.key | string | `""` | The path to the private key. When using this option, setting the cert option is required. | | tracing.otlp.http.enabled | bool | `false` | Set to true in order to send metrics to the OpenTelemetry Collector using HTTP. | -| tracing.otlp.http.endpoint | string | `nil` | Format: ://:. Default: http://localhost:4318/v1/metrics | -| tracing.otlp.http.headers | string | `nil` | Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. | -| tracing.otlp.http.tls.ca | string | `nil` | The path to the certificate authority, it defaults to the system bundle. | -| tracing.otlp.http.tls.cert | string | `nil` | The path to the public certificate. When using this option, setting the key option is required. | -| tracing.otlp.http.tls.insecureSkipVerify | string | `nil` | When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. | -| tracing.otlp.http.tls.key | string | `nil` | The path to the private key. When using this option, setting the cert option is required. | +| tracing.otlp.http.endpoint | string | `""` | Format: ://:. Default: http://localhost:4318/v1/metrics | +| tracing.otlp.http.headers | object | `{}` | Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. | +| tracing.otlp.http.tls.ca | string | `""` | The path to the certificate authority, it defaults to the system bundle. | +| tracing.otlp.http.tls.cert | string | `""` | The path to the public certificate. When using this option, setting the key option is required. | +| tracing.otlp.http.tls.insecureSkipVerify | bool | `false` | When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. | +| tracing.otlp.http.tls.key | string | `""` | The path to the private key. When using this option, setting the cert option is required. | | updateStrategy.rollingUpdate.maxSurge | int | `1` | | | updateStrategy.rollingUpdate.maxUnavailable | int | `0` | | -| updateStrategy.type | string | `"RollingUpdate"` | Customize updateStrategy: RollingUpdate or OnDelete | +| updateStrategy.type | string | `"RollingUpdate"` | Customize updateStrategy of Deployment or DaemonSet | | volumes | list | `[]` | Add volumes to the traefik pod. The volume name will be passed to tpl. This can be used to mount a cert pair or a configmap that holds a config.toml file. After the volume has been mounted, add the configs into traefik by using the `additionalArguments` list below, eg: `additionalArguments: - "--providers.file.filename=/config/dynamic.toml" - "--ping" - "--ping.entrypoint=web"` | ---------------------------------------------- diff --git a/charts/traefik/traefik/crds/gateway-standard-install-v1.2.0.yaml b/charts/traefik/traefik/crds/gateway-standard-install-v1.2.0.yaml new file mode 100644 index 0000000..0efb1ac --- /dev/null +++ b/charts/traefik/traefik/crds/gateway-standard-install-v1.2.0.yaml @@ -0,0 +1,10345 @@ +# Copyright 2024 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# Gateway API Standard channel install +# +--- +# +# config/crd/standard/gateway.networking.k8s.io_gatewayclasses.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 + gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: gatewayclasses.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GatewayClass + listKind: GatewayClassList + plural: gatewayclasses + shortNames: + - gc + singular: gatewayclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + GatewayClass is a Cluster level resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of GatewayClass. + properties: + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + Example: "example.net/gateway-controller". + + This field is not mutable and cannot be empty. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + If the referent cannot be found, refers to an unsupported kind, or when + the data within that resource is malformed, the GatewayClass SHOULD be + rejected with the "Accepted" status condition set to "False" and an + "InvalidParameters" reason. + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + Support: Implementation-specific + properties: + group: + description: Group is the group of the referent. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Status defines the current state of GatewayClass. + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.controllerName + name: Controller + type: string + - jsonPath: .status.conditions[?(@.type=="Accepted")].status + name: Accepted + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .spec.description + name: Description + priority: 1 + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + GatewayClass describes a class of Gateways available to the user for creating + Gateway resources. + + It is recommended that this resource be used as a template for Gateways. This + means that a Gateway is based on the state of the GatewayClass at the time it + was created and changes to the GatewayClass or associated parameters are not + propagated down to existing Gateways. This recommendation is intended to + limit the blast radius of changes to GatewayClass or associated parameters. + If implementations choose to propagate GatewayClass changes to existing + Gateways, that MUST be clearly documented by the implementation. + + Whenever one or more Gateways are using a GatewayClass, implementations SHOULD + add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the + associated GatewayClass. This ensures that a GatewayClass associated with a + Gateway is not deleted while in use. + + GatewayClass is a Cluster level resource. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of GatewayClass. + properties: + controllerName: + description: |- + ControllerName is the name of the controller that is managing Gateways of + this class. The value of this field MUST be a domain prefixed path. + + Example: "example.net/gateway-controller". + + This field is not mutable and cannot be empty. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + x-kubernetes-validations: + - message: Value is immutable + rule: self == oldSelf + description: + description: Description helps describe a GatewayClass with more details. + maxLength: 64 + type: string + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the GatewayClass. This is optional if the + controller does not require any additional configuration. + + ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, + or an implementation-specific custom resource. The resource can be + cluster-scoped or namespace-scoped. + + If the referent cannot be found, refers to an unsupported kind, or when + the data within that resource is malformed, the GatewayClass SHOULD be + rejected with the "Accepted" status condition set to "False" and an + "InvalidParameters" reason. + + A Gateway for this GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + Support: Implementation-specific + properties: + group: + description: Group is the group of the referent. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. + This field is required when referring to a Namespace-scoped resource and + MUST be unset when referring to a Cluster-scoped resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - name + type: object + required: + - controllerName + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Status defines the current state of GatewayClass. + + Implementations MUST populate status on all GatewayClass resources which + specify their controller name. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + description: |- + Conditions is the current status from the controller for + this GatewayClass. + + Controllers should prefer to publish conditions using values + of GatewayClassConditionType for the type of each Condition. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_gateways.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 + gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: gateways.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gtw + singular: gateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + Support: Extended + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |- + Infrastructure defines infrastructure level attributes about this Gateway instance. + + Support: Extended + properties: + annotations: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Annotations that SHOULD be applied to any resources created in response to this Gateway. + + For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. + For other implementations, this refers to any relevant (implementation specific) "annotations" concepts. + + An implementation may chose to add additional implementation-specific annotations as they see fit. + + Support: Extended + maxProperties: 8 + type: object + x-kubernetes-validations: + - message: Annotation keys must be in the form of an optional + DNS subdomain prefix followed by a required name segment of + up to 63 characters. + rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$""")) + - message: If specified, the annotation key's prefix must be a + DNS subdomain not longer than 253 characters in total. + rule: self.all(key, key.split("/")[0].size() < 253) + labels: + additionalProperties: + description: |- + LabelValue is the value of a label in the Gateway API. This is used for validation + of maps such as Gateway infrastructure labels. This matches the Kubernetes + label validation rules: + * must be 63 characters or less (can be empty), + * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]), + * could contain dashes (-), underscores (_), dots (.), and alphanumerics between. + + Valid values include: + + * MyValue + * my.name + * 123-my-value + maxLength: 63 + minLength: 0 + pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$ + type: string + description: |- + Labels that SHOULD be applied to any resources created in response to this Gateway. + + For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. + For other implementations, this refers to any relevant (implementation specific) "labels" concepts. + + An implementation may chose to add additional implementation-specific labels as they see fit. + + If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels + change, it SHOULD clearly warn about this behavior in documentation. + + Support: Extended + maxProperties: 8 + type: object + x-kubernetes-validations: + - message: Label keys must be in the form of an optional DNS subdomain + prefix followed by a required name segment of up to 63 characters. + rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$""")) + - message: If specified, the label key's prefix must be a DNS + subdomain not longer than 253 characters in total. + rule: self.all(key, key.split("/")[0].size() < 253) + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the Gateway. This is optional if the + controller does not require any additional configuration. + + This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis + + The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + Support: Implementation-specific + properties: + group: + description: Group is the group of the referent. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + HTTP Profile + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + TLS Profile + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + "Distinct" Listeners have the following property: + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + For example, the following Listener scenarios are distinct: + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + A Gateway's Listeners are considered "compatible" if: + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + Support: Core + items: + description: RouteGroupKind indicates the group and kind + of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + type: string + tls: + description: |- + TLS is the TLS configuration for the Listener. This field is required if + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Secret + description: Kind is kind of the referent. For example + "Secret". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referenced object. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + maxItems: 64 + type: array + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Options are a list of key/value pairs to enable extended TLS + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + Support: Implementation-specific + maxProperties: 16 + type: object + type: object + x-kubernetes-validations: + - message: certificateRefs or options must be specified when + mode is Terminate + rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) + > 0 || size(self.options) > 0 : true' + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: tls must not be specified for protocols ['HTTP', 'TCP', + 'UDP'] + rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? + !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' + - message: hostname must not be specified for protocols ['TCP', 'UDP'] + rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) + || l.hostname == '''') : true)' + - message: Listener name must be unique within the Gateway + rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) + - message: Combination of port, protocol and hostname must be unique + for each listener + rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol + == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname + == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + This list may differ from the addresses provided in the spec under some + conditions: + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the Gateway. + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + Known condition types are: + + * "Accepted" + * "Programmed" + * "Ready" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port + defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: |- + AttachedRoutes represents the total number of Routes that have been + successfully attached to this Listener. + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + Uses for this field include troubleshooting Route attachment and + measuring blast radius/impact of changes to a Listener. + format: int32 + type: integer + conditions: + description: Conditions describe the current condition of this + listener. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status + corresponds to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + supportedKinds: + description: |- + SupportedKinds is the list indicating the Kinds supported by this + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. + items: + description: RouteGroupKind indicates the group and kind of + a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.gatewayClassName + name: Class + type: string + - jsonPath: .status.addresses[*].value + name: Address + type: string + - jsonPath: .status.conditions[?(@.type=="Programmed")].status + name: Programmed + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + Gateway represents an instance of a service-traffic handling infrastructure + by binding Listeners to a set of IP addresses. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of Gateway. + properties: + addresses: + description: |+ + Addresses requested for this Gateway. This is optional and behavior can + depend on the implementation. If a value is set in the spec and the + requested address is invalid or unavailable, the implementation MUST + indicate this in the associated entry in GatewayStatus.Addresses. + + The Addresses field represents a request for the address(es) on the + "outside of the Gateway", that traffic bound for this Gateway will use. + This could be the IP address or hostname of an external load balancer or + other networking infrastructure, or some other address that traffic will + be sent to. + + If no Addresses are specified, the implementation MAY schedule the + Gateway in an implementation-specific manner, assigning an appropriate + set of Addresses. + + The implementation MUST bind all Listeners to every GatewayAddress that + it assigns to the Gateway and add a corresponding entry in + GatewayStatus.Addresses. + + Support: Extended + + items: + description: GatewayAddress describes an address that can be bound + to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: IPAddress values must be unique + rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + - message: Hostname values must be unique + rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, + a2.type == a1.type && a2.value == a1.value) : true )' + gatewayClassName: + description: |- + GatewayClassName used for this Gateway. This is the name of a + GatewayClass resource. + maxLength: 253 + minLength: 1 + type: string + infrastructure: + description: |- + Infrastructure defines infrastructure level attributes about this Gateway instance. + + Support: Extended + properties: + annotations: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Annotations that SHOULD be applied to any resources created in response to this Gateway. + + For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. + For other implementations, this refers to any relevant (implementation specific) "annotations" concepts. + + An implementation may chose to add additional implementation-specific annotations as they see fit. + + Support: Extended + maxProperties: 8 + type: object + x-kubernetes-validations: + - message: Annotation keys must be in the form of an optional + DNS subdomain prefix followed by a required name segment of + up to 63 characters. + rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$""")) + - message: If specified, the annotation key's prefix must be a + DNS subdomain not longer than 253 characters in total. + rule: self.all(key, key.split("/")[0].size() < 253) + labels: + additionalProperties: + description: |- + LabelValue is the value of a label in the Gateway API. This is used for validation + of maps such as Gateway infrastructure labels. This matches the Kubernetes + label validation rules: + * must be 63 characters or less (can be empty), + * unless empty, must begin and end with an alphanumeric character ([a-z0-9A-Z]), + * could contain dashes (-), underscores (_), dots (.), and alphanumerics between. + + Valid values include: + + * MyValue + * my.name + * 123-my-value + maxLength: 63 + minLength: 0 + pattern: ^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?$ + type: string + description: |- + Labels that SHOULD be applied to any resources created in response to this Gateway. + + For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. + For other implementations, this refers to any relevant (implementation specific) "labels" concepts. + + An implementation may chose to add additional implementation-specific labels as they see fit. + + If an implementation maps these labels to Pods, or any other resource that would need to be recreated when labels + change, it SHOULD clearly warn about this behavior in documentation. + + Support: Extended + maxProperties: 8 + type: object + x-kubernetes-validations: + - message: Label keys must be in the form of an optional DNS subdomain + prefix followed by a required name segment of up to 63 characters. + rule: self.all(key, key.matches(r"""^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?([A-Za-z0-9][-A-Za-z0-9_.]{0,61})?[A-Za-z0-9]$""")) + - message: If specified, the label key's prefix must be a DNS + subdomain not longer than 253 characters in total. + rule: self.all(key, key.split("/")[0].size() < 253) + parametersRef: + description: |- + ParametersRef is a reference to a resource that contains the configuration + parameters corresponding to the Gateway. This is optional if the + controller does not require any additional configuration. + + This follows the same semantics as GatewayClass's `parametersRef`, but on a per-Gateway basis + + The Gateway's GatewayClass may provide its own `parametersRef`. When both are specified, + the merging behavior is implementation specific. + It is generally recommended that GatewayClass provides defaults that can be overridden by a Gateway. + + Support: Implementation-specific + properties: + group: + description: Group is the group of the referent. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + type: object + listeners: + description: |- + Listeners associated with this Gateway. Listeners define + logical endpoints that are bound on this Gateway's addresses. + At least one Listener MUST be specified. + + Each Listener in a set of Listeners (for example, in a single Gateway) + MUST be _distinct_, in that a traffic flow MUST be able to be assigned to + exactly one listener. (This section uses "set of Listeners" rather than + "Listeners in a single Gateway" because implementations MAY merge configuration + from multiple Gateways onto a single data plane, and these rules _also_ + apply in that case). + + Practically, this means that each listener in a set MUST have a unique + combination of Port, Protocol, and, if supported by the protocol, Hostname. + + Some combinations of port, protocol, and TLS settings are considered + Core support and MUST be supported by implementations based on their + targeted conformance profile: + + HTTP Profile + + 1. HTTPRoute, Port: 80, Protocol: HTTP + 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided + + TLS Profile + + 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough + + "Distinct" Listeners have the following property: + + The implementation can match inbound requests to a single distinct + Listener. When multiple Listeners share values for fields (for + example, two Listeners with the same Port value), the implementation + can match requests to only one of the Listeners using other + Listener fields. + + For example, the following Listener scenarios are distinct: + + 1. Multiple Listeners with the same Port that all use the "HTTP" + Protocol that all have unique Hostname values. + 2. Multiple Listeners with the same Port that use either the "HTTPS" or + "TLS" Protocol that all have unique Hostname values. + 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener + with the same Protocol has the same Port value. + + Some fields in the Listener struct have possible values that affect + whether the Listener is distinct. Hostname is particularly relevant + for HTTP or HTTPS protocols. + + When using the Hostname value to select between same-Port, same-Protocol + Listeners, the Hostname value must be different on each Listener for the + Listener to be distinct. + + When the Listeners are distinct based on Hostname, inbound request + hostnames MUST match from the most specific to least specific Hostname + values to choose the correct Listener and its associated set of Routes. + + Exact matches must be processed before wildcard matches, and wildcard + matches must be processed before fallback (empty Hostname value) + matches. For example, `"foo.example.com"` takes precedence over + `"*.example.com"`, and `"*.example.com"` takes precedence over `""`. + + Additionally, if there are multiple wildcard entries, more specific + wildcard entries must be processed before less specific wildcard entries. + For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`. + The precise definition here is that the higher the number of dots in the + hostname to the right of the wildcard character, the higher the precedence. + + The wildcard character will match any number of characters _and dots_ to + the left, however, so `"*.example.com"` will match both + `"foo.bar.example.com"` _and_ `"bar.example.com"`. + + If a set of Listeners contains Listeners that are not distinct, then those + Listeners are Conflicted, and the implementation MUST set the "Conflicted" + condition in the Listener Status to "True". + + Implementations MAY choose to accept a Gateway with some Conflicted + Listeners only if they only accept the partial Listener set that contains + no Conflicted Listeners. To put this another way, implementations may + accept a partial Listener set only if they throw out *all* the conflicting + Listeners. No picking one of the conflicting listeners as the winner. + This also means that the Gateway must have at least one non-conflicting + Listener in this case, otherwise it violates the requirement that at + least one Listener must be present. + + The implementation MUST set a "ListenersNotValid" condition on the + Gateway Status when the Gateway contains Conflicted Listeners whether or + not they accept the Gateway. That Condition SHOULD clearly + indicate in the Message which Listeners are conflicted, and which are + Accepted. Additionally, the Listener status for those listeners SHOULD + indicate which Listeners are conflicted and not Accepted. + + A Gateway's Listeners are considered "compatible" if: + + 1. They are distinct. + 2. The implementation can serve them in compliance with the Addresses + requirement that all Listeners are available on all assigned + addresses. + + Compatible combinations in Extended support are expected to vary across + implementations. A combination that is compatible for one implementation + may not be compatible for another. + + For example, an implementation that cannot serve both TCP and UDP listeners + on the same address, or cannot mix HTTPS and generic TLS listens on the same port + would not consider those cases compatible, even though they are distinct. + + Note that requests SHOULD match at most one Listener. For example, if + Listeners are defined for "foo.example.com" and "*.example.com", a + request to "foo.example.com" SHOULD only be routed using routes attached + to the "foo.example.com" Listener (and not the "*.example.com" Listener). + This concept is known as "Listener Isolation". Implementations that do + not support Listener Isolation MUST clearly document this. + + Implementations MAY merge separate Gateways onto a single set of + Addresses if all Listeners across all Gateways are compatible. + + Support: Core + items: + description: |- + Listener embodies the concept of a logical endpoint where a Gateway accepts + network connections. + properties: + allowedRoutes: + default: + namespaces: + from: Same + description: |- + AllowedRoutes defines the types of routes that MAY be attached to a + Listener and the trusted namespaces where those Route resources MAY be + present. + + Although a client request may match multiple route rules, only one rule + may ultimately receive the request. Matching precedence MUST be + determined in order of the following criteria: + + * The most specific match as defined by the Route type. + * The oldest Route based on creation timestamp. For example, a Route with + a creation timestamp of "2020-09-08 01:02:03" is given precedence over + a Route with a creation timestamp of "2020-09-08 01:02:04". + * If everything else is equivalent, the Route appearing first in + alphabetical order (namespace/name) should be given precedence. For + example, foo/bar is given precedence over foo/baz. + + All valid rules within a Route attached to this Listener should be + implemented. Invalid Route rules can be ignored (sometimes that will mean + the full Route). If a Route rule transitions from valid to invalid, + support for that Route rule should be dropped to ensure consistency. For + example, even if a filter specified by a Route rule is invalid, the rest + of the rules within that Route should still be supported. + + Support: Core + properties: + kinds: + description: |- + Kinds specifies the groups and kinds of Routes that are allowed to bind + to this Gateway Listener. When unspecified or empty, the kinds of Routes + selected are determined using the Listener protocol. + + A RouteGroupKind MUST correspond to kinds of Routes that are compatible + with the application protocol specified in the Listener's Protocol field. + If an implementation does not support or recognize this resource type, it + MUST set the "ResolvedRefs" condition to False for this Listener with the + "InvalidRouteKinds" reason. + + Support: Core + items: + description: RouteGroupKind indicates the group and kind + of a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + namespaces: + default: + from: Same + description: |- + Namespaces indicates namespaces from which Routes may be attached to this + Listener. This is restricted to the namespace of this Gateway by default. + + Support: Core + properties: + from: + default: Same + description: |- + From indicates where Routes will be selected for this Gateway. Possible + values are: + + * All: Routes in all namespaces may be used by this Gateway. + * Selector: Routes in namespaces selected by the selector may be used by + this Gateway. + * Same: Only Routes in the same namespace may be used by this Gateway. + + Support: Core + enum: + - All + - Selector + - Same + type: string + selector: + description: |- + Selector must be specified when From is set to "Selector". In that case, + only Routes in Namespaces matching this Selector will be selected by this + Gateway. This field is ignored for other values of "From". + + Support: Core + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: object + hostname: + description: |- + Hostname specifies the virtual hostname to match for protocol types that + define this concept. When unspecified, all hostnames are matched. This + field is ignored for protocols that don't require hostname based + matching. + + Implementations MUST apply Hostname matching appropriately for each of + the following protocols: + + * TLS: The Listener Hostname MUST match the SNI. + * HTTP: The Listener Hostname MUST match the Host header of the request. + * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP + protocol layers as described above. If an implementation does not + ensure that both the SNI and Host header match the Listener hostname, + it MUST clearly document that. + + For HTTPRoute and TLSRoute resources, there is an interaction with the + `spec.hostnames` array. When both listener and route specify hostnames, + there MUST be an intersection between the values for a Route to be + accepted. For more information, refer to the Route specific Hostnames + documentation. + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + name: + description: |- + Name is the name of the Listener. This name MUST be unique within a + Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + port: + description: |- + Port is the network port. Multiple listeners may use the + same port, subject to the Listener compatibility rules. + + Support: Core + format: int32 + maximum: 65535 + minimum: 1 + type: integer + protocol: + description: |- + Protocol specifies the network protocol this listener expects to receive. + + Support: Core + maxLength: 255 + minLength: 1 + pattern: ^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ + type: string + tls: + description: |- + TLS is the TLS configuration for the Listener. This field is required if + the Protocol field is "HTTPS" or "TLS". It is invalid to set this field + if the Protocol field is "HTTP", "TCP", or "UDP". + + The association of SNIs to Certificate defined in GatewayTLSConfig is + defined based on the Hostname field for this listener. + + The GatewayClass MUST use the longest matching SNI out of all + available certificates for any TLS handshake. + + Support: Core + properties: + certificateRefs: + description: |- + CertificateRefs contains a series of references to Kubernetes objects that + contains TLS certificates and private keys. These certificates are used to + establish a TLS handshake for requests that match the hostname of the + associated listener. + + A single CertificateRef to a Kubernetes Secret has "Core" support. + Implementations MAY choose to support attaching multiple certificates to + a Listener, but this behavior is implementation-specific. + + References to a resource in different namespace are invalid UNLESS there + is a ReferenceGrant in the target namespace that allows the certificate + to be attached. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + This field is required to have at least one element when the mode is set + to "Terminate" (default) and is optional otherwise. + + CertificateRefs can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls + + Support: Implementation-specific (More than one reference or other resource types) + items: + description: |- + SecretObjectReference identifies an API object including its namespace, + defaulting to Secret. + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + + References to objects with invalid Group and Kind are not valid, and must + be rejected by the implementation, with appropriate Conditions set + on the containing object. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Secret + description: Kind is kind of the referent. For example + "Secret". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referenced object. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - name + type: object + maxItems: 64 + type: array + mode: + default: Terminate + description: |- + Mode defines the TLS behavior for the TLS session initiated by the client. + There are two possible modes: + + - Terminate: The TLS session between the downstream client and the + Gateway is terminated at the Gateway. This mode requires certificates + to be specified in some way, such as populating the certificateRefs + field. + - Passthrough: The TLS session is NOT terminated by the Gateway. This + implies that the Gateway can't decipher the TLS stream except for + the ClientHello message of the TLS protocol. The certificateRefs field + is ignored in this mode. + + Support: Core + enum: + - Terminate + - Passthrough + type: string + options: + additionalProperties: + description: |- + AnnotationValue is the value of an annotation in Gateway API. This is used + for validation of maps such as TLS options. This roughly matches Kubernetes + annotation validation, although the length validation in that case is based + on the entire size of the annotations struct. + maxLength: 4096 + minLength: 0 + type: string + description: |- + Options are a list of key/value pairs to enable extended TLS + configuration for each implementation. For example, configuring the + minimum TLS version or supported cipher suites. + + A set of common keys MAY be defined by the API in the future. To avoid + any ambiguity, implementation-specific definitions MUST use + domain-prefixed names, such as `example.com/my-custom-option`. + Un-prefixed names are reserved for key names defined by Gateway API. + + Support: Implementation-specific + maxProperties: 16 + type: object + type: object + x-kubernetes-validations: + - message: certificateRefs or options must be specified when + mode is Terminate + rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) + > 0 || size(self.options) > 0 : true' + required: + - name + - port + - protocol + type: object + maxItems: 64 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: tls must not be specified for protocols ['HTTP', 'TCP', + 'UDP'] + rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? + !has(l.tls) : true)' + - message: tls mode must be Terminate for protocol HTTPS + rule: 'self.all(l, (l.protocol == ''HTTPS'' && has(l.tls)) ? (l.tls.mode + == '''' || l.tls.mode == ''Terminate'') : true)' + - message: hostname must not be specified for protocols ['TCP', 'UDP'] + rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) + || l.hostname == '''') : true)' + - message: Listener name must be unique within the Gateway + rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) + - message: Combination of port, protocol and hostname must be unique + for each listener + rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol + == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname + == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' + required: + - gatewayClassName + - listeners + type: object + status: + default: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: Status defines the current state of Gateway. + properties: + addresses: + description: |+ + Addresses lists the network addresses that have been bound to the + Gateway. + + This list may differ from the addresses provided in the spec under some + conditions: + + * no addresses are specified, all addresses are dynamically assigned + * a combination of specified and dynamic addresses are assigned + * a specified address was unusable (e.g. already in use) + + items: + description: GatewayStatusAddress describes a network address that + is bound to a Gateway. + oneOf: + - properties: + type: + enum: + - IPAddress + value: + anyOf: + - format: ipv4 + - format: ipv6 + - properties: + type: + not: + enum: + - IPAddress + properties: + type: + default: IPAddress + description: Type of the address. + maxLength: 253 + minLength: 1 + pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + value: + description: |- + Value of the address. The validity of the values will depend + on the type and support by the controller. + + Examples: `1.2.3.4`, `128::1`, `my-ip-address`. + maxLength: 253 + minLength: 1 + type: string + required: + - value + type: object + x-kubernetes-validations: + - message: Hostname value must only contain valid characters (matching + ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) + rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): + true' + maxItems: 16 + type: array + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Accepted + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the Gateway. + + Implementations should prefer to express Gateway conditions + using the `GatewayConditionType` and `GatewayConditionReason` + constants so that operators and tools can converge on a common + vocabulary to describe Gateway state. + + Known condition types are: + + * "Accepted" + * "Programmed" + * "Ready" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + listeners: + description: Listeners provide status for each unique listener port + defined in the Spec. + items: + description: ListenerStatus is the status associated with a Listener. + properties: + attachedRoutes: + description: |- + AttachedRoutes represents the total number of Routes that have been + successfully attached to this Listener. + + Successful attachment of a Route to a Listener is based solely on the + combination of the AllowedRoutes field on the corresponding Listener + and the Route's ParentRefs field. A Route is successfully attached to + a Listener when it is selected by the Listener's AllowedRoutes field + AND the Route has a valid ParentRef selecting the whole Gateway + resource or a specific Listener as a parent resource (more detail on + attachment semantics can be found in the documentation on the various + Route kinds ParentRefs fields). Listener or Route status does not impact + successful attachment, i.e. the AttachedRoutes field count MUST be set + for Listeners with condition Accepted: false and MUST count successfully + attached Routes that may themselves have Accepted: false conditions. + + Uses for this field include troubleshooting Route attachment and + measuring blast radius/impact of changes to a Listener. + format: int32 + type: integer + conditions: + description: Conditions describe the current condition of this + listener. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + name: + description: Name is the name of the Listener that this status + corresponds to. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + supportedKinds: + description: |- + SupportedKinds is the list indicating the Kinds supported by this + listener. This MUST represent the kinds an implementation supports for + that Listener configuration. + + If kinds are specified in Spec that are not supported, they MUST NOT + appear in this list and an implementation MUST set the "ResolvedRefs" + condition to "False" with the "InvalidRouteKinds" reason. If both valid + and invalid Route kinds are specified, the implementation MUST + reference the valid Route kinds that have been specified. + items: + description: RouteGroupKind indicates the group and kind of + a Route resource. + properties: + group: + default: gateway.networking.k8s.io + description: Group is the group of the Route. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is the kind of the Route. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + required: + - kind + type: object + maxItems: 8 + type: array + required: + - attachedRoutes + - conditions + - name + - supportedKinds + type: object + maxItems: 64 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 + gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: grpcroutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: GRPCRoute + listKind: GRPCRouteList + plural: grpcroutes + singular: grpcroute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + GRPCRoute provides a way to route gRPC requests. This includes the capability + to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. + Filters can be used to specify additional processing steps. Backends specify + where matching requests will be routed. + + GRPCRoute falls under extended support within the Gateway API. Within the + following specification, the word "MUST" indicates that an implementation + supporting GRPCRoute must conform to the indicated requirement, but an + implementation not supporting this route type need not follow the requirement + unless explicitly indicated. + + Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST + accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via + ALPN. If the implementation does not support this, then it MUST set the + "Accepted" condition to "False" for the affected listener with a reason of + "UnsupportedProtocol". Implementations MAY also accept HTTP/2 connections + with an upgrade from HTTP/1. + + Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST + support HTTP/2 over cleartext TCP (h2c, + https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial + upgrade from HTTP/1.1, i.e. with prior knowledge + (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation + does not support this, then it MUST set the "Accepted" condition to "False" + for the affected listener with a reason of "UnsupportedProtocol". + Implementations MAY also accept HTTP/2 connections with an upgrade from + HTTP/1, i.e. without prior knowledge. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of GRPCRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames to match against the GRPC + Host header to select a GRPCRoute to process the request. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label MUST appear by itself as the first label. + + If a hostname is specified by both the Listener and GRPCRoute, there + MUST be at least one intersecting hostname for the GRPCRoute to be + attached to the Listener. For example: + + * A Listener with `test.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches GRPCRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `test.example.com` and `*.example.com` would both match. On the other + hand, `example.com` and `test.example.net` would not match. + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + If both the Listener and GRPCRoute have specified hostnames, any + GRPCRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + GRPCRoute specified `test.example.com` and `test.example.net`, + `test.example.net` MUST NOT be considered for a match. + + If both the Listener and GRPCRoute have specified hostnames, and none + match with the criteria above, then the GRPCRoute MUST NOT be accepted by + the implementation. The implementation MUST raise an 'Accepted' Condition + with a status of `False` in the corresponding RouteParentStatus. + + If a Route (A) of type HTTPRoute or GRPCRoute is attached to a + Listener and that listener already has another Route (B) of the other + type attached and the intersection of the hostnames of A and B is + non-empty, then the implementation MUST accept exactly one of these two + routes, determined by the following criteria, in order: + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + The rejected Route MUST raise an 'Accepted' condition with a status of + 'False' in the corresponding RouteParentStatus. + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + This API may be extended in the future to support additional kinds of parent + resources. + + ParentRefs must be _distinct_. This means either that: + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + Some examples: + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + This API may be extended in the future to support additional kinds of parent + resources. + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName must be specified when parentRefs includes + 2 or more references to the same parent + rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ + == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) + || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName + == '''')) : true))' + - message: sectionName must be unique when parentRefs includes 2 or + more references to the same parent + rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ + == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) + || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName + == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName + == p2.sectionName)))) + rules: + description: |+ + Rules are a list of GRPC matchers, filters and actions. + + items: + description: |- + GRPCRouteRule defines the semantics for matching a gRPC request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive an `UNAVAILABLE` status. + + See the GRPCBackendRef definition for the rules about what makes a single + GRPCBackendRef invalid. + + When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive an `UNAVAILABLE` status. + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. + Implementations may choose how that 50 percent is determined. + + Support: Core for Kubernetes Service + + Support: Implementation-specific for any other resource + + Support for weight: Core + items: + description: |- + GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + properties: + filters: + description: |- + Filters defined at this level MUST be executed if and only if the + request is being forwarded to the backend defined here. + + Support: Implementation-specific (For broader support of filters, use the + Filters field in GRPCRouteRule.) + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + Support: Implementation-specific + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |+ + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + Support: Extended + + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + Support: Extended for Kubernetes Service + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + Support for this field varies based on the context where used. + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + The effects of ordering of multiple behaviors are currently unspecified. + This can change in the future based on feedback during the alpha stage. + + Conformance-levels at this level are defined based on the type of filter: + + - ALL core filters MUST be supported by all implementations that support + GRPCRoute. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + If an implementation can not support a combination of filters, it must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + Support: Core + items: + description: |- + GRPCRouteFilter defines processing steps that must be completed during the + request or response lifecycle. GRPCRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + Support: Implementation-specific + + This filter can be used multiple times within the same rule. + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |+ + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + Support: Extended + + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + Support: Extended for Kubernetes Service + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + required: + - backendRef + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |+ + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations supporting GRPCRoute MUST support core filters. + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + - Implementation-specific: Filters that are defined and supported by specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` MUST be set to + "ExtensionRef" for custom filters. + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + enum: + - ResponseHeaderModifier + - RequestHeaderModifier + - RequestMirror + - ExtensionRef + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + matches: + description: |- + Matches define conditions used for matching the rule against incoming + gRPC requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + For example, take the following matches configuration: + + ``` + matches: + - method: + service: foo.bar + headers: + values: + version: 2 + - method: + service: foo.bar.v2 + ``` + + For a request to match against this rule, it MUST satisfy + EITHER of the two conditions: + + - service of foo.bar AND contains the header `version: 2` + - service of foo.bar.v2 + + See the documentation for GRPCRouteMatch on how to specify multiple + match conditions to be ANDed together. + + If no matches are specified, the implementation MUST match every gRPC request. + + Proxy or Load Balancer routing configuration generated from GRPCRoutes + MUST prioritize rules based on the following criteria, continuing on + ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. + Precedence MUST be given to the rule with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + * Characters in a matching service. + * Characters in a matching method. + * Header matches. + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + If ties still exist within the Route that has been given precedence, + matching precedence MUST be granted to the first matching rule meeting + the above criteria. + items: + description: |- + GRPCRouteMatch defines the predicate used to match requests to a given + action. Multiple match types are ANDed together, i.e. the match will + evaluate to true only if all conditions are satisfied. + + For example, the match below will match a gRPC request only if its service + is `foo` AND it contains the `version: v1` header: + + ``` + matches: + - method: + type: Exact + service: "foo" + headers: + - name: "version" + value "v1" + + ``` + properties: + headers: + description: |- + Headers specifies gRPC request header matchers. Multiple match values are + ANDed together, meaning, a request MUST match all the specified headers + to select the route. + items: + description: |- + GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request + headers. + properties: + name: + description: |- + Name is the name of the gRPC Header to be matched. + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: Type specifies how to match against + the value of the header. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of the gRPC Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies a gRPC request service/method matcher. If this field is + not specified, all services and methods will match. + properties: + method: + description: |- + Value of the method to match against. If left empty or omitted, will + match all services. + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + service: + description: |- + Value of the service to match against. If left empty or omitted, will + match any service. + + At least one of Service and Method MUST be a non-empty string. + maxLength: 1024 + type: string + type: + default: Exact + description: |- + Type specifies how to match against the service and/or method. + Support: Core (Exact with service and method specified) + + Support: Implementation-specific (Exact with method specified but no service specified) + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - RegularExpression + type: string + type: object + x-kubernetes-validations: + - message: One or both of 'service' or 'method' must be + specified + rule: 'has(self.type) ? has(self.service) || has(self.method) + : true' + - message: service must only contain valid characters + (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): + true' + - message: method must only contain valid characters (matching + ^[A-Za-z_][A-Za-z_0-9]*$) + rule: '(!has(self.type) || self.type == ''Exact'') && + has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): + true' + type: object + maxItems: 8 + type: array + type: object + maxItems: 16 + type: array + x-kubernetes-validations: + - message: While 16 rules and 64 matches per rule are allowed, the + total number of matches across all rules in a route must be less + than 128 + rule: '(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size() + : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size() + : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size() + : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size() + : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size() + : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size() + : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size() + : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size() + : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size() + : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size() + : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size() + : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size() + : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size() + : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size() + : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() + : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() + : 0) : 0) <= 128' + type: object + status: + description: Status defines the current state of GRPCRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_httproutes.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 + gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: httproutes.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: HTTPRoute + listKind: HTTPRouteList + plural: httproutes + singular: httproute + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of HTTPRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + If ties exist across multiple Routes, the matching precedence rules for + HTTPRouteMatches takes over. + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + This API may be extended in the future to support additional kinds of parent + resources. + + ParentRefs must be _distinct_. This means either that: + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + Some examples: + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + This API may be extended in the future to support additional kinds of parent + resources. + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName must be specified when parentRefs includes + 2 or more references to the same parent + rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ + == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) + || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName + == '''')) : true))' + - message: sectionName must be unique when parentRefs includes 2 or + more references to the same parent + rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ + == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) + || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName + == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName + == p2.sectionName)))) + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: |+ + Rules are a list of HTTP matchers, filters and actions. + + items: + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + When a HTTPBackendRef refers to a Service that has no ready endpoints, + implementations SHOULD return a 503 for requests to that backend instead. + If an implementation chooses to do this, all of the above rules for 500 responses + MUST also apply for responses that return a 503. + + Support: Core for Kubernetes Service + + Support: Extended for Kubernetes ServiceImport + + Support: Implementation-specific for any other resource + + Support for weight: Core + items: + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + properties: + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |+ + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + Support: Extended + + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + Support: Extended for Kubernetes Service + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + If no port is specified, the redirect port MUST be derived using the + following rules: + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines a path rewrite. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + Support for this field varies based on the context where used. + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + Conformance-levels at this level are defined based on the type of filter: + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + Support: Core + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |+ + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + Support: Extended + + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + Support: Extended for Kubernetes Service + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + If no port is specified, the redirect port MUST be derived using the + following rules: + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines a path rewrite. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - path: + type: PathPrefix + value: / + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + For example, take the following matches configuration: + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + Note: The precedence of RegularExpression path matches are implementation-specific. + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given\naction. Multiple match types + are ANDed together, i.e. the match will\nevaluate to true + only if all conditions are satisfied.\n\nFor example, the + match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n```\nmatch:\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n```" + properties: + headers: + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. + items: + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the header. + + Support: Core (Exact) + + Support: Implementation-specific (RegularExpression) + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + Support: Extended + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + Support: Core (Exact, PathPrefix) + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") + : true' + queryParams: + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + Support: Extended + items: + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. + properties: + name: + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the query parameter. + + Support: Extended (Exact) + + Support: Implementation-specific (RegularExpression) + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 64 + type: array + timeouts: + description: |- + Timeouts defines the timeouts that can be configured for an HTTP request. + + Support: Extended + properties: + backendRequest: + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + to a backend. This covers the time from when the request first starts being + sent from the gateway to when the full response has been received from the backend. + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + An entire client HTTP transaction with a gateway, covered by the Request timeout, + may result in more than one call from the gateway to the destination backend, + for example, if automatic retries are supported. + + The value of BackendRequest must be a Gateway API Duration string as defined by + GEP-2257. When this field is unspecified, its behavior is implementation-specific; + when specified, the value of BackendRequest must be no more than the value of the + Request timeout (since the Request timeout encompasses the BackendRequest timeout). + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + request: + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + If the gateway has not been able to respond before this deadline is met, the gateway + MUST return a timeout error. + + For example, setting the `rules.timeouts.request` field to the value `10s` in an + `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds + to complete. + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + This timeout is intended to cover as close to the whole request-response transaction + as possible although an implementation MAY choose to start the timeout after the entire + request stream has been received instead of immediately after the transaction is + initiated by the client. + + The value of Request is a Gateway API Duration string as defined by GEP-2257. When this + field is unspecified, request timeout behavior is implementation-specific. + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + x-kubernetes-validations: + - message: backendRequest timeout cannot be longer than request + timeout + rule: '!(has(self.request) && has(self.backendRequest) && + duration(self.request) != duration(''0s'') && duration(self.backendRequest) + > duration(self.request))' + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: While 16 rules and 64 matches per rule are allowed, the + total number of matches across all rules in a route must be less + than 128 + rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size() + > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size() + : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size() + > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size() + : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size() + > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size() + : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size() + > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size() + : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() + > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() + : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128' + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .spec.hostnames + name: Hostnames + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + HTTPRoute provides a way to route HTTP requests. This includes the capability + to match requests by hostname, path, header, or query param. Filters can be + used to specify additional processing steps. Backends specify where matching + requests should be routed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of HTTPRoute. + properties: + hostnames: + description: |- + Hostnames defines a set of hostnames that should match against the HTTP Host + header to select a HTTPRoute used to process the request. Implementations + MUST ignore any port value specified in the HTTP Host header while + performing a match and (absent of any applicable header modification + configuration) MUST forward this header unmodified to the backend. + + Valid values for Hostnames are determined by RFC 1123 definition of a + hostname with 2 notable exceptions: + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + If a hostname is specified by both the Listener and HTTPRoute, there + must be at least one intersecting hostname for the HTTPRoute to be + attached to the Listener. For example: + + * A Listener with `test.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames, or have specified at + least one of `test.example.com` or `*.example.com`. + * A Listener with `*.example.com` as the hostname matches HTTPRoutes + that have either not specified any hostnames or have specified at least + one hostname that matches the Listener hostname. For example, + `*.example.com`, `test.example.com`, and `foo.test.example.com` would + all match. On the other hand, `example.com` and `test.example.net` would + not match. + + Hostnames that are prefixed with a wildcard label (`*.`) are interpreted + as a suffix match. That means that a match for `*.example.com` would match + both `test.example.com`, and `foo.test.example.com`, but not `example.com`. + + If both the Listener and HTTPRoute have specified hostnames, any + HTTPRoute hostnames that do not match the Listener hostname MUST be + ignored. For example, if a Listener specified `*.example.com`, and the + HTTPRoute specified `test.example.com` and `test.example.net`, + `test.example.net` must not be considered for a match. + + If both the Listener and HTTPRoute have specified hostnames, and none + match with the criteria above, then the HTTPRoute is not accepted. The + implementation must raise an 'Accepted' Condition with a status of + `False` in the corresponding RouteParentStatus. + + In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. + overlapping wildcard matching and exact matching hostnames), precedence must + be given to rules from the HTTPRoute with the largest number of: + + * Characters in a matching non-wildcard hostname. + * Characters in a matching hostname. + + If ties exist across multiple Routes, the matching precedence rules for + HTTPRouteMatches takes over. + + Support: Core + items: + description: |- + Hostname is the fully qualified domain name of a network host. This matches + the RFC 1123 definition of a hostname with 2 notable exceptions: + + 1. IPs are not allowed. + 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard + label must appear by itself as the first label. + + Hostname can be "precise" which is a domain name without the terminating + dot of a network host (e.g. "foo.example.com") or "wildcard", which is a + domain name prefixed with a single wildcard label (e.g. `*.example.com`). + + Note that as per RFC1035 and RFC1123, a *label* must consist of lower case + alphanumeric characters or '-', and must start and end with an alphanumeric + character. No other punctuation is allowed. + maxLength: 253 + minLength: 1 + pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + maxItems: 16 + type: array + parentRefs: + description: |+ + ParentRefs references the resources (usually Gateways) that a Route wants + to be attached to. Note that the referenced parent resource needs to + allow this for the attachment to be complete. For Gateways, that means + the Gateway needs to allow attachment from Routes of this kind and + namespace. For Services, that means the Service must either be in the same + namespace for a "producer" route, or the mesh implementation must support + and allow "consumer" routes for the referenced Service. ReferenceGrant is + not applicable for governing ParentRefs to Services - it is not possible to + create a "producer" route for a Service in a different namespace from the + Route. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + This API may be extended in the future to support additional kinds of parent + resources. + + ParentRefs must be _distinct_. This means either that: + + * They select different objects. If this is the case, then parentRef + entries are distinct. In terms of fields, this means that the + multi-part key defined by `group`, `kind`, `namespace`, and `name` must + be unique across all parentRef entries in the Route. + * They do not select different objects, but for each optional field used, + each ParentRef that selects the same object must set the same set of + optional fields to different values. If one ParentRef sets a + combination of optional fields, all must set the same combination. + + Some examples: + + * If one ParentRef sets `sectionName`, all ParentRefs referencing the + same object must also set `sectionName`. + * If one ParentRef sets `port`, all ParentRefs referencing the same + object must also set `port`. + * If one ParentRef sets `sectionName` and `port`, all ParentRefs + referencing the same object must also set `sectionName` and `port`. + + It is possible to separately reference multiple distinct objects that may + be collapsed by an implementation. For example, some implementations may + choose to merge compatible Gateway Listeners together. If that is the + case, the list of routes attached to those resources should also be + merged. + + Note that for ParentRefs that cross namespace boundaries, there are specific + rules. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example, + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable other kinds of cross-namespace reference. + + + + + + + items: + description: |- + ParentReference identifies an API object (usually a Gateway) that can be considered + a parent of this resource (usually a route). There are two kinds of parent resources + with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + This API may be extended in the future to support additional kinds of parent + resources. + + The API object must be valid in the cluster; the Group and Kind must + be registered in the cluster for this reference to be valid. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + maxItems: 32 + type: array + x-kubernetes-validations: + - message: sectionName must be specified when parentRefs includes + 2 or more references to the same parent + rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ + == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) + || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName + == '''')) : true))' + - message: sectionName must be unique when parentRefs includes 2 or + more references to the same parent + rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind + == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) + || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ + == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && + p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) + || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName + == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName + == p2.sectionName)))) + rules: + default: + - matches: + - path: + type: PathPrefix + value: / + description: |+ + Rules are a list of HTTP matchers, filters and actions. + + items: + description: |- + HTTPRouteRule defines semantics for matching an HTTP request based on + conditions (matches), processing it (filters), and forwarding the request to + an API object (backendRefs). + properties: + backendRefs: + description: |- + BackendRefs defines the backend(s) where matching requests should be + sent. + + Failure behavior here depends on how many BackendRefs are specified and + how many are invalid. + + If *all* entries in BackendRefs are invalid, and there are also no filters + specified in this route rule, *all* traffic which matches this rule MUST + receive a 500 status code. + + See the HTTPBackendRef definition for the rules about what makes a single + HTTPBackendRef invalid. + + When a HTTPBackendRef is invalid, 500 status codes MUST be returned for + requests that would have otherwise been routed to an invalid backend. If + multiple backends are specified, and some are invalid, the proportion of + requests that would otherwise have been routed to an invalid backend + MUST receive a 500 status code. + + For example, if two backends are specified with equal weights, and one is + invalid, 50 percent of traffic must receive a 500. Implementations may + choose how that 50 percent is determined. + + When a HTTPBackendRef refers to a Service that has no ready endpoints, + implementations SHOULD return a 503 for requests to that backend instead. + If an implementation chooses to do this, all of the above rules for 500 responses + MUST also apply for responses that return a 503. + + Support: Core for Kubernetes Service + + Support: Extended for Kubernetes ServiceImport + + Support: Implementation-specific for any other resource + + Support for weight: Core + items: + description: |- + HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. + + Note that when a namespace different than the local namespace is specified, a + ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + + When the BackendRef points to a Kubernetes Service, implementations SHOULD + honor the appProtocol field if it is set for the target Service Port. + + Implementations supporting appProtocol SHOULD recognize the Kubernetes + Standard Application Protocols defined in KEP-3726. + + If a Service appProtocol isn't specified, an implementation MAY infer the + backend protocol through its own means. Implementations MAY infer the + protocol from the Route type referring to the backend Service. + + If a Route is not able to send traffic to the backend using the specified + protocol then the backend is considered invalid. Implementations MUST set the + "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason. + + + properties: + filters: + description: |- + Filters defined at this level should be executed if and only if the + request is being forwarded to the backend defined here. + + Support: Implementation-specific (For broader support of filters, use the + Filters field in HTTPRouteRule.) + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For + example "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |+ + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + Support: Extended + + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + Support: Extended for Kubernetes Service + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + If no port is specified, the redirect port MUST be derived using the + following rules: + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP + Header name and value as defined by RFC + 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP + Header to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines a path rewrite. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified + when type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? + has(self.replaceFullPath) : true' + - message: type must be 'ReplaceFullPath' when + replaceFullPath is set + rule: 'has(self.replaceFullPath) ? self.type + == ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified + when type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' + ? has(self.replacePrefixMatch) : true' + - message: type must be 'ReplacePrefixMatch' + when replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil + if the filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type + != ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type + == ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil + if the filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type + != ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for + RequestMirror filter.type + rule: '!(!has(self.requestMirror) && self.type == + ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the + filter.type is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != + ''RequestRedirect'')' + - message: filter.requestRedirect must be specified + for RequestRedirect filter.type + rule: '!(!has(self.requestRedirect) && self.type == + ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for + ExtensionRef filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') + && self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() + <= 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() + <= 1 + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + weight: + default: 1 + description: |- + Weight specifies the proportion of requests forwarded to the referenced + backend. This is computed as weight/(sum of all weights in this + BackendRefs list). For non-zero values, there may be some epsilon from + the exact proportion defined here depending on the precision an + implementation supports. Weight is not a percentage and the sum of + weights does not need to equal 100. + + If only one backend is specified and it has a weight greater than 0, 100% + of the traffic is forwarded to that backend. If weight is set to 0, no + traffic should be forwarded for this entry. If unspecified, weight + defaults to 1. + + Support for this field varies based on the context where used. + format: int32 + maximum: 1000000 + minimum: 0 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + maxItems: 16 + type: array + filters: + description: |- + Filters define the filters that are applied to requests that match + this rule. + + Wherever possible, implementations SHOULD implement filters in the order + they are specified. + + Implementations MAY choose to implement this ordering strictly, rejecting + any combination or order of filters that can not be supported. If implementations + choose a strict interpretation of filter ordering, they MUST clearly document + that behavior. + + To reject an invalid combination or order of filters, implementations SHOULD + consider the Route Rules with this configuration invalid. If all Route Rules + in a Route are invalid, the entire Route would be considered invalid. If only + a portion of Route Rules are invalid, implementations MUST set the + "PartiallyInvalid" condition for the Route. + + Conformance-levels at this level are defined based on the type of filter: + + - ALL core filters MUST be supported by all implementations. + - Implementers are encouraged to support extended filters. + - Implementation-specific custom filters have no API guarantees across + implementations. + + Specifying the same filter multiple times is not supported unless explicitly + indicated in the filter. + + All filters are expected to be compatible with each other except for the + URLRewrite and RequestRedirect filters, which may not be combined. If an + implementation can not support other combinations of filters, they must clearly + document that limitation. In cases where incompatible or unsupported + filters are specified and cause the `Accepted` condition to be set to status + `False`, implementations may use the `IncompatibleFilters` reason to specify + this configuration error. + + Support: Core + items: + description: |- + HTTPRouteFilter defines processing steps that must be completed during the + request or response lifecycle. HTTPRouteFilters are meant as an extension + point to express processing that may be done in Gateway implementations. Some + examples include request or response modification, implementing + authentication strategies, rate-limiting, and traffic shaping. API + guarantee/conformance is defined based on the type of the filter. + properties: + extensionRef: + description: |- + ExtensionRef is an optional, implementation-specific extension to the + "filter" behavior. For example, resource "myroutefilter" in group + "networking.example.net"). ExtensionRef MUST NOT be used for core and + extended filters. + + This filter can be used multiple times within the same rule. + + Support: Implementation-specific + properties: + group: + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: Kind is kind of the referent. For example + "HTTPRoute" or "Service". + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + - name + type: object + requestHeaderModifier: + description: |- + RequestHeaderModifier defines a schema for a filter that modifies request + headers. + + Support: Core + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + requestMirror: + description: |+ + RequestMirror defines a schema for a filter that mirrors requests. + Requests are sent to the specified destination, but responses from + that destination are ignored. + + This filter can be used multiple times within the same rule. Note that + not all implementations will be able to support mirroring to multiple + backends. + + Support: Extended + + properties: + backendRef: + description: |- + BackendRef references a resource where mirrored requests are sent. + + Mirrored requests must be sent only to a single destination endpoint + within this BackendRef, irrespective of how many endpoints are present + within this BackendRef. + + If the referent cannot be found, this BackendRef is invalid and must be + dropped from the Gateway. The controller must ensure the "ResolvedRefs" + condition on the Route status is set to `status: False` and not configure + this backend in the underlying implementation. + + If there is a cross-namespace reference to an *existing* object + that is not allowed by a ReferenceGrant, the controller must ensure the + "ResolvedRefs" condition on the Route is set to `status: False`, + with the "RefNotPermitted" reason and not configure this backend in the + underlying implementation. + + In either error case, the Message of the `ResolvedRefs` Condition + should be used to provide more detail about the problem. + + Support: Extended for Kubernetes Service + + Support: Implementation-specific for any other resource + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + Defaults to "Service" when not specified. + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + Support: Core (Services with a type other than ExternalName) + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' + required: + - backendRef + type: object + requestRedirect: + description: |- + RequestRedirect defines a schema for a filter that responds to the + request with an HTTP redirection. + + Support: Core + properties: + hostname: + description: |- + Hostname is the hostname to be used in the value of the `Location` + header in the response. + When empty, the hostname in the `Host` header of the request is used. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines parameters used to modify the path of the incoming request. + The modified path is then used to construct the `Location` header. When + empty, the request path is used as-is. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + port: + description: |- + Port is the port to be used in the value of the `Location` + header in the response. + + If no port is specified, the redirect port MUST be derived using the + following rules: + + * If redirect scheme is not-empty, the redirect port MUST be the well-known + port associated with the redirect scheme. Specifically "http" to port 80 + and "https" to port 443. If the redirect scheme does not have a + well-known port, the listener port of the Gateway SHOULD be used. + * If redirect scheme is empty, the redirect port MUST be the Gateway + Listener port. + + Implementations SHOULD NOT add the port number in the 'Location' + header in the following cases: + + * A Location header that will use HTTP (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 80. + * A Location header that will use HTTPS (whether that is determined via + the Listener protocol or the Scheme field) _and_ use port 443. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + scheme: + description: |- + Scheme is the scheme to be used in the value of the `Location` header in + the response. When empty, the scheme of the request is used. + + Scheme redirects can affect the port of the redirect, for more information, + refer to the documentation for the port field of this filter. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Extended + enum: + - http + - https + type: string + statusCode: + default: 302 + description: |- + StatusCode is the HTTP status code to be used in response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + + Support: Core + enum: + - 301 + - 302 + type: integer + type: object + responseHeaderModifier: + description: |- + ResponseHeaderModifier defines a schema for a filter that modifies response + headers. + + Support: Extended + properties: + add: + description: |- + Add adds the given header(s) (name, value) to the request + before the action. It appends to any existing values associated + with the header name. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + add: + - name: "my-header" + value: "bar,baz" + + Output: + GET /foo HTTP/1.1 + my-header: foo,bar,baz + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + remove: + description: |- + Remove the given header(s) from the HTTP request before the action. The + value of Remove is a list of HTTP header names. Note that the header + names are case-insensitive (see + https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). + + Input: + GET /foo HTTP/1.1 + my-header1: foo + my-header2: bar + my-header3: baz + + Config: + remove: ["my-header1", "my-header3"] + + Output: + GET /foo HTTP/1.1 + my-header2: bar + items: + type: string + maxItems: 16 + type: array + x-kubernetes-list-type: set + set: + description: |- + Set overwrites the request with the given header (name, value) + before the action. + + Input: + GET /foo HTTP/1.1 + my-header: foo + + Config: + set: + - name: "my-header" + value: "bar" + + Output: + GET /foo HTTP/1.1 + my-header: bar + items: + description: HTTPHeader represents an HTTP Header + name and value as defined by RFC 7230. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, the first entry with + an equivalent name MUST be considered for a match. Subsequent entries + with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + value: + description: Value is the value of HTTP Header + to be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + type: + description: |- + Type identifies the type of filter to apply. As with other API fields, + types are classified into three conformance levels: + + - Core: Filter types and their corresponding configuration defined by + "Support: Core" in this package, e.g. "RequestHeaderModifier". All + implementations must support core filters. + + - Extended: Filter types and their corresponding configuration defined by + "Support: Extended" in this package, e.g. "RequestMirror". Implementers + are encouraged to support extended filters. + + - Implementation-specific: Filters that are defined and supported by + specific vendors. + In the future, filters showing convergence in behavior across multiple + implementations will be considered for inclusion in extended or core + conformance levels. Filter-specific configuration for such filters + is specified using the ExtensionRef field. `Type` should be set to + "ExtensionRef" for custom filters. + + Implementers are encouraged to define custom implementation types to + extend the core API with implementation-specific behavior. + + If a reference to a custom filter type cannot be resolved, the filter + MUST NOT be skipped. Instead, requests that would have been processed by + that filter MUST receive a HTTP error response. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - RequestHeaderModifier + - ResponseHeaderModifier + - RequestMirror + - RequestRedirect + - URLRewrite + - ExtensionRef + type: string + urlRewrite: + description: |- + URLRewrite defines a schema for a filter that modifies a request during forwarding. + + Support: Extended + properties: + hostname: + description: |- + Hostname is the value to be used to replace the Host header value during + forwarding. + + Support: Extended + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + path: + description: |- + Path defines a path rewrite. + + Support: Extended + properties: + replaceFullPath: + description: |- + ReplaceFullPath specifies the value with which to replace the full path + of a request during a rewrite or redirect. + maxLength: 1024 + type: string + replacePrefixMatch: + description: |- + ReplacePrefixMatch specifies the value with which to replace the prefix + match of a request during a rewrite or redirect. For example, a request + to "/foo/bar" with a prefix match of "/foo" and a ReplacePrefixMatch + of "/xyz" would be modified to "/xyz/bar". + + Note that this matches the behavior of the PathPrefix match type. This + matches full path elements. A path element refers to the list of labels + in the path split by the `/` separator. When specified, a trailing `/` is + ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all + match the prefix `/abc`, but the path `/abcd` would not. + + ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. + Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in + the implementation setting the Accepted Condition for the Route to `status: False`. + + Request Path | Prefix Match | Replace Prefix | Modified Path + maxLength: 1024 + type: string + type: + description: |- + Type defines the type of path modifier. Additional types may be + added in a future release of the API. + + Note that values may be added to this enum, implementations + must ensure that unknown values will not cause a crash. + + Unknown values here must result in the implementation setting the + Accepted Condition for the Route to `status: False`, with a + Reason of `UnsupportedValue`. + enum: + - ReplaceFullPath + - ReplacePrefixMatch + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: replaceFullPath must be specified when + type is set to 'ReplaceFullPath' + rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) + : true' + - message: type must be 'ReplaceFullPath' when replaceFullPath + is set + rule: 'has(self.replaceFullPath) ? self.type == + ''ReplaceFullPath'' : true' + - message: replacePrefixMatch must be specified when + type is set to 'ReplacePrefixMatch' + rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) + : true' + - message: type must be 'ReplacePrefixMatch' when + replacePrefixMatch is set + rule: 'has(self.replacePrefixMatch) ? self.type + == ''ReplacePrefixMatch'' : true' + type: object + required: + - type + type: object + x-kubernetes-validations: + - message: filter.requestHeaderModifier must be nil if the + filter.type is not RequestHeaderModifier + rule: '!(has(self.requestHeaderModifier) && self.type != + ''RequestHeaderModifier'')' + - message: filter.requestHeaderModifier must be specified + for RequestHeaderModifier filter.type + rule: '!(!has(self.requestHeaderModifier) && self.type == + ''RequestHeaderModifier'')' + - message: filter.responseHeaderModifier must be nil if the + filter.type is not ResponseHeaderModifier + rule: '!(has(self.responseHeaderModifier) && self.type != + ''ResponseHeaderModifier'')' + - message: filter.responseHeaderModifier must be specified + for ResponseHeaderModifier filter.type + rule: '!(!has(self.responseHeaderModifier) && self.type + == ''ResponseHeaderModifier'')' + - message: filter.requestMirror must be nil if the filter.type + is not RequestMirror + rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' + - message: filter.requestMirror must be specified for RequestMirror + filter.type + rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' + - message: filter.requestRedirect must be nil if the filter.type + is not RequestRedirect + rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' + - message: filter.requestRedirect must be specified for RequestRedirect + filter.type + rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' + - message: filter.urlRewrite must be nil if the filter.type + is not URLRewrite + rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' + - message: filter.urlRewrite must be specified for URLRewrite + filter.type + rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' + - message: filter.extensionRef must be nil if the filter.type + is not ExtensionRef + rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' + - message: filter.extensionRef must be specified for ExtensionRef + filter.type + rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: May specify either httpRouteFilterRequestRedirect + or httpRouteFilterRequestRewrite, but not both + rule: '!(self.exists(f, f.type == ''RequestRedirect'') && + self.exists(f, f.type == ''URLRewrite''))' + - message: RequestHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'RequestHeaderModifier').size() + <= 1 + - message: ResponseHeaderModifier filter cannot be repeated + rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() + <= 1 + - message: RequestRedirect filter cannot be repeated + rule: self.filter(f, f.type == 'RequestRedirect').size() <= + 1 + - message: URLRewrite filter cannot be repeated + rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 + matches: + default: + - path: + type: PathPrefix + value: / + description: |- + Matches define conditions used for matching the rule against incoming + HTTP requests. Each match is independent, i.e. this rule will be matched + if **any** one of the matches is satisfied. + + For example, take the following matches configuration: + + ``` + matches: + - path: + value: "/foo" + headers: + - name: "version" + value: "v2" + - path: + value: "/v2/foo" + ``` + + For a request to match against this rule, a request must satisfy + EITHER of the two conditions: + + - path prefixed with `/foo` AND contains the header `version: v2` + - path prefix of `/v2/foo` + + See the documentation for HTTPRouteMatch on how to specify multiple + match conditions that should be ANDed together. + + If no matches are specified, the default is a prefix + path match on "/", which has the effect of matching every + HTTP request. + + Proxy or Load Balancer routing configuration generated from HTTPRoutes + MUST prioritize matches based on the following criteria, continuing on + ties. Across all rules specified on applicable Routes, precedence must be + given to the match having: + + * "Exact" path match. + * "Prefix" path match with largest number of characters. + * Method match. + * Largest number of header matches. + * Largest number of query param matches. + + Note: The precedence of RegularExpression path matches are implementation-specific. + + If ties still exist across multiple Routes, matching precedence MUST be + determined in order of the following criteria, continuing on ties: + + * The oldest Route based on creation timestamp. + * The Route appearing first in alphabetical order by + "{namespace}/{name}". + + If ties still exist within an HTTPRoute, matching precedence MUST be granted + to the FIRST matching rule (in list order) with a match meeting the above + criteria. + + When no rules matching a request have been successfully attached to the + parent a request is coming from, a HTTP 404 status code MUST be returned. + items: + description: "HTTPRouteMatch defines the predicate used to + match requests to a given\naction. Multiple match types + are ANDed together, i.e. the match will\nevaluate to true + only if all conditions are satisfied.\n\nFor example, the + match below will match a HTTP request only if its path\nstarts + with `/foo` AND it contains the `version: v1` header:\n\n```\nmatch:\n\n\tpath:\n\t + \ value: \"/foo\"\n\theaders:\n\t- name: \"version\"\n\t + \ value \"v1\"\n\n```" + properties: + headers: + description: |- + Headers specifies HTTP request header matchers. Multiple match values are + ANDed together, meaning, a request must match all the specified headers + to select the route. + items: + description: |- + HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request + headers. + properties: + name: + description: |- + Name is the name of the HTTP Header to be matched. Name matching MUST be + case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). + + If multiple entries specify equivalent header names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent header name MUST be ignored. Due to the + case-insensitivity of header names, "foo" and "Foo" are considered + equivalent. + + When a header is repeated in an HTTP request, it is + implementation-specific behavior as to how this is represented. + Generally, proxies should follow the guidance from the RFC: + https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding + processing a repeated header, with special handling for "Set-Cookie". + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the header. + + Support: Core (Exact) + + Support: Implementation-specific (RegularExpression) + + Since RegularExpression HeaderMatchType has implementation-specific + conformance, implementations can support POSIX, PCRE or any other dialects + of regular expressions. Please read the implementation's documentation to + determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP Header to + be matched. + maxLength: 4096 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + method: + description: |- + Method specifies HTTP method matcher. + When specified, this route will be matched only if the request has the + specified method. + + Support: Extended + enum: + - GET + - HEAD + - POST + - PUT + - DELETE + - CONNECT + - OPTIONS + - TRACE + - PATCH + type: string + path: + default: + type: PathPrefix + value: / + description: |- + Path specifies a HTTP request path matcher. If this field is not + specified, a default prefix match on the "/" path is provided. + properties: + type: + default: PathPrefix + description: |- + Type specifies how to match against the path Value. + + Support: Core (Exact, PathPrefix) + + Support: Implementation-specific (RegularExpression) + enum: + - Exact + - PathPrefix + - RegularExpression + type: string + value: + default: / + description: Value of the HTTP path to match against. + maxLength: 1024 + type: string + type: object + x-kubernetes-validations: + - message: value must be an absolute path and start with + '/' when type one of ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') + : true' + - message: must not contain '//' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') + : true' + - message: must not contain '/./' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') + : true' + - message: must not contain '/../' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') + : true' + - message: must not contain '%2f' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') + : true' + - message: must not contain '%2F' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') + : true' + - message: must not contain '#' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') + : true' + - message: must not end with '/..' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') + : true' + - message: must not end with '/.' when type one of ['Exact', + 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') + : true' + - message: type must be one of ['Exact', 'PathPrefix', + 'RegularExpression'] + rule: self.type in ['Exact','PathPrefix'] || self.type + == 'RegularExpression' + - message: must only contain valid characters (matching + ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) + for types ['Exact', 'PathPrefix'] + rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") + : true' + queryParams: + description: |- + QueryParams specifies HTTP query parameter matchers. Multiple match + values are ANDed together, meaning, a request must match all the + specified query parameters to select the route. + + Support: Extended + items: + description: |- + HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP + query parameters. + properties: + name: + description: |- + Name is the name of the HTTP query param to be matched. This must be an + exact string match. (See + https://tools.ietf.org/html/rfc7230#section-2.7.3). + + If multiple entries specify equivalent query param names, only the first + entry with an equivalent name MUST be considered for a match. Subsequent + entries with an equivalent query param name MUST be ignored. + + If a query param is repeated in an HTTP request, the behavior is + purposely left undefined, since different data planes have different + capabilities. However, it is *recommended* that implementations should + match against the first value of the param if the data plane supports it, + as this behavior is expected in other load balancing contexts outside of + the Gateway API. + + Users SHOULD NOT route traffic based on repeated query params to guard + themselves against potential differences in the implementations. + maxLength: 256 + minLength: 1 + pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ + type: string + type: + default: Exact + description: |- + Type specifies how to match against the value of the query parameter. + + Support: Extended (Exact) + + Support: Implementation-specific (RegularExpression) + + Since RegularExpression QueryParamMatchType has Implementation-specific + conformance, implementations can support POSIX, PCRE or any other + dialects of regular expressions. Please read the implementation's + documentation to determine the supported dialect. + enum: + - Exact + - RegularExpression + type: string + value: + description: Value is the value of HTTP query param + to be matched. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + - value + type: object + maxItems: 16 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + maxItems: 64 + type: array + timeouts: + description: |- + Timeouts defines the timeouts that can be configured for an HTTP request. + + Support: Extended + properties: + backendRequest: + description: |- + BackendRequest specifies a timeout for an individual request from the gateway + to a backend. This covers the time from when the request first starts being + sent from the gateway to when the full response has been received from the backend. + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + An entire client HTTP transaction with a gateway, covered by the Request timeout, + may result in more than one call from the gateway to the destination backend, + for example, if automatic retries are supported. + + The value of BackendRequest must be a Gateway API Duration string as defined by + GEP-2257. When this field is unspecified, its behavior is implementation-specific; + when specified, the value of BackendRequest must be no more than the value of the + Request timeout (since the Request timeout encompasses the BackendRequest timeout). + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + request: + description: |- + Request specifies the maximum duration for a gateway to respond to an HTTP request. + If the gateway has not been able to respond before this deadline is met, the gateway + MUST return a timeout error. + + For example, setting the `rules.timeouts.request` field to the value `10s` in an + `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds + to complete. + + Setting a timeout to the zero duration (e.g. "0s") SHOULD disable the timeout + completely. Implementations that cannot completely disable the timeout MUST + instead interpret the zero duration as the longest possible value to which + the timeout can be set. + + This timeout is intended to cover as close to the whole request-response transaction + as possible although an implementation MAY choose to start the timeout after the entire + request stream has been received instead of immediately after the transaction is + initiated by the client. + + The value of Request is a Gateway API Duration string as defined by GEP-2257. When this + field is unspecified, request timeout behavior is implementation-specific. + + Support: Extended + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + x-kubernetes-validations: + - message: backendRequest timeout cannot be longer than request + timeout + rule: '!(has(self.request) && has(self.backendRequest) && + duration(self.request) != duration(''0s'') && duration(self.backendRequest) + > duration(self.request))' + type: object + x-kubernetes-validations: + - message: RequestRedirect filter must not be used together with + backendRefs + rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? + (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): + true' + - message: When using RequestRedirect filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + ? ((size(self.matches) != 1 || !has(self.matches[0].path) || + self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: When using URLRewrite filter with path.replacePrefixMatch, + exactly one PathPrefix match must be specified + rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + - message: Within backendRefs, when using RequestRedirect filter + with path.replacePrefixMatch, exactly one PathPrefix match must + be specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) + && has(f.requestRedirect.path) && f.requestRedirect.path.type + == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) + )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) + || self.matches[0].path.type != ''PathPrefix'') ? false : true) + : true' + - message: Within backendRefs, When using URLRewrite filter with + path.replacePrefixMatch, exactly one PathPrefix match must be + specified + rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, + (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) + && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' + && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) + != 1 || !has(self.matches[0].path) || self.matches[0].path.type + != ''PathPrefix'') ? false : true) : true' + maxItems: 16 + type: array + x-kubernetes-validations: + - message: While 16 rules and 64 matches per rule are allowed, the + total number of matches across all rules in a route must be less + than 128 + rule: '(self.size() > 0 ? self[0].matches.size() : 0) + (self.size() + > 1 ? self[1].matches.size() : 0) + (self.size() > 2 ? self[2].matches.size() + : 0) + (self.size() > 3 ? self[3].matches.size() : 0) + (self.size() + > 4 ? self[4].matches.size() : 0) + (self.size() > 5 ? self[5].matches.size() + : 0) + (self.size() > 6 ? self[6].matches.size() : 0) + (self.size() + > 7 ? self[7].matches.size() : 0) + (self.size() > 8 ? self[8].matches.size() + : 0) + (self.size() > 9 ? self[9].matches.size() : 0) + (self.size() + > 10 ? self[10].matches.size() : 0) + (self.size() > 11 ? self[11].matches.size() + : 0) + (self.size() > 12 ? self[12].matches.size() : 0) + (self.size() + > 13 ? self[13].matches.size() : 0) + (self.size() > 14 ? self[14].matches.size() + : 0) + (self.size() > 15 ? self[15].matches.size() : 0) <= 128' + type: object + status: + description: Status defines the current state of HTTPRoute. + properties: + parents: + description: |- + Parents is a list of parent resources (usually Gateways) that are + associated with the route, and the status of the route with respect to + each parent. When this route attaches to a parent, the controller that + manages the parent must add an entry to this list when the controller + first sees the route and should update the entry as appropriate when the + route or gateway is modified. + + Note that parent references that cannot be resolved by an implementation + of this API will not be added to this list. Implementations of this API + can only populate Route status for the Gateways/parent resources they are + responsible for. + + A maximum of 32 Gateways will be represented in this list. An empty list + means the route has not been attached to any Gateway. + items: + description: |- + RouteParentStatus describes the status of a route with respect to an + associated Parent. + properties: + conditions: + description: |- + Conditions describes the status of the route with respect to the Gateway. + Note that the route's availability is also subject to the Gateway's own + status conditions and listener status. + + If the Route's ParentRef specifies an existing Gateway that supports + Routes of this kind AND that Gateway's controller has sufficient access, + then that Gateway's controller MUST set the "Accepted" condition on the + Route, to indicate whether the route has been accepted or rejected by the + Gateway, and why. + + A Route MUST be considered "Accepted" if at least one of the Route's + rules is implemented by the Gateway. + + There are a number of cases where the "Accepted" condition may not be set + due to lack of controller visibility, that includes when: + + * The Route refers to a non-existent parent. + * The Route is of a type that the controller does not support. + * The Route is in a namespace the controller does not have access to. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, + Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + minItems: 1 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + controllerName: + description: |- + ControllerName is a domain/path string that indicates the name of the + controller that wrote this status. This corresponds with the + controllerName field on GatewayClass. + + Example: "example.net/gateway-controller". + + The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are + valid Kubernetes names + (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). + + Controllers MUST populate this field when writing status. Controllers should ensure that + entries to status populated with their ControllerName are cleaned up when they are no + longer necessary. + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ + type: string + parentRef: + description: |- + ParentRef corresponds with a ParentRef in the spec that this + RouteParentStatus struct describes the status of. + properties: + group: + default: gateway.networking.k8s.io + description: |- + Group is the group of the referent. + When unspecified, "gateway.networking.k8s.io" is inferred. + To set the core API group (such as for a "Service" kind referent), + Group must be explicitly set to "" (empty string). + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Gateway + description: |- + Kind is kind of the referent. + + There are two kinds of parent resources with "Core" support: + + * Gateway (Gateway conformance profile) + * Service (Mesh conformance profile, ClusterIP Services only) + + Support for other resources is Implementation-Specific. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. + + Support: Core + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the referent. When unspecified, this refers + to the local namespace of the Route. + + Note that there are specific rules for ParentRefs which cross namespace + boundaries. Cross-namespace references are only valid if they are explicitly + allowed by something in the namespace they are referring to. For example: + Gateway has the AllowedRoutes field, and ReferenceGrant provides a + generic way to enable any other kind of cross-namespace reference. + + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port is the network port this Route targets. It can be interpreted + differently based on the type of parent resource. + + When the parent resource is a Gateway, this targets all listeners + listening on the specified port that also support this kind of Route(and + select this Route). It's not recommended to set `Port` unless the + networking behaviors specified in a Route must apply to a specific port + as opposed to a listener(s) whose port(s) may be changed. When both Port + and SectionName are specified, the name and port of the selected listener + must match both specified values. + + + + Implementations MAY choose to support other parent resources. + Implementations supporting other types of parent resources MUST clearly + document how/if Port is interpreted. + + For the purpose of status, an attachment is considered successful as + long as the parent resource accepts it partially. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment + from the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, + the Route MUST be considered detached from the Gateway. + + Support: Extended + format: int32 + maximum: 65535 + minimum: 1 + type: integer + sectionName: + description: |- + SectionName is the name of a section within the target resource. In the + following resources, SectionName is interpreted as the following: + + * Gateway: Listener name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + * Service: Port name. When both Port (experimental) and SectionName + are specified, the name and port of the selected listener must match + both specified values. + + Implementations MAY choose to support attaching Routes to other resources. + If that is the case, they MUST clearly document how SectionName is + interpreted. + + When unspecified (empty string), this will reference the entire resource. + For the purpose of status, an attachment is considered successful if at + least one section in the parent resource accepts it. For example, Gateway + listeners can restrict which Routes can attach to them by Route kind, + namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from + the referencing Route, the Route MUST be considered successfully + attached. If no Gateway listeners accept attachment from this Route, the + Route MUST be considered detached from the Gateway. + + Support: Core + maxLength: 253 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + required: + - name + type: object + required: + - controllerName + - parentRef + type: object + maxItems: 32 + type: array + required: + - parents + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null +--- +# +# config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml +# +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328 + gateway.networking.k8s.io/bundle-version: v1.2.0 + gateway.networking.k8s.io/channel: standard + creationTimestamp: null + name: referencegrants.gateway.networking.k8s.io +spec: + group: gateway.networking.k8s.io + names: + categories: + - gateway-api + kind: ReferenceGrant + listKind: ReferenceGrantList + plural: referencegrants + shortNames: + - refgrant + singular: referencegrant + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: |- + ReferenceGrant identifies kinds of resources in other namespaces that are + trusted to reference the specified kinds of resources in the same namespace + as the policy. + + Each ReferenceGrant can be used to represent a unique trust relationship. + Additional Reference Grants can be used to add to the set of trusted + sources of inbound references for the namespace they are defined within. + + All cross-namespace references in Gateway API (with the exception of cross-namespace + Gateway-route attachment) require a ReferenceGrant. + + ReferenceGrant is a form of runtime verification allowing users to assert + which cross-namespace object references are permitted. Implementations that + support ReferenceGrant MUST NOT permit cross-namespace references which have + no grant, and MUST respond to the removal of a grant by revoking the access + that the grant allowed. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of ReferenceGrant. + properties: + from: + description: |- + From describes the trusted namespaces and kinds that can reference the + resources described in "To". Each entry in this list MUST be considered + to be an additional place that references can be valid from, or to put + this another way, entries MUST be combined using OR. + + Support: Core + items: + description: ReferenceGrantFrom describes trusted namespaces and + kinds. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: |- + Kind is the kind of the referent. Although implementations may support + additional resources, the following types are part of the "Core" + support level for this field. + + When used to permit a SecretObjectReference: + + * Gateway + + When used to permit a BackendObjectReference: + + * GRPCRoute + * HTTPRoute + * TCPRoute + * TLSRoute + * UDPRoute + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + namespace: + description: |- + Namespace is the namespace of the referent. + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + required: + - group + - kind + - namespace + type: object + maxItems: 16 + minItems: 1 + type: array + to: + description: |- + To describes the resources that may be referenced by the resources + described in "From". Each entry in this list MUST be considered to be an + additional place that references can be valid to, or to put this another + way, entries MUST be combined using OR. + + Support: Core + items: + description: |- + ReferenceGrantTo describes what Kinds are allowed as targets of the + references. + properties: + group: + description: |- + Group is the group of the referent. + When empty, the Kubernetes core API group is inferred. + + Support: Core + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: |- + Kind is the kind of the referent. Although implementations may support + additional resources, the following types are part of the "Core" + support level for this field: + + * Secret when used to permit a SecretObjectReference + * Service when used to permit a BackendObjectReference + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: |- + Name is the name of the referent. When unspecified, this policy + refers to all resources of the specified Group and Kind in the local + namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - group + - kind + type: object + maxItems: 16 + minItems: 1 + type: array + required: + - from + - to + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_backendtlspolicies.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_backendtlspolicies.yaml deleted file mode 100644 index bb90c54..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_backendtlspolicies.yaml +++ /dev/null @@ -1,281 +0,0 @@ -# Copyright 2023 The Kubernetes Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# -# Gateway API Experimental channel install -# -# -# config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - labels: - gateway.networking.k8s.io/policy: Direct - name: backendtlspolicies.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: BackendTLSPolicy - listKind: BackendTLSPolicyList - plural: backendtlspolicies - shortNames: - - btlspolicy - singular: backendtlspolicy - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha2 - schema: - openAPIV3Schema: - description: BackendTLSPolicy provides a way to configure how a Gateway connects to a Backend via TLS. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of BackendTLSPolicy. - properties: - targetRef: - description: "TargetRef identifies an API object to apply the policy to. Only Services have Extended support. Implementations MAY support additional objects, with Implementation Specific support. Note that this config applies to the entire referenced resource by default, but this default may change in the future to provide a more granular application of the policy. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource" - properties: - group: - description: Group is the group of the target resource. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the target resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the target resource. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace is the namespace of the referent. When unspecified, the local namespace is inferred. Even when policy targets a resource in a different namespace, it MUST only apply to traffic originating from the same namespace as the policy. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - sectionName: - description: "SectionName is the name of a section within the target resource. When unspecified, this targetRef targets the entire resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name * Service: Port Name \n If a SectionName is specified, but does not exist on the targeted object, the Policy must fail to attach, and the policy implementation should record a `ResolvedRefs` or similar Condition in the Policy's status." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - group - - kind - - name - type: object - tls: - description: TLS contains backend TLS policy configuration. - properties: - caCertRefs: - description: "CACertRefs contains one or more references to Kubernetes objects that contain a PEM-encoded TLS CA certificate bundle, which is used to validate a TLS handshake between the Gateway and backend Pod. \n If CACertRefs is empty or unspecified, then WellKnownCACerts must be specified. Only one of CACertRefs or WellKnownCACerts may be specified, not both. If CACertRefs is empty or unspecified, the configuration for WellKnownCACerts MUST be honored instead. \n References to a resource in a different namespace are invalid for the moment, although we will revisit this in the future. \n A single CACertRef to a Kubernetes ConfigMap kind has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific. \n Support: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`. \n Support: Implementation-specific (More than one reference, or other kinds of resources)." - items: - description: "LocalObjectReference identifies an API object within the namespace of the referrer. The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." - properties: - group: - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. For example "HTTPRoute" or "Service". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - maxItems: 8 - type: array - hostname: - description: "Hostname is used for two purposes in the connection between Gateways and backends: \n 1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066). 2. Hostname MUST be used for authentication and MUST match the certificate served by the matching backend. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - wellKnownCACerts: - description: "WellKnownCACerts specifies whether system CA certificates may be used in the TLS handshake between the gateway and backend pod. \n If WellKnownCACerts is unspecified or empty (\"\"), then CACertRefs must be specified with at least one entry for a valid configuration. Only one of CACertRefs or WellKnownCACerts may be specified, not both. \n Support: Core for \"System\"" - enum: - - System - type: string - required: - - hostname - type: object - x-kubernetes-validations: - - message: must not contain both CACertRefs and WellKnownCACerts - rule: '!(has(self.caCertRefs) && size(self.caCertRefs) > 0 && has(self.wellKnownCACerts) && self.wellKnownCACerts != "")' - - message: must specify either CACertRefs or WellKnownCACerts - rule: (has(self.caCertRefs) && size(self.caCertRefs) > 0 || has(self.wellKnownCACerts) && self.wellKnownCACerts != "") - required: - - targetRef - - tls - type: object - status: - description: Status defines the current state of BackendTLSPolicy. - properties: - ancestors: - description: "Ancestors is a list of ancestor resources (usually Gateways) that are associated with the policy, and the status of the policy with respect to each ancestor. When this policy attaches to a parent, the controller that manages the parent and the ancestors MUST add an entry to this list when the controller first sees the policy and SHOULD update the entry as appropriate when the relevant ancestor is modified. \n Note that choosing the relevant ancestor is left to the Policy designers; an important part of Policy design is designing the right object level at which to namespace this status. \n Note also that implementations MUST ONLY populate ancestor status for the Ancestor resources they are responsible for. Implementations MUST use the ControllerName field to uniquely identify the entries in this list that they are responsible for. \n Note that to achieve this, the list of PolicyAncestorStatus structs MUST be treated as a map with a composite key, made up of the AncestorRef and ControllerName fields combined. \n A maximum of 16 ancestors will be represented in this list. An empty list means the Policy is not relevant for any ancestors. \n If this slice is full, implementations MUST NOT add further entries. Instead they MUST consider the policy unimplementable and signal that on any related resources such as the ancestor that would be referenced here. For example, if this list was full on BackendTLSPolicy, no additional Gateways would be able to reference the Service targeted by the BackendTLSPolicy." - items: - description: "PolicyAncestorStatus describes the status of a route with respect to an associated Ancestor. \n Ancestors refer to objects that are either the Target of a policy or above it in terms of object hierarchy. For example, if a policy targets a Service, the Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most useful object to place Policy status on, so we recommend that implementations SHOULD use Gateway as the PolicyAncestorStatus object unless the designers have a _very_ good reason otherwise. \n In the context of policy attachment, the Ancestor is used to distinguish which resource results in a distinct application of this policy. For example, if a policy targets a Service, it may have a distinct result per attached Gateway. \n Policies targeting the same resource may have different effects depending on the ancestors of those resources. For example, different Gateways targeting the same Service may have different capabilities, especially if they have different underlying implementations. \n For example, in BackendTLSPolicy, the Policy attaches to a Service that is used as a backend in a HTTPRoute that is itself attached to a Gateway. In this case, the relevant object for status is the Gateway, and that is the ancestor object referred to in this status. \n Note that a parent is also an ancestor, so for objects where the parent is the relevant object for status, this struct SHOULD still be used. \n This struct is intended to be used in a slice that's effectively a map, with a composite key made up of the AncestorRef and the ControllerName." - properties: - ancestorRef: - description: AncestorRef corresponds with a ParentRef in the spec that this PolicyAncestorStatus struct describes the status of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - conditions: - description: Conditions describes the status of the Policy with respect to the given Ancestor. - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - required: - - ancestorRef - - controllerName - type: object - maxItems: 16 - type: array - required: - - ancestors - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_gatewayclasses.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_gatewayclasses.yaml deleted file mode 100644 index 7ebf7c7..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_gatewayclasses.yaml +++ /dev/null @@ -1,381 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_gatewayclasses.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: gatewayclasses.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: GatewayClass - listKind: GatewayClassList - plural: gatewayclasses - shortNames: - - gc - singular: gatewayclass - scope: Cluster - versions: - - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1 - schema: - openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the user for creating Gateway resources. \n It is recommended that this resource be used as a template for Gateways. This means that a Gateway is based on the state of the GatewayClass at the time it was created and changes to the GatewayClass or associated parameters are not propagated down to existing Gateways. This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. \n Whenever one or more Gateways are using a GatewayClass, implementations SHOULD add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the associated GatewayClass. This ensures that a GatewayClass associated with a Gateway is not deleted while in use. \n GatewayClass is a Cluster level resource." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of GatewayClass. - properties: - controllerName: - description: "ControllerName is the name of the controller that is managing Gateways of this class. The value of this field MUST be a domain prefixed path. \n Example: \"example.net/gateway-controller\". \n This field is not mutable and cannot be empty. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains the configuration parameters corresponding to the GatewayClass. This is optional if the controller does not require any additional configuration. \n ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, or an implementation-specific custom resource. The resource can be cluster-scoped or namespace-scoped. \n If the referent cannot be found, the GatewayClass's \"InvalidParameters\" status condition will be true. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace is the namespace of the referent. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - name - type: object - required: - - controllerName - type: object - status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations MUST populate status on all GatewayClass resources which specify their controller name." - properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller for this GatewayClass. \n Controllers should prefer to publish conditions using values of GatewayClassConditionType for the type of each Condition." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 - type: array - x-kubernetes-list-type: set - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.controllerName - name: Controller - type: string - - jsonPath: .status.conditions[?(@.type=="Accepted")].status - name: Accepted - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .spec.description - name: Description - priority: 1 - type: string - name: v1beta1 - schema: - openAPIV3Schema: - description: "GatewayClass describes a class of Gateways available to the user for creating Gateway resources. \n It is recommended that this resource be used as a template for Gateways. This means that a Gateway is based on the state of the GatewayClass at the time it was created and changes to the GatewayClass or associated parameters are not propagated down to existing Gateways. This recommendation is intended to limit the blast radius of changes to GatewayClass or associated parameters. If implementations choose to propagate GatewayClass changes to existing Gateways, that MUST be clearly documented by the implementation. \n Whenever one or more Gateways are using a GatewayClass, implementations SHOULD add the `gateway-exists-finalizer.gateway.networking.k8s.io` finalizer on the associated GatewayClass. This ensures that a GatewayClass associated with a Gateway is not deleted while in use. \n GatewayClass is a Cluster level resource." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of GatewayClass. - properties: - controllerName: - description: "ControllerName is the name of the controller that is managing Gateways of this class. The value of this field MUST be a domain prefixed path. \n Example: \"example.net/gateway-controller\". \n This field is not mutable and cannot be empty. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - x-kubernetes-validations: - - message: Value is immutable - rule: self == oldSelf - description: - description: Description helps describe a GatewayClass with more details. - maxLength: 64 - type: string - parametersRef: - description: "ParametersRef is a reference to a resource that contains the configuration parameters corresponding to the GatewayClass. This is optional if the controller does not require any additional configuration. \n ParametersRef can reference a standard Kubernetes resource, i.e. ConfigMap, or an implementation-specific custom resource. The resource can be cluster-scoped or namespace-scoped. \n If the referent cannot be found, the GatewayClass's \"InvalidParameters\" status condition will be true. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace is the namespace of the referent. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource. - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - name - type: object - required: - - controllerName - type: object - status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Waiting - status: Unknown - type: Accepted - description: "Status defines the current state of GatewayClass. \n Implementations MUST populate status on all GatewayClass resources which specify their controller name." - properties: - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - description: "Conditions is the current status from the controller for this GatewayClass. \n Controllers should prefer to publish conditions using values of GatewayClassConditionType for the type of each Condition." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - supportedFeatures: - description: 'SupportedFeatures is the set of features the GatewayClass support. It MUST be sorted in ascending alphabetical order. ' - items: - description: SupportedFeature is used to describe distinct features that are covered by conformance tests. - enum: - - Gateway - - GatewayPort8080 - - GatewayStaticAddresses - - HTTPRoute - - HTTPRouteDestinationPortMatching - - HTTPRouteHostRewrite - - HTTPRouteMethodMatching - - HTTPRoutePathRedirect - - HTTPRoutePathRewrite - - HTTPRoutePortRedirect - - HTTPRouteQueryParamMatching - - HTTPRouteRequestMirror - - HTTPRouteRequestMultipleMirrors - - HTTPRouteResponseHeaderModification - - HTTPRouteSchemeRedirect - - Mesh - - ReferenceGrant - - TLSRoute - type: string - maxItems: 64 - type: array - x-kubernetes-list-type: set - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_gateways.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_gateways.yaml deleted file mode 100644 index 2a4b26f..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_gateways.yaml +++ /dev/null @@ -1,1037 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_gateways.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: gateways.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: Gateway - listKind: GatewayList - plural: gateways - shortNames: - - gtw - singular: gateway - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.gatewayClassName - name: Class - type: string - - jsonPath: .status.addresses[*].value - name: Address - type: string - - jsonPath: .status.conditions[?(@.type=="Programmed")].status - name: Programmed - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling infrastructure by binding Listeners to a set of IP addresses. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of Gateway. - properties: - addresses: - description: "Addresses requested for this Gateway. This is optional and behavior can depend on the implementation. If a value is set in the spec and the requested address is invalid or unavailable, the implementation MUST indicate this in the associated entry in GatewayStatus.Addresses. \n The Addresses field represents a request for the address(es) on the \"outside of the Gateway\", that traffic bound for this Gateway will use. This could be the IP address or hostname of an external load balancer or other networking infrastructure, or some other address that traffic will be sent to. \n If no Addresses are specified, the implementation MAY schedule the Gateway in an implementation-specific manner, assigning an appropriate set of Addresses. \n The implementation MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway and add a corresponding entry in GatewayStatus.Addresses. \n Support: Extended \n " - items: - description: GatewayAddress describes an address that can be bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): true' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: IPAddress values must be unique - rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' - - message: Hostname values must be unique - rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' - gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name of a GatewayClass resource. - maxLength: 253 - minLength: 1 - type: string - infrastructure: - description: "Infrastructure defines infrastructure level attributes about this Gateway instance. \n Support: Core \n " - properties: - annotations: - additionalProperties: - description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Annotations that SHOULD be applied to any resources created in response to this Gateway. \n For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. For other implementations, this refers to any relevant (implementation specific) \"annotations\" concepts. \n An implementation may chose to add additional implementation-specific annotations as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - labels: - additionalProperties: - description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Labels that SHOULD be applied to any resources created in response to this Gateway. \n For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. For other implementations, this refers to any relevant (implementation specific) \"labels\" concepts. \n An implementation may chose to add additional implementation-specific labels as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. \n Each Listener in a set of Listeners (for example, in a single Gateway) MUST be _distinct_, in that a traffic flow MUST be able to be assigned to exactly one listener. (This section uses \"set of Listeners\" rather than \"Listeners in a single Gateway\" because implementations MAY merge configuration from multiple Gateways onto a single data plane, and these rules _also_ apply in that case). \n Practically, this means that each listener in a set MUST have a unique combination of Port, Protocol, and, if supported by the protocol, Hostname. \n Some combinations of port, protocol, and TLS settings are considered Core support and MUST be supported by implementations based on their targeted conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners have the following property: \n The implementation can match inbound requests to a single distinct Listener. When multiple Listeners share values for fields (for example, two Listeners with the same Port value), the implementation can match requests to only one of the Listeners using other Listener fields. \n For example, the following Listener scenarios are distinct: \n 1. Multiple Listeners with the same Port that all use the \"HTTP\" Protocol that all have unique Hostname values. 2. Multiple Listeners with the same Port that use either the \"HTTPS\" or \"TLS\" Protocol that all have unique Hostname values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, where no Listener with the same Protocol has the same Port value. \n Some fields in the Listener struct have possible values that affect whether the Listener is distinct. Hostname is particularly relevant for HTTP or HTTPS protocols. \n When using the Hostname value to select between same-Port, same-Protocol Listeners, the Hostname value must be different on each Listener for the Listener to be distinct. \n When the Listeners are distinct based on Hostname, inbound request hostnames MUST match from the most specific to least specific Hostname values to choose the correct Listener and its associated set of Routes. \n Exact matches must be processed before wildcard matches, and wildcard matches must be processed before fallback (empty Hostname value) matches. For example, `\"foo.example.com\"` takes precedence over `\"*.example.com\"`, and `\"*.example.com\"` takes precedence over `\"\"`. \n Additionally, if there are multiple wildcard entries, more specific wildcard entries must be processed before less specific wildcard entries. For example, `\"*.foo.example.com\"` takes precedence over `\"*.example.com\"`. The precise definition here is that the higher the number of dots in the hostname to the right of the wildcard character, the higher the precedence. \n The wildcard character will match any number of characters _and dots_ to the left, however, so `\"*.example.com\"` will match both `\"foo.bar.example.com\"` _and_ `\"bar.example.com\"`. \n If a set of Listeners contains Listeners that are not distinct, then those Listeners are Conflicted, and the implementation MUST set the \"Conflicted\" condition in the Listener Status to \"True\". \n Implementations MAY choose to accept a Gateway with some Conflicted Listeners only if they only accept the partial Listener set that contains no Conflicted Listeners. To put this another way, implementations may accept a partial Listener set only if they throw out *all* the conflicting Listeners. No picking one of the conflicting listeners as the winner. This also means that the Gateway must have at least one non-conflicting Listener in this case, otherwise it violates the requirement that at least one Listener must be present. \n The implementation MUST set a \"ListenersNotValid\" condition on the Gateway Status when the Gateway contains Conflicted Listeners whether or not they accept the Gateway. That Condition SHOULD clearly indicate in the Message which Listeners are conflicted, and which are Accepted. Additionally, the Listener status for those listeners SHOULD indicate which Listeners are conflicted and not Accepted. \n A Gateway's Listeners are considered \"compatible\" if: \n 1. They are distinct. 2. The implementation can serve them in compliance with the Addresses requirement that all Listeners are available on all assigned addresses. \n Compatible combinations in Extended support are expected to vary across implementations. A combination that is compatible for one implementation may not be compatible for another. \n For example, an implementation that cannot serve both TCP and UDP listeners on the same address, or cannot mix HTTPS and generic TLS listens on the same port would not consider those cases compatible, even though they are distinct. \n Note that requests SHOULD match at most one Listener. For example, if Listeners are defined for \"foo.example.com\" and \"*.example.com\", a request to \"foo.example.com\" SHOULD only be routed using routes attached to the \"foo.example.com\" Listener (and not the \"*.example.com\" Listener). This concept is known as \"Listener Isolation\". Implementations that do not support Listener Isolation MUST clearly document this. \n Implementations MAY merge separate Gateways onto a single set of Addresses if all Listeners across all Gateways are compatible. \n Support: Core" - items: - description: Listener embodies the concept of a logical endpoint where a Gateway accepts network connections. - properties: - allowedRoutes: - default: - namespaces: - from: Same - description: "AllowedRoutes defines the types of routes that MAY be attached to a Listener and the trusted namespaces where those Route resources MAY be present. \n Although a client request may match multiple route rules, only one rule may ultimately receive the request. Matching precedence MUST be determined in order of the following criteria: \n * The most specific match as defined by the Route type. * The oldest Route based on creation timestamp. For example, a Route with a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over a Route with a creation timestamp of \"2020-09-08 01:02:04\". * If everything else is equivalent, the Route appearing first in alphabetical order (namespace/name) should be given precedence. For example, foo/bar is given precedence over foo/baz. \n All valid rules within a Route attached to this Listener should be implemented. Invalid Route rules can be ignored (sometimes that will mean the full Route). If a Route rule transitions from valid to invalid, support for that Route rule should be dropped to ensure consistency. For example, even if a filter specified by a Route rule is invalid, the rest of the rules within that Route should still be supported. \n Support: Core" - properties: - kinds: - description: "Kinds specifies the groups and kinds of Routes that are allowed to bind to this Gateway Listener. When unspecified or empty, the kinds of Routes selected are determined using the Listener protocol. \n A RouteGroupKind MUST correspond to kinds of Routes that are compatible with the application protocol specified in the Listener's Protocol field. If an implementation does not support or recognize this resource type, it MUST set the \"ResolvedRefs\" condition to False for this Listener with the \"InvalidRouteKinds\" reason. \n Support: Core" - items: - description: RouteGroupKind indicates the group and kind of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - namespaces: - default: - from: Same - description: "Namespaces indicates namespaces from which Routes may be attached to this Listener. This is restricted to the namespace of this Gateway by default. \n Support: Core" - properties: - from: - default: Same - description: "From indicates where Routes will be selected for this Gateway. Possible values are: \n * All: Routes in all namespaces may be used by this Gateway. * Selector: Routes in namespaces selected by the selector may be used by this Gateway. * Same: Only Routes in the same namespace may be used by this Gateway. \n Support: Core" - enum: - - All - - Selector - - Same - type: string - selector: - description: "Selector must be specified when From is set to \"Selector\". In that case, only Routes in Namespaces matching this Selector will be selected by this Gateway. This field is ignored for other values of \"From\". \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - type: object - hostname: - description: "Hostname specifies the virtual hostname to match for protocol types that define this concept. When unspecified, all hostnames are matched. This field is ignored for protocols that don't require hostname based matching. \n Implementations MUST apply Hostname matching appropriately for each of the following protocols: \n * TLS: The Listener Hostname MUST match the SNI. * HTTP: The Listener Hostname MUST match the Host header of the request. * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP protocol layers as described above. If an implementation does not ensure that both the SNI and Host header match the Listener hostname, it MUST clearly document that. \n For HTTPRoute and TLSRoute resources, there is an interaction with the `spec.hostnames` array. When both listener and route specify hostnames, there MUST be an intersection between the values for a Route to be accepted. For more information, refer to the Route specific Hostnames documentation. \n Hostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - name: - description: "Name is the name of the Listener. This name MUST be unique within a Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - port: - description: "Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. \n Support: Core" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - protocol: - description: "Protocol specifies the network protocol this listener expects to receive. \n Support: Core" - maxLength: 255 - minLength: 1 - pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ - type: string - tls: - description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\". \n The association of SNIs to Certificate defined in GatewayTLSConfig is defined based on the Hostname field for this listener. \n The GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake. \n Support: Core" - properties: - certificateRefs: - description: "CertificateRefs contains a series of references to Kubernetes objects that contains TLS certificates and private keys. These certificates are used to establish a TLS handshake for requests that match the hostname of the associated listener. \n A single CertificateRef to a Kubernetes Secret has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a Listener, but this behavior is implementation-specific. \n References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason. \n This field is required to have at least one element when the mode is set to \"Terminate\" (default) and is optional otherwise. \n CertificateRefs can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources. \n Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls \n Support: Implementation-specific (More than one reference or other resource types)" - items: - description: "SecretObjectReference identifies an API object including its namespace, defaulting to Secret. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Secret - description: Kind is kind of the referent. For example "Secret". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referenced object. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - name - type: object - maxItems: 64 - type: array - mode: - default: Terminate - description: "Mode defines the TLS behavior for the TLS session initiated by the client. There are two possible modes: \n - Terminate: The TLS session between the downstream client and the Gateway is terminated at the Gateway. This mode requires certificateRefs to be set and contain at least one element. - Passthrough: The TLS session is NOT terminated by the Gateway. This implies that the Gateway can't decipher the TLS stream except for the ClientHello message of the TLS protocol. CertificateRefs field is ignored in this mode. \n Support: Core" - enum: - - Terminate - - Passthrough - type: string - options: - additionalProperties: - description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Options are a list of key/value pairs to enable extended TLS configuration for each implementation. For example, configuring the minimum TLS version or supported cipher suites. \n A set of common keys MAY be defined by the API in the future. To avoid any ambiguity, implementation-specific definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. Un-prefixed names are reserved for key names defined by Gateway API. \n Support: Implementation-specific" - maxProperties: 16 - type: object - type: object - x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType is Terminate - rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) > 0 : true' - required: - - name - - port - - protocol - type: object - maxItems: 64 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) : true)' - - message: tls must not be specified for protocols ['HTTP', 'TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? !has(l.tls) : true)' - - message: hostname must not be specified for protocols ['TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) || l.hostname == '''') : true)' - - message: Listener name must be unique within the Gateway - rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) - - message: Combination of port, protocol and hostname must be unique for each listener - rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' - required: - - gatewayClassName - - listeners - type: object - status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: Status defines the current state of Gateway. - properties: - addresses: - description: "Addresses lists the network addresses that have been bound to the Gateway. \n This list may differ from the addresses provided in the spec under some conditions: \n * no addresses are specified, all addresses are dynamically assigned * a combination of specified and dynamic addresses are assigned * a specified address was unusable (e.g. already in use) \n " - items: - description: GatewayStatusAddress describes a network address that is bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): true' - maxItems: 16 - type: array - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: "Conditions describe the current conditions of the Gateway. \n Implementations should prefer to express Gateway conditions using the `GatewayConditionType` and `GatewayConditionReason` constants so that operators and tools can converge on a common vocabulary to describe Gateway state. \n Known condition types are: \n * \"Accepted\" * \"Programmed\" * \"Ready\"" - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - listeners: - description: Listeners provide status for each unique listener port defined in the Spec. - items: - description: ListenerStatus is the status associated with a Listener. - properties: - attachedRoutes: - description: "AttachedRoutes represents the total number of Routes that have been successfully attached to this Listener. \n Successful attachment of a Route to a Listener is based solely on the combination of the AllowedRoutes field on the corresponding Listener and the Route's ParentRefs field. A Route is successfully attached to a Listener when it is selected by the Listener's AllowedRoutes field AND the Route has a valid ParentRef selecting the whole Gateway resource or a specific Listener as a parent resource (more detail on attachment semantics can be found in the documentation on the various Route kinds ParentRefs fields). Listener or Route status does not impact successful attachment, i.e. the AttachedRoutes field count MUST be set for Listeners with condition Accepted: false and MUST count successfully attached Routes that may themselves have Accepted: false conditions. \n Uses for this field include troubleshooting Route attachment and measuring blast radius/impact of changes to a Listener." - format: int32 - type: integer - conditions: - description: Conditions describe the current condition of this listener. - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - name: - description: Name is the name of the Listener that this status corresponds to. - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - supportedKinds: - description: "SupportedKinds is the list indicating the Kinds supported by this listener. This MUST represent the kinds an implementation supports for that Listener configuration. \n If kinds are specified in Spec that are not supported, they MUST NOT appear in this list and an implementation MUST set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid and invalid Route kinds are specified, the implementation MUST reference the valid Route kinds that have been specified." - items: - description: RouteGroupKind indicates the group and kind of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - required: - - attachedRoutes - - conditions - - name - - supportedKinds - type: object - maxItems: 64 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.gatewayClassName - name: Class - type: string - - jsonPath: .status.addresses[*].value - name: Address - type: string - - jsonPath: .status.conditions[?(@.type=="Programmed")].status - name: Programmed - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: Gateway represents an instance of a service-traffic handling infrastructure by binding Listeners to a set of IP addresses. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of Gateway. - properties: - addresses: - description: "Addresses requested for this Gateway. This is optional and behavior can depend on the implementation. If a value is set in the spec and the requested address is invalid or unavailable, the implementation MUST indicate this in the associated entry in GatewayStatus.Addresses. \n The Addresses field represents a request for the address(es) on the \"outside of the Gateway\", that traffic bound for this Gateway will use. This could be the IP address or hostname of an external load balancer or other networking infrastructure, or some other address that traffic will be sent to. \n If no Addresses are specified, the implementation MAY schedule the Gateway in an implementation-specific manner, assigning an appropriate set of Addresses. \n The implementation MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway and add a corresponding entry in GatewayStatus.Addresses. \n Support: Extended \n " - items: - description: GatewayAddress describes an address that can be bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): true' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: IPAddress values must be unique - rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' - - message: Hostname values must be unique - rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )' - gatewayClassName: - description: GatewayClassName used for this Gateway. This is the name of a GatewayClass resource. - maxLength: 253 - minLength: 1 - type: string - infrastructure: - description: "Infrastructure defines infrastructure level attributes about this Gateway instance. \n Support: Core \n " - properties: - annotations: - additionalProperties: - description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Annotations that SHOULD be applied to any resources created in response to this Gateway. \n For implementations creating other Kubernetes objects, this should be the `metadata.annotations` field on resources. For other implementations, this refers to any relevant (implementation specific) \"annotations\" concepts. \n An implementation may chose to add additional implementation-specific annotations as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - labels: - additionalProperties: - description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Labels that SHOULD be applied to any resources created in response to this Gateway. \n For implementations creating other Kubernetes objects, this should be the `metadata.labels` field on resources. For other implementations, this refers to any relevant (implementation specific) \"labels\" concepts. \n An implementation may chose to add additional implementation-specific labels as they see fit. \n Support: Extended" - maxProperties: 8 - type: object - type: object - listeners: - description: "Listeners associated with this Gateway. Listeners define logical endpoints that are bound on this Gateway's addresses. At least one Listener MUST be specified. \n Each Listener in a set of Listeners (for example, in a single Gateway) MUST be _distinct_, in that a traffic flow MUST be able to be assigned to exactly one listener. (This section uses \"set of Listeners\" rather than \"Listeners in a single Gateway\" because implementations MAY merge configuration from multiple Gateways onto a single data plane, and these rules _also_ apply in that case). \n Practically, this means that each listener in a set MUST have a unique combination of Port, Protocol, and, if supported by the protocol, Hostname. \n Some combinations of port, protocol, and TLS settings are considered Core support and MUST be supported by implementations based on their targeted conformance profile: \n HTTP Profile \n 1. HTTPRoute, Port: 80, Protocol: HTTP 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided \n TLS Profile \n 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough \n \"Distinct\" Listeners have the following property: \n The implementation can match inbound requests to a single distinct Listener. When multiple Listeners share values for fields (for example, two Listeners with the same Port value), the implementation can match requests to only one of the Listeners using other Listener fields. \n For example, the following Listener scenarios are distinct: \n 1. Multiple Listeners with the same Port that all use the \"HTTP\" Protocol that all have unique Hostname values. 2. Multiple Listeners with the same Port that use either the \"HTTPS\" or \"TLS\" Protocol that all have unique Hostname values. 3. A mixture of \"TCP\" and \"UDP\" Protocol Listeners, where no Listener with the same Protocol has the same Port value. \n Some fields in the Listener struct have possible values that affect whether the Listener is distinct. Hostname is particularly relevant for HTTP or HTTPS protocols. \n When using the Hostname value to select between same-Port, same-Protocol Listeners, the Hostname value must be different on each Listener for the Listener to be distinct. \n When the Listeners are distinct based on Hostname, inbound request hostnames MUST match from the most specific to least specific Hostname values to choose the correct Listener and its associated set of Routes. \n Exact matches must be processed before wildcard matches, and wildcard matches must be processed before fallback (empty Hostname value) matches. For example, `\"foo.example.com\"` takes precedence over `\"*.example.com\"`, and `\"*.example.com\"` takes precedence over `\"\"`. \n Additionally, if there are multiple wildcard entries, more specific wildcard entries must be processed before less specific wildcard entries. For example, `\"*.foo.example.com\"` takes precedence over `\"*.example.com\"`. The precise definition here is that the higher the number of dots in the hostname to the right of the wildcard character, the higher the precedence. \n The wildcard character will match any number of characters _and dots_ to the left, however, so `\"*.example.com\"` will match both `\"foo.bar.example.com\"` _and_ `\"bar.example.com\"`. \n If a set of Listeners contains Listeners that are not distinct, then those Listeners are Conflicted, and the implementation MUST set the \"Conflicted\" condition in the Listener Status to \"True\". \n Implementations MAY choose to accept a Gateway with some Conflicted Listeners only if they only accept the partial Listener set that contains no Conflicted Listeners. To put this another way, implementations may accept a partial Listener set only if they throw out *all* the conflicting Listeners. No picking one of the conflicting listeners as the winner. This also means that the Gateway must have at least one non-conflicting Listener in this case, otherwise it violates the requirement that at least one Listener must be present. \n The implementation MUST set a \"ListenersNotValid\" condition on the Gateway Status when the Gateway contains Conflicted Listeners whether or not they accept the Gateway. That Condition SHOULD clearly indicate in the Message which Listeners are conflicted, and which are Accepted. Additionally, the Listener status for those listeners SHOULD indicate which Listeners are conflicted and not Accepted. \n A Gateway's Listeners are considered \"compatible\" if: \n 1. They are distinct. 2. The implementation can serve them in compliance with the Addresses requirement that all Listeners are available on all assigned addresses. \n Compatible combinations in Extended support are expected to vary across implementations. A combination that is compatible for one implementation may not be compatible for another. \n For example, an implementation that cannot serve both TCP and UDP listeners on the same address, or cannot mix HTTPS and generic TLS listens on the same port would not consider those cases compatible, even though they are distinct. \n Note that requests SHOULD match at most one Listener. For example, if Listeners are defined for \"foo.example.com\" and \"*.example.com\", a request to \"foo.example.com\" SHOULD only be routed using routes attached to the \"foo.example.com\" Listener (and not the \"*.example.com\" Listener). This concept is known as \"Listener Isolation\". Implementations that do not support Listener Isolation MUST clearly document this. \n Implementations MAY merge separate Gateways onto a single set of Addresses if all Listeners across all Gateways are compatible. \n Support: Core" - items: - description: Listener embodies the concept of a logical endpoint where a Gateway accepts network connections. - properties: - allowedRoutes: - default: - namespaces: - from: Same - description: "AllowedRoutes defines the types of routes that MAY be attached to a Listener and the trusted namespaces where those Route resources MAY be present. \n Although a client request may match multiple route rules, only one rule may ultimately receive the request. Matching precedence MUST be determined in order of the following criteria: \n * The most specific match as defined by the Route type. * The oldest Route based on creation timestamp. For example, a Route with a creation timestamp of \"2020-09-08 01:02:03\" is given precedence over a Route with a creation timestamp of \"2020-09-08 01:02:04\". * If everything else is equivalent, the Route appearing first in alphabetical order (namespace/name) should be given precedence. For example, foo/bar is given precedence over foo/baz. \n All valid rules within a Route attached to this Listener should be implemented. Invalid Route rules can be ignored (sometimes that will mean the full Route). If a Route rule transitions from valid to invalid, support for that Route rule should be dropped to ensure consistency. For example, even if a filter specified by a Route rule is invalid, the rest of the rules within that Route should still be supported. \n Support: Core" - properties: - kinds: - description: "Kinds specifies the groups and kinds of Routes that are allowed to bind to this Gateway Listener. When unspecified or empty, the kinds of Routes selected are determined using the Listener protocol. \n A RouteGroupKind MUST correspond to kinds of Routes that are compatible with the application protocol specified in the Listener's Protocol field. If an implementation does not support or recognize this resource type, it MUST set the \"ResolvedRefs\" condition to False for this Listener with the \"InvalidRouteKinds\" reason. \n Support: Core" - items: - description: RouteGroupKind indicates the group and kind of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - namespaces: - default: - from: Same - description: "Namespaces indicates namespaces from which Routes may be attached to this Listener. This is restricted to the namespace of this Gateway by default. \n Support: Core" - properties: - from: - default: Same - description: "From indicates where Routes will be selected for this Gateway. Possible values are: \n * All: Routes in all namespaces may be used by this Gateway. * Selector: Routes in namespaces selected by the selector may be used by this Gateway. * Same: Only Routes in the same namespace may be used by this Gateway. \n Support: Core" - enum: - - All - - Selector - - Same - type: string - selector: - description: "Selector must be specified when From is set to \"Selector\". In that case, only Routes in Namespaces matching this Selector will be selected by this Gateway. This field is ignored for other values of \"From\". \n Support: Core" - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - type: object - hostname: - description: "Hostname specifies the virtual hostname to match for protocol types that define this concept. When unspecified, all hostnames are matched. This field is ignored for protocols that don't require hostname based matching. \n Implementations MUST apply Hostname matching appropriately for each of the following protocols: \n * TLS: The Listener Hostname MUST match the SNI. * HTTP: The Listener Hostname MUST match the Host header of the request. * HTTPS: The Listener Hostname SHOULD match at both the TLS and HTTP protocol layers as described above. If an implementation does not ensure that both the SNI and Host header match the Listener hostname, it MUST clearly document that. \n For HTTPRoute and TLSRoute resources, there is an interaction with the `spec.hostnames` array. When both listener and route specify hostnames, there MUST be an intersection between the values for a Route to be accepted. For more information, refer to the Route specific Hostnames documentation. \n Hostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - name: - description: "Name is the name of the Listener. This name MUST be unique within a Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - port: - description: "Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. \n Support: Core" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - protocol: - description: "Protocol specifies the network protocol this listener expects to receive. \n Support: Core" - maxLength: 255 - minLength: 1 - pattern: ^[a-zA-Z0-9]([-a-zSA-Z0-9]*[a-zA-Z0-9])?$|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9]+$ - type: string - tls: - description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\". \n The association of SNIs to Certificate defined in GatewayTLSConfig is defined based on the Hostname field for this listener. \n The GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake. \n Support: Core" - properties: - certificateRefs: - description: "CertificateRefs contains a series of references to Kubernetes objects that contains TLS certificates and private keys. These certificates are used to establish a TLS handshake for requests that match the hostname of the associated listener. \n A single CertificateRef to a Kubernetes Secret has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a Listener, but this behavior is implementation-specific. \n References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason. \n This field is required to have at least one element when the mode is set to \"Terminate\" (default) and is optional otherwise. \n CertificateRefs can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources. \n Support: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls \n Support: Implementation-specific (More than one reference or other resource types)" - items: - description: "SecretObjectReference identifies an API object including its namespace, defaulting to Secret. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid. \n References to objects with invalid Group and Kind are not valid, and must be rejected by the implementation, with appropriate Conditions set on the containing object." - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Secret - description: Kind is kind of the referent. For example "Secret". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referenced object. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - name - type: object - maxItems: 64 - type: array - mode: - default: Terminate - description: "Mode defines the TLS behavior for the TLS session initiated by the client. There are two possible modes: \n - Terminate: The TLS session between the downstream client and the Gateway is terminated at the Gateway. This mode requires certificateRefs to be set and contain at least one element. - Passthrough: The TLS session is NOT terminated by the Gateway. This implies that the Gateway can't decipher the TLS stream except for the ClientHello message of the TLS protocol. CertificateRefs field is ignored in this mode. \n Support: Core" - enum: - - Terminate - - Passthrough - type: string - options: - additionalProperties: - description: AnnotationValue is the value of an annotation in Gateway API. This is used for validation of maps such as TLS options. This roughly matches Kubernetes annotation validation, although the length validation in that case is based on the entire size of the annotations struct. - maxLength: 4096 - minLength: 0 - type: string - description: "Options are a list of key/value pairs to enable extended TLS configuration for each implementation. For example, configuring the minimum TLS version or supported cipher suites. \n A set of common keys MAY be defined by the API in the future. To avoid any ambiguity, implementation-specific definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. Un-prefixed names are reserved for key names defined by Gateway API. \n Support: Implementation-specific" - maxProperties: 16 - type: object - type: object - x-kubernetes-validations: - - message: certificateRefs must be specified when TLSModeType is Terminate - rule: 'self.mode == ''Terminate'' ? size(self.certificateRefs) > 0 : true' - required: - - name - - port - - protocol - type: object - maxItems: 64 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - x-kubernetes-validations: - - message: tls must be specified for protocols ['HTTPS', 'TLS'] - rule: 'self.all(l, l.protocol in [''HTTPS'', ''TLS''] ? has(l.tls) : true)' - - message: tls must not be specified for protocols ['HTTP', 'TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''HTTP'', ''TCP'', ''UDP''] ? !has(l.tls) : true)' - - message: hostname must not be specified for protocols ['TCP', 'UDP'] - rule: 'self.all(l, l.protocol in [''TCP'', ''UDP''] ? (!has(l.hostname) || l.hostname == '''') : true)' - - message: Listener name must be unique within the Gateway - rule: self.all(l1, self.exists_one(l2, l1.name == l2.name)) - - message: Combination of port, protocol and hostname must be unique for each listener - rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))' - required: - - gatewayClassName - - listeners - type: object - status: - default: - conditions: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: Status defines the current state of Gateway. - properties: - addresses: - description: "Addresses lists the network addresses that have been bound to the Gateway. \n This list may differ from the addresses provided in the spec under some conditions: \n * no addresses are specified, all addresses are dynamically assigned * a combination of specified and dynamic addresses are assigned * a specified address was unusable (e.g. already in use) \n " - items: - description: GatewayStatusAddress describes a network address that is bound to a Gateway. - oneOf: - - properties: - type: - enum: - - IPAddress - value: - anyOf: - - format: ipv4 - - format: ipv6 - - properties: - type: - not: - enum: - - IPAddress - properties: - type: - default: IPAddress - description: Type of the address. - maxLength: 253 - minLength: 1 - pattern: ^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - value: - description: "Value of the address. The validity of the values will depend on the type and support by the controller. \n Examples: `1.2.3.4`, `128::1`, `my-ip-address`." - maxLength: 253 - minLength: 1 - type: string - required: - - value - type: object - x-kubernetes-validations: - - message: Hostname value must only contain valid characters (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$) - rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""): true' - maxItems: 16 - type: array - conditions: - default: - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Accepted - - lastTransitionTime: "1970-01-01T00:00:00Z" - message: Waiting for controller - reason: Pending - status: Unknown - type: Programmed - description: "Conditions describe the current conditions of the Gateway. \n Implementations should prefer to express Gateway conditions using the `GatewayConditionType` and `GatewayConditionReason` constants so that operators and tools can converge on a common vocabulary to describe Gateway state. \n Known condition types are: \n * \"Accepted\" * \"Programmed\" * \"Ready\"" - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - listeners: - description: Listeners provide status for each unique listener port defined in the Spec. - items: - description: ListenerStatus is the status associated with a Listener. - properties: - attachedRoutes: - description: "AttachedRoutes represents the total number of Routes that have been successfully attached to this Listener. \n Successful attachment of a Route to a Listener is based solely on the combination of the AllowedRoutes field on the corresponding Listener and the Route's ParentRefs field. A Route is successfully attached to a Listener when it is selected by the Listener's AllowedRoutes field AND the Route has a valid ParentRef selecting the whole Gateway resource or a specific Listener as a parent resource (more detail on attachment semantics can be found in the documentation on the various Route kinds ParentRefs fields). Listener or Route status does not impact successful attachment, i.e. the AttachedRoutes field count MUST be set for Listeners with condition Accepted: false and MUST count successfully attached Routes that may themselves have Accepted: false conditions. \n Uses for this field include troubleshooting Route attachment and measuring blast radius/impact of changes to a Listener." - format: int32 - type: integer - conditions: - description: Conditions describe the current condition of this listener. - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - name: - description: Name is the name of the Listener that this status corresponds to. - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - supportedKinds: - description: "SupportedKinds is the list indicating the Kinds supported by this listener. This MUST represent the kinds an implementation supports for that Listener configuration. \n If kinds are specified in Spec that are not supported, they MUST NOT appear in this list and an implementation MUST set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid and invalid Route kinds are specified, the implementation MUST reference the valid Route kinds that have been specified." - items: - description: RouteGroupKind indicates the group and kind of a Route resource. - properties: - group: - default: gateway.networking.k8s.io - description: Group is the group of the Route. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is the kind of the Route. - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - required: - - kind - type: object - maxItems: 8 - type: array - required: - - attachedRoutes - - conditions - - name - - supportedKinds - type: object - maxItems: 64 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_grpcroutes.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_grpcroutes.yaml deleted file mode 100644 index 1d29641..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_grpcroutes.yaml +++ /dev/null @@ -1,819 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: grpcroutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: GRPCRoute - listKind: GRPCRouteList - plural: grpcroutes - singular: grpcroute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.hostnames - name: Hostnames - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha2 - schema: - openAPIV3Schema: - description: "GRPCRoute provides a way to route gRPC requests. This includes the capability to match requests by hostname, gRPC service, gRPC method, or HTTP/2 header. Filters can be used to specify additional processing steps. Backends specify where matching requests will be routed. \n GRPCRoute falls under extended support within the Gateway API. Within the following specification, the word \"MUST\" indicates that an implementation supporting GRPCRoute must conform to the indicated requirement, but an implementation not supporting this route type need not follow the requirement unless explicitly indicated. \n Implementations supporting `GRPCRoute` with the `HTTPS` `ProtocolType` MUST accept HTTP/2 connections without an initial upgrade from HTTP/1.1, i.e. via ALPN. If the implementation does not support this, then it MUST set the \"Accepted\" condition to \"False\" for the affected listener with a reason of \"UnsupportedProtocol\". Implementations MAY also accept HTTP/2 connections with an upgrade from HTTP/1. \n Implementations supporting `GRPCRoute` with the `HTTP` `ProtocolType` MUST support HTTP/2 over cleartext TCP (h2c, https://www.rfc-editor.org/rfc/rfc7540#section-3.1) without an initial upgrade from HTTP/1.1, i.e. with prior knowledge (https://www.rfc-editor.org/rfc/rfc7540#section-3.4). If the implementation does not support this, then it MUST set the \"Accepted\" condition to \"False\" for the affected listener with a reason of \"UnsupportedProtocol\". Implementations MAY also accept HTTP/2 connections with an upgrade from HTTP/1, i.e. without prior knowledge." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of GRPCRoute. - properties: - hostnames: - description: "Hostnames defines a set of hostnames to match against the GRPC Host header to select a GRPCRoute to process the request. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label MUST appear by itself as the first label. \n If a hostname is specified by both the Listener and GRPCRoute, there MUST be at least one intersecting hostname for the GRPCRoute to be attached to the Listener. For example: \n * A Listener with `test.example.com` as the hostname matches GRPCRoutes that have either not specified any hostnames, or have specified at least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches GRPCRoutes that have either not specified any hostnames or have specified at least one hostname that matches the Listener hostname. For example, `test.example.com` and `*.example.com` would both match. On the other hand, `example.com` and `test.example.net` would not match. \n Hostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`. \n If both the Listener and GRPCRoute have specified hostnames, any GRPCRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the GRPCRoute specified `test.example.com` and `test.example.net`, `test.example.net` MUST NOT be considered for a match. \n If both the Listener and GRPCRoute have specified hostnames, and none match with the criteria above, then the GRPCRoute MUST NOT be accepted by the implementation. The implementation MUST raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. \n If a Route (A) of type HTTPRoute or GRPCRoute is attached to a Listener and that listener already has another Route (B) of the other type attached and the intersection of the hostnames of A and B is non-empty, then the implementation MUST accept exactly one of these two routes, determined by the following criteria, in order: \n * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by \"{namespace}/{name}\". \n The rejected Route MUST raise an 'Accepted' condition with a status of 'False' in the corresponding RouteParentStatus. \n Support: Core" - items: - description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. `*.example.com`). \n Note that as per RFC1035 and RFC1123, a *label* must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character. No other punctuation is allowed." - maxLength: 253 - minLength: 1 - pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - maxItems: 16 - type: array - parentRefs: - description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n " - items: - description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - maxItems: 32 - type: array - x-kubernetes-validations: - - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent - rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))' - - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent - rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) - rules: - description: Rules are a list of GRPC matchers, filters and actions. - items: - description: GRPCRouteRule defines the semantics for matching a gRPC request based on conditions (matches), processing it (filters), and forwarding the request to an API object (backendRefs). - properties: - backendRefs: - description: "BackendRefs defines the backend(s) where matching requests should be sent. \n Failure behavior here depends on how many BackendRefs are specified and how many are invalid. \n If *all* entries in BackendRefs are invalid, and there are also no filters specified in this route rule, *all* traffic which matches this rule MUST receive an `UNAVAILABLE` status. \n See the GRPCBackendRef definition for the rules about what makes a single GRPCBackendRef invalid. \n When a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for requests that would have otherwise been routed to an invalid backend. If multiple backends are specified, and some are invalid, the proportion of requests that would otherwise have been routed to an invalid backend MUST receive an `UNAVAILABLE` status. \n For example, if two backends are specified with equal weights, and one is invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. Implementations may choose how that 50 percent is determined. \n Support: Core for Kubernetes Service \n Support: Implementation-specific for any other resource \n Support for weight: Core" - items: - description: "GRPCBackendRef defines how a GRPCRoute forwards a gRPC request. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n " - properties: - filters: - description: "Filters defined at this level MUST be executed if and only if the request is being forwarded to the backend defined here. \n Support: Implementation-specific (For broader support of filters, use the Filters field in GRPCRouteRule.)" - items: - description: GRPCRouteFilter defines processing steps that must be completed during the request or response lifecycle. GRPCRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. - properties: - extensionRef: - description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n Support: Implementation-specific \n This filter can be used multiple times within the same rule." - properties: - group: - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. For example "HTTPRoute" or "Service". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - requestMirror: - description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended" - properties: - backendRef: - description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource" - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - required: - - backendRef - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - type: - description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations supporting GRPCRoute MUST support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` MUST be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n " - enum: - - ResponseHeaderModifier - - RequestHeaderModifier - - RequestMirror - - ExtensionRef - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier - rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')' - - message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type - rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')' - - message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier - rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')' - - message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type - rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')' - - message: filter.requestMirror must be nil if the filter.type is not RequestMirror - rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' - - message: filter.requestMirror must be specified for RequestMirror filter.type - rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' - - message: filter.extensionRef must be nil if the filter.type is not ExtensionRef - rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' - - message: filter.extensionRef must be specified for ExtensionRef filter.type - rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: RequestHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1 - - message: ResponseHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1 - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - weight: - default: 1 - description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used." - format: int32 - maximum: 1000000 - minimum: 0 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 16 - type: array - filters: - description: "Filters define the filters that are applied to requests that match this rule. \n The effects of ordering of multiple behaviors are currently unspecified. This can change in the future based on feedback during the alpha stage. \n Conformance-levels at this level are defined based on the type of filter: \n - ALL core filters MUST be supported by all implementations that support GRPCRoute. - Implementers are encouraged to support extended filters. - Implementation-specific custom filters have no API guarantees across implementations. \n Specifying the same filter multiple times is not supported unless explicitly indicated in the filter. \n If an implementation can not support a combination of filters, it must clearly document that limitation. In cases where incompatible or unsupported filters are specified and cause the `Accepted` condition to be set to status `False`, implementations may use the `IncompatibleFilters` reason to specify this configuration error. \n Support: Core" - items: - description: GRPCRouteFilter defines processing steps that must be completed during the request or response lifecycle. GRPCRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. - properties: - extensionRef: - description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n Support: Implementation-specific \n This filter can be used multiple times within the same rule." - properties: - group: - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. For example "HTTPRoute" or "Service". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - requestMirror: - description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended" - properties: - backendRef: - description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource" - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - required: - - backendRef - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - type: - description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations supporting GRPCRoute MUST support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` MUST be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n " - enum: - - ResponseHeaderModifier - - RequestHeaderModifier - - RequestMirror - - ExtensionRef - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier - rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')' - - message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type - rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')' - - message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier - rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')' - - message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type - rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')' - - message: filter.requestMirror must be nil if the filter.type is not RequestMirror - rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' - - message: filter.requestMirror must be specified for RequestMirror filter.type - rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' - - message: filter.extensionRef must be nil if the filter.type is not ExtensionRef - rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' - - message: filter.extensionRef must be specified for ExtensionRef filter.type - rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: RequestHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1 - - message: ResponseHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1 - matches: - description: "Matches define conditions used for matching the rule against incoming gRPC requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied. \n For example, take the following matches configuration: \n ``` matches: - method: service: foo.bar headers: values: version: 2 - method: service: foo.bar.v2 ``` \n For a request to match against this rule, it MUST satisfy EITHER of the two conditions: \n - service of foo.bar AND contains the header `version: 2` - service of foo.bar.v2 \n See the documentation for GRPCRouteMatch on how to specify multiple match conditions to be ANDed together. \n If no matches are specified, the implementation MUST match every gRPC request. \n Proxy or Load Balancer routing configuration generated from GRPCRoutes MUST prioritize rules based on the following criteria, continuing on ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. Precedence MUST be given to the rule with the largest number of: \n * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. * Characters in a matching service. * Characters in a matching method. * Header matches. \n If ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties: \n * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by \"{namespace}/{name}\". \n If ties still exist within the Route that has been given precedence, matching precedence MUST be granted to the first matching rule meeting the above criteria." - items: - description: "GRPCRouteMatch defines the predicate used to match requests to a given action. Multiple match types are ANDed together, i.e. the match will evaluate to true only if all conditions are satisfied. \n For example, the match below will match a gRPC request only if its service is `foo` AND it contains the `version: v1` header: \n ``` matches: - method: type: Exact service: \"foo\" headers: - name: \"version\" value \"v1\" \n ```" - properties: - headers: - description: Headers specifies gRPC request header matchers. Multiple match values are ANDed together, meaning, a request MUST match all the specified headers to select the route. - items: - description: GRPCHeaderMatch describes how to select a gRPC route by matching gRPC request headers. - properties: - name: - description: "Name is the name of the gRPC Header to be matched. \n If multiple entries specify equivalent header names, only the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - type: - default: Exact - description: Type specifies how to match against the value of the header. - enum: - - Exact - - RegularExpression - type: string - value: - description: Value is the value of the gRPC Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - method: - description: Method specifies a gRPC request service/method matcher. If this field is not specified, all services and methods will match. - properties: - method: - description: "Value of the method to match against. If left empty or omitted, will match all services. \n At least one of Service and Method MUST be a non-empty string." - maxLength: 1024 - type: string - service: - description: "Value of the service to match against. If left empty or omitted, will match any service. \n At least one of Service and Method MUST be a non-empty string." - maxLength: 1024 - type: string - type: - default: Exact - description: "Type specifies how to match against the service and/or method. Support: Core (Exact with service and method specified) \n Support: Implementation-specific (Exact with method specified but no service specified) \n Support: Implementation-specific (RegularExpression)" - enum: - - Exact - - RegularExpression - type: string - type: object - x-kubernetes-validations: - - message: One or both of 'service' or 'method' must be specified - rule: 'has(self.type) ? has(self.service) || has(self.method) : true' - - message: service must only contain valid characters (matching ^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$) - rule: '(!has(self.type) || self.type == ''Exact'') && has(self.service) ? self.service.matches(r"""^(?i)\.?[a-z_][a-z_0-9]*(\.[a-z_][a-z_0-9]*)*$"""): true' - - message: method must only contain valid characters (matching ^[A-Za-z_][A-Za-z_0-9]*$) - rule: '(!has(self.type) || self.type == ''Exact'') && has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): true' - type: object - maxItems: 8 - type: array - type: object - maxItems: 16 - type: array - type: object - status: - description: Status defines the current state of GRPCRoute. - properties: - parents: - description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway." - items: - description: RouteParentStatus describes the status of a route with respect to an associated Parent. - properties: - conditions: - description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - parentRef: - description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_httproutes.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_httproutes.yaml deleted file mode 100644 index 5ce7697..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_httproutes.yaml +++ /dev/null @@ -1,2263 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: httproutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: HTTPRoute - listKind: HTTPRouteList - plural: httproutes - singular: httproute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.hostnames - name: Hostnames - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes the capability to match requests by hostname, path, header, or query param. Filters can be used to specify additional processing steps. Backends specify where matching requests should be routed. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of HTTPRoute. - properties: - hostnames: - description: "Hostnames defines a set of hostnames that should match against the HTTP Host header to select a HTTPRoute used to process the request. Implementations MUST ignore any port value specified in the HTTP Host header while performing a match and (absent of any applicable header modification configuration) MUST forward this header unmodified to the backend. \n Valid values for Hostnames are determined by RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n If a hostname is specified by both the Listener and HTTPRoute, there must be at least one intersecting hostname for the HTTPRoute to be attached to the Listener. For example: \n * A Listener with `test.example.com` as the hostname matches HTTPRoutes that have either not specified any hostnames, or have specified at least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes that have either not specified any hostnames or have specified at least one hostname that matches the Listener hostname. For example, `*.example.com`, `test.example.com`, and `foo.test.example.com` would all match. On the other hand, `example.com` and `test.example.net` would not match. \n Hostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`. \n If both the Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the HTTPRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match. \n If both the Listener and HTTPRoute have specified hostnames, and none match with the criteria above, then the HTTPRoute is not accepted. The implementation must raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. \n In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. overlapping wildcard matching and exact matching hostnames), precedence must be given to rules from the HTTPRoute with the largest number of: \n * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. \n If ties exist across multiple Routes, the matching precedence rules for HTTPRouteMatches takes over. \n Support: Core" - items: - description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. `*.example.com`). \n Note that as per RFC1035 and RFC1123, a *label* must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character. No other punctuation is allowed." - maxLength: 253 - minLength: 1 - pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - maxItems: 16 - type: array - parentRefs: - description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n " - items: - description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - maxItems: 32 - type: array - x-kubernetes-validations: - - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent - rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))' - - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent - rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) - rules: - default: - - matches: - - path: - type: PathPrefix - value: / - description: Rules are a list of HTTP matchers, filters and actions. - items: - description: HTTPRouteRule defines semantics for matching an HTTP request based on conditions (matches), processing it (filters), and forwarding the request to an API object (backendRefs). - properties: - backendRefs: - description: "BackendRefs defines the backend(s) where matching requests should be sent. \n Failure behavior here depends on how many BackendRefs are specified and how many are invalid. \n If *all* entries in BackendRefs are invalid, and there are also no filters specified in this route rule, *all* traffic which matches this rule MUST receive a 500 status code. \n See the HTTPBackendRef definition for the rules about what makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef is invalid, 500 status codes MUST be returned for requests that would have otherwise been routed to an invalid backend. If multiple backends are specified, and some are invalid, the proportion of requests that would otherwise have been routed to an invalid backend MUST receive a 500 status code. \n For example, if two backends are specified with equal weights, and one is invalid, 50 percent of traffic must receive a 500. Implementations may choose how that 50 percent is determined. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Core" - items: - description: "HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n " - properties: - filters: - description: "Filters defined at this level should be executed if and only if the request is being forwarded to the backend defined here. \n Support: Implementation-specific (For broader support of filters, use the Filters field in HTTPRouteRule.)" - items: - description: HTTPRouteFilter defines processing steps that must be completed during the request or response lifecycle. HTTPRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. - properties: - extensionRef: - description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n This filter can be used multiple times within the same rule. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. For example "HTTPRoute" or "Service". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - requestMirror: - description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended" - properties: - backendRef: - description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource" - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - required: - - backendRef - type: object - requestRedirect: - description: "RequestRedirect defines a schema for a filter that responds to the request with an HTTP redirection. \n Support: Core" - properties: - hostname: - description: "Hostname is the hostname to be used in the value of the `Location` header in the response. When empty, the hostname in the `Host` header of the request is used. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines parameters used to modify the path of the incoming request. The modified path is then used to construct the `Location` header. When empty, the request path is used as-is. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - port: - description: "Port is the port to be used in the value of the `Location` header in the response. \n If no port is specified, the redirect port MUST be derived using the following rules: \n * If redirect scheme is not-empty, the redirect port MUST be the well-known port associated with the redirect scheme. Specifically \"http\" to port 80 and \"https\" to port 443. If the redirect scheme does not have a well-known port, the listener port of the Gateway SHOULD be used. * If redirect scheme is empty, the redirect port MUST be the Gateway Listener port. \n Implementations SHOULD NOT add the port number in the 'Location' header in the following cases: \n * A Location header that will use HTTP (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 80. * A Location header that will use HTTPS (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 443. \n Support: Extended" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - scheme: - description: "Scheme is the scheme to be used in the value of the `Location` header in the response. When empty, the scheme of the request is used. \n Scheme redirects can affect the port of the redirect, for more information, refer to the documentation for the port field of this filter. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Extended" - enum: - - http - - https - type: string - statusCode: - default: 302 - description: "StatusCode is the HTTP status code to be used in response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Core" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - type: - description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations must support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` should be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a filter that modifies a request during forwarding. \n Support: Extended" - properties: - hostname: - description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines a path rewrite. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - type: object - required: - - type - type: object - x-kubernetes-validations: - - message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier - rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')' - - message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type - rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')' - - message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier - rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')' - - message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type - rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')' - - message: filter.requestMirror must be nil if the filter.type is not RequestMirror - rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' - - message: filter.requestMirror must be specified for RequestMirror filter.type - rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' - - message: filter.requestRedirect must be nil if the filter.type is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' - - message: filter.requestRedirect must be specified for RequestRedirect filter.type - rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - message: filter.extensionRef must be nil if the filter.type is not ExtensionRef - rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' - - message: filter.extensionRef must be specified for ExtensionRef filter.type - rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && self.exists(f, f.type == ''URLRewrite''))' - - message: May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && self.exists(f, f.type == ''URLRewrite''))' - - message: RequestHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1 - - message: ResponseHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() <= 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - weight: - default: 1 - description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used." - format: int32 - maximum: 1000000 - minimum: 0 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 16 - type: array - filters: - description: "Filters define the filters that are applied to requests that match this rule. \n The effects of ordering of multiple behaviors are currently unspecified. This can change in the future based on feedback during the alpha stage. \n Conformance-levels at this level are defined based on the type of filter: \n - ALL core filters MUST be supported by all implementations. - Implementers are encouraged to support extended filters. - Implementation-specific custom filters have no API guarantees across implementations. \n Specifying the same filter multiple times is not supported unless explicitly indicated in the filter. \n All filters are expected to be compatible with each other except for the URLRewrite and RequestRedirect filters, which may not be combined. If an implementation can not support other combinations of filters, they must clearly document that limitation. In cases where incompatible or unsupported filters are specified and cause the `Accepted` condition to be set to status `False`, implementations may use the `IncompatibleFilters` reason to specify this configuration error. \n Support: Core" - items: - description: HTTPRouteFilter defines processing steps that must be completed during the request or response lifecycle. HTTPRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. - properties: - extensionRef: - description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n This filter can be used multiple times within the same rule. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. For example "HTTPRoute" or "Service". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - requestMirror: - description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended" - properties: - backendRef: - description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource" - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - required: - - backendRef - type: object - requestRedirect: - description: "RequestRedirect defines a schema for a filter that responds to the request with an HTTP redirection. \n Support: Core" - properties: - hostname: - description: "Hostname is the hostname to be used in the value of the `Location` header in the response. When empty, the hostname in the `Host` header of the request is used. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines parameters used to modify the path of the incoming request. The modified path is then used to construct the `Location` header. When empty, the request path is used as-is. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - port: - description: "Port is the port to be used in the value of the `Location` header in the response. \n If no port is specified, the redirect port MUST be derived using the following rules: \n * If redirect scheme is not-empty, the redirect port MUST be the well-known port associated with the redirect scheme. Specifically \"http\" to port 80 and \"https\" to port 443. If the redirect scheme does not have a well-known port, the listener port of the Gateway SHOULD be used. * If redirect scheme is empty, the redirect port MUST be the Gateway Listener port. \n Implementations SHOULD NOT add the port number in the 'Location' header in the following cases: \n * A Location header that will use HTTP (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 80. * A Location header that will use HTTPS (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 443. \n Support: Extended" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - scheme: - description: "Scheme is the scheme to be used in the value of the `Location` header in the response. When empty, the scheme of the request is used. \n Scheme redirects can affect the port of the redirect, for more information, refer to the documentation for the port field of this filter. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Extended" - enum: - - http - - https - type: string - statusCode: - default: 302 - description: "StatusCode is the HTTP status code to be used in response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Core" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - type: - description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations must support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` should be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a filter that modifies a request during forwarding. \n Support: Extended" - properties: - hostname: - description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines a path rewrite. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - type: object - required: - - type - type: object - x-kubernetes-validations: - - message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier - rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')' - - message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type - rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')' - - message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier - rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')' - - message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type - rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')' - - message: filter.requestMirror must be nil if the filter.type is not RequestMirror - rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' - - message: filter.requestMirror must be specified for RequestMirror filter.type - rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' - - message: filter.requestRedirect must be nil if the filter.type is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' - - message: filter.requestRedirect must be specified for RequestRedirect filter.type - rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - message: filter.extensionRef must be nil if the filter.type is not ExtensionRef - rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' - - message: filter.extensionRef must be specified for ExtensionRef filter.type - rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && self.exists(f, f.type == ''URLRewrite''))' - - message: RequestHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1 - - message: ResponseHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() <= 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 - matches: - default: - - path: - type: PathPrefix - value: / - description: "Matches define conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied. \n For example, take the following matches configuration: \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request to match against this rule, a request must satisfy EITHER of the two conditions: \n - path prefixed with `/foo` AND contains the header `version: v2` - path prefix of `/v2/foo` \n See the documentation for HTTPRouteMatch on how to specify multiple match conditions that should be ANDed together. \n If no matches are specified, the default is a prefix path match on \"/\", which has the effect of matching every HTTP request. \n Proxy or Load Balancer routing configuration generated from HTTPRoutes MUST prioritize matches based on the following criteria, continuing on ties. Across all rules specified on applicable Routes, precedence must be given to the match having: \n * \"Exact\" path match. * \"Prefix\" path match with largest number of characters. * Method match. * Largest number of header matches. * Largest number of query param matches. \n Note: The precedence of RegularExpression path matches are implementation-specific. \n If ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties: \n * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by \"{namespace}/{name}\". \n If ties still exist within an HTTPRoute, matching precedence MUST be granted to the FIRST matching rule (in list order) with a match meeting the above criteria. \n When no rules matching a request have been successfully attached to the parent a request is coming from, a HTTP 404 status code MUST be returned." - items: - description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple match types are ANDed together, i.e. the match will evaluate to true only if all conditions are satisfied. \n For example, the match below will match a HTTP request only if its path starts with `/foo` AND it contains the `version: v1` header: \n ``` match: \n path: value: \"/foo\" headers: - name: \"version\" value \"v1\" \n ```" - properties: - headers: - description: Headers specifies HTTP request header matchers. Multiple match values are ANDed together, meaning, a request must match all the specified headers to select the route. - items: - description: HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request headers. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, only the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent. \n When a header is repeated in an HTTP request, it is implementation-specific behavior as to how this is represented. Generally, proxies should follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding processing a repeated header, with special handling for \"Set-Cookie\"." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - type: - default: Exact - description: "Type specifies how to match against the value of the header. \n Support: Core (Exact) \n Support: Implementation-specific (RegularExpression) \n Since RegularExpression HeaderMatchType has implementation-specific conformance, implementations can support POSIX, PCRE or any other dialects of regular expressions. Please read the implementation's documentation to determine the supported dialect." - enum: - - Exact - - RegularExpression - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - method: - description: "Method specifies HTTP method matcher. When specified, this route will be matched only if the request has the specified method. \n Support: Extended" - enum: - - GET - - HEAD - - POST - - PUT - - DELETE - - CONNECT - - OPTIONS - - TRACE - - PATCH - type: string - path: - default: - type: PathPrefix - value: / - description: Path specifies a HTTP request path matcher. If this field is not specified, a default prefix match on the "/" path is provided. - properties: - type: - default: PathPrefix - description: "Type specifies how to match against the path Value. \n Support: Core (Exact, PathPrefix) \n Support: Implementation-specific (RegularExpression)" - enum: - - Exact - - PathPrefix - - RegularExpression - type: string - value: - default: / - description: Value of the HTTP path to match against. - maxLength: 1024 - type: string - type: object - x-kubernetes-validations: - - message: value must be an absolute path and start with '/' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') : true' - - message: must not contain '//' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') : true' - - message: must not contain '/./' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') : true' - - message: must not contain '/../' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') : true' - - message: must not contain '%2f' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') : true' - - message: must not contain '%2F' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') : true' - - message: must not contain '#' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') : true' - - message: must not end with '/..' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') : true' - - message: must not end with '/.' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') : true' - - message: type must be one of ['Exact', 'PathPrefix', 'RegularExpression'] - rule: self.type in ['Exact','PathPrefix'] || self.type == 'RegularExpression' - - message: must only contain valid characters (matching ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) for types ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' - queryParams: - description: "QueryParams specifies HTTP query parameter matchers. Multiple match values are ANDed together, meaning, a request must match all the specified query parameters to select the route. \n Support: Extended" - items: - description: HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP query parameters. - properties: - name: - description: "Name is the name of the HTTP query param to be matched. This must be an exact string match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). \n If multiple entries specify equivalent query param names, only the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent query param name MUST be ignored. \n If a query param is repeated in an HTTP request, the behavior is purposely left undefined, since different data planes have different capabilities. However, it is *recommended* that implementations should match against the first value of the param if the data plane supports it, as this behavior is expected in other load balancing contexts outside of the Gateway API. \n Users SHOULD NOT route traffic based on repeated query params to guard themselves against potential differences in the implementations." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - type: - default: Exact - description: "Type specifies how to match against the value of the query parameter. \n Support: Extended (Exact) \n Support: Implementation-specific (RegularExpression) \n Since RegularExpression QueryParamMatchType has Implementation-specific conformance, implementations can support POSIX, PCRE or any other dialects of regular expressions. Please read the implementation's documentation to determine the supported dialect." - enum: - - Exact - - RegularExpression - type: string - value: - description: Value is the value of HTTP query param to be matched. - maxLength: 1024 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - maxItems: 8 - type: array - timeouts: - description: "Timeouts defines the timeouts that can be configured for an HTTP request. \n Support: Extended \n " - properties: - backendRequest: - description: "BackendRequest specifies a timeout for an individual request from the gateway to a backend. This covers the time from when the request first starts being sent from the gateway to when the full response has been received from the backend. \n An entire client HTTP transaction with a gateway, covered by the Request timeout, may result in more than one call from the gateway to the destination backend, for example, if automatic retries are supported. \n Because the Request timeout encompasses the BackendRequest timeout, the value of BackendRequest must be <= the value of Request timeout. \n Support: Extended" - pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ - type: string - request: - description: "Request specifies the maximum duration for a gateway to respond to an HTTP request. If the gateway has not been able to respond before this deadline is met, the gateway MUST return a timeout error. \n For example, setting the `rules.timeouts.request` field to the value `10s` in an `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds to complete. \n This timeout is intended to cover as close to the whole request-response transaction as possible although an implementation MAY choose to start the timeout after the entire request stream has been received instead of immediately after the transaction is initiated by the client. \n When this field is unspecified, request timeout behavior is implementation-specific. \n Support: Extended" - pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ - type: string - type: object - x-kubernetes-validations: - - message: backendRequest timeout cannot be longer than request timeout - rule: '!(has(self.request) && has(self.backendRequest) && duration(self.request) != duration(''0s'') && duration(self.backendRequest) > duration(self.request))' - type: object - x-kubernetes-validations: - - message: RequestRedirect filter must not be used together with backendRefs - rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): true' - - message: When using RequestRedirect filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) && has(f.requestRedirect.path) && f.requestRedirect.path.type == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - - message: When using URLRewrite filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - - message: Within backendRefs, when using RequestRedirect filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) && has(f.requestRedirect.path) && f.requestRedirect.path.type == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - - message: Within backendRefs, When using URLRewrite filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - maxItems: 16 - type: array - type: object - status: - description: Status defines the current state of HTTPRoute. - properties: - parents: - description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway." - items: - description: RouteParentStatus describes the status of a route with respect to an associated Parent. - properties: - conditions: - description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - parentRef: - description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - required: - - spec - type: object - served: true - storage: false - subresources: - status: {} - - additionalPrinterColumns: - - jsonPath: .spec.hostnames - name: Hostnames - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: HTTPRoute provides a way to route HTTP requests. This includes the capability to match requests by hostname, path, header, or query param. Filters can be used to specify additional processing steps. Backends specify where matching requests should be routed. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of HTTPRoute. - properties: - hostnames: - description: "Hostnames defines a set of hostnames that should match against the HTTP Host header to select a HTTPRoute used to process the request. Implementations MUST ignore any port value specified in the HTTP Host header while performing a match and (absent of any applicable header modification configuration) MUST forward this header unmodified to the backend. \n Valid values for Hostnames are determined by RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n If a hostname is specified by both the Listener and HTTPRoute, there must be at least one intersecting hostname for the HTTPRoute to be attached to the Listener. For example: \n * A Listener with `test.example.com` as the hostname matches HTTPRoutes that have either not specified any hostnames, or have specified at least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches HTTPRoutes that have either not specified any hostnames or have specified at least one hostname that matches the Listener hostname. For example, `*.example.com`, `test.example.com`, and `foo.test.example.com` would all match. On the other hand, `example.com` and `test.example.net` would not match. \n Hostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`. \n If both the Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the HTTPRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match. \n If both the Listener and HTTPRoute have specified hostnames, and none match with the criteria above, then the HTTPRoute is not accepted. The implementation must raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. \n In the event that multiple HTTPRoutes specify intersecting hostnames (e.g. overlapping wildcard matching and exact matching hostnames), precedence must be given to rules from the HTTPRoute with the largest number of: \n * Characters in a matching non-wildcard hostname. * Characters in a matching hostname. \n If ties exist across multiple Routes, the matching precedence rules for HTTPRouteMatches takes over. \n Support: Core" - items: - description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. `*.example.com`). \n Note that as per RFC1035 and RFC1123, a *label* must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character. No other punctuation is allowed." - maxLength: 253 - minLength: 1 - pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - maxItems: 16 - type: array - parentRefs: - description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n " - items: - description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - maxItems: 32 - type: array - x-kubernetes-validations: - - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent - rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))' - - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent - rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) - rules: - default: - - matches: - - path: - type: PathPrefix - value: / - description: Rules are a list of HTTP matchers, filters and actions. - items: - description: HTTPRouteRule defines semantics for matching an HTTP request based on conditions (matches), processing it (filters), and forwarding the request to an API object (backendRefs). - properties: - backendRefs: - description: "BackendRefs defines the backend(s) where matching requests should be sent. \n Failure behavior here depends on how many BackendRefs are specified and how many are invalid. \n If *all* entries in BackendRefs are invalid, and there are also no filters specified in this route rule, *all* traffic which matches this rule MUST receive a 500 status code. \n See the HTTPBackendRef definition for the rules about what makes a single HTTPBackendRef invalid. \n When a HTTPBackendRef is invalid, 500 status codes MUST be returned for requests that would have otherwise been routed to an invalid backend. If multiple backends are specified, and some are invalid, the proportion of requests that would otherwise have been routed to an invalid backend MUST receive a 500 status code. \n For example, if two backends are specified with equal weights, and one is invalid, 50 percent of traffic must receive a 500. Implementations may choose how that 50 percent is determined. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Core" - items: - description: "HTTPBackendRef defines how a HTTPRoute forwards a HTTP request. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n " - properties: - filters: - description: "Filters defined at this level should be executed if and only if the request is being forwarded to the backend defined here. \n Support: Implementation-specific (For broader support of filters, use the Filters field in HTTPRouteRule.)" - items: - description: HTTPRouteFilter defines processing steps that must be completed during the request or response lifecycle. HTTPRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. - properties: - extensionRef: - description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n This filter can be used multiple times within the same rule. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. For example "HTTPRoute" or "Service". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - requestMirror: - description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended" - properties: - backendRef: - description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource" - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - required: - - backendRef - type: object - requestRedirect: - description: "RequestRedirect defines a schema for a filter that responds to the request with an HTTP redirection. \n Support: Core" - properties: - hostname: - description: "Hostname is the hostname to be used in the value of the `Location` header in the response. When empty, the hostname in the `Host` header of the request is used. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines parameters used to modify the path of the incoming request. The modified path is then used to construct the `Location` header. When empty, the request path is used as-is. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - port: - description: "Port is the port to be used in the value of the `Location` header in the response. \n If no port is specified, the redirect port MUST be derived using the following rules: \n * If redirect scheme is not-empty, the redirect port MUST be the well-known port associated with the redirect scheme. Specifically \"http\" to port 80 and \"https\" to port 443. If the redirect scheme does not have a well-known port, the listener port of the Gateway SHOULD be used. * If redirect scheme is empty, the redirect port MUST be the Gateway Listener port. \n Implementations SHOULD NOT add the port number in the 'Location' header in the following cases: \n * A Location header that will use HTTP (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 80. * A Location header that will use HTTPS (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 443. \n Support: Extended" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - scheme: - description: "Scheme is the scheme to be used in the value of the `Location` header in the response. When empty, the scheme of the request is used. \n Scheme redirects can affect the port of the redirect, for more information, refer to the documentation for the port field of this filter. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Extended" - enum: - - http - - https - type: string - statusCode: - default: 302 - description: "StatusCode is the HTTP status code to be used in response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Core" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - type: - description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations must support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` should be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a filter that modifies a request during forwarding. \n Support: Extended" - properties: - hostname: - description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines a path rewrite. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - type: object - required: - - type - type: object - x-kubernetes-validations: - - message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier - rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')' - - message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type - rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')' - - message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier - rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')' - - message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type - rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')' - - message: filter.requestMirror must be nil if the filter.type is not RequestMirror - rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' - - message: filter.requestMirror must be specified for RequestMirror filter.type - rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' - - message: filter.requestRedirect must be nil if the filter.type is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' - - message: filter.requestRedirect must be specified for RequestRedirect filter.type - rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - message: filter.extensionRef must be nil if the filter.type is not ExtensionRef - rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' - - message: filter.extensionRef must be specified for ExtensionRef filter.type - rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && self.exists(f, f.type == ''URLRewrite''))' - - message: May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && self.exists(f, f.type == ''URLRewrite''))' - - message: RequestHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1 - - message: ResponseHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() <= 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - weight: - default: 1 - description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used." - format: int32 - maximum: 1000000 - minimum: 0 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 16 - type: array - filters: - description: "Filters define the filters that are applied to requests that match this rule. \n The effects of ordering of multiple behaviors are currently unspecified. This can change in the future based on feedback during the alpha stage. \n Conformance-levels at this level are defined based on the type of filter: \n - ALL core filters MUST be supported by all implementations. - Implementers are encouraged to support extended filters. - Implementation-specific custom filters have no API guarantees across implementations. \n Specifying the same filter multiple times is not supported unless explicitly indicated in the filter. \n All filters are expected to be compatible with each other except for the URLRewrite and RequestRedirect filters, which may not be combined. If an implementation can not support other combinations of filters, they must clearly document that limitation. In cases where incompatible or unsupported filters are specified and cause the `Accepted` condition to be set to status `False`, implementations may use the `IncompatibleFilters` reason to specify this configuration error. \n Support: Core" - items: - description: HTTPRouteFilter defines processing steps that must be completed during the request or response lifecycle. HTTPRouteFilters are meant as an extension point to express processing that may be done in Gateway implementations. Some examples include request or response modification, implementing authentication strategies, rate-limiting, and traffic shaping. API guarantee/conformance is defined based on the type of the filter. - properties: - extensionRef: - description: "ExtensionRef is an optional, implementation-specific extension to the \"filter\" behavior. For example, resource \"myroutefilter\" in group \"networking.example.net\"). ExtensionRef MUST NOT be used for core and extended filters. \n This filter can be used multiple times within the same rule. \n Support: Implementation-specific" - properties: - group: - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: Kind is kind of the referent. For example "HTTPRoute" or "Service". - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - - name - type: object - requestHeaderModifier: - description: "RequestHeaderModifier defines a schema for a filter that modifies request headers. \n Support: Core" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - requestMirror: - description: "RequestMirror defines a schema for a filter that mirrors requests. Requests are sent to the specified destination, but responses from that destination are ignored. \n This filter can be used multiple times within the same rule. Note that not all implementations will be able to support mirroring to multiple backends. \n Support: Extended" - properties: - backendRef: - description: "BackendRef references a resource where mirrored requests are sent. \n Mirrored requests must be sent only to a single destination endpoint within this BackendRef, irrespective of how many endpoints are present within this BackendRef. \n If the referent cannot be found, this BackendRef is invalid and must be dropped from the Gateway. The controller must ensure the \"ResolvedRefs\" condition on the Route status is set to `status: False` and not configure this backend in the underlying implementation. \n If there is a cross-namespace reference to an *existing* object that is not allowed by a ReferenceGrant, the controller must ensure the \"ResolvedRefs\" condition on the Route is set to `status: False`, with the \"RefNotPermitted\" reason and not configure this backend in the underlying implementation. \n In either error case, the Message of the `ResolvedRefs` Condition should be used to provide more detail about the problem. \n Support: Extended for Kubernetes Service \n Support: Implementation-specific for any other resource" - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - required: - - backendRef - type: object - requestRedirect: - description: "RequestRedirect defines a schema for a filter that responds to the request with an HTTP redirection. \n Support: Core" - properties: - hostname: - description: "Hostname is the hostname to be used in the value of the `Location` header in the response. When empty, the hostname in the `Host` header of the request is used. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines parameters used to modify the path of the incoming request. The modified path is then used to construct the `Location` header. When empty, the request path is used as-is. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - port: - description: "Port is the port to be used in the value of the `Location` header in the response. \n If no port is specified, the redirect port MUST be derived using the following rules: \n * If redirect scheme is not-empty, the redirect port MUST be the well-known port associated with the redirect scheme. Specifically \"http\" to port 80 and \"https\" to port 443. If the redirect scheme does not have a well-known port, the listener port of the Gateway SHOULD be used. * If redirect scheme is empty, the redirect port MUST be the Gateway Listener port. \n Implementations SHOULD NOT add the port number in the 'Location' header in the following cases: \n * A Location header that will use HTTP (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 80. * A Location header that will use HTTPS (whether that is determined via the Listener protocol or the Scheme field) _and_ use port 443. \n Support: Extended" - format: int32 - maximum: 65535 - minimum: 1 - type: integer - scheme: - description: "Scheme is the scheme to be used in the value of the `Location` header in the response. When empty, the scheme of the request is used. \n Scheme redirects can affect the port of the redirect, for more information, refer to the documentation for the port field of this filter. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Extended" - enum: - - http - - https - type: string - statusCode: - default: 302 - description: "StatusCode is the HTTP status code to be used in response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`. \n Support: Core" - enum: - - 301 - - 302 - type: integer - type: object - responseHeaderModifier: - description: "ResponseHeaderModifier defines a schema for a filter that modifies response headers. \n Support: Extended" - properties: - add: - description: "Add adds the given header(s) (name, value) to the request before the action. It appends to any existing values associated with the header name. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: add: - name: \"my-header\" value: \"bar,baz\" \n Output: GET /foo HTTP/1.1 my-header: foo,bar,baz" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - remove: - description: "Remove the given header(s) from the HTTP request before the action. The value of Remove is a list of HTTP header names. Note that the header names are case-insensitive (see https://datatracker.ietf.org/doc/html/rfc2616#section-4.2). \n Input: GET /foo HTTP/1.1 my-header1: foo my-header2: bar my-header3: baz \n Config: remove: [\"my-header1\", \"my-header3\"] \n Output: GET /foo HTTP/1.1 my-header2: bar" - items: - type: string - maxItems: 16 - type: array - x-kubernetes-list-type: set - set: - description: "Set overwrites the request with the given header (name, value) before the action. \n Input: GET /foo HTTP/1.1 my-header: foo \n Config: set: - name: \"my-header\" value: \"bar\" \n Output: GET /foo HTTP/1.1 my-header: bar" - items: - description: HTTPHeader represents an HTTP Header name and value as defined by RFC 7230. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - type: - description: "Type identifies the type of filter to apply. As with other API fields, types are classified into three conformance levels: \n - Core: Filter types and their corresponding configuration defined by \"Support: Core\" in this package, e.g. \"RequestHeaderModifier\". All implementations must support core filters. \n - Extended: Filter types and their corresponding configuration defined by \"Support: Extended\" in this package, e.g. \"RequestMirror\". Implementers are encouraged to support extended filters. \n - Implementation-specific: Filters that are defined and supported by specific vendors. In the future, filters showing convergence in behavior across multiple implementations will be considered for inclusion in extended or core conformance levels. Filter-specific configuration for such filters is specified using the ExtensionRef field. `Type` should be set to \"ExtensionRef\" for custom filters. \n Implementers are encouraged to define custom implementation types to extend the core API with implementation-specific behavior. \n If a reference to a custom filter type cannot be resolved, the filter MUST NOT be skipped. Instead, requests that would have been processed by that filter MUST receive a HTTP error response. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - RequestHeaderModifier - - ResponseHeaderModifier - - RequestMirror - - RequestRedirect - - URLRewrite - - ExtensionRef - type: string - urlRewrite: - description: "URLRewrite defines a schema for a filter that modifies a request during forwarding. \n Support: Extended" - properties: - hostname: - description: "Hostname is the value to be used to replace the Host header value during forwarding. \n Support: Extended" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - path: - description: "Path defines a path rewrite. \n Support: Extended" - properties: - replaceFullPath: - description: ReplaceFullPath specifies the value with which to replace the full path of a request during a rewrite or redirect. - maxLength: 1024 - type: string - replacePrefixMatch: - description: "ReplacePrefixMatch specifies the value with which to replace the prefix match of a request during a rewrite or redirect. For example, a request to \"/foo/bar\" with a prefix match of \"/foo\" and a ReplacePrefixMatch of \"/xyz\" would be modified to \"/xyz/bar\". \n Note that this matches the behavior of the PathPrefix match type. This matches full path elements. A path element refers to the list of labels in the path split by the `/` separator. When specified, a trailing `/` is ignored. For example, the paths `/abc`, `/abc/`, and `/abc/def` would all match the prefix `/abc`, but the path `/abcd` would not. \n ReplacePrefixMatch is only compatible with a `PathPrefix` HTTPRouteMatch. Using any other HTTPRouteMatch type on the same HTTPRouteRule will result in the implementation setting the Accepted Condition for the Route to `status: False`. \n Request Path | Prefix Match | Replace Prefix | Modified Path -------------|--------------|----------------|---------- /foo/bar | /foo | /xyz | /xyz/bar /foo/bar | /foo | /xyz/ | /xyz/bar /foo/bar | /foo/ | /xyz | /xyz/bar /foo/bar | /foo/ | /xyz/ | /xyz/bar /foo | /foo | /xyz | /xyz /foo/ | /foo | /xyz | /xyz/ /foo/bar | /foo | | /bar /foo/ | /foo | | / /foo | /foo | | / /foo/ | /foo | / | / /foo | /foo | / | /" - maxLength: 1024 - type: string - type: - description: "Type defines the type of path modifier. Additional types may be added in a future release of the API. \n Note that values may be added to this enum, implementations must ensure that unknown values will not cause a crash. \n Unknown values here must result in the implementation setting the Accepted Condition for the Route to `status: False`, with a Reason of `UnsupportedValue`." - enum: - - ReplaceFullPath - - ReplacePrefixMatch - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: replaceFullPath must be specified when type is set to 'ReplaceFullPath' - rule: 'self.type == ''ReplaceFullPath'' ? has(self.replaceFullPath) : true' - - message: type must be 'ReplaceFullPath' when replaceFullPath is set - rule: 'has(self.replaceFullPath) ? self.type == ''ReplaceFullPath'' : true' - - message: replacePrefixMatch must be specified when type is set to 'ReplacePrefixMatch' - rule: 'self.type == ''ReplacePrefixMatch'' ? has(self.replacePrefixMatch) : true' - - message: type must be 'ReplacePrefixMatch' when replacePrefixMatch is set - rule: 'has(self.replacePrefixMatch) ? self.type == ''ReplacePrefixMatch'' : true' - type: object - required: - - type - type: object - x-kubernetes-validations: - - message: filter.requestHeaderModifier must be nil if the filter.type is not RequestHeaderModifier - rule: '!(has(self.requestHeaderModifier) && self.type != ''RequestHeaderModifier'')' - - message: filter.requestHeaderModifier must be specified for RequestHeaderModifier filter.type - rule: '!(!has(self.requestHeaderModifier) && self.type == ''RequestHeaderModifier'')' - - message: filter.responseHeaderModifier must be nil if the filter.type is not ResponseHeaderModifier - rule: '!(has(self.responseHeaderModifier) && self.type != ''ResponseHeaderModifier'')' - - message: filter.responseHeaderModifier must be specified for ResponseHeaderModifier filter.type - rule: '!(!has(self.responseHeaderModifier) && self.type == ''ResponseHeaderModifier'')' - - message: filter.requestMirror must be nil if the filter.type is not RequestMirror - rule: '!(has(self.requestMirror) && self.type != ''RequestMirror'')' - - message: filter.requestMirror must be specified for RequestMirror filter.type - rule: '!(!has(self.requestMirror) && self.type == ''RequestMirror'')' - - message: filter.requestRedirect must be nil if the filter.type is not RequestRedirect - rule: '!(has(self.requestRedirect) && self.type != ''RequestRedirect'')' - - message: filter.requestRedirect must be specified for RequestRedirect filter.type - rule: '!(!has(self.requestRedirect) && self.type == ''RequestRedirect'')' - - message: filter.urlRewrite must be nil if the filter.type is not URLRewrite - rule: '!(has(self.urlRewrite) && self.type != ''URLRewrite'')' - - message: filter.urlRewrite must be specified for URLRewrite filter.type - rule: '!(!has(self.urlRewrite) && self.type == ''URLRewrite'')' - - message: filter.extensionRef must be nil if the filter.type is not ExtensionRef - rule: '!(has(self.extensionRef) && self.type != ''ExtensionRef'')' - - message: filter.extensionRef must be specified for ExtensionRef filter.type - rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')' - maxItems: 16 - type: array - x-kubernetes-validations: - - message: May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both - rule: '!(self.exists(f, f.type == ''RequestRedirect'') && self.exists(f, f.type == ''URLRewrite''))' - - message: RequestHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1 - - message: ResponseHeaderModifier filter cannot be repeated - rule: self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1 - - message: RequestRedirect filter cannot be repeated - rule: self.filter(f, f.type == 'RequestRedirect').size() <= 1 - - message: URLRewrite filter cannot be repeated - rule: self.filter(f, f.type == 'URLRewrite').size() <= 1 - matches: - default: - - path: - type: PathPrefix - value: / - description: "Matches define conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied. \n For example, take the following matches configuration: \n ``` matches: - path: value: \"/foo\" headers: - name: \"version\" value: \"v2\" - path: value: \"/v2/foo\" ``` \n For a request to match against this rule, a request must satisfy EITHER of the two conditions: \n - path prefixed with `/foo` AND contains the header `version: v2` - path prefix of `/v2/foo` \n See the documentation for HTTPRouteMatch on how to specify multiple match conditions that should be ANDed together. \n If no matches are specified, the default is a prefix path match on \"/\", which has the effect of matching every HTTP request. \n Proxy or Load Balancer routing configuration generated from HTTPRoutes MUST prioritize matches based on the following criteria, continuing on ties. Across all rules specified on applicable Routes, precedence must be given to the match having: \n * \"Exact\" path match. * \"Prefix\" path match with largest number of characters. * Method match. * Largest number of header matches. * Largest number of query param matches. \n Note: The precedence of RegularExpression path matches are implementation-specific. \n If ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties: \n * The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by \"{namespace}/{name}\". \n If ties still exist within an HTTPRoute, matching precedence MUST be granted to the FIRST matching rule (in list order) with a match meeting the above criteria. \n When no rules matching a request have been successfully attached to the parent a request is coming from, a HTTP 404 status code MUST be returned." - items: - description: "HTTPRouteMatch defines the predicate used to match requests to a given action. Multiple match types are ANDed together, i.e. the match will evaluate to true only if all conditions are satisfied. \n For example, the match below will match a HTTP request only if its path starts with `/foo` AND it contains the `version: v1` header: \n ``` match: \n path: value: \"/foo\" headers: - name: \"version\" value \"v1\" \n ```" - properties: - headers: - description: Headers specifies HTTP request header matchers. Multiple match values are ANDed together, meaning, a request must match all the specified headers to select the route. - items: - description: HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request headers. - properties: - name: - description: "Name is the name of the HTTP Header to be matched. Name matching MUST be case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2). \n If multiple entries specify equivalent header names, only the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent header name MUST be ignored. Due to the case-insensitivity of header names, \"foo\" and \"Foo\" are considered equivalent. \n When a header is repeated in an HTTP request, it is implementation-specific behavior as to how this is represented. Generally, proxies should follow the guidance from the RFC: https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding processing a repeated header, with special handling for \"Set-Cookie\"." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - type: - default: Exact - description: "Type specifies how to match against the value of the header. \n Support: Core (Exact) \n Support: Implementation-specific (RegularExpression) \n Since RegularExpression HeaderMatchType has implementation-specific conformance, implementations can support POSIX, PCRE or any other dialects of regular expressions. Please read the implementation's documentation to determine the supported dialect." - enum: - - Exact - - RegularExpression - type: string - value: - description: Value is the value of HTTP Header to be matched. - maxLength: 4096 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - method: - description: "Method specifies HTTP method matcher. When specified, this route will be matched only if the request has the specified method. \n Support: Extended" - enum: - - GET - - HEAD - - POST - - PUT - - DELETE - - CONNECT - - OPTIONS - - TRACE - - PATCH - type: string - path: - default: - type: PathPrefix - value: / - description: Path specifies a HTTP request path matcher. If this field is not specified, a default prefix match on the "/" path is provided. - properties: - type: - default: PathPrefix - description: "Type specifies how to match against the path Value. \n Support: Core (Exact, PathPrefix) \n Support: Implementation-specific (RegularExpression)" - enum: - - Exact - - PathPrefix - - RegularExpression - type: string - value: - default: / - description: Value of the HTTP path to match against. - maxLength: 1024 - type: string - type: object - x-kubernetes-validations: - - message: value must be an absolute path and start with '/' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.startsWith(''/'') : true' - - message: must not contain '//' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''//'') : true' - - message: must not contain '/./' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/./'') : true' - - message: must not contain '/../' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''/../'') : true' - - message: must not contain '%2f' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2f'') : true' - - message: must not contain '%2F' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''%2F'') : true' - - message: must not contain '#' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.contains(''#'') : true' - - message: must not end with '/..' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/..'') : true' - - message: must not end with '/.' when type one of ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? !self.value.endsWith(''/.'') : true' - - message: type must be one of ['Exact', 'PathPrefix', 'RegularExpression'] - rule: self.type in ['Exact','PathPrefix'] || self.type == 'RegularExpression' - - message: must only contain valid characters (matching ^(?:[-A-Za-z0-9/._~!$&'()*+,;=:@]|[%][0-9a-fA-F]{2})+$) for types ['Exact', 'PathPrefix'] - rule: '(self.type in [''Exact'',''PathPrefix'']) ? self.value.matches(r"""^(?:[-A-Za-z0-9/._~!$&''()*+,;=:@]|[%][0-9a-fA-F]{2})+$""") : true' - queryParams: - description: "QueryParams specifies HTTP query parameter matchers. Multiple match values are ANDed together, meaning, a request must match all the specified query parameters to select the route. \n Support: Extended" - items: - description: HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP query parameters. - properties: - name: - description: "Name is the name of the HTTP query param to be matched. This must be an exact string match. (See https://tools.ietf.org/html/rfc7230#section-2.7.3). \n If multiple entries specify equivalent query param names, only the first entry with an equivalent name MUST be considered for a match. Subsequent entries with an equivalent query param name MUST be ignored. \n If a query param is repeated in an HTTP request, the behavior is purposely left undefined, since different data planes have different capabilities. However, it is *recommended* that implementations should match against the first value of the param if the data plane supports it, as this behavior is expected in other load balancing contexts outside of the Gateway API. \n Users SHOULD NOT route traffic based on repeated query params to guard themselves against potential differences in the implementations." - maxLength: 256 - minLength: 1 - pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ - type: string - type: - default: Exact - description: "Type specifies how to match against the value of the query parameter. \n Support: Extended (Exact) \n Support: Implementation-specific (RegularExpression) \n Since RegularExpression QueryParamMatchType has Implementation-specific conformance, implementations can support POSIX, PCRE or any other dialects of regular expressions. Please read the implementation's documentation to determine the supported dialect." - enum: - - Exact - - RegularExpression - type: string - value: - description: Value is the value of HTTP query param to be matched. - maxLength: 1024 - minLength: 1 - type: string - required: - - name - - value - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - type: object - maxItems: 8 - type: array - timeouts: - description: "Timeouts defines the timeouts that can be configured for an HTTP request. \n Support: Extended \n " - properties: - backendRequest: - description: "BackendRequest specifies a timeout for an individual request from the gateway to a backend. This covers the time from when the request first starts being sent from the gateway to when the full response has been received from the backend. \n An entire client HTTP transaction with a gateway, covered by the Request timeout, may result in more than one call from the gateway to the destination backend, for example, if automatic retries are supported. \n Because the Request timeout encompasses the BackendRequest timeout, the value of BackendRequest must be <= the value of Request timeout. \n Support: Extended" - pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ - type: string - request: - description: "Request specifies the maximum duration for a gateway to respond to an HTTP request. If the gateway has not been able to respond before this deadline is met, the gateway MUST return a timeout error. \n For example, setting the `rules.timeouts.request` field to the value `10s` in an `HTTPRoute` will cause a timeout if a client request is taking longer than 10 seconds to complete. \n This timeout is intended to cover as close to the whole request-response transaction as possible although an implementation MAY choose to start the timeout after the entire request stream has been received instead of immediately after the transaction is initiated by the client. \n When this field is unspecified, request timeout behavior is implementation-specific. \n Support: Extended" - pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ - type: string - type: object - x-kubernetes-validations: - - message: backendRequest timeout cannot be longer than request timeout - rule: '!(has(self.request) && has(self.backendRequest) && duration(self.request) != duration(''0s'') && duration(self.backendRequest) > duration(self.request))' - type: object - x-kubernetes-validations: - - message: RequestRedirect filter must not be used together with backendRefs - rule: '(has(self.backendRefs) && size(self.backendRefs) > 0) ? (!has(self.filters) || self.filters.all(f, !has(f.requestRedirect))): true' - - message: When using RequestRedirect filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.requestRedirect) && has(f.requestRedirect.path) && f.requestRedirect.path.type == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - - message: When using URLRewrite filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.filters) && self.filters.exists_one(f, has(f.urlRewrite) && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' && has(f.urlRewrite.path.replacePrefixMatch))) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - - message: Within backendRefs, when using RequestRedirect filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, (has(b.filters) && b.filters.exists_one(f, has(f.requestRedirect) && has(f.requestRedirect.path) && f.requestRedirect.path.type == ''ReplacePrefixMatch'' && has(f.requestRedirect.path.replacePrefixMatch))) )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - - message: Within backendRefs, When using URLRewrite filter with path.replacePrefixMatch, exactly one PathPrefix match must be specified - rule: '(has(self.backendRefs) && self.backendRefs.exists_one(b, (has(b.filters) && b.filters.exists_one(f, has(f.urlRewrite) && has(f.urlRewrite.path) && f.urlRewrite.path.type == ''ReplacePrefixMatch'' && has(f.urlRewrite.path.replacePrefixMatch))) )) ? ((size(self.matches) != 1 || !has(self.matches[0].path) || self.matches[0].path.type != ''PathPrefix'') ? false : true) : true' - maxItems: 16 - type: array - type: object - status: - description: Status defines the current state of HTTPRoute. - properties: - parents: - description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway." - items: - description: RouteParentStatus describes the status of a route with respect to an associated Parent. - properties: - conditions: - description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - parentRef: - description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_referencegrants.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_referencegrants.yaml deleted file mode 100644 index fb9a6dc..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_referencegrants.yaml +++ /dev/null @@ -1,205 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: referencegrants.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: ReferenceGrant - listKind: ReferenceGrantList - plural: referencegrants - shortNames: - - refgrant - singular: referencegrant - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - deprecated: true - deprecationWarning: The v1alpha2 version of ReferenceGrant has been deprecated and will be removed in a future release of the API. Please upgrade to v1beta1. - name: v1alpha2 - schema: - openAPIV3Schema: - description: "ReferenceGrant identifies kinds of resources in other namespaces that are trusted to reference the specified kinds of resources in the same namespace as the policy. \n Each ReferenceGrant can be used to represent a unique trust relationship. Additional Reference Grants can be used to add to the set of trusted sources of inbound references for the namespace they are defined within. \n A ReferenceGrant is required for all cross-namespace references in Gateway API (with the exception of cross-namespace Route-Gateway attachment, which is governed by the AllowedRoutes configuration on the Gateway, and cross-namespace Service ParentRefs on a \"consumer\" mesh Route, which defines routing rules applicable only to workloads in the Route namespace). ReferenceGrants allowing a reference from a Route to a Service are only applicable to BackendRefs. \n ReferenceGrant is a form of runtime verification allowing users to assert which cross-namespace object references are permitted. Implementations that support ReferenceGrant MUST NOT permit cross-namespace references which have no grant, and MUST respond to the removal of a grant by revoking the access that the grant allowed." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of ReferenceGrant. - properties: - from: - description: "From describes the trusted namespaces and kinds that can reference the resources described in \"To\". Each entry in this list MUST be considered to be an additional place that references can be valid from, or to put this another way, entries MUST be combined using OR. \n Support: Core" - items: - description: ReferenceGrantFrom describes trusted namespaces and kinds. - properties: - group: - description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field. \n When used to permit a SecretObjectReference: \n * Gateway \n When used to permit a BackendObjectReference: \n * GRPCRoute * HTTPRoute * TCPRoute * TLSRoute * UDPRoute" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - namespace: - description: "Namespace is the namespace of the referent. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - namespace - type: object - maxItems: 16 - minItems: 1 - type: array - to: - description: "To describes the resources that may be referenced by the resources described in \"From\". Each entry in this list MUST be considered to be an additional place that references can be valid to, or to put this another way, entries MUST be combined using OR. \n Support: Core" - items: - description: ReferenceGrantTo describes what Kinds are allowed as targets of the references. - properties: - group: - description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field: \n * Secret when used to permit a SecretObjectReference * Service when used to permit a BackendObjectReference" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. When unspecified, this policy refers to all resources of the specified Group and Kind in the local namespace. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - from - - to - type: object - type: object - served: true - storage: false - subresources: {} - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: "ReferenceGrant identifies kinds of resources in other namespaces that are trusted to reference the specified kinds of resources in the same namespace as the policy. \n Each ReferenceGrant can be used to represent a unique trust relationship. Additional Reference Grants can be used to add to the set of trusted sources of inbound references for the namespace they are defined within. \n All cross-namespace references in Gateway API (with the exception of cross-namespace Gateway-route attachment) require a ReferenceGrant. \n ReferenceGrant is a form of runtime verification allowing users to assert which cross-namespace object references are permitted. Implementations that support ReferenceGrant MUST NOT permit cross-namespace references which have no grant, and MUST respond to the removal of a grant by revoking the access that the grant allowed." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of ReferenceGrant. - properties: - from: - description: "From describes the trusted namespaces and kinds that can reference the resources described in \"To\". Each entry in this list MUST be considered to be an additional place that references can be valid from, or to put this another way, entries MUST be combined using OR. \n Support: Core" - items: - description: ReferenceGrantFrom describes trusted namespaces and kinds. - properties: - group: - description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field. \n When used to permit a SecretObjectReference: \n * Gateway \n When used to permit a BackendObjectReference: \n * GRPCRoute * HTTPRoute * TCPRoute * TLSRoute * UDPRoute" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - namespace: - description: "Namespace is the namespace of the referent. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - required: - - group - - kind - - namespace - type: object - maxItems: 16 - minItems: 1 - type: array - to: - description: "To describes the resources that may be referenced by the resources described in \"From\". Each entry in this list MUST be considered to be an additional place that references can be valid to, or to put this another way, entries MUST be combined using OR. \n Support: Core" - items: - description: ReferenceGrantTo describes what Kinds are allowed as targets of the references. - properties: - group: - description: "Group is the group of the referent. When empty, the Kubernetes core API group is inferred. \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - description: "Kind is the kind of the referent. Although implementations may support additional resources, the following types are part of the \"Core\" support level for this field: \n * Secret when used to permit a SecretObjectReference * Service when used to permit a BackendObjectReference" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. When unspecified, this policy refers to all resources of the specified Group and Kind in the local namespace. - maxLength: 253 - minLength: 1 - type: string - required: - - group - - kind - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - from - - to - type: object - type: object - served: true - storage: true - subresources: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_tcproutes.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_tcproutes.yaml deleted file mode 100644 index b228497..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_tcproutes.yaml +++ /dev/null @@ -1,284 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: tcproutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: TCPRoute - listKind: TCPRouteList - plural: tcproutes - singular: tcproute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha2 - schema: - openAPIV3Schema: - description: TCPRoute provides a way to route TCP requests. When combined with a Gateway listener, it can be used to forward connections on the port specified by the listener to a set of backends specified by the TCPRoute. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of TCPRoute. - properties: - parentRefs: - description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n " - items: - description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - maxItems: 32 - type: array - x-kubernetes-validations: - - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent - rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))' - - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent - rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) - rules: - description: Rules are a list of TCP matchers and actions. - items: - description: TCPRouteRule is the configuration for a given rule. - properties: - backendRefs: - description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Connection rejections must respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Extended" - items: - description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n \n Note that when the BackendTLSPolicy object is enabled by the implementation, there are some extra rules about validity to consider here. See the fields where this struct is used for more information about the exact behavior." - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - weight: - default: 1 - description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used." - format: int32 - maximum: 1000000 - minimum: 0 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 16 - minItems: 1 - type: array - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - rules - type: object - status: - description: Status defines the current state of TCPRoute. - properties: - parents: - description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway." - items: - description: RouteParentStatus describes the status of a route with respect to an associated Parent. - properties: - conditions: - description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - parentRef: - description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_tlsroutes.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_tlsroutes.yaml deleted file mode 100644 index fa097ea..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_tlsroutes.yaml +++ /dev/null @@ -1,294 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: tlsroutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: TLSRoute - listKind: TLSRouteList - plural: tlsroutes - singular: tlsroute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha2 - schema: - openAPIV3Schema: - description: "The TLSRoute resource is similar to TCPRoute, but can be configured to match against TLS-specific metadata. This allows more flexibility in matching streams for a given TLS listener. \n If you need to forward traffic to a single target for a TLS listener, you could choose to use a TCPRoute with a TLS listener." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of TLSRoute. - properties: - hostnames: - description: "Hostnames defines a set of SNI names that should match against the SNI attribute of TLS ClientHello message in TLS handshake. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed in SNI names per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n If a hostname is specified by both the Listener and TLSRoute, there must be at least one intersecting hostname for the TLSRoute to be attached to the Listener. For example: \n * A Listener with `test.example.com` as the hostname matches TLSRoutes that have either not specified any hostnames, or have specified at least one of `test.example.com` or `*.example.com`. * A Listener with `*.example.com` as the hostname matches TLSRoutes that have either not specified any hostnames or have specified at least one hostname that matches the Listener hostname. For example, `test.example.com` and `*.example.com` would both match. On the other hand, `example.com` and `test.example.net` would not match. \n If both the Listener and TLSRoute have specified hostnames, any TLSRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the TLSRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match. \n If both the Listener and TLSRoute have specified hostnames, and none match with the criteria above, then the TLSRoute is not accepted. The implementation must raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus. \n Support: Core" - items: - description: "Hostname is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 2 notable exceptions: \n 1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard label must appear by itself as the first label. \n Hostname can be \"precise\" which is a domain name without the terminating dot of a network host (e.g. \"foo.example.com\") or \"wildcard\", which is a domain name prefixed with a single wildcard label (e.g. `*.example.com`). \n Note that as per RFC1035 and RFC1123, a *label* must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character. No other punctuation is allowed." - maxLength: 253 - minLength: 1 - pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - maxItems: 16 - type: array - parentRefs: - description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n " - items: - description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - maxItems: 32 - type: array - x-kubernetes-validations: - - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent - rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))' - - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent - rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) - rules: - description: Rules are a list of TLS matchers and actions. - items: - description: TLSRouteRule is the configuration for a given rule. - properties: - backendRefs: - description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the rule performs no forwarding; if no filters are specified that would result in a response being sent, the underlying implementation must actively reject request attempts to this backend, by rejecting the connection or returning a 500 status code. Request rejections must respect weight; if an invalid backend is requested to have 80% of requests, then 80% of requests must be rejected instead. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Extended" - items: - description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n \n Note that when the BackendTLSPolicy object is enabled by the implementation, there are some extra rules about validity to consider here. See the fields where this struct is used for more information about the exact behavior." - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - weight: - default: 1 - description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used." - format: int32 - maximum: 1000000 - minimum: 0 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 16 - minItems: 1 - type: array - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - rules - type: object - status: - description: Status defines the current state of TLSRoute. - properties: - parents: - description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway." - items: - description: RouteParentStatus describes the status of a route with respect to an associated Parent. - properties: - conditions: - description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - parentRef: - description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/gateway.networking.k8s.io_udproutes.yaml b/charts/traefik/traefik/crds/gateway.networking.k8s.io_udproutes.yaml deleted file mode 100644 index bb48563..0000000 --- a/charts/traefik/traefik/crds/gateway.networking.k8s.io_udproutes.yaml +++ /dev/null @@ -1,284 +0,0 @@ -# -# config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml -# -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/2466 - gateway.networking.k8s.io/bundle-version: v1.0.0 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null - name: udproutes.gateway.networking.k8s.io -spec: - group: gateway.networking.k8s.io - names: - categories: - - gateway-api - kind: UDPRoute - listKind: UDPRouteList - plural: udproutes - singular: udproute - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha2 - schema: - openAPIV3Schema: - description: UDPRoute provides a way to route UDP traffic. When combined with a Gateway listener, it can be used to forward traffic on the port specified by the listener to a set of backends specified by the UDPRoute. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of UDPRoute. - properties: - parentRefs: - description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) This API may be extended in the future to support additional kinds of parent resources. \n ParentRefs must be _distinct_. This means either that: \n * They select different objects. If this is the case, then parentRef entries are distinct. In terms of fields, this means that the multi-part key defined by `group`, `kind`, `namespace`, and `name` must be unique across all parentRef entries in the Route. * They do not select different objects, but for each optional field used, each ParentRef that selects the same object must set the same set of optional fields to different values. If one ParentRef sets a combination of optional fields, all must set the same combination. \n Some examples: \n * If one ParentRef sets `sectionName`, all ParentRefs referencing the same object must also set `sectionName`. * If one ParentRef sets `port`, all ParentRefs referencing the same object must also set `port`. * If one ParentRef sets `sectionName` and `port`, all ParentRefs referencing the same object must also set `sectionName` and `port`. \n It is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged. \n Note that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n " - items: - description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n This API may be extended in the future to support additional kinds of parent resources. \n The API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid." - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - maxItems: 32 - type: array - x-kubernetes-validations: - - message: sectionName or port must be specified when parentRefs includes 2 or more references to the same parent - rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '''') && (!has(p2.__namespace__) || p2.__namespace__ == '''')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '''') == (!has(p2.sectionName) || p2.sectionName == '''') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))' - - message: sectionName or port must be unique when parentRefs includes 2 or more references to the same parent - rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port)))) - rules: - description: Rules are a list of UDP matchers and actions. - items: - description: UDPRouteRule is the configuration for a given rule. - properties: - backendRefs: - description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a non-existent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Packet drops must respect weight; if an invalid backend is requested to have 80% of the packets, then 80% of packets must be dropped instead. \n Support: Core for Kubernetes Service \n Support: Extended for Kubernetes ServiceImport \n Support: Implementation-specific for any other resource \n Support for weight: Extended" - items: - description: "BackendRef defines how a Route should forward a request to a Kubernetes resource. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n \n When the BackendRef points to a Kubernetes Service, implementations SHOULD honor the appProtocol field if it is set for the target Service Port. \n Implementations supporting appProtocol SHOULD recognize the Kubernetes Standard Application Protocols defined in KEP-3726. \n If a Service appProtocol isn't specified, an implementation MAY infer the backend protocol through its own means. Implementations MAY infer the protocol from the Route type referring to the backend Service. \n If a Route is not able to send traffic to the backend using the specified protocol then the backend is considered invalid. Implementations MUST set the \"ResolvedRefs\" condition to \"False\" with the \"UnsupportedProtocol\" reason. \n \n Note that when the BackendTLSPolicy object is enabled by the implementation, there are some extra rules about validity to consider here. See the fields where this struct is used for more information about the exact behavior." - properties: - group: - default: "" - description: Group is the group of the referent. For example, "gateway.networking.k8s.io". When unspecified or empty string, core API group is inferred. - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Service - description: "Kind is the Kubernetes resource kind of the referent. For example \"Service\". \n Defaults to \"Service\" when not specified. \n ExternalName services can refer to CNAME DNS records that may live outside of the cluster and as such are difficult to reason about in terms of conformance. They also may not be safe to forward to (see CVE-2021-25740 for more information). Implementations SHOULD NOT support ExternalName Services. \n Support: Core (Services with a type other than ExternalName) \n Support: Implementation-specific (Services with type ExternalName)" - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: Name is the name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the backend. When unspecified, the local namespace is inferred. \n Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. - format: int32 - maximum: 65535 - minimum: 1 - type: integer - weight: - default: 1 - description: "Weight specifies the proportion of requests forwarded to the referenced backend. This is computed as weight/(sum of all weights in this BackendRefs list). For non-zero values, there may be some epsilon from the exact proportion defined here depending on the precision an implementation supports. Weight is not a percentage and the sum of weights does not need to equal 100. \n If only one backend is specified and it has a weight greater than 0, 100% of the traffic is forwarded to that backend. If weight is set to 0, no traffic should be forwarded for this entry. If unspecified, weight defaults to 1. \n Support for this field varies based on the context where used." - format: int32 - maximum: 1000000 - minimum: 0 - type: integer - required: - - name - type: object - x-kubernetes-validations: - - message: Must have port for Service reference - rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 16 - minItems: 1 - type: array - type: object - maxItems: 16 - minItems: 1 - type: array - required: - - rules - type: object - status: - description: Status defines the current state of UDPRoute. - properties: - parents: - description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified. \n Note that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for. \n A maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway." - items: - description: RouteParentStatus describes the status of a route with respect to an associated Parent. - properties: - conditions: - description: "Conditions describes the status of the route with respect to the Gateway. Note that the route's availability is also subject to the Gateway's own status conditions and listener status. \n If the Route's ParentRef specifies an existing Gateway that supports Routes of this kind AND that Gateway's controller has sufficient access, then that Gateway's controller MUST set the \"Accepted\" condition on the Route, to indicate whether the route has been accepted or rejected by the Gateway, and why. \n A Route MUST be considered \"Accepted\" if at least one of the Route's rules is implemented by the Gateway. \n There are a number of cases where the \"Accepted\" condition may not be set due to lack of controller visibility, that includes when: \n * The Route refers to a non-existent parent. * The Route is of a type that the controller does not support. * The Route is in a namespace the controller does not have access to." - items: - description: "Condition contains details for one aspect of the current state of this API Resource. --- This struct is intended for direct use as an array at the field path .status.conditions. For example, \n type FooStatus struct{ // Represents the observations of a foo's current state. // Known .status.conditions.type are: \"Available\", \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" - properties: - lastTransitionTime: - description: lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: message is a human readable message indicating details about the transition. This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. --- Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be useful (see .node.status.conditions), the ability to deconflict is important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - maxItems: 8 - minItems: 1 - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map - controllerName: - description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass. \n Example: \"example.net/gateway-controller\". \n The format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). \n Controllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary." - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$ - type: string - parentRef: - description: ParentRef corresponds with a ParentRef in the spec that this RouteParentStatus struct describes the status of. - properties: - group: - default: gateway.networking.k8s.io - description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string). \n Support: Core" - maxLength: 253 - pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - kind: - default: Gateway - description: "Kind is kind of the referent. \n There are two kinds of parent resources with \"Core\" support: \n * Gateway (Gateway conformance profile) * Service (Mesh conformance profile, experimental, ClusterIP Services only) \n Support for other resources is Implementation-Specific." - maxLength: 63 - minLength: 1 - pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ - type: string - name: - description: "Name is the name of the referent. \n Support: Core" - maxLength: 253 - minLength: 1 - type: string - namespace: - description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route. \n Note that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference. \n ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service. \n ParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. \n Support: Core" - maxLength: 63 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ - type: string - port: - description: "Port is the network port this Route targets. It can be interpreted differently based on the type of parent resource. \n When the parent resource is a Gateway, this targets all listeners listening on the specified port that also support this kind of Route(and select this Route). It's not recommended to set `Port` unless the networking behaviors specified in a Route must apply to a specific port as opposed to a listener(s) whose port(s) may be changed. When both Port and SectionName are specified, the name and port of the selected listener must match both specified values. \n When the parent resource is a Service, this targets a specific port in the Service spec. When both Port (experimental) and SectionName are specified, the name and port of the selected port must match both specified values. \n Implementations MAY choose to support other parent resources. Implementations supporting other types of parent resources MUST clearly document how/if Port is interpreted. \n For the purpose of status, an attachment is considered successful as long as the parent resource accepts it partially. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Extended \n " - format: int32 - maximum: 65535 - minimum: 1 - type: integer - sectionName: - description: "SectionName is the name of a section within the target resource. In the following resources, SectionName is interpreted as the following: \n * Gateway: Listener Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. * Service: Port Name. When both Port (experimental) and SectionName are specified, the name and port of the selected listener must match both specified values. Note that attaching Routes to Services as Parents is part of experimental Mesh support and is not supported for any other purpose. \n Implementations MAY choose to support attaching Routes to other resources. If that is the case, they MUST clearly document how SectionName is interpreted. \n When unspecified (empty string), this will reference the entire resource. For the purpose of status, an attachment is considered successful if at least one section in the parent resource accepts it. For example, Gateway listeners can restrict which Routes can attach to them by Route kind, namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from the referencing Route, the Route MUST be considered successfully attached. If no Gateway listeners accept attachment from this Route, the Route MUST be considered detached from the Gateway. \n Support: Core" - maxLength: 253 - minLength: 1 - pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ - type: string - required: - - name - type: object - required: - - controllerName - - parentRef - type: object - maxItems: 32 - type: array - required: - - parents - type: object - required: - - spec - type: object - served: true - storage: true - subresources: - status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/charts/traefik/traefik/crds/hub.traefik.io_apiaccesses.yaml b/charts/traefik/traefik/crds/hub.traefik.io_apiaccesses.yaml index d1b9998..ee8ecaf 100644 --- a/charts/traefik/traefik/crds/hub.traefik.io_apiaccesses.yaml +++ b/charts/traefik/traefik/crds/hub.traefik.io_apiaccesses.yaml @@ -39,6 +39,35 @@ spec: spec: description: The desired behavior of this APIAccess. properties: + apiBundles: + description: |- + APIBundles defines a set of APIBundle that will be accessible to the configured audience. + Multiple APIAccesses can select the same APIBundles. + items: + description: APIBundleReference references an APIBundle. + properties: + name: + description: Name of the APIBundle. + maxLength: 253 + type: string + required: + - name + type: object + maxItems: 100 + type: array + x-kubernetes-validations: + - message: duplicated apiBundles + rule: self.all(x, self.exists_one(y, x.name == y.name)) + apiPlan: + description: APIPlan defines which APIPlan will be used. + properties: + name: + description: Name of the APIPlan. + maxLength: 253 + type: string + required: + - name + type: object apiSelector: description: |- APISelector selects the APIs that will be accessible to the configured audience. @@ -131,6 +160,12 @@ spec: maxItems: 100 type: array type: object + weight: + description: Weight specifies the evaluation order of the plan. + type: integer + x-kubernetes-validations: + - message: must be a positive number + rule: self >= 0 type: object x-kubernetes-validations: - message: groups and everyone are mutually exclusive diff --git a/charts/traefik/traefik/crds/hub.traefik.io_apibundles.yaml b/charts/traefik/traefik/crds/hub.traefik.io_apibundles.yaml new file mode 100644 index 0000000..a45a0b1 --- /dev/null +++ b/charts/traefik/traefik/crds/hub.traefik.io_apibundles.yaml @@ -0,0 +1,125 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: apibundles.hub.traefik.io +spec: + group: hub.traefik.io + names: + kind: APIBundle + listKind: APIBundleList + plural: apibundles + singular: apibundle + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: APIBundle defines a set of APIs. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: The desired behavior of this APIBundle. + properties: + apiSelector: + description: |- + APISelector selects the APIs that will be accessible to the configured audience. + Multiple APIBundles can select the same set of APIs. + This field is optional and follows standard label selector semantics. + An empty APISelector matches any API. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + apis: + description: |- + APIs defines a set of APIs that will be accessible to the configured audience. + Multiple APIBundles can select the same APIs. + When combined with APISelector, this set of APIs is appended to the matching APIs. + items: + description: APIReference references an API. + properties: + name: + description: Name of the API. + maxLength: 253 + type: string + required: + - name + type: object + maxItems: 100 + type: array + x-kubernetes-validations: + - message: duplicated apis + rule: self.all(x, self.exists_one(y, x.name == y.name)) + type: object + status: + description: The current status of this APIBundle. + properties: + hash: + description: Hash is a hash representing the APIBundle. + type: string + syncedAt: + format: date-time + type: string + version: + type: string + type: object + type: object + served: true + storage: true diff --git a/charts/traefik/traefik/crds/hub.traefik.io_apiplans.yaml b/charts/traefik/traefik/crds/hub.traefik.io_apiplans.yaml new file mode 100644 index 0000000..92e1b9b --- /dev/null +++ b/charts/traefik/traefik/crds/hub.traefik.io_apiplans.yaml @@ -0,0 +1,103 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: apiplans.hub.traefik.io +spec: + group: hub.traefik.io + names: + kind: APIPlan + listKind: APIPlanList + plural: apiplans + singular: apiplan + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: APIPlan defines API Plan policy. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: The desired behavior of this APIPlan. + properties: + description: + description: Description describes the plan. + type: string + quota: + description: Quota defines the quota policy. + properties: + limit: + description: Limit is the maximum number of token in the bucket. + type: integer + x-kubernetes-validations: + - message: must be a positive number + rule: self >= 0 + period: + description: Period is the unit of time for the Limit. + format: duration + type: string + x-kubernetes-validations: + - message: must be between 1s and 9999h + rule: self >= duration('1s') && self <= duration('9999h') + required: + - limit + type: object + rateLimit: + description: RateLimit defines the rate limit policy. + properties: + limit: + description: Limit is the maximum number of token in the bucket. + type: integer + x-kubernetes-validations: + - message: must be a positive number + rule: self >= 0 + period: + description: Period is the unit of time for the Limit. + format: duration + type: string + x-kubernetes-validations: + - message: must be between 1s and 1h + rule: self >= duration('1s') && self <= duration('1h') + required: + - limit + type: object + title: + description: Title is the human-readable name of the plan. + type: string + required: + - title + type: object + status: + description: The current status of this APIPlan. + properties: + hash: + description: Hash is a hash representing the APIPlan. + type: string + syncedAt: + format: date-time + type: string + version: + type: string + type: object + type: object + served: true + storage: true diff --git a/charts/traefik/traefik/crds/traefik.io_ingressroutes.yaml b/charts/traefik/traefik/crds/traefik.io_ingressroutes.yaml index 7b23dba..ccb374a 100644 --- a/charts/traefik/traefik/crds/traefik.io_ingressroutes.yaml +++ b/charts/traefik/traefik/crds/traefik.io_ingressroutes.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: ingressroutes.traefik.io spec: group: traefik.io @@ -43,7 +43,7 @@ spec: description: |- EntryPoints defines the list of entry point names to bind to. Entry points have to be configured in the static configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/entrypoints/ + More info: https://doc.traefik.io/traefik/v3.2/routing/entrypoints/ Default: all. items: type: string @@ -63,12 +63,12 @@ spec: match: description: |- Match defines the router's rule. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#rule + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#rule type: string middlewares: description: |- Middlewares defines the list of references to Middleware resources. - More info: https://doc.traefik.io/traefik/v3.0/routing/providers/kubernetes-crd/#kind-middleware + More info: https://doc.traefik.io/traefik/v3.2/routing/providers/kubernetes-crd/#kind-middleware items: description: MiddlewareRef is a reference to a Middleware resource. @@ -88,7 +88,7 @@ spec: priority: description: |- Priority defines the router's priority. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#priority + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#priority type: integer services: description: |- @@ -229,7 +229,7 @@ spec: sticky: description: |- Sticky defines the sticky sessions configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#sticky-sessions + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#sticky-sessions properties: cookie: description: Cookie defines the sticky cookie configuration. @@ -277,7 +277,7 @@ spec: syntax: description: |- Syntax defines the router's rule syntax. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#rulesyntax + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#rulesyntax type: string required: - kind @@ -287,18 +287,18 @@ spec: tls: description: |- TLS defines the TLS configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#tls + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#tls properties: certResolver: description: |- CertResolver defines the name of the certificate resolver to use. Cert resolvers have to be configured in the static configuration. - More info: https://doc.traefik.io/traefik/v3.0/https/acme/#certificate-resolvers + More info: https://doc.traefik.io/traefik/v3.2/https/acme/#certificate-resolvers type: string domains: description: |- Domains defines the list of domains that will be used to issue certificates. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#domains + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#domains items: description: Domain holds a domain name with SANs. properties: @@ -317,17 +317,17 @@ spec: description: |- Options defines the reference to a TLSOption, that specifies the parameters of the TLS connection. If not defined, the `default` TLSOption is used. - More info: https://doc.traefik.io/traefik/v3.0/https/tls/#tls-options + More info: https://doc.traefik.io/traefik/v3.2/https/tls/#tls-options properties: name: description: |- Name defines the name of the referenced TLSOption. - More info: https://doc.traefik.io/traefik/v3.0/routing/providers/kubernetes-crd/#kind-tlsoption + More info: https://doc.traefik.io/traefik/v3.2/routing/providers/kubernetes-crd/#kind-tlsoption type: string namespace: description: |- Namespace defines the namespace of the referenced TLSOption. - More info: https://doc.traefik.io/traefik/v3.0/routing/providers/kubernetes-crd/#kind-tlsoption + More info: https://doc.traefik.io/traefik/v3.2/routing/providers/kubernetes-crd/#kind-tlsoption type: string required: - name @@ -344,12 +344,12 @@ spec: name: description: |- Name defines the name of the referenced TLSStore. - More info: https://doc.traefik.io/traefik/v3.0/routing/providers/kubernetes-crd/#kind-tlsstore + More info: https://doc.traefik.io/traefik/v3.2/routing/providers/kubernetes-crd/#kind-tlsstore type: string namespace: description: |- Namespace defines the namespace of the referenced TLSStore. - More info: https://doc.traefik.io/traefik/v3.0/routing/providers/kubernetes-crd/#kind-tlsstore + More info: https://doc.traefik.io/traefik/v3.2/routing/providers/kubernetes-crd/#kind-tlsstore type: string required: - name diff --git a/charts/traefik/traefik/crds/traefik.io_ingressroutetcps.yaml b/charts/traefik/traefik/crds/traefik.io_ingressroutetcps.yaml index f3eea5e..ae675f6 100644 --- a/charts/traefik/traefik/crds/traefik.io_ingressroutetcps.yaml +++ b/charts/traefik/traefik/crds/traefik.io_ingressroutetcps.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: ingressroutetcps.traefik.io spec: group: traefik.io @@ -43,7 +43,7 @@ spec: description: |- EntryPoints defines the list of entry point names to bind to. Entry points have to be configured in the static configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/entrypoints/ + More info: https://doc.traefik.io/traefik/v3.2/routing/entrypoints/ Default: all. items: type: string @@ -56,7 +56,7 @@ spec: match: description: |- Match defines the router's rule. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#rule_1 + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#rule_1 type: string middlewares: description: Middlewares defines the list of references to MiddlewareTCP @@ -80,7 +80,7 @@ spec: priority: description: |- Priority defines the router's priority. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#priority_1 + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#priority_1 type: integer services: description: Services defines the list of TCP services. @@ -121,7 +121,7 @@ spec: proxyProtocol: description: |- ProxyProtocol defines the PROXY protocol configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#proxy-protocol + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#proxy-protocol properties: version: description: Version defines the PROXY Protocol version @@ -141,7 +141,7 @@ spec: hence fully terminating the connection. It is a duration in milliseconds, defaulting to 100. A negative value means an infinite deadline (i.e. the reading capability is never closed). - Deprecated: TerminationDelay is not supported APIVersion traefik.io/v1, please use ServersTransport to configure the TerminationDelay instead. + Deprecated: TerminationDelay will not be supported in future APIVersions, please use ServersTransport to configure the TerminationDelay instead. type: integer tls: description: TLS determines whether to use TLS when dialing @@ -159,7 +159,7 @@ spec: syntax: description: |- Syntax defines the router's rule syntax. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#rulesyntax_1 + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#rulesyntax_1 type: string required: - match @@ -168,18 +168,18 @@ spec: tls: description: |- TLS defines the TLS configuration on a layer 4 / TCP Route. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#tls_1 + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#tls_1 properties: certResolver: description: |- CertResolver defines the name of the certificate resolver to use. Cert resolvers have to be configured in the static configuration. - More info: https://doc.traefik.io/traefik/v3.0/https/acme/#certificate-resolvers + More info: https://doc.traefik.io/traefik/v3.2/https/acme/#certificate-resolvers type: string domains: description: |- Domains defines the list of domains that will be used to issue certificates. - More info: https://doc.traefik.io/traefik/v3.0/routing/routers/#domains + More info: https://doc.traefik.io/traefik/v3.2/routing/routers/#domains items: description: Domain holds a domain name with SANs. properties: @@ -198,7 +198,7 @@ spec: description: |- Options defines the reference to a TLSOption, that specifies the parameters of the TLS connection. If not defined, the `default` TLSOption is used. - More info: https://doc.traefik.io/traefik/v3.0/https/tls/#tls-options + More info: https://doc.traefik.io/traefik/v3.2/https/tls/#tls-options properties: name: description: Name defines the name of the referenced Traefik diff --git a/charts/traefik/traefik/crds/traefik.io_ingressrouteudps.yaml b/charts/traefik/traefik/crds/traefik.io_ingressrouteudps.yaml index 19bbfe6..a815d86 100644 --- a/charts/traefik/traefik/crds/traefik.io_ingressrouteudps.yaml +++ b/charts/traefik/traefik/crds/traefik.io_ingressrouteudps.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: ingressrouteudps.traefik.io spec: group: traefik.io @@ -43,7 +43,7 @@ spec: description: |- EntryPoints defines the list of entry point names to bind to. Entry points have to be configured in the static configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/entrypoints/ + More info: https://doc.traefik.io/traefik/v3.2/routing/entrypoints/ Default: all. items: type: string diff --git a/charts/traefik/traefik/crds/traefik.io_middlewares.yaml b/charts/traefik/traefik/crds/traefik.io_middlewares.yaml index 0d005e6..f3ea9fc 100644 --- a/charts/traefik/traefik/crds/traefik.io_middlewares.yaml +++ b/charts/traefik/traefik/crds/traefik.io_middlewares.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: middlewares.traefik.io spec: group: traefik.io @@ -19,7 +19,7 @@ spec: openAPIV3Schema: description: |- Middleware is the CRD implementation of a Traefik Middleware. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/overview/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/overview/ properties: apiVersion: description: |- @@ -45,7 +45,7 @@ spec: description: |- AddPrefix holds the add prefix middleware configuration. This middleware updates the path of a request before forwarding it. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/addprefix/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/addprefix/ properties: prefix: description: |- @@ -57,12 +57,12 @@ spec: description: |- BasicAuth holds the basic auth middleware configuration. This middleware restricts access to your services to known users. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/basicauth/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/basicauth/ properties: headerField: description: |- HeaderField defines a header field to store the authenticated user. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/basicauth/#headerfield + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/basicauth/#headerfield type: string realm: description: |- @@ -83,7 +83,7 @@ spec: description: |- Buffering holds the buffering middleware configuration. This middleware retries or limits the size of requests that can be forwarded to backends. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/buffering/#maxrequestbodybytes + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/buffering/#maxrequestbodybytes properties: maxRequestBodyBytes: description: |- @@ -115,14 +115,14 @@ spec: description: |- RetryExpression defines the retry conditions. It is a logical combination of functions with operators AND (&&) and OR (||). - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/buffering/#retryexpression + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/buffering/#retryexpression type: string type: object chain: description: |- Chain holds the configuration of the chain middleware. This middleware enables to define reusable combinations of other pieces of middleware. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/chain/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/chain/ properties: middlewares: description: Middlewares is the list of MiddlewareRef which composes @@ -180,14 +180,20 @@ spec: compress: description: |- Compress holds the compress middleware configuration. - This middleware compresses responses before sending them to the client, using gzip compression. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/compress/ + This middleware compresses responses before sending them to the client, using gzip, brotli, or zstd compression. + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/compress/ properties: defaultEncoding: description: DefaultEncoding specifies the default encoding if the `Accept-Encoding` header is not in the request or contains a wildcard (`*`). type: string + encodings: + description: Encodings defines the list of supported compression + algorithms. + items: + type: string + type: array excludedContentTypes: description: |- ExcludedContentTypes defines the list of content types to compare the Content-Type header of the incoming requests and responses before compressing. @@ -224,12 +230,12 @@ spec: description: |- DigestAuth holds the digest auth middleware configuration. This middleware restricts access to your services to known users. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/digestauth/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/digestauth/ properties: headerField: description: |- HeaderField defines a header field to store the authenticated user. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/basicauth/#headerfield + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/basicauth/#headerfield type: string realm: description: |- @@ -249,7 +255,7 @@ spec: description: |- ErrorPage holds the custom error middleware configuration. This middleware returns a custom page in lieu of the default, according to configured ranges of HTTP Status codes. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/errorpages/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/errorpages/ properties: query: description: |- @@ -259,7 +265,7 @@ spec: service: description: |- Service defines the reference to a Kubernetes Service that will serve the error page. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/errorpages/#service + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/errorpages/#service properties: healthCheck: description: Healthcheck defines health checks for ExternalName @@ -392,7 +398,7 @@ spec: sticky: description: |- Sticky defines the sticky sessions configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#sticky-sessions + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#sticky-sessions properties: cookie: description: Cookie defines the sticky cookie configuration. @@ -450,7 +456,7 @@ spec: description: |- ForwardAuth holds the forward auth middleware configuration. This middleware delegates the request authentication to a Service. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/forwardauth/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/forwardauth/ properties: addAuthCookiesToResponse: description: AddAuthCookiesToResponse defines the list of cookies @@ -478,7 +484,7 @@ spec: authResponseHeadersRegex: description: |- AuthResponseHeadersRegex defines the regex to match headers to copy from the authentication server response and set on forwarded request, after stripping all headers that match the regex. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/forwardauth/#authresponseheadersregex + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/forwardauth/#authresponseheadersregex type: string tls: description: TLS defines the configuration used to secure the @@ -525,7 +531,7 @@ spec: description: |- Headers holds the headers middleware configuration. This middleware manages the requests and responses headers. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/headers/#customrequestheaders + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/headers/#customrequestheaders properties: accessControlAllowCredentials: description: AccessControlAllowCredentials defines whether the @@ -696,7 +702,7 @@ spec: description: |- InFlightReq holds the in-flight request middleware configuration. This middleware limits the number of requests being processed and served concurrently. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/inflightreq/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/inflightreq/ properties: amount: description: |- @@ -709,12 +715,12 @@ spec: SourceCriterion defines what criterion is used to group requests as originating from a common source. If several strategies are defined at the same time, an error will be raised. If none are set, the default is to use the requestHost. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/inflightreq/#sourcecriterion + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/inflightreq/#sourcecriterion properties: ipStrategy: description: |- IPStrategy holds the IP strategy configuration used by Traefik to determine the client IP. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/#ipstrategy + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/ipallowlist/#ipstrategy properties: depth: description: Depth tells Traefik to use the X-Forwarded-For @@ -728,6 +734,12 @@ spec: items: type: string type: array + ipv6Subnet: + description: IPv6Subnet configures Traefik to consider + all IPv6 addresses from the defined subnet as originating + from the same IP. Applies to RemoteAddrStrategy and + DepthStrategy. + type: integer type: object requestHeaderName: description: RequestHeaderName defines the name of the header @@ -743,12 +755,12 @@ spec: description: |- IPAllowList holds the IP allowlist middleware configuration. This middleware limits allowed requests based on the client IP. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/ipallowlist/ properties: ipStrategy: description: |- IPStrategy holds the IP strategy configuration used by Traefik to determine the client IP. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/#ipstrategy + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/ipallowlist/#ipstrategy properties: depth: description: Depth tells Traefik to use the X-Forwarded-For @@ -761,6 +773,11 @@ spec: items: type: string type: array + ipv6Subnet: + description: IPv6Subnet configures Traefik to consider all + IPv6 addresses from the defined subnet as originating from + the same IP. Applies to RemoteAddrStrategy and DepthStrategy. + type: integer type: object rejectStatusCode: description: |- @@ -780,7 +797,7 @@ spec: ipStrategy: description: |- IPStrategy holds the IP strategy configuration used by Traefik to determine the client IP. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/#ipstrategy + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/ipallowlist/#ipstrategy properties: depth: description: Depth tells Traefik to use the X-Forwarded-For @@ -793,6 +810,11 @@ spec: items: type: string type: array + ipv6Subnet: + description: IPv6Subnet configures Traefik to consider all + IPv6 addresses from the defined subnet as originating from + the same IP. Applies to RemoteAddrStrategy and DepthStrategy. + type: integer type: object sourceRange: description: SourceRange defines the set of allowed IPs (or ranges @@ -805,7 +827,7 @@ spec: description: |- PassTLSClientCert holds the pass TLS client cert middleware configuration. This middleware adds the selected data from the passed client TLS certificate to a header. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/passtlsclientcert/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/passtlsclientcert/ properties: info: description: Info selects the specific client certificate details @@ -914,7 +936,7 @@ spec: description: |- RateLimit holds the rate limit configuration. This middleware ensures that services will receive a fair amount of requests, and allows one to define what fair is. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ratelimit/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/ratelimit/ properties: average: description: |- @@ -947,7 +969,7 @@ spec: ipStrategy: description: |- IPStrategy holds the IP strategy configuration used by Traefik to determine the client IP. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/ipallowlist/#ipstrategy + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/ipallowlist/#ipstrategy properties: depth: description: Depth tells Traefik to use the X-Forwarded-For @@ -961,6 +983,12 @@ spec: items: type: string type: array + ipv6Subnet: + description: IPv6Subnet configures Traefik to consider + all IPv6 addresses from the defined subnet as originating + from the same IP. Applies to RemoteAddrStrategy and + DepthStrategy. + type: integer type: object requestHeaderName: description: RequestHeaderName defines the name of the header @@ -976,7 +1004,7 @@ spec: description: |- RedirectRegex holds the redirect regex middleware configuration. This middleware redirects a request using regex matching and replacement. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/redirectregex/#regex + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/redirectregex/#regex properties: permanent: description: Permanent defines whether the redirection is permanent @@ -995,7 +1023,7 @@ spec: description: |- RedirectScheme holds the redirect scheme middleware configuration. This middleware redirects requests from a scheme/port to another. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/redirectscheme/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/redirectscheme/ properties: permanent: description: Permanent defines whether the redirection is permanent @@ -1012,7 +1040,7 @@ spec: description: |- ReplacePath holds the replace path middleware configuration. This middleware replaces the path of the request URL and store the original path in an X-Replaced-Path header. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/replacepath/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/replacepath/ properties: path: description: Path defines the path to use as replacement in the @@ -1023,7 +1051,7 @@ spec: description: |- ReplacePathRegex holds the replace path regex middleware configuration. This middleware replaces the path of a URL using regex matching and replacement. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/replacepathregex/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/replacepathregex/ properties: regex: description: Regex defines the regular expression used to match @@ -1039,7 +1067,7 @@ spec: Retry holds the retry middleware configuration. This middleware reissues requests a given number of times to a backend server if that server does not reply. As soon as the server answers, the middleware stops retrying, regardless of the response status. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/retry/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/retry/ properties: attempts: description: Attempts defines how many times the request should @@ -1061,7 +1089,7 @@ spec: description: |- StripPrefix holds the strip prefix middleware configuration. This middleware removes the specified prefixes from the URL path. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/stripprefix/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/stripprefix/ properties: forceSlash: description: |- @@ -1080,7 +1108,7 @@ spec: description: |- StripPrefixRegex holds the strip prefix regex middleware configuration. This middleware removes the matching prefixes from the URL path. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/http/stripprefixregex/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/http/stripprefixregex/ properties: regex: description: Regex defines the regular expression to match the diff --git a/charts/traefik/traefik/crds/traefik.io_middlewaretcps.yaml b/charts/traefik/traefik/crds/traefik.io_middlewaretcps.yaml index 250ac1b..fc23e11 100644 --- a/charts/traefik/traefik/crds/traefik.io_middlewaretcps.yaml +++ b/charts/traefik/traefik/crds/traefik.io_middlewaretcps.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: middlewaretcps.traefik.io spec: group: traefik.io @@ -19,7 +19,7 @@ spec: openAPIV3Schema: description: |- MiddlewareTCP is the CRD implementation of a Traefik TCP middleware. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/overview/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/overview/ properties: apiVersion: description: |- @@ -55,7 +55,7 @@ spec: description: |- IPAllowList defines the IPAllowList middleware configuration. This middleware accepts/refuses connections based on the client IP. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/tcp/ipallowlist/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/tcp/ipallowlist/ properties: sourceRange: description: SourceRange defines the allowed IPs (or ranges of @@ -69,7 +69,7 @@ spec: IPWhiteList defines the IPWhiteList middleware configuration. This middleware accepts/refuses connections based on the client IP. Deprecated: please use IPAllowList instead. - More info: https://doc.traefik.io/traefik/v3.0/middlewares/tcp/ipwhitelist/ + More info: https://doc.traefik.io/traefik/v3.2/middlewares/tcp/ipwhitelist/ properties: sourceRange: description: SourceRange defines the allowed IPs (or ranges of diff --git a/charts/traefik/traefik/crds/traefik.io_serverstransports.yaml b/charts/traefik/traefik/crds/traefik.io_serverstransports.yaml index 287943f..fe2f129 100644 --- a/charts/traefik/traefik/crds/traefik.io_serverstransports.yaml +++ b/charts/traefik/traefik/crds/traefik.io_serverstransports.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: serverstransports.traefik.io spec: group: traefik.io @@ -21,7 +21,7 @@ spec: ServersTransport is the CRD implementation of a ServersTransport. If no serversTransport is specified, the default@internal will be used. The default@internal serversTransport is created from the static configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#serverstransport_1 + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#serverstransport_1 properties: apiVersion: description: |- diff --git a/charts/traefik/traefik/crds/traefik.io_serverstransporttcps.yaml b/charts/traefik/traefik/crds/traefik.io_serverstransporttcps.yaml index b255d32..2f24c84 100644 --- a/charts/traefik/traefik/crds/traefik.io_serverstransporttcps.yaml +++ b/charts/traefik/traefik/crds/traefik.io_serverstransporttcps.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: serverstransporttcps.traefik.io spec: group: traefik.io @@ -21,7 +21,7 @@ spec: ServersTransportTCP is the CRD implementation of a TCPServersTransport. If no tcpServersTransport is specified, a default one named default@internal will be used. The default@internal tcpServersTransport can be configured in the static configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#serverstransport_3 + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#serverstransport_3 properties: apiVersion: description: |- diff --git a/charts/traefik/traefik/crds/traefik.io_tlsoptions.yaml b/charts/traefik/traefik/crds/traefik.io_tlsoptions.yaml index 2380e8e..498fc3c 100644 --- a/charts/traefik/traefik/crds/traefik.io_tlsoptions.yaml +++ b/charts/traefik/traefik/crds/traefik.io_tlsoptions.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: tlsoptions.traefik.io spec: group: traefik.io @@ -19,7 +19,7 @@ spec: openAPIV3Schema: description: |- TLSOption is the CRD implementation of a Traefik TLS Option, allowing to configure some parameters of the TLS connection. - More info: https://doc.traefik.io/traefik/v3.0/https/tls/#tls-options + More info: https://doc.traefik.io/traefik/v3.2/https/tls/#tls-options properties: apiVersion: description: |- @@ -44,14 +44,14 @@ spec: alpnProtocols: description: |- ALPNProtocols defines the list of supported application level protocols for the TLS handshake, in order of preference. - More info: https://doc.traefik.io/traefik/v3.0/https/tls/#alpn-protocols + More info: https://doc.traefik.io/traefik/v3.2/https/tls/#alpn-protocols items: type: string type: array cipherSuites: description: |- CipherSuites defines the list of supported cipher suites for TLS versions up to TLS 1.2. - More info: https://doc.traefik.io/traefik/v3.0/https/tls/#cipher-suites + More info: https://doc.traefik.io/traefik/v3.2/https/tls/#cipher-suites items: type: string type: array @@ -79,7 +79,7 @@ spec: curvePreferences: description: |- CurvePreferences defines the preferred elliptic curves in a specific order. - More info: https://doc.traefik.io/traefik/v3.0/https/tls/#curve-preferences + More info: https://doc.traefik.io/traefik/v3.2/https/tls/#curve-preferences items: type: string type: array diff --git a/charts/traefik/traefik/crds/traefik.io_tlsstores.yaml b/charts/traefik/traefik/crds/traefik.io_tlsstores.yaml index 15c4951..7eacb77 100644 --- a/charts/traefik/traefik/crds/traefik.io_tlsstores.yaml +++ b/charts/traefik/traefik/crds/traefik.io_tlsstores.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: tlsstores.traefik.io spec: group: traefik.io @@ -21,7 +21,7 @@ spec: TLSStore is the CRD implementation of a Traefik TLS Store. For the time being, only the TLSStore named default is supported. This means that you cannot have two stores that are named default in different Kubernetes namespaces. - More info: https://doc.traefik.io/traefik/v3.0/https/tls/#certificates-stores + More info: https://doc.traefik.io/traefik/v3.2/https/tls/#certificates-stores properties: apiVersion: description: |- diff --git a/charts/traefik/traefik/crds/traefik.io_traefikservices.yaml b/charts/traefik/traefik/crds/traefik.io_traefikservices.yaml index 7a0f7da..01e28fc 100644 --- a/charts/traefik/traefik/crds/traefik.io_traefikservices.yaml +++ b/charts/traefik/traefik/crds/traefik.io_traefikservices.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.14.0 + controller-gen.kubebuilder.io/version: v0.16.1 name: traefikservices.traefik.io spec: group: traefik.io @@ -22,7 +22,7 @@ spec: TraefikService object allows to: - Apply weight to Services on load-balancing - Mirror traffic on services - More info: https://doc.traefik.io/traefik/v3.0/routing/providers/kubernetes-crd/#kind-traefikservice + More info: https://doc.traefik.io/traefik/v3.2/routing/providers/kubernetes-crd/#kind-traefikservice properties: apiVersion: description: |- @@ -121,6 +121,11 @@ spec: Default value is -1, which means unlimited size. format: int64 type: integer + mirrorBody: + description: |- + MirrorBody defines whether the body of the request should be mirrored. + Default value is true. + type: boolean mirrors: description: Mirrors defines the list of mirrors where Traefik will duplicate the traffic. @@ -263,7 +268,7 @@ spec: sticky: description: |- Sticky defines the sticky sessions configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#sticky-sessions + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#sticky-sessions properties: cookie: description: Cookie defines the sticky cookie configuration. @@ -370,7 +375,7 @@ spec: sticky: description: |- Sticky defines the sticky sessions configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#sticky-sessions + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#sticky-sessions properties: cookie: description: Cookie defines the sticky cookie configuration. @@ -553,7 +558,7 @@ spec: sticky: description: |- Sticky defines the sticky sessions configuration. - More info: https://doc.traefik.io/traefik/v3.0/routing/services/#sticky-sessions + More info: https://doc.traefik.io/traefik/v3.2/routing/services/#sticky-sessions properties: cookie: description: Cookie defines the sticky cookie configuration. @@ -600,7 +605,7 @@ spec: sticky: description: |- Sticky defines whether sticky sessions are enabled. - More info: https://doc.traefik.io/traefik/v3.0/routing/providers/kubernetes-crd/#stickiness-and-load-balancing + More info: https://doc.traefik.io/traefik/v3.2/routing/providers/kubernetes-crd/#stickiness-and-load-balancing properties: cookie: description: Cookie defines the sticky cookie configuration. diff --git a/charts/traefik/traefik/templates/_helpers.tpl b/charts/traefik/traefik/templates/_helpers.tpl index 2183f84..284e912 100644 --- a/charts/traefik/traefik/templates/_helpers.tpl +++ b/charts/traefik/traefik/templates/_helpers.tpl @@ -159,3 +159,20 @@ Cert: {{ $cert.Cert | b64enc }} Key: {{ $cert.Key | b64enc }} {{- end -}} {{- end -}} + +{{- define "traefik.yaml2CommandLineArgsRec" -}} + {{- $path := .path -}} + {{- range $key, $value := .content -}} + {{- if kindIs "map" $value }} + {{- include "traefik.yaml2CommandLineArgsRec" (dict "path" (printf "%s.%s" $path $key) "content" $value) -}} + {{- else }} +--{{ join "." (list $path $key)}}={{ join "," $value }} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- define "traefik.yaml2CommandLineArgs" -}} + {{- range ((regexSplit "\n" ((include "traefik.yaml2CommandLineArgsRec" (dict "path" .path "content" .content)) | trim) -1) | compact) -}} + {{ printf "- \"%s\"\n" . }} + {{- end -}} +{{- end -}} diff --git a/charts/traefik/traefik/templates/_podtemplate.tpl b/charts/traefik/traefik/templates/_podtemplate.tpl index ff363fd..ba7dc2b 100644 --- a/charts/traefik/traefik/templates/_podtemplate.tpl +++ b/charts/traefik/traefik/templates/_podtemplate.tpl @@ -1,4 +1,5 @@ {{- define "traefik.podTemplate" }} + {{- $version := include "imageVersion" $ }} metadata: annotations: {{- if .Values.deployment.podAnnotations }} @@ -463,6 +464,9 @@ {{- end }} {{- if .Values.providers.kubernetesCRD.allowEmptyServices }} - "--providers.kubernetescrd.allowEmptyServices=true" + {{- end }} + {{- if and .Values.rbac.namespaced (semverCompare ">=3.1.2-0" $version) }} + - "--providers.kubernetescrd.disableClusterScopeResources=true" {{- end }} {{- if .Values.providers.kubernetesCRD.nativeLBByDefault }} - "--providers.kubernetescrd.nativeLBByDefault=true" @@ -485,8 +489,15 @@ {{- if .Values.providers.kubernetesIngress.ingressClass }} - "--providers.kubernetesingress.ingressClass={{ .Values.providers.kubernetesIngress.ingressClass }}" {{- end }} - {{- if .Values.providers.kubernetesIngress.disableIngressClassLookup }} + {{- if .Values.rbac.namespaced }} + {{- if semverCompare "<3.1.5-0" $version }} - "--providers.kubernetesingress.disableIngressClassLookup=true" + {{- if semverCompare ">=3.1.2-0" $version }} + - "--providers.kubernetesingress.disableClusterScopeResources=true" + {{- end }} + {{- else }} + - "--providers.kubernetesingress.disableClusterScopeResources=true" + {{- end }} {{- end }} {{- if .Values.providers.kubernetesIngress.nativeLBByDefault }} - "--providers.kubernetesingress.nativeLBByDefault=true" @@ -503,6 +514,18 @@ {{- with .Values.providers.kubernetesGateway }} {{- if .enabled }} - "--providers.kubernetesgateway" + {{- with .statusAddress }} + {{- with .ip }} + - "--providers.kubernetesgateway.statusaddress.ip={{ . }}" + {{- end }} + {{- with .hostname }} + - "--providers.kubernetesgateway.statusaddress.hostname={{ . }}" + {{- end }} + {{- with .service }} + - "--providers.kubernetesgateway.statusaddress.service.name={{ tpl .name $ }}" + - "--providers.kubernetesgateway.statusaddress.service.namespace={{ tpl .namespace $ }}" + {{- end }} + {{- end }} {{- if or .namespaces (and $.Values.rbac.enabled $.Values.rbac.namespaced) }} - "--providers.kubernetesgateway.namespaces={{ template "providers.kubernetesGateway.namespaces" $ }}" {{- end }} @@ -530,9 +553,6 @@ {{- range $entrypoint, $config := $.Values.ports }} {{- if $config }} {{- if $config.redirectTo }} - {{- if eq (typeOf $config.redirectTo) "string" }} - {{- fail "ERROR: Syntax of `ports.web.redirectTo` has changed to `ports.web.redirectTo.port`. Details in PR #934." }} - {{- end }} {{- $toPort := index $.Values.ports $config.redirectTo.port }} - "--entryPoints.{{ $entrypoint }}.http.redirections.entryPoint.to=:{{ $toPort.exposedPort }}" - "--entryPoints.{{ $entrypoint }}.http.redirections.entryPoint.scheme=https" @@ -575,6 +595,12 @@ {{- end }} {{- end }} {{- end }} + {{- if $config.allowACMEByPass }} + {{- if (semverCompare "<3.1.3-0" $version) }} + {{- fail "ERROR: allowACMEByPass has been introduced with Traefik v3.1.3+" -}} + {{- end }} + - "--entryPoints.name.allowACMEByPass=true" + {{- end }} {{- if $config.forwardedHeaders }} {{- if $config.forwardedHeaders.trustedIPs }} - "--entryPoints.{{ $entrypoint }}.forwardedHeaders.trustedIPs={{ join "," $config.forwardedHeaders.trustedIPs }}" @@ -624,20 +650,17 @@ {{- if and .general.format (not (has .general.format (list "common" "json"))) }} {{- fail "ERROR: .Values.logs.general.format must be either common or json" }} {{- end }} - {{- if .general.format }} - - "--log.format={{ .general.format }}" + {{- with .general.format }} + - "--log.format={{ . }}" {{- end }} - {{- if .general.filePath }} - - "--log.filePath={{ .general.filePath }}" + {{- with .general.filePath }} + - "--log.filePath={{ . }}" {{- end }} {{- if and (or (eq .general.format "common") (not .general.format)) (eq .general.noColor true) }} - "--log.noColor={{ .general.noColor }}" {{- end }} - {{- if and .general.level (not (has (.general.level | upper) (list "DEBUG" "PANIC" "FATAL" "ERROR" "WARN" "INFO"))) }} - {{- fail "ERROR: .Values.logs.level must be DEBUG, PANIC, FATAL, ERROR, WARN, and INFO" }} - {{- end }} - {{- if .general.level }} - - "--log.level={{ .general.level | upper }}" + {{- with .general.level }} + - "--log.level={{ . | upper }}" {{- end }} {{- if .access.enabled }} - "--accesslog=true" @@ -674,17 +697,7 @@ {{- end }} {{- end }} {{- end }} - {{- range $resolver, $config := $.Values.certResolvers }} - {{- range $option, $setting := $config }} - {{- if kindIs "map" $setting }} - {{- range $field, $value := $setting }} - - "--certificatesresolvers.{{ $resolver }}.acme.{{ $option }}.{{ $field }}={{ if kindIs "slice" $value }}{{ join "," $value }}{{ else }}{{ $value }}{{ end }}" - {{- end }} - {{- else }} - - "--certificatesresolvers.{{ $resolver }}.acme.{{ $option }}={{ $setting }}" - {{- end }} - {{- end }} - {{- end }} + {{- include "traefik.yaml2CommandLineArgs" (dict "path" "certificatesresolvers" "content" $.Values.certificatesResolvers) | nindent 10 }} {{- with .Values.additionalArguments }} {{- range . }} - {{ . | quote }} @@ -709,24 +722,24 @@ {{- with .platformUrl }} - "--hub.platformUrl={{ . }}" {{- end -}} - {{- range $field, $value := .ratelimit.redis }} + {{- range $field, $value := .redis }} {{- if has $field (list "cluster" "database" "endpoints" "username" "password" "timeout") -}} {{- with $value }} - - "--hub.ratelimit.redis.{{ $field }}={{ $value }}" + - "--hub.redis.{{ $field }}={{ $value }}" {{- end }} {{- end }} {{- end }} - {{- range $field, $value := .ratelimit.redis.sentinel }} + {{- range $field, $value := .redis.sentinel }} {{- if has $field (list "masterset" "password" "username") -}} {{- with $value }} - - "--hub.ratelimit.redis.sentinel.{{ $field }}={{ $value }}" + - "--hub.redis.sentinel.{{ $field }}={{ $value }}" {{- end }} {{- end }} {{- end }} - {{- range $field, $value := .ratelimit.redis.tls }} + {{- range $field, $value := .redis.tls }} {{- if has $field (list "ca" "cert" "insecureSkipVerify" "key") -}} {{- with $value }} - - "--hub.ratelimit.redis.tls.{{ $field }}={{ $value }}" + - "--hub.redis.tls.{{ $field }}={{ $value }}" {{- end }} {{- end }} {{- end }} @@ -736,6 +749,14 @@ {{- end }} {{- end }} env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace {{- if ($.Values.resources.limits).cpu }} - name: GOMAXPROCS valueFrom: diff --git a/charts/traefik/traefik/templates/_service.tpl b/charts/traefik/traefik/templates/_service.tpl index 03004e5..27d5bc4 100644 --- a/charts/traefik/traefik/templates/_service.tpl +++ b/charts/traefik/traefik/templates/_service.tpl @@ -66,11 +66,11 @@ {{- if $config.appProtocol }} appProtocol: {{ $config.appProtocol }} {{- end }} - {{- if ($config.http3).enabled }} + {{- if and ($config.http3).enabled ($config.single) }} {{- $http3Port := default $config.exposedPort $config.http3.advertisedPort }} - port: {{ $http3Port }} name: "{{ $name }}-http3" - targetPort: {{ $name }}-http3 + targetPort: "{{ $name }}-http3" protocol: UDP {{- if $config.nodePort }} nodePort: {{ $config.nodePort }} diff --git a/charts/traefik/traefik/templates/daemonset.yaml b/charts/traefik/traefik/templates/daemonset.yaml index 5be6a0a..b370c22 100644 --- a/charts/traefik/traefik/templates/daemonset.yaml +++ b/charts/traefik/traefik/templates/daemonset.yaml @@ -10,7 +10,7 @@ {{- fail "\n\n ERROR: latest tag should not be used" }} {{- end }} {{- with .Values.updateStrategy }} - {{- if eq (.type) "RollingUpdate" }} + {{- if and (eq (.type) "RollingUpdate") (.rollingUpdate) }} {{- if not (contains "%" (toString .rollingUpdate.maxUnavailable)) }} {{- if and ($.Values.hostNetwork) (lt (float64 .rollingUpdate.maxUnavailable) 1.0) }} {{- fail "maxUnavailable should be greater than 1 when using hostNetwork." }} @@ -41,7 +41,15 @@ spec: selector: matchLabels: {{- include "traefik.labelselector" . | nindent 6 }} - updateStrategy: {{ toYaml .Values.updateStrategy | nindent 4 }} + {{- with .Values.updateStrategy }} + updateStrategy: + type: {{ .type }} + {{- if (eq .type "RollingUpdate") }} + rollingUpdate: + maxUnavailable: {{ .rollingUpdate.maxUnavailable }} + maxSurge: {{ .rollingUpdate.maxSurge }} + {{- end }} + {{- end }} minReadySeconds: {{ .Values.deployment.minReadySeconds }} {{- if .Values.deployment.revisionHistoryLimit }} revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }} diff --git a/charts/traefik/traefik/templates/deployment.yaml b/charts/traefik/traefik/templates/deployment.yaml index 3e9c8ad..4b3a1ae 100644 --- a/charts/traefik/traefik/templates/deployment.yaml +++ b/charts/traefik/traefik/templates/deployment.yaml @@ -16,10 +16,6 @@ {{- if eq (default .Chart.AppVersion .Values.image.tag) "latest" }} {{- fail "\n\n ERROR: latest tag should not be used" }} {{- end }} - -{{- if ne (typeOf .Values.experimental.plugins) "map[string]interface {}" }} - {{- fail (printf "ERROR: .Values.experimental.plugins should be a map (%s provided) !" (typeOf .Values.experimental.plugins)) }} -{{- end }} --- apiVersion: apps/v1 kind: Deployment @@ -48,7 +44,15 @@ spec: selector: matchLabels: {{- include "traefik.labelselector" . | nindent 6 }} - strategy: {{ toYaml .Values.updateStrategy | nindent 4 }} + {{- with .Values.updateStrategy }} + strategy: + type: {{ .type }} + {{- if (eq .type "RollingUpdate") }} + rollingUpdate: + maxUnavailable: {{ .rollingUpdate.maxUnavailable }} + maxSurge: {{ .rollingUpdate.maxSurge }} + {{- end }} + {{- end }} minReadySeconds: {{ .Values.deployment.minReadySeconds }} template: {{ template "traefik.podTemplate" . }} {{- end -}} diff --git a/charts/traefik/traefik/templates/gateway.yaml b/charts/traefik/traefik/templates/gateway.yaml index ab51c92..42bc33d 100644 --- a/charts/traefik/traefik/templates/gateway.yaml +++ b/charts/traefik/traefik/templates/gateway.yaml @@ -16,9 +16,16 @@ metadata: {{- end }} spec: gatewayClassName: {{ default "traefik" .Values.gatewayClass.name }} + {{- with .Values.gateway.infrastructure }} + infrastructure: + {{ toYaml . | nindent 4 }} + {{- end }} listeners: {{- range $name, $config := .Values.gateway.listeners }} - name: {{ $name }} + {{ if not .port }} + {{- fail "ERROR: port needs to be specified" }} + {{- end -}} {{ $found := false }} {{- range $portName, $portConfig := $.Values.ports -}} {{- if eq $portConfig.port $config.port -}} @@ -31,13 +38,16 @@ spec: port: {{ .port }} protocol: {{ .protocol }} {{- with .hostname }} - hostname: {{ . }} + hostname: {{ . | toYaml }} {{- end }} {{- with .namespacePolicy }} allowedRoutes: namespaces: from: {{ . }} {{- end }} + {{ if and (eq .protocol "HTTPS") (not .certificateRefs) }} + {{- fail "ERROR: certificateRefs needs to be specified using HTTPS" }} + {{- end }} {{ if or .certificateRefs .mode }} tls: {{ with .mode }} diff --git a/charts/traefik/traefik/templates/hub-admission-controller.yaml b/charts/traefik/traefik/templates/hub-admission-controller.yaml index 6a64516..37b2314 100644 --- a/charts/traefik/traefik/templates/hub-admission-controller.yaml +++ b/charts/traefik/traefik/templates/hub-admission-controller.yaml @@ -14,37 +14,6 @@ data: tls.crt: {{ $cert.Cert }} tls.key: {{ $cert.Key }} ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: MutatingWebhookConfiguration -metadata: - name: hub-edge-ingress - labels: - {{- include "traefik.labels" . | nindent 4 }} -webhooks: - - name: admission.traefik.svc - clientConfig: - service: - name: admission - namespace: {{ template "traefik.namespace" . }} - path: /edge-ingress - caBundle: {{ $cert.Cert }} - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - - DELETE - apiGroups: - - hub.traefik.io - apiVersions: - - v1alpha1 - resources: - - edgeingresses - scope: Namespaced - --- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration @@ -104,27 +73,6 @@ webhooks: - v1alpha1 resources: - apiportals - - name: hub-agent.traefik.gateway - clientConfig: - service: - name: admission - namespace: {{ template "traefik.namespace" . }} - path: /api-gateway - caBundle: {{ $cert.Cert }} - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - - DELETE - apiGroups: - - hub.traefik.io - apiVersions: - - v1alpha1 - resources: - - apigateways - name: hub-agent.traefik.api clientConfig: service: @@ -146,27 +94,6 @@ webhooks: - v1alpha1 resources: - apis - - name: hub-agent.traefik.collection - clientConfig: - service: - name: admission - namespace: {{ template "traefik.namespace" . }} - path: /api-collection - caBundle: {{ $cert.Cert }} - sideEffects: None - admissionReviewVersions: - - v1 - rules: - - operations: - - CREATE - - UPDATE - - DELETE - apiGroups: - - hub.traefik.io - apiVersions: - - v1alpha1 - resources: - - apicollections - name: hub-agent.traefik.access clientConfig: service: @@ -188,12 +115,12 @@ webhooks: - v1alpha1 resources: - apiaccesses - - name: hub-agent.traefik.rate-limit + - name: hub-agent.traefik.plan clientConfig: service: name: admission namespace: {{ template "traefik.namespace" . }} - path: /api-rate-limit + path: /api-plan caBundle: {{ $cert.Cert }} sideEffects: None admissionReviewVersions: @@ -208,7 +135,28 @@ webhooks: apiVersions: - v1alpha1 resources: - - apiratelimits + - apiplans + - name: hub-agent.traefik.bundle + clientConfig: + service: + name: admission + namespace: {{ template "traefik.namespace" . }} + path: /api-bundle + caBundle: {{ $cert.Cert }} + sideEffects: None + admissionReviewVersions: + - v1 + rules: + - operations: + - CREATE + - UPDATE + - DELETE + apiGroups: + - hub.traefik.io + apiVersions: + - v1alpha1 + resources: + - apibundles - name: hub-agent.traefik.version clientConfig: service: diff --git a/charts/traefik/traefik/templates/rbac/clusterrole.yaml b/charts/traefik/traefik/templates/rbac/clusterrole.yaml index 3ab9c69..9e52d53 100644 --- a/charts/traefik/traefik/templates/rbac/clusterrole.yaml +++ b/charts/traefik/traefik/templates/rbac/clusterrole.yaml @@ -1,11 +1,5 @@ {{- $version := include "imageVersion" $ }} -{{- if .Values.rbac.enabled }} -{{- if or - (semverCompare ">=v3.1.0-0" $version) - (.Values.providers.kubernetesGateway.enabled) - (not .Values.rbac.namespaced) - (and .Values.rbac.namespaced .Values.providers.kubernetesIngress.enabled (not .Values.providers.kubernetesIngress.disableIngressClassLookup)) -}} +{{- if and .Values.rbac.enabled (not .Values.rbac.namespaced) }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 @@ -27,42 +21,6 @@ rules: - list - watch {{- end }} - - apiGroups: - - extensions - - networking.k8s.io - resources: - - ingressclasses - {{- if not .Values.rbac.namespaced }} - - ingresses - {{- end }} - verbs: - - get - - list - - watch - {{- if (.Values.providers.kubernetesGateway).enabled }} - - apiGroups: - - "" - resources: - - namespaces - verbs: - - list - - watch - - apiGroups: - - gateway.networking.k8s.io - resources: - - gatewayclasses - verbs: - - get - - list - - watch - - apiGroups: - - gateway.networking.k8s.io - resources: - - gatewayclasses/status - verbs: - - update - {{- end }} - {{- if not .Values.rbac.namespaced }} {{- if (semverCompare "=v3.2.0-0" $version }} + - configmaps + {{- end }} verbs: - get - list @@ -180,7 +152,14 @@ rules: - apiGroups: - gateway.networking.k8s.io resources: + {{- if semverCompare ">=v3.2.0-0" $version }} + - backendtlspolicies + {{- end }} + - gatewayclasses - gateways + {{- if semverCompare ">=v3.2.0-0" $version }} + - grpcroutes + {{- end }} - httproutes - referencegrants - tcproutes @@ -192,7 +171,14 @@ rules: - apiGroups: - gateway.networking.k8s.io resources: + {{- if semverCompare ">=v3.2.0-0" $version }} + - backendtlspolicies/status + {{- end }} + - gatewayclasses/status - gateways/status + {{- if semverCompare ">=v3.2.0-0" $version }} + - grpcroutes/status + {{- end }} - httproutes/status - tcproutes/status - tlsroutes/status @@ -213,10 +199,8 @@ rules: - patch - delete {{- end }} -{{- /* not .Values.rbac.namespace */}} -{{- end }} -{{- if .Values.hub.token }} - {{- if or (semverCompare ">=v3.1.0-0" $version) .Values.hub.apimanagement.enabled }} + {{- if .Values.hub.token }} + {{- if or (semverCompare ">=v3.1.0-0" $version) .Values.hub.apimanagement.enabled }} - apiGroups: - "" resources: @@ -224,7 +208,7 @@ rules: verbs: - list - watch - {{- end }} + {{- end }} - apiGroups: - "" resources: @@ -238,7 +222,7 @@ rules: {{- if .Values.hub.apimanagement.enabled }} - watch {{- end }} - {{- if .Values.hub.apimanagement.enabled }} + {{- if .Values.hub.apimanagement.enabled }} - apiGroups: - hub.traefik.io resources: @@ -248,6 +232,8 @@ rules: - apiratelimits - apis - apiversions + - apibundles + - apiplans verbs: - list - watch @@ -271,7 +257,7 @@ rules: - get - list - watch - {{- if (semverCompare "=v3.1.0-0" $version) - (not .Values.rbac.namespaced) - (and .Values.rbac.namespaced .Values.providers.kubernetesIngress.enabled (not .Values.providers.kubernetesIngress.disableIngressClassLookup)) -}} +{{- if and .Values.rbac.enabled (not .Values.rbac.namespaced) }} --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 @@ -21,4 +15,3 @@ subjects: name: {{ include "traefik.serviceAccountName" . }} namespace: {{ template "traefik.namespace" . }} {{- end -}} -{{- end -}} diff --git a/charts/traefik/traefik/templates/rbac/role.yaml b/charts/traefik/traefik/templates/rbac/role.yaml index 8cd9837..e81aaa8 100644 --- a/charts/traefik/traefik/templates/rbac/role.yaml +++ b/charts/traefik/traefik/templates/rbac/role.yaml @@ -1,8 +1,7 @@ {{- $version := include "imageVersion" $ }} {{- $ingressNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesIngress.namespaces -}} {{- $CRDNamespaces := concat (include "traefik.namespace" . | list) .Values.providers.kubernetesCRD.namespaces -}} -{{- $gatewayNamespaces := concat (include "traefik.namespace" . | list) ((.Values.providers.kubernetesGateway).namespaces) -}} -{{- $allNamespaces := sortAlpha (uniq (concat $ingressNamespaces $CRDNamespaces $gatewayNamespaces)) -}} +{{- $allNamespaces := sortAlpha (uniq (concat $ingressNamespaces $CRDNamespaces)) -}} {{- if and .Values.rbac.enabled .Values.rbac.namespaced -}} {{- range $allNamespaces }} @@ -107,30 +106,6 @@ rules: verbs: - use {{- end -}} -{{- if (and (has . $gatewayNamespaces) ($.Values.providers.kubernetesGateway).enabled) }} - - apiGroups: - - gateway.networking.k8s.io - resources: - - gateways - - httproutes - - referencegrants - - tcproutes - - tlsroutes - verbs: - - get - - list - - watch - - apiGroups: - - gateway.networking.k8s.io - resources: - - gatewayclasses/status - - gateways/status - - httproutes/status - - tcproutes/status - - tlsroutes/status - verbs: - - update -{{- end -}} {{- if $.Values.hub.token }} - apiGroups: - "" diff --git a/charts/traefik/traefik/templates/requirements.yaml b/charts/traefik/traefik/templates/requirements.yaml index 0175ca0..611a187 100644 --- a/charts/traefik/traefik/templates/requirements.yaml +++ b/charts/traefik/traefik/templates/requirements.yaml @@ -5,6 +5,10 @@ {{- end }} {{- end }} +{{- if .Values.certResolvers }} + {{- fail "ERROR: certResolvers setting has been removed. See v33.0.0 Changelog." }} +{{- end }} + {{- if and .Values.hub.enabled (not (contains "traefik-hub" .Values.image.repository)) }} {{- fail "ERROR: traefik-hub image is required when enabling Traefik Hub" -}} {{- end }} @@ -18,3 +22,12 @@ {{- fail "ERROR: Currently Traefik Hub doesn't support namespaced RBACs" -}} {{- end }} {{- end }} + +{{- if .Values.rbac.namespaced }} + {{- if .Values.providers.kubernetesGateway.enabled }} + {{- fail "ERROR: Kubernetes Gateway provider requires ClusterRole. RBAC cannot be namespaced." }} + {{- end }} + {{- if and (not .Values.providers.kubernetesIngress.enabled) (not .Values.providers.kubernetesCRD.enabled) }} + {{- fail "ERROR: namespaced rbac requires Kubernetes CRD or Kubernetes Ingress provider." }} + {{- end }} +{{- end }} diff --git a/charts/traefik/traefik/templates/service.yaml b/charts/traefik/traefik/templates/service.yaml index d63113c..1658f3f 100644 --- a/charts/traefik/traefik/templates/service.yaml +++ b/charts/traefik/traefik/templates/service.yaml @@ -15,6 +15,14 @@ {{- if (not $config.tls.enabled) -}} {{- fail "ERROR: You cannot enable http3 without enabling tls" -}} {{- end -}} + {{ $udpConfig := deepCopy $config -}} + {{ $_ := set $udpConfig "protocol" "UDP" -}} + {{ $_ := set $udpConfig "exposedPort" (default $config.exposedPort $config.http3.advertisedPort) -}} + {{- if (not $service.single) }} + {{ $_ := set $udpPorts (printf "%s-http3" $portName) $udpConfig -}} + {{- else }} + {{ $_ := set $tcpPorts (printf "%s-http3" $portName) $udpConfig -}} + {{- end }} {{- end -}} {{- if eq (toString $config.protocol) "UDP" -}} {{ $_ := set $udpPorts $portName $config -}} @@ -54,6 +62,8 @@ spec: {{- end }} {{- if and $exposedPorts (and $udpPorts (not $service.single)) }} + {{- $ports := include "traefik.service-ports" (dict "ports" $udpPorts "serviceName" $name) }} + {{- if not (empty $ports) }} --- apiVersion: v1 kind: Service @@ -68,7 +78,8 @@ metadata: spec: {{- template "traefik.service-spec" (dict "root" $ "service" $service) }} ports: - {{- template "traefik.service-ports" (dict "ports" $udpPorts "serviceName" $name) }} + {{- $ports }} + {{- end }} {{- end }} {{- end -}} diff --git a/charts/traefik/traefik/values.schema.json b/charts/traefik/traefik/values.schema.json new file mode 100644 index 0000000..41ca8e7 --- /dev/null +++ b/charts/traefik/traefik/values.schema.json @@ -0,0 +1,1676 @@ +{ + "$id": "https://traefik.io/traefik-helm-chart.schema.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": true, + "description": "The Cloud Native Application Proxy", + "properties": { + "additionalArguments": { + "type": "array" + }, + "additionalVolumeMounts": { + "type": "array" + }, + "affinity": { + "properties": {}, + "type": "object" + }, + "autoscaling": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "certificatesResolvers": { + "properties": {}, + "type": "object" + }, + "commonLabels": { + "properties": {}, + "type": "object" + }, + "core": { + "additionalProperties": false, + "properties": { + "defaultRuleSyntax": { + "type": "string" + } + }, + "type": "object" + }, + "deployment": { + "properties": { + "additionalContainers": { + "type": "array" + }, + "additionalVolumes": { + "type": "array" + }, + "annotations": { + "properties": {}, + "type": "object" + }, + "dnsConfig": { + "properties": {}, + "type": "object" + }, + "dnsPolicy": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "healthchecksHost": { + "type": "string" + }, + "healthchecksPort": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "healthchecksScheme": { + "enum": [ + "HTTP", + "HTTPS", + null + ], + "type": [ + "string", + "null" + ] + }, + "hostAliases": { + "type": "array" + }, + "imagePullSecrets": { + "type": "array" + }, + "initContainers": { + "type": "array" + }, + "kind": { + "type": "string" + }, + "labels": { + "properties": {}, + "type": "object" + }, + "lifecycle": { + "properties": {}, + "type": "object" + }, + "livenessPath": { + "type": "string" + }, + "minReadySeconds": { + "type": "integer" + }, + "podAnnotations": { + "properties": {}, + "type": "object" + }, + "podLabels": { + "properties": {}, + "type": "object" + }, + "readinessPath": { + "type": "string" + }, + "replicas": { + "type": "integer" + }, + "revisionHistoryLimit": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "runtimeClassName": { + "type": "string" + }, + "shareProcessNamespace": { + "type": "boolean" + }, + "terminationGracePeriodSeconds": { + "type": "integer" + } + }, + "type": "object" + }, + "env": { + "type": "array" + }, + "envFrom": { + "type": "array" + }, + "experimental": { + "properties": { + "kubernetesGateway": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "plugins": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + }, + "extraObjects": { + "type": "array" + }, + "gateway": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "infrastructure": { + "properties": {}, + "type": "object" + }, + "listeners": { + "properties": { + "web": { + "properties": { + "hostname": { + "type": "string" + }, + "namespacePolicy": { + "type": [ + "string", + "null" + ] + }, + "port": { + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + }, + "type": "object" + }, + "gatewayClass": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "labels": { + "properties": {}, + "type": "object" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "globalArguments": { + "items": { + "type": "string" + }, + "type": "array" + }, + "hostNetwork": { + "type": "boolean" + }, + "hub": { + "properties": { + "apimanagement": { + "properties": { + "admission": { + "properties": { + "listenAddr": { + "type": "string" + }, + "secretName": { + "type": "string" + } + }, + "type": "object" + }, + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "redis": { + "properties": { + "cluster": { + "type": [ + "boolean", + "null" + ] + }, + "database": { + "type": [ + "string", + "null" + ] + }, + "endpoints": { + "type": "string" + }, + "password": { + "type": "string" + }, + "sentinel": { + "properties": { + "masterset": { + "type": "string" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "timeout": { + "type": "string" + }, + "tls": { + "properties": { + "ca": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "insecureSkipVerify": { + "type": "boolean" + }, + "key": { + "type": "string" + } + }, + "type": "object" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "sendlogs": { + "type": [ + "boolean", + "null" + ] + }, + "token": { + "type": "string" + } + }, + "type": "object" + }, + "image": { + "additionalProperties": false, + "properties": { + "pullPolicy": { + "type": "string" + }, + "registry": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "ingressClass": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "isDefaultClass": { + "type": "boolean" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "ingressRoute": { + "properties": { + "dashboard": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "entryPoints": { + "items": { + "type": "string" + }, + "type": "array" + }, + "labels": { + "properties": {}, + "type": "object" + }, + "matchRule": { + "type": "string" + }, + "middlewares": { + "type": "array" + }, + "services": { + "items": { + "properties": { + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "tls": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + }, + "healthcheck": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "entryPoints": { + "items": { + "type": "string" + }, + "type": "array" + }, + "labels": { + "properties": {}, + "type": "object" + }, + "matchRule": { + "type": "string" + }, + "middlewares": { + "type": "array" + }, + "services": { + "items": { + "properties": { + "kind": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "tls": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "instanceLabelOverride": { + "type": "string" + }, + "livenessProbe": { + "additionalProperties": false, + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + }, + "type": "object" + }, + "logs": { + "properties": { + "access": { + "properties": { + "addInternals": { + "type": "boolean" + }, + "bufferingSize": { + "type": [ + "integer", + "null" + ] + }, + "enabled": { + "type": "boolean" + }, + "fields": { + "properties": { + "general": { + "properties": { + "defaultmode": { + "enum": [ + "keep", + "drop", + "redact" + ], + "type": "string" + }, + "names": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + }, + "headers": { + "properties": { + "defaultmode": { + "enum": [ + "keep", + "drop", + "redact" + ], + "type": "string" + }, + "names": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "filters": { + "additionalProperties": false, + "properties": { + "minduration": { + "type": "string" + }, + "retryattempts": { + "type": "boolean" + }, + "statuscodes": { + "type": "string" + } + }, + "type": "object" + }, + "format": { + "default": "common", + "enum": [ + "common", + "json", + null + ], + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "general": { + "properties": { + "filePath": { + "type": "string" + }, + "format": { + "default": "common", + "enum": [ + "common", + "json", + null + ], + "type": [ + "string", + "null" + ] + }, + "level": { + "default": "INFO", + "enum": [ + "TRACE", + "DEBUG", + "INFO", + "WARN", + "ERROR", + "FATAL", + "PANIC" + ], + "type": "string" + }, + "noColor": { + "type": "boolean" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "metrics": { + "properties": { + "addInternals": { + "type": "boolean" + }, + "otlp": { + "properties": { + "addEntryPointsLabels": { + "type": [ + "boolean", + "null" + ] + }, + "addRoutersLabels": { + "type": [ + "boolean", + "null" + ] + }, + "addServicesLabels": { + "type": [ + "boolean", + "null" + ] + }, + "enabled": { + "type": "boolean" + }, + "explicitBoundaries": { + "type": "array" + }, + "grpc": { + "properties": { + "enabled": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "insecure": { + "type": "boolean" + }, + "tls": { + "properties": { + "ca": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "insecureSkipVerify": { + "type": "boolean" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "http": { + "properties": { + "enabled": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "headers": { + "properties": {}, + "type": "object" + }, + "tls": { + "properties": { + "ca": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "insecureSkipVerify": { + "type": [ + "boolean", + "null" + ] + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "pushInterval": { + "type": "string" + } + }, + "type": "object" + }, + "prometheus": { + "properties": { + "addEntryPointsLabels": { + "type": [ + "boolean", + "null" + ] + }, + "addRoutersLabels": { + "type": [ + "boolean", + "null" + ] + }, + "addServicesLabels": { + "type": [ + "boolean", + "null" + ] + }, + "buckets": { + "type": "string" + }, + "disableAPICheck": { + "type": [ + "boolean", + "null" + ] + }, + "entryPoint": { + "type": "string" + }, + "manualRouting": { + "type": "boolean" + }, + "prometheusRule": { + "properties": { + "additionalLabels": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "namespace": { + "type": "string" + } + }, + "type": "object" + }, + "service": { + "properties": { + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "labels": { + "properties": {}, + "type": "object" + } + }, + "type": "object" + }, + "serviceMonitor": { + "properties": { + "additionalLabels": { + "properties": {}, + "type": "object" + }, + "enableHttp2": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "followRedirects": { + "type": "boolean" + }, + "honorLabels": { + "type": "boolean" + }, + "honorTimestamps": { + "type": "boolean" + }, + "interval": { + "type": "string" + }, + "jobLabel": { + "type": "string" + }, + "metricRelabelings": { + "type": "array" + }, + "namespace": { + "type": "string" + }, + "namespaceSelector": { + "properties": {}, + "type": "object" + }, + "relabelings": { + "type": "array" + }, + "scrapeTimeout": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "namespaceOverride": { + "type": "string" + }, + "nodeSelector": { + "properties": {}, + "type": "object" + }, + "persistence": { + "properties": { + "accessMode": { + "type": "string" + }, + "annotations": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "existingClaim": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "size": { + "type": "string" + }, + "storageClass": { + "type": "string" + }, + "subPath": { + "type": "string" + }, + "volumeName": { + "type": "string" + } + }, + "type": "object" + }, + "podDisruptionBudget": { + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "maxUnavailable": { + "minimum": 0, + "type": [ + "string", + "integer", + "null" + ] + }, + "minAvailable": { + "minimum": 0, + "type": [ + "string", + "integer", + "null" + ] + } + }, + "type": "object" + }, + "podSecurityContext": { + "properties": { + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "runAsUser": { + "type": "integer" + } + }, + "type": "object" + }, + "podSecurityPolicy": { + "properties": { + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "ports": { + "properties": { + "metrics": { + "properties": { + "expose": { + "properties": { + "default": { + "type": "boolean" + } + }, + "type": "object" + }, + "exposedPort": { + "type": "integer" + }, + "port": { + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "type": "object" + }, + "traefik": { + "properties": { + "expose": { + "properties": { + "default": { + "type": "boolean" + } + }, + "type": "object" + }, + "exposedPort": { + "type": "integer" + }, + "hostIP": { + "type": [ + "string", + "null" + ] + }, + "hostPort": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "port": { + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "type": "object" + }, + "web": { + "properties": { + "expose": { + "properties": { + "default": { + "type": "boolean" + } + }, + "type": "object" + }, + "exposedPort": { + "type": "integer" + }, + "forwardedHeaders": { + "properties": { + "insecure": { + "type": "boolean" + }, + "trustedIPs": { + "type": "array" + } + }, + "type": "object" + }, + "nodePort": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "port": { + "type": "integer" + }, + "protocol": { + "type": "string" + }, + "proxyProtocol": { + "properties": { + "insecure": { + "type": "boolean" + }, + "trustedIPs": { + "type": "array" + } + }, + "type": "object" + }, + "redirectTo": { + "properties": {}, + "type": "object" + }, + "targetPort": { + "minimum": 0, + "type": [ + "string", + "integer", + "null" + ] + }, + "transport": { + "properties": { + "keepAliveMaxRequests": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "keepAliveMaxTime": { + "type": [ + "string", + "integer", + "null" + ] + }, + "lifeCycle": { + "properties": { + "graceTimeOut": { + "type": [ + "string", + "integer", + "null" + ] + }, + "requestAcceptGraceTimeout": { + "type": [ + "string", + "integer", + "null" + ] + } + }, + "type": "object" + }, + "respondingTimeouts": { + "properties": { + "idleTimeout": { + "type": [ + "string", + "integer", + "null" + ] + }, + "readTimeout": { + "type": [ + "string", + "integer", + "null" + ] + }, + "writeTimeout": { + "type": [ + "string", + "integer", + "null" + ] + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "websecure": { + "properties": { + "allowACMEByPass": { + "type": "boolean" + }, + "appProtocol": { + "type": [ + "string", + "null" + ] + }, + "containerPort": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "expose": { + "properties": { + "default": { + "type": "boolean" + } + }, + "type": "object" + }, + "exposedPort": { + "type": "integer" + }, + "forwardedHeaders": { + "properties": { + "insecure": { + "type": "boolean" + }, + "trustedIPs": { + "type": "array" + } + }, + "type": "object" + }, + "hostPort": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "http3": { + "properties": { + "advertisedPort": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "enabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "middlewares": { + "type": "array" + }, + "nodePort": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "port": { + "type": "integer" + }, + "protocol": { + "type": "string" + }, + "proxyProtocol": { + "properties": { + "insecure": { + "type": "boolean" + }, + "trustedIPs": { + "type": "array" + } + }, + "type": "object" + }, + "targetPort": { + "minimum": 0, + "type": [ + "string", + "integer", + "null" + ] + }, + "tls": { + "properties": { + "certResolver": { + "type": "string" + }, + "domains": { + "type": "array" + }, + "enabled": { + "type": "boolean" + }, + "options": { + "type": "string" + } + }, + "type": "object" + }, + "transport": { + "properties": { + "keepAliveMaxRequests": { + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "keepAliveMaxTime": { + "type": [ + "string", + "integer", + "null" + ] + }, + "lifeCycle": { + "properties": { + "graceTimeOut": { + "type": [ + "string", + "integer", + "null" + ] + }, + "requestAcceptGraceTimeout": { + "type": [ + "string", + "integer", + "null" + ] + } + }, + "type": "object" + }, + "respondingTimeouts": { + "properties": { + "idleTimeout": { + "type": [ + "string", + "integer", + "null" + ] + }, + "readTimeout": { + "type": [ + "string", + "integer", + "null" + ] + }, + "writeTimeout": { + "type": [ + "string", + "integer", + "null" + ] + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "priorityClassName": { + "type": "string" + }, + "providers": { + "additionalProperties": false, + "properties": { + "file": { + "properties": { + "content": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "watch": { + "type": "boolean" + } + }, + "type": "object" + }, + "kubernetesCRD": { + "properties": { + "allowCrossNamespace": { + "type": "boolean" + }, + "allowEmptyServices": { + "type": "boolean" + }, + "allowExternalNameServices": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "ingressClass": { + "type": "string" + }, + "namespaces": { + "type": "array" + }, + "nativeLBByDefault": { + "type": "boolean" + } + }, + "type": "object" + }, + "kubernetesGateway": { + "properties": { + "enabled": { + "type": "boolean" + }, + "experimentalChannel": { + "type": "boolean" + }, + "labelselector": { + "type": "string" + }, + "namespaces": { + "type": "array" + }, + "statusAddress": { + "properties": { + "hostname": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "service": { + "properties": { + "name": { + "type": "string" + }, + "namespace": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "kubernetesIngress": { + "properties": { + "allowEmptyServices": { + "type": "boolean" + }, + "allowExternalNameServices": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "ingressClass": { + "type": [ + "string", + "null" + ] + }, + "namespaces": { + "type": "array" + }, + "nativeLBByDefault": { + "type": "boolean" + }, + "publishedService": { + "properties": { + "enabled": { + "type": "boolean" + }, + "pathOverride": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "rbac": { + "additionalProperties": false, + "properties": { + "aggregateTo": { + "type": "array" + }, + "enabled": { + "type": "boolean" + }, + "namespaced": { + "type": "boolean" + }, + "secretResourceNames": { + "type": "array" + } + }, + "type": "object" + }, + "readinessProbe": { + "additionalProperties": false, + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + }, + "type": "object" + }, + "resources": { + "properties": {}, + "type": "object" + }, + "securityContext": { + "properties": { + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "capabilities": { + "properties": { + "drop": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + } + }, + "type": "object" + }, + "service": { + "properties": { + "additionalServices": { + "properties": {}, + "type": "object" + }, + "annotations": { + "properties": {}, + "type": "object" + }, + "annotationsTCP": { + "properties": {}, + "type": "object" + }, + "annotationsUDP": { + "properties": {}, + "type": "object" + }, + "enabled": { + "type": "boolean" + }, + "externalIPs": { + "type": "array" + }, + "labels": { + "properties": {}, + "type": "object" + }, + "loadBalancerSourceRanges": { + "type": "array" + }, + "single": { + "type": "boolean" + }, + "spec": { + "properties": {}, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "serviceAccount": { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "serviceAccountAnnotations": { + "properties": {}, + "type": "object" + }, + "startupProbe": { + "properties": {}, + "type": "object" + }, + "tlsOptions": { + "properties": {}, + "type": "object" + }, + "tlsStore": { + "properties": {}, + "type": "object" + }, + "tolerations": { + "type": "array" + }, + "topologySpreadConstraints": { + "type": "array" + }, + "tracing": { + "additionalProperties": false, + "properties": { + "addInternals": { + "type": "boolean" + }, + "otlp": { + "properties": { + "enabled": { + "type": "boolean" + }, + "grpc": { + "properties": { + "enabled": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "insecure": { + "type": "boolean" + }, + "tls": { + "properties": { + "ca": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "insecureSkipVerify": { + "type": "boolean" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "http": { + "properties": { + "enabled": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "headers": { + "properties": {}, + "type": "object" + }, + "tls": { + "properties": { + "ca": { + "type": "string" + }, + "cert": { + "type": "string" + }, + "insecureSkipVerify": { + "type": "boolean" + }, + "key": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "updateStrategy": { + "additionalProperties": false, + "properties": { + "rollingUpdate": { + "properties": { + "maxSurge": { + "type": [ + "integer", + "string", + "null" + ] + }, + "maxUnavailable": { + "type": [ + "integer", + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "volumes": { + "type": "array" + } + }, + "title": "Traefik Proxy Helm Chart", + "type": "object" +} diff --git a/charts/traefik/traefik/values.yaml b/charts/traefik/traefik/values.yaml index 83b6d98..be89b00 100644 --- a/charts/traefik/traefik/values.yaml +++ b/charts/traefik/traefik/values.yaml @@ -2,13 +2,13 @@ # This is a YAML-formatted file. # Declare variables to be passed into templates -image: +image: # @schema additionalProperties: false # -- Traefik image host registry registry: docker.io # -- Traefik image repository repository: traefik # -- defaults to appVersion - tag: + tag: # @schema type:[string, null] # -- Traefik image pull policy pullPolicy: IfNotPresent @@ -23,27 +23,27 @@ deployment: # -- Number of pods of the deployment (only applies when kind == Deployment) replicas: 1 # -- Number of old history to retain to allow rollback (If not set, default Kubernetes value is set to 10) - # revisionHistoryLimit: 1 + revisionHistoryLimit: # @schema type:[integer, null];minimum:0 # -- Amount of time (in seconds) before Kubernetes will send the SIGKILL signal if Traefik does not shut down terminationGracePeriodSeconds: 60 # -- The minimum number of seconds Traefik needs to be up and running before the DaemonSet/Deployment controller considers it available minReadySeconds: 0 - ## Override the liveness/readiness port. This is useful to integrate traefik + ## -- Override the liveness/readiness port. This is useful to integrate traefik ## with an external Load Balancer that performs healthchecks. ## Default: ports.traefik.port - # healthchecksPort: 9000 - ## Override the liveness/readiness host. Useful for getting ping to respond on non-default entryPoint. + healthchecksPort: # @schema type:[integer, null];minimum:0 + ## -- Override the liveness/readiness host. Useful for getting ping to respond on non-default entryPoint. ## Default: ports.traefik.hostIP if set, otherwise Pod IP - # healthchecksHost: localhost - ## Override the liveness/readiness scheme. Useful for getting ping to + healthchecksHost: "" + ## -- Override the liveness/readiness scheme. Useful for getting ping to ## respond on websecure entryPoint. - # healthchecksScheme: HTTPS - ## Override the readiness path. + healthchecksScheme: # @schema enum:[HTTP, HTTPS, null]; type:[string, null]; default: HTTP + ## -- Override the readiness path. ## Default: /ping - # readinessPath: /ping - # Override the liveness path. + readinessPath: "" + # -- Override the liveness path. # Default: /ping - # livenessPath: /ping + livenessPath: "" # -- Additional deployment annotations (e.g. for jaeger-operator sidecar injection) annotations: {} # -- Additional deployment labels (e.g. for filtering deployment by custom labels) @@ -80,7 +80,7 @@ deployment: # -- Use process namespace sharing shareProcessNamespace: false # -- Custom pod DNS policy. Apply if `hostNetwork: true` - # dnsPolicy: ClusterFirstWithHostNet + dnsPolicy: "" # -- Custom pod [DNS config](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#poddnsconfig-v1-core) dnsConfig: {} # -- Custom [host aliases](https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/) @@ -95,28 +95,28 @@ deployment: # postStart: # httpGet: # path: /ping - # port: 9000 + # port: 8080 # host: localhost # scheme: HTTP # -- Set a runtimeClassName on pod - runtimeClassName: + runtimeClassName: "" # -- [Pod Disruption Budget](https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/pod-disruption-budget-v1/) -podDisruptionBudget: - enabled: - maxUnavailable: - minAvailable: +podDisruptionBudget: # @schema additionalProperties: false + enabled: false + maxUnavailable: # @schema type:[string, integer, null];minimum:0 + minAvailable: # @schema type:[string, integer, null];minimum:0 # -- Create a default IngressClass for Traefik -ingressClass: +ingressClass: # @schema additionalProperties: false enabled: true isDefaultClass: true - # name: my-custom-class + name: "" -core: +core: # @schema additionalProperties: false # -- Can be used to use globally v2 router syntax # See https://doc.traefik.io/traefik/v3.0/migration/v2-to-v3/#new-v3-syntax-notable-changes - defaultRuleSyntax: + defaultRuleSyntax: "" # Traefik experimental features experimental: @@ -133,11 +133,13 @@ gateway: # -- When providers.kubernetesGateway.enabled, deploy a default gateway enabled: true # -- Set a custom name to gateway - name: + name: "" # -- By default, Gateway is created in the same `Namespace` than Traefik. - namespace: + namespace: "" # -- Additional gateway annotations (e.g. for cert-manager.io/issuer) - annotations: + annotations: {} + # -- [Infrastructure](https://kubernetes.io/blog/2023/11/28/gateway-api-ga/#gateway-infrastructure-labels) + infrastructure: {} # -- Define listeners listeners: web: @@ -145,33 +147,35 @@ gateway: # The port must match a port declared in ports section. port: 8000 # -- Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) - hostname: + hostname: "" # Specify expected protocol on this listener. See [ProtocolType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ProtocolType) protocol: HTTP # -- Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces - namespacePolicy: - websecure: - # -- Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. - # The port must match a port declared in ports section. - port: 8443 - # -- Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) - hostname: - # Specify expected protocol on this listener See [ProtocolType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ProtocolType) - protocol: HTTPS - # -- Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces) - namespacePolicy: - # -- Add certificates for TLS or HTTPS protocols. See [GatewayTLSConfig](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.GatewayTLSConfig) - certificateRefs: - # -- TLS behavior for the TLS session initiated by the client. See [TLSModeType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.TLSModeType). - mode: + namespacePolicy: # @schema type:[string, null] + # websecure listener is disabled by default because certificateRefs needs to be added, + # or you may specify TLS protocol with Passthrough mode and add "--providers.kubernetesGateway.experimentalChannel=true" in additionalArguments section. + # websecure: + # # -- Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules. + # # The port must match a port declared in ports section. + # port: 8443 + # # -- Optional hostname. See [Hostname](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Hostname) + # hostname: + # # Specify expected protocol on this listener See [ProtocolType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.ProtocolType) + # protocol: HTTPS + # # -- Routes are restricted to namespace of the gateway [by default](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.FromNamespaces) + # namespacePolicy: + # # -- Add certificates for TLS or HTTPS protocols. See [GatewayTLSConfig](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io%2fv1.GatewayTLSConfig) + # certificateRefs: + # # -- TLS behavior for the TLS session initiated by the client. See [TLSModeType](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.TLSModeType). + # mode: -gatewayClass: +gatewayClass: # @schema additionalProperties: false # -- When providers.kubernetesGateway.enabled and gateway.enabled, deploy a default gatewayClass enabled: true # -- Set a custom name to GatewayClass - name: + name: "" # -- Additional gatewayClass labels (e.g. for filtering gateway objects by custom labels) - labels: + labels: {} ingressRoute: dashboard: @@ -216,14 +220,14 @@ ingressRoute: # -- TLS options (e.g. secret containing certificate) tls: {} -updateStrategy: - # -- Customize updateStrategy: RollingUpdate or OnDelete +updateStrategy: # @schema additionalProperties: false + # -- Customize updateStrategy of Deployment or DaemonSet type: RollingUpdate rollingUpdate: - maxUnavailable: 0 - maxSurge: 1 + maxUnavailable: 0 # @schema type:[integer, string, null] + maxSurge: 1 # @schema type:[integer, string, null] -readinessProbe: +readinessProbe: # @schema additionalProperties: false # -- The number of consecutive failures allowed before considering the probe as failed. failureThreshold: 1 # -- The number of seconds to wait before starting the first probe. @@ -234,7 +238,7 @@ readinessProbe: successThreshold: 1 # -- The number of seconds to wait for a probe response before considering it as failed. timeoutSeconds: 2 -livenessProbe: +livenessProbe: # @schema additionalProperties: false # -- The number of consecutive failures allowed before considering the probe as failed. failureThreshold: 3 # -- The number of seconds to wait before starting the first probe. @@ -247,9 +251,9 @@ livenessProbe: timeoutSeconds: 2 # -- Define [Startup Probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-startup-probes) -startupProbe: +startupProbe: {} -providers: +providers: # @schema additionalProperties: false kubernetesCRD: # -- Load Kubernetes IngressRoute provider enabled: true @@ -258,14 +262,14 @@ providers: # -- Allows to reference ExternalName services in IngressRoute allowExternalNameServices: false # -- Allows to return 503 when there is no endpoints available - allowEmptyServices: false + allowEmptyServices: true # -- When the parameter is set, only resources containing an annotation with the same value are processed. Otherwise, resources missing the annotation, having an empty value, or the value traefik are processed. It will also set required annotation on Dashboard and Healthcheck IngressRoute when enabled. - ingressClass: + ingressClass: "" # labelSelector: environment=production,method=traefik # -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. namespaces: [] # -- Defines whether to use Native Kubernetes load-balancing mode by default. - nativeLBByDefault: + nativeLBByDefault: false kubernetesIngress: # -- Load Kubernetes Ingress provider @@ -273,24 +277,21 @@ providers: # -- Allows to reference ExternalName services in Ingress allowExternalNameServices: false # -- Allows to return 503 when there is no endpoints available - allowEmptyServices: false + allowEmptyServices: true # -- When ingressClass is set, only Ingresses containing an annotation with the same value are processed. Otherwise, Ingresses missing the annotation, having an empty value, or the value traefik are processed. - ingressClass: + ingressClass: # @schema type:[string, null] # labelSelector: environment=production,method=traefik # -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. namespaces: [] - # - "default" - # Disable cluster IngressClass Lookup - Requires Traefik V3. - # When combined with rbac.namespaced: true, ClusterRole will not be created and ingresses must use kubernetes.io/ingress.class annotation instead of spec.ingressClassName. - disableIngressClassLookup: false # IP used for Kubernetes Ingress endpoints publishedService: - enabled: false - # Published Kubernetes Service to copy status from. Format: namespace/servicename - # By default this Traefik service - # pathOverride: "" + # -- Enable [publishedService](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#publishedservice) + enabled: true + # -- Override path of Kubernetes Service used to copy status from. Format: namespace/servicename. + # Default to Service deployed with this Chart. + pathOverride: "" # -- Defines whether to use Native Kubernetes load-balancing mode by default. - nativeLBByDefault: + nativeLBByDefault: false kubernetesGateway: # -- Enable Traefik Gateway provider for Gateway API @@ -301,7 +302,16 @@ providers: # -- Array of namespaces to watch. If left empty, Traefik watches all namespaces. namespaces: [] # -- A label selector can be defined to filter on specific GatewayClass objects only. - labelselector: + labelselector: "" + statusAddress: + # -- This IP will get copied to the Gateway status.addresses, and currently only supports one IP value (IPv4 or IPv6). + ip: "" + # -- This Hostname will get copied to the Gateway status.addresses. + hostname: "" + # -- The Kubernetes service to copy status addresses from. When using third parties tools like External-DNS, this option can be used to copy the service loadbalancer.status (containing the service's endpoints IPs) to the gateways. Default to Service of this Chart. + service: + name: "{{ (include \"traefik.fullname\" .) }}" + namespace: "{{ .Release.Namespace }}" file: # -- Create a file provider @@ -309,7 +319,7 @@ providers: # -- Allows Traefik to automatically watch for file changes watch: true # -- File content (YAML format, go template supported) (see https://doc.traefik.io/traefik/providers/file/) - content: + content: "" # -- Add volumes to the traefik pod. The volume name will be passed to tpl. # This can be used to mount a cert pair or a configmap that holds a config.toml file. @@ -335,90 +345,91 @@ additionalVolumeMounts: [] logs: general: # -- Set [logs format](https://doc.traefik.io/traefik/observability/logs/#format) - # @default common - format: + format: # @schema enum:["common", "json", null]; type:[string, null]; default: "common" # By default, the level is set to INFO. - # -- Alternative logging levels are DEBUG, PANIC, FATAL, ERROR, WARN, and INFO. - level: INFO - # - # filePath: "/var/log/traefik/traefik.log - # noColor: true + # -- Alternative logging levels are TRACE, DEBUG, INFO, WARN, ERROR, FATAL, and PANIC. + level: "INFO" # @schema enum:[TRACE,DEBUG,INFO,WARN,ERROR,FATAL,PANIC]; default: "INFO" + # -- To write the logs into a log file, use the filePath option. + filePath: "" + # -- When set to true and format is common, it disables the colorized output. + noColor: false access: # -- To enable access logs enabled: false # -- Set [access log format](https://doc.traefik.io/traefik/observability/access-logs/#format) - format: + format: # @schema enum:["common", "json", null]; type:[string, null]; default: "common" # filePath: "/var/log/traefik/access.log # -- Set [bufferingSize](https://doc.traefik.io/traefik/observability/access-logs/#bufferingsize) - bufferingSize: + bufferingSize: # @schema type:[integer, null] # -- Set [filtering](https://docs.traefik.io/observability/access-logs/#filtering) - filters: {} - # statuscodes: "200,300-302" - # retryattempts: true - # minduration: 10ms + filters: # @schema additionalProperties: false + # -- Set statusCodes, to limit the access logs to requests with a status codes in the specified range + statuscodes: "" + # -- Set retryAttempts, to keep the access logs when at least one retry has happened + retryattempts: false + # -- Set minDuration, to keep access logs when requests take longer than the specified duration + minduration: "" # -- Enables accessLogs for internal resources. Default: false. - addInternals: + addInternals: false fields: general: - # -- Available modes: keep, drop, redact. - defaultmode: keep + # -- Set default mode for fields.names + defaultmode: keep # @schema enum:[keep, drop, redact]; default: keep # -- Names of the fields to limit. names: {} - ## Examples: - # ClientUsername: drop # -- [Limit logged fields or headers](https://doc.traefik.io/traefik/observability/access-logs/#limiting-the-fieldsincluding-headers) headers: - # -- Available modes: keep, drop, redact. - defaultmode: drop + # -- Set default mode for fields.headers + defaultmode: drop # @schema enum:[keep, drop, redact]; default: drop names: {} metrics: ## -- Enable metrics for internal resources. Default: false - addInternals: + addInternals: false ## -- Prometheus is enabled by default. ## -- It can be disabled by setting "prometheus: null" prometheus: # -- Entry point used to expose metrics. entryPoint: metrics - ## Enable metrics on entry points. Default=true - # addEntryPointsLabels: false - ## Enable metrics on routers. Default=false - # addRoutersLabels: true - ## Enable metrics on services. Default=true - # addServicesLabels: false + ## Enable metrics on entry points. Default: true + addEntryPointsLabels: # @schema type:[boolean, null] + ## Enable metrics on routers. Default: false + addRoutersLabels: # @schema type:[boolean, null] + ## Enable metrics on services. Default: true + addServicesLabels: # @schema type:[boolean, null] ## Buckets for latency metrics. Default="0.1,0.3,1.2,5.0" - # buckets: "0.5,1.0,2.5" + buckets: "" ## When manualRouting is true, it disables the default internal router in ## order to allow creating a custom router for prometheus@internal service. - # manualRouting: true + manualRouting: false service: # -- Create a dedicated metrics service to use with ServiceMonitor - enabled: - labels: - annotations: + enabled: false + labels: {} + annotations: {} # -- When set to true, it won't check if Prometheus Operator CRDs are deployed - disableAPICheck: + disableAPICheck: # @schema type:[boolean, null] serviceMonitor: # -- Enable optional CR for Prometheus Operator. See EXAMPLES.md for more details. enabled: false - metricRelabelings: - relabelings: - jobLabel: - interval: - honorLabels: - scrapeTimeout: - honorTimestamps: - enableHttp2: - followRedirects: - additionalLabels: - namespace: - namespaceSelector: + metricRelabelings: [] + relabelings: [] + jobLabel: "" + interval: "" + honorLabels: false + scrapeTimeout: "" + honorTimestamps: false + enableHttp2: false + followRedirects: false + additionalLabels: {} + namespace: "" + namespaceSelector: {} prometheusRule: # -- Enable optional CR for Prometheus Operator. See EXAMPLES.md for more details. enabled: false - additionalLabels: - namespace: + additionalLabels: {} + namespace: "" # datadog: # ## Address instructs exporter to send metrics to datadog-agent at this address. @@ -471,55 +482,55 @@ metrics: # -- Set to true in order to enable the OpenTelemetry metrics enabled: false # -- Enable metrics on entry points. Default: true - addEntryPointsLabels: + addEntryPointsLabels: # @schema type:[boolean, null] # -- Enable metrics on routers. Default: false - addRoutersLabels: + addRoutersLabels: # @schema type:[boolean, null] # -- Enable metrics on services. Default: true - addServicesLabels: + addServicesLabels: # @schema type:[boolean, null] # -- Explicit boundaries for Histogram data points. Default: [.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10] - explicitBoundaries: + explicitBoundaries: [] # -- Interval at which metrics are sent to the OpenTelemetry Collector. Default: 10s - pushInterval: + pushInterval: "" http: # -- Set to true in order to send metrics to the OpenTelemetry Collector using HTTP. enabled: false # -- Format: ://:. Default: http://localhost:4318/v1/metrics - endpoint: + endpoint: "" # -- Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. - headers: + headers: {} ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. tls: # -- The path to the certificate authority, it defaults to the system bundle. - ca: + ca: "" # -- The path to the public certificate. When using this option, setting the key option is required. - cert: + cert: "" # -- The path to the private key. When using this option, setting the cert option is required. - key: + key: "" # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. - insecureSkipVerify: + insecureSkipVerify: # @schema type:[boolean, null] grpc: # -- Set to true in order to send metrics to the OpenTelemetry Collector using gRPC enabled: false # -- Format: ://:. Default: http://localhost:4318/v1/metrics - endpoint: + endpoint: "" # -- Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. - insecure: + insecure: false ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. tls: # -- The path to the certificate authority, it defaults to the system bundle. - ca: + ca: "" # -- The path to the public certificate. When using this option, setting the key option is required. - cert: + cert: "" # -- The path to the private key. When using this option, setting the cert option is required. - key: + key: "" # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. - insecureSkipVerify: + insecureSkipVerify: false ## Tracing # -- https://doc.traefik.io/traefik/observability/tracing/overview/ -tracing: +tracing: # @schema additionalProperties: false # -- Enables tracing for internal resources. Default: false. - addInternals: + addInternals: false otlp: # -- See https://doc.traefik.io/traefik/v3.0/observability/tracing/opentelemetry/ enabled: false @@ -527,36 +538,36 @@ tracing: # -- Set to true in order to send metrics to the OpenTelemetry Collector using HTTP. enabled: false # -- Format: ://:. Default: http://localhost:4318/v1/metrics - endpoint: + endpoint: "" # -- Additional headers sent with metrics by the reporter to the OpenTelemetry Collector. - headers: + headers: {} ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. tls: # -- The path to the certificate authority, it defaults to the system bundle. - ca: + ca: "" # -- The path to the public certificate. When using this option, setting the key option is required. - cert: + cert: "" # -- The path to the private key. When using this option, setting the cert option is required. - key: + key: "" # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. - insecureSkipVerify: + insecureSkipVerify: false grpc: # -- Set to true in order to send metrics to the OpenTelemetry Collector using gRPC enabled: false # -- Format: ://:. Default: http://localhost:4318/v1/metrics - endpoint: + endpoint: "" # -- Allows reporter to send metrics to the OpenTelemetry Collector without using a secured protocol. - insecure: + insecure: false ## Defines the TLS configuration used by the reporter to send metrics to the OpenTelemetry Collector. tls: # -- The path to the certificate authority, it defaults to the system bundle. - ca: + ca: "" # -- The path to the public certificate. When using this option, setting the key option is required. - cert: + cert: "" # -- The path to the private key. When using this option, setting the cert option is required. - key: + key: "" # -- When set to true, the TLS connection accepts any certificate presented by the server regardless of the hostnames it covers. - insecureSkipVerify: + insecureSkipVerify: false # -- Global command arguments to be passed to all traefik's pods globalArguments: @@ -570,32 +581,23 @@ additionalArguments: [] # - "--providers.kubernetesingress.ingressclass=traefik-internal" # - "--log.level=DEBUG" -# -- Environment variables to be passed to Traefik's binary +# -- Additional Environment variables to be passed to Traefik's binary # @default -- See _values.yaml_ -env: -- name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name -- name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace +env: [] # -- Environment variables to be passed to Traefik's binary from configMaps or secrets envFrom: [] ports: traefik: - port: 9000 + port: 8080 # -- Use hostPort if set. - # hostPort: 9000 - # + hostPort: # @schema type:[integer, null]; minimum:0 # -- Use hostIP if set. If not set, Kubernetes will default to 0.0.0.0, which # means it's listening on all your interfaces and all your IPs. You may want # to set this value if you need traefik to listen on specific interface # only. - # hostIP: 192.168.100.10 + hostIP: # @schema type:[string, null] # Defines whether the port is exposed if service.type is LoadBalancer or # NodePort. @@ -606,7 +608,7 @@ ports: expose: default: false # -- The exposed port for this service - exposedPort: 9000 + exposedPort: 8080 # -- The port protocol (TCP/UDP) protocol: TCP web: @@ -619,112 +621,93 @@ ports: default: true exposedPort: 80 ## -- Different target traefik port on the cluster, useful for IP type LB - # targetPort: 80 + targetPort: # @schema type:[string, integer, null]; minimum:0 # The port protocol (TCP/UDP) protocol: TCP - # -- Use nodeport if set. This is useful if you have configured Traefik in a - # LoadBalancer. - # nodePort: 32080 + # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) + nodePort: # @schema type:[integer, null]; minimum:0 # Port Redirections # Added in 2.2, you can make permanent redirects via entrypoints. # https://docs.traefik.io/routing/entrypoints/#redirection - # redirectTo: - # port: websecure - # (Optional) - # priority: 10 - # permanent: true - # - # -- Trust forwarded headers information (X-Forwarded-*). - # forwardedHeaders: - # trustedIPs: [] - # insecure: false - # - # -- Enable the Proxy Protocol header parsing for the entry point - # proxyProtocol: - # trustedIPs: [] - # insecure: false - # + redirectTo: {} + forwardedHeaders: + # -- Trust forwarded headers information (X-Forwarded-*). + trustedIPs: [] + insecure: false + proxyProtocol: + # -- Enable the Proxy Protocol header parsing for the entry point + trustedIPs: [] + insecure: false # -- Set transport settings for the entrypoint; see also # https://doc.traefik.io/traefik/routing/entrypoints/#transport transport: respondingTimeouts: - readTimeout: - writeTimeout: - idleTimeout: + readTimeout: # @schema type:[string, integer, null] + writeTimeout: # @schema type:[string, integer, null] + idleTimeout: # @schema type:[string, integer, null] lifeCycle: - requestAcceptGraceTimeout: - graceTimeOut: - keepAliveMaxRequests: - keepAliveMaxTime: + requestAcceptGraceTimeout: # @schema type:[string, integer, null] + graceTimeOut: # @schema type:[string, integer, null] + keepAliveMaxRequests: # @schema type:[integer, null]; minimum:0 + keepAliveMaxTime: # @schema type:[string, integer, null] websecure: ## -- Enable this entrypoint as a default entrypoint. When a service doesn't explicitly set an entrypoint it will only use this entrypoint. # asDefault: true port: 8443 - # hostPort: 8443 - # containerPort: 8443 + hostPort: # @schema type:[integer, null]; minimum:0 + containerPort: # @schema type:[integer, null]; minimum:0 expose: default: true exposedPort: 443 ## -- Different target traefik port on the cluster, useful for IP type LB - # targetPort: 80 + targetPort: # @schema type:[string, integer, null]; minimum:0 ## -- The port protocol (TCP/UDP) protocol: TCP - # nodePort: 32443 - ## -- Specify an application protocol. This may be used as a hint for a Layer 7 load balancer. - # appProtocol: https - # - ## -- Enable HTTP/3 on the entrypoint - ## Enabling it will also enable http3 experimental feature - ## https://doc.traefik.io/traefik/routing/entrypoints/#http3 - ## There are known limitations when trying to listen on same ports for - ## TCP & UDP (Http3). There is a workaround in this chart using dual Service. - ## https://github.com/kubernetes/kubernetes/issues/47249#issuecomment-587960741 + # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport) + nodePort: # @schema type:[integer, null]; minimum:0 + # -- See [upstream documentation](https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol) + appProtocol: # @schema type:[string, null] + # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#allowacmebypass) + allowACMEByPass: false http3: + ## -- Enable HTTP/3 on the entrypoint + ## Enabling it will also enable http3 experimental feature + ## https://doc.traefik.io/traefik/routing/entrypoints/#http3 + ## There are known limitations when trying to listen on same ports for + ## TCP & UDP (Http3). There is a workaround in this chart using dual Service. + ## https://github.com/kubernetes/kubernetes/issues/47249#issuecomment-587960741 enabled: false - # advertisedPort: 4443 - # - # -- Trust forwarded headers information (X-Forwarded-*). - # forwardedHeaders: - # trustedIPs: [] - # insecure: false - # - # -- Enable the Proxy Protocol header parsing for the entry point - # proxyProtocol: - # trustedIPs: [] - # insecure: false - # - # -- Set transport settings for the entrypoint; see also - # https://doc.traefik.io/traefik/routing/entrypoints/#transport + advertisedPort: # @schema type:[integer, null]; minimum:0 + forwardedHeaders: + # -- Trust forwarded headers information (X-Forwarded-*). + trustedIPs: [] + insecure: false + proxyProtocol: + # -- Enable the Proxy Protocol header parsing for the entry point + trustedIPs: [] + insecure: false + # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#transport) transport: respondingTimeouts: - readTimeout: - writeTimeout: - idleTimeout: + readTimeout: # @schema type:[string, integer, null] + writeTimeout: # @schema type:[string, integer, null] + idleTimeout: # @schema type:[string, integer, null] lifeCycle: - requestAcceptGraceTimeout: - graceTimeOut: - keepAliveMaxRequests: - keepAliveMaxTime: - # - ## Set TLS at the entrypoint - ## https://doc.traefik.io/traefik/routing/entrypoints/#tls + requestAcceptGraceTimeout: # @schema type:[string, integer, null] + graceTimeOut: # @schema type:[string, integer, null] + keepAliveMaxRequests: # @schema type:[integer, null]; minimum:0 + keepAliveMaxTime: # @schema type:[string, integer, null] + # -- See [upstream documentation](https://doc.traefik.io/traefik/routing/entrypoints/#tls) tls: enabled: true - # this is the name of a TLSOption definition options: "" certResolver: "" domains: [] - # - main: example.com - # sans: - # - foo.example.com - # - bar.example.com - # # -- One can apply Middlewares on an entrypoint # https://doc.traefik.io/traefik/middlewares/overview/ # https://doc.traefik.io/traefik/routing/entrypoints/#middlewares # -- /!\ It introduces here a link between your static configuration and your dynamic configuration /!\ # It follows the provider naming convention: https://doc.traefik.io/traefik/providers/overview/#provider-namespace - # middlewares: # - namespace-name1@kubernetescrd # - namespace-name2@kubernetescrd middlewares: [] @@ -732,10 +715,6 @@ ports: # -- When using hostNetwork, use another port to avoid conflict with node exporter: # https://github.com/prometheus/prometheus/wiki/Default-port-allocations port: 9100 - # hostPort: 9100 - # Defines whether the port is exposed if service.type is LoadBalancer or - # NodePort. - # # -- You may not want to expose the metrics port on production deployments. # If you want to access it from outside your cluster, # use `kubectl port-forward` or create a secure ingress @@ -808,24 +787,24 @@ autoscaling: persistence: # -- Enable persistence using Persistent Volume Claims - # ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ - # It can be used to store TLS certificates, see `storage` in certResolvers + # ref: http://kubernetes.io/docs/user-guide/persistent-volumes/. + # It can be used to store TLS certificates along with `certificatesResolvers..acme.storage` option enabled: false name: data - # existingClaim: "" + existingClaim: "" accessMode: ReadWriteOnce size: 128Mi - # storageClass: "" - # volumeName: "" + storageClass: "" + volumeName: "" path: /data annotations: {} # -- Only mount a subpath of the Volume into the pod - # subPath: "" + subPath: "" # -- Certificates resolvers configuration. # Ref: https://doc.traefik.io/traefik/https/acme/#certificate-resolvers # See EXAMPLES.md for more details. -certResolvers: {} +certificatesResolvers: {} # -- If hostNetwork is true, runs traefik in the host network namespace # To prevent unschedulabel pods due to port collisions, if hostNetwork=true @@ -834,15 +813,18 @@ certResolvers: {} hostNetwork: false # -- Whether Role Based Access Control objects like roles and rolebindings should be created -rbac: +rbac: # @schema additionalProperties: false enabled: true - # If set to false, installs ClusterRole and ClusterRoleBinding so Traefik can be used across namespaces. - # If set to true, installs Role and RoleBinding instead of ClusterRole/ClusterRoleBinding. Providers will only watch target namespace. - # When combined with providers.kubernetesIngress.disableIngressClassLookup: true and Traefik V3, ClusterRole to watch IngressClass is also disabled. + # When set to true: + # 1. It switches respectively the use of `ClusterRole` and `ClusterRoleBinding` to `Role` and `RoleBinding`. + # 2. It adds `disableIngressClassLookup` on Kubernetes Ingress with Traefik Proxy v3 until v3.1.4 + # 3. It adds `disableClusterScopeResources` on Ingress and CRD (Kubernetes) providers with Traefik Proxy v3.1.2+ + # **NOTE**: `IngressClass`, `NodePortLB` and **Gateway** provider cannot be used with namespaced RBAC. + # See [upstream documentation](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#disableclusterscoperesources) for more details. namespaced: false # Enable user-facing roles # https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles - # aggregateTo: [ "admin" ] + aggregateTo: [] # List of Kubernetes secrets that are accessible for Traefik. If empty, then access is granted to every secret. secretResourceNames: [] @@ -851,7 +833,7 @@ podSecurityPolicy: enabled: false # -- The service account the pods will use to interact with the Kubernetes API -serviceAccount: +serviceAccount: # @schema additionalProperties: false # If set, an existing service account is used # If not set, a service account is created automatically using the fullname template name: "" @@ -885,7 +867,7 @@ topologySpreadConstraints: [] # on nodes where no other traefik pods are scheduled. # - labelSelector: # matchLabels: -# app: '{{ template "traefik.name" . }}' +# app.kubernetes.io/name: '{{ template "traefik.name" . }}' # maxSkew: 1 # topologyKey: kubernetes.io/hostname # whenUnsatisfiable: DoNotSchedule @@ -917,54 +899,53 @@ extraObjects: [] # -- This field override the default Release Namespace for Helm. # It will not affect optional CRDs such as `ServiceMonitor` and `PrometheusRules` -namespaceOverride: +namespaceOverride: "" ## -- This field override the default app.kubernetes.io/instance label for all Objects. -instanceLabelOverride: +instanceLabelOverride: "" # Traefik Hub configuration. See https://doc.traefik.io/traefik-hub/ hub: # -- Name of `Secret` with key 'token' set to a valid license token. # It enables API Gateway. - token: + token: "" apimanagement: # -- Set to true in order to enable API Management. Requires a valid license token. - enabled: + enabled: false admission: # -- WebHook admission server listen address. Default: "0.0.0.0:9943". - listenAddr: + listenAddr: "" # -- Certificate of the WebHook admission server. Default: "hub-agent-cert". - secretName: + secretName: "" - ratelimit: - redis: - # -- Enable Redis Cluster. Default: true. - cluster: - # -- Database used to store information. Default: "0". - database: - # -- Endpoints of the Redis instances to connect to. Default: "". - endpoints: - # -- The username to use when connecting to Redis endpoints. Default: "". - username: - # -- The password to use when connecting to Redis endpoints. Default: "". - password: - sentinel: - # -- Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". - masterset: - # -- Username to use for sentinel authentication (can be different from endpoint username). Default: "". - username: - # -- Password to use for sentinel authentication (can be different from endpoint password). Default: "". - password: - # -- Timeout applied on connection with redis. Default: "0s". - timeout: - tls: - # -- Path to the certificate authority used for the secured connection. - ca: - # -- Path to the public certificate used for the secure connection. - cert: - # -- Path to the private key used for the secure connection. - key: - # -- When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. - insecureSkipVerify: + redis: + # -- Enable Redis Cluster. Default: true. + cluster: # @schema type:[boolean, null] + # -- Database used to store information. Default: "0". + database: # @schema type:[string, null] + # -- Endpoints of the Redis instances to connect to. Default: "". + endpoints: "" + # -- The username to use when connecting to Redis endpoints. Default: "". + username: "" + # -- The password to use when connecting to Redis endpoints. Default: "". + password: "" + sentinel: + # -- Name of the set of main nodes to use for main selection. Required when using Sentinel. Default: "". + masterset: "" + # -- Username to use for sentinel authentication (can be different from endpoint username). Default: "". + username: "" + # -- Password to use for sentinel authentication (can be different from endpoint password). Default: "". + password: "" + # -- Timeout applied on connection with redis. Default: "0s". + timeout: "" + tls: + # -- Path to the certificate authority used for the secured connection. + ca: "" + # -- Path to the public certificate used for the secure connection. + cert: "" + # -- Path to the private key used for the secure connection. + key: "" + # -- When insecureSkipVerify is set to true, the TLS connection accepts any certificate presented by the server. Default: false. + insecureSkipVerify: false # Enable export of errors logs to the platform. Default: true. - sendlogs: + sendlogs: # @schema type:[boolean, null] diff --git a/charts/traefik/values-overrides.yaml b/charts/traefik/values-overrides.yaml index 2fcdec9..5c5ceb9 100644 --- a/charts/traefik/values-overrides.yaml +++ b/charts/traefik/values-overrides.yaml @@ -1,10 +1,16 @@ + +fullnameOverride: traefik + globalArguments: - --global.sendanonymoususage=false + - --api.insecure=true # api.insecure=true is required for the dashboard to be reachable via traefik entrypoint service: enabled: true annotations: - chisel-operator.io/exit-node-name: "traefik-exit-node" + # chisel-operator.io/exit-node-name: "vault-exit-node" + type: ClusterIP # this needs to be LoadBalancer in prod, but here in dev we want ClusterIP + logs: access: enabled: true @@ -13,10 +19,21 @@ logs: level: DEBUG format: json providers: + kubernetesCRD: + enabled: false kubernetesIngress: + enabled: false publishedService: - enabled: true + enabled: false + kubernetesGateway: + enabled: true -ingressRoute: - dashboard: - enabled: true \ No newline at end of file +# ingressRoute: +# dashboard: +# # we disable dashboard via the chart and enable it ourselves in traefik.yaml +# enabled: false +# matchRule: PathPrefix(`/doshboard`) +# # # -- The internal service used for the dashboard ingressRoute +# services: +# - name: dashboard@internal +# kind: TraefikService \ No newline at end of file diff --git a/devbox.json b/devbox.json index 8e9c5f6..64e3454 100644 --- a/devbox.json +++ b/devbox.json @@ -12,7 +12,8 @@ "yt-dlp@latest", "python310@latest", "python310Packages.pip@latest", - "vips@latest" + "vips@latest", + "kubefwd@latest" ], "env": { "DEVBOX_COREPACK_ENABLED": "true", diff --git a/devbox.lock b/devbox.lock index 72cd4cc..174b2ce 100644 --- a/devbox.lock +++ b/devbox.lock @@ -377,6 +377,54 @@ } } }, + "kubefwd@latest": { + "last_modified": "2024-10-13T23:44:06Z", + "resolved": "github:NixOS/nixpkgs/d4f247e89f6e10120f911e2e2d2254a050d0f732#kubefwd", + "source": "devbox-search", + "version": "1.22.5", + "systems": { + "aarch64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/sq746gibrmkw13dlnbn7ybfl5hpdj3gx-kubefwd-1.22.5", + "default": true + } + ], + "store_path": "/nix/store/sq746gibrmkw13dlnbn7ybfl5hpdj3gx-kubefwd-1.22.5" + }, + "aarch64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/yydhb67m0n5pwhfkhmqw50x7bihhpss6-kubefwd-1.22.5", + "default": true + } + ], + "store_path": "/nix/store/yydhb67m0n5pwhfkhmqw50x7bihhpss6-kubefwd-1.22.5" + }, + "x86_64-darwin": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/50xiwkb0lqn680m38w3jagrh4z696y92-kubefwd-1.22.5", + "default": true + } + ], + "store_path": "/nix/store/50xiwkb0lqn680m38w3jagrh4z696y92-kubefwd-1.22.5" + }, + "x86_64-linux": { + "outputs": [ + { + "name": "out", + "path": "/nix/store/hh52q0fm8437y32v3ssih45n770fysaf-kubefwd-1.22.5", + "default": true + } + ], + "store_path": "/nix/store/hh52q0fm8437y32v3ssih45n770fysaf-kubefwd-1.22.5" + } + } + }, "kubernetes-helm@latest": { "last_modified": "2024-07-20T09:11:00Z", "resolved": "github:NixOS/nixpkgs/6e14bbce7bea6c4efd7adfa88a40dac750d80100#kubernetes-helm", @@ -492,7 +540,7 @@ }, "python310@latest": { "last_modified": "2024-07-07T07:43:47Z", - "plugin_version": "0.0.3", + "plugin_version": "0.0.4", "resolved": "github:NixOS/nixpkgs/b60793b86201040d9dee019a05089a9150d08b5b#python310", "source": "devbox-search", "version": "3.10.14", diff --git a/dockerfiles/build.dockerfile b/dockerfiles/factory.dockerfile similarity index 79% rename from dockerfiles/build.dockerfile rename to dockerfiles/factory.dockerfile index 3476bb9..9e1311d 100644 --- a/dockerfiles/build.dockerfile +++ b/dockerfiles/factory.dockerfile @@ -1,7 +1,7 @@ -## d.build.dockerfile +## factory.dockerfile ## -## @futureporn/build is the system component which processes video segments into a VOD. -## Build does tasks such as thumbnail generation, video encoding, file transfers, strapi record creation, etc. +## @futureporn/factory is the system component which processes video segments into a VOD. +## factory does tasks such as thumbnail generation, video encoding, file transfers, strapi record creation, etc. FROM node:20 AS base @@ -15,7 +15,7 @@ ENTRYPOINT ["pnpm"] FROM base AS install WORKDIR /app -RUN mkdir -p /app/services/build && mkdir -p /prod/build +RUN mkdir -p /app/services/factory && mkdir -p /prod/factory ## Copy manfiests, lockfiles, and configs into docker context COPY package.json pnpm-lock.yaml .npmrc . @@ -23,7 +23,7 @@ COPY ./packages/utils/pnpm-lock.yaml ./packages/utils/package.json ./packages/ut COPY ./packages/fetchers/package.json ./packages/fetchers/pnpm-lock.yaml ./packages/fetchers/ COPY ./packages/storage/pnpm-lock.yaml ./packages/storage/package.json ./packages/storage/ COPY ./packages/types/pnpm-lock.yaml ./packages/types/package.json ./packages/types/ -COPY ./services/build/pnpm-lock.yaml ./services/build/package.json ./services/build/ +COPY ./services/factory/pnpm-lock.yaml ./services/factory/package.json ./services/factory/ ## Install npm packages RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch @@ -37,7 +37,7 @@ RUN ls -la /app/packages/utils/node_modules/prevvy/ RUn cat ./packages/utils/package.json COPY ./packages/storage/ ./packages/storage/ COPY ./packages/types/ ./packages/types/ -COPY ./services/build/ ./services/build/ +COPY ./services/factory/ ./services/factory/ # we are grabbing the mp4 files from capture so we can run tests with them COPY ./services/capture/src/fixtures ./services/capture/src/fixtures @@ -49,15 +49,15 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm -r build ## Copy all production code into one place ## `pnpm deploy` copies all dependencies into an isolated node_modules directory inside the target dir ## @see https://pnpm.io/cli/deploy -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm deploy --filter=@futureporn/build --prod /prod/build +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm deploy --filter=@futureporn/factory --prod /prod/factory FROM install AS dev -WORKDIR /app/services/build +WORKDIR /app/services/factory RUN ls -lash CMD ["run", "dev"] FROM base AS prod -COPY --from=build /prod/build . +COPY --from=build /prod/factory . RUN ls -la . CMD ["start"] diff --git a/dockerfiles/strapi.dockerfile b/dockerfiles/strapi.dockerfile deleted file mode 100644 index 5b47918..0000000 --- a/dockerfiles/strapi.dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM node:20 AS strapi -WORKDIR /usr/src/app/ -RUN corepack enable && corepack prepare pnpm@9.6.0 --activate -ENV PNPM_HOME="/pnpm" -ENV PATH="$PNPM_HOME:$PATH" -# ENV NODE_EXTRA_CA_CERTS ${NODE_EXTRA_CA_CERTS} -# COPY ./certs ./certs -# RUN ls -la /usr/src/app/certs -COPY ./services/strapi/package.json ./services/strapi/pnpm-lock.yaml . -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile --prefer-offline -COPY ./services/strapi/ . -# RUN ls -la . -RUN ["pnpm", "run", "build"] -CMD ["pnpm", "run", "develop"] diff --git a/dockerfiles/strapi.dockerfile.full b/dockerfiles/strapi.dockerfile.full deleted file mode 100644 index a852ab7..0000000 --- a/dockerfiles/strapi.dockerfile.full +++ /dev/null @@ -1,58 +0,0 @@ -FROM node:20-alpine3.18 AS base -## Installing libvips-dev for sharp Compatibility -## (only necessary for alpine docker images) -RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev nasm bash vips-dev git -RUN corepack enable && corepack prepare pnpm@9.6.0 --activate -ENV PNPM_HOME="/pnpm" -ENV PATH="$PNPM_HOME:$PATH" -ARG NODE_ENV=development -ENV NODE_ENV=${NODE_ENV} -EXPOSE 1339 -ENTRYPOINT ["pnpm"] - -FROM base AS build -WORKDIR /app -RUN mkdir -p /prod/strapi -COPY pnpm-workspace.yaml pnpm-lock.yaml .npmrc package.json . -COPY ./packages/types ./packages/types -COPY ./packages/strapi ./packages/strapi -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm fetch -# Do I need node-gyp? -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install -g node-gyp --prefer-offline -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --recursive --prefer-offline -RUN pnpm -r build -RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm deploy --filter=strapi /prod/strapi -RUN ls -lah ./ -RUN ls -lah ./packages -RUN ls -lah ./packages/strapi -RUN ls -lah /prod/strapi - - -# FROM base AS build -# RUN mkdir -p /prod/strapi -# WORKDIR /opt/ -# COPY ./packages/strapi/package.json ./packages/strapi/pnpm-lock.yaml ./ -# RUN pnpm fetch -# RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install -g node-gyp -# RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile -# ENV PATH /opt/node_modules/.bin:$PATH -# WORKDIR /opt/app -# COPY ./packages/strapi/. . -# RUN pnpm -r build -# RUN pnpm deploy --filter=strapi /prod/strapi - - - -FROM base AS dev -COPY --from=build /prod/strapi . -CMD ["run", "develop"] - - - -FROM base AS strapi -WORKDIR /opt/app -RUN chown -R node:node /opt/app -USER node -COPY --from=build /prod/strapi . -RUN ls -la . -CMD ["start"] \ No newline at end of file diff --git a/flux/apps/base/drupal/kustomization.yaml b/flux/apps/base/drupal/kustomization.yaml new file mode 100644 index 0000000..7d4eed5 --- /dev/null +++ b/flux/apps/base/drupal/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: futureporn +resources: + - release.yaml diff --git a/flux/apps/base/drupal/release.yaml b/flux/apps/base/drupal/release.yaml new file mode 100644 index 0000000..f0cb671 --- /dev/null +++ b/flux/apps/base/drupal/release.yaml @@ -0,0 +1,25 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + namespace: futureporn + name: drupal +spec: + releaseName: drupal + chart: + spec: + version: "20.0.10" + chart: drupal + sourceRef: + kind: HelmRepository + name: bitnami + interval: 5m + install: + remediation: + retries: -1 + # Default values + # https://artifacthub.io/packages/helm/bitnami/drupal?modal=values + values: + fullnameOverride: drupal + mariadb: + enabled: true + allowEmptyPassword: true diff --git a/flux/apps/base/mariadb/kustomization.yaml b/flux/apps/base/mariadb/kustomization.yaml new file mode 100644 index 0000000..7d4eed5 --- /dev/null +++ b/flux/apps/base/mariadb/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: futureporn +resources: + - release.yaml diff --git a/flux/apps/base/mariadb/release.yaml b/flux/apps/base/mariadb/release.yaml new file mode 100644 index 0000000..7220dc6 --- /dev/null +++ b/flux/apps/base/mariadb/release.yaml @@ -0,0 +1,23 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + namespace: futureporn + name: mariadb +spec: + releaseName: mariadb + chart: + spec: + version: "19.0.1" + chart: mariadb + sourceRef: + kind: HelmRepository + name: bitnami + interval: 5m + install: + remediation: + retries: -1 + # Default values + # https://artifacthub.io/packages/helm/bitnami/mariadb?modal=values + values: + fullnameOverride: mariadb-via-kustomize + diff --git a/flux/apps/development/README.md b/flux/apps/development/README.md new file mode 100644 index 0000000..7275cc3 --- /dev/null +++ b/flux/apps/development/README.md @@ -0,0 +1,10 @@ +Right now, we use Tilt for dev, flux for prod. + +It would be very nice to have only one way of deploying things regardless of the environment (development|staging|production) + +however, this doesn't work because fp Helm chart is pulled from git rather than a folder relative to the flux dir. (kind: GitRepository) + +We are constrained to CrossNamespaceObjectReference kind list + +https://fluxcd.io/flux/components/helm/api/v2/#helm.toolkit.fluxcd.io/v2.CrossNamespaceObjectReference +https://github.com/fluxcd/helm-controller/blob/c8ae4b6ad225d37b19bacb634db784d6096908ac/api/v2beta2/reference_types.go#L53 \ No newline at end of file diff --git a/flux/apps/development/fp-values.yaml b/flux/apps/development/fp-values.yaml new file mode 100644 index 0000000..2379d25 --- /dev/null +++ b/flux/apps/development/fp-values.yaml @@ -0,0 +1,20 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: fp + namespace: futureporn +spec: + values: + next: + hostname: next.fp.sbtp.xyz + scout: + cdnBucketUrl: https://fp-dev.b-cdn.net + s3BucketName: fp-dev + imageName: gitea.futureporn.net/futureporn/scout:latest + strapi: + url: https://strapi.sbtp.xyz + hostname: strapi.fp.sbtp.xyz + imageName: gitea.futureporn.net/futureporn/strapi:latest + managedBy: Helm + certManager: + issuer: letsencrypt-staging \ No newline at end of file diff --git a/flux/apps/development/kustomization.yaml b/flux/apps/development/kustomization.yaml new file mode 100644 index 0000000..7486b38 --- /dev/null +++ b/flux/apps/development/kustomization.yaml @@ -0,0 +1,19 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: futureporn +resources: + - ../base/bitnami + - ../base/podinfo + - ../base/postgresql + - ../base/mariadb + - ../base/drupal + # - ../base/fp +patches: + # - path: podinfo-values.yaml + # target: + # kind: HelmRelease + # name: podinfo + - path: fp-values.yaml + target: + kind: HelmRelease + name: fp diff --git a/flux/apps/development/podinfo-values.yaml b/flux/apps/development/podinfo-values.yaml new file mode 100644 index 0000000..174cc82 --- /dev/null +++ b/flux/apps/development/podinfo-values.yaml @@ -0,0 +1,19 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: podinfo + namespace: futureporn +spec: + chart: + spec: + version: ">=1.0.0-alpha" + test: + enable: false + values: + fullnameOverride: mariadb-taco + ingress: + hosts: + - host: podinfo.fp.sbtp.xyz + paths: + - path: / + pathType: ImplementationSpecific diff --git a/package.json b/package.json index c098c2c..511125b 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,7 @@ "main": "index.js", "scripts": { "test": "act -W ./.gitea/workflows", - "clean": "rm -rf node_modules && rm -rf pnpm-lock.yaml", - "dev": "tilt up" + "clean": "rm -rf node_modules && rm -rf pnpm-lock.yaml" }, "keywords": [], "author": "@CJ_Clippy", diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 7e8fc7c..5ebe31f 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -7,6 +7,12 @@ export type ProcessingState = 'processing' export type WaitingState = 'pending_recording' export type Status = Partial + +export interface IPatron { + username: string; + vanityLink?: string; +} + // @see https://www.baeldung.com/rest-api-error-handling-best-practices export interface GenericApiResponse { error: string|null; diff --git a/packages/types/tsconfig.json b/packages/types/tsconfig.json index 6619133..a0928d2 100644 --- a/packages/types/tsconfig.json +++ b/packages/types/tsconfig.json @@ -28,7 +28,7 @@ }, // Include the necessary files for your project "files": [ - "src/index.ts" + "src/index.ts", ], "exclude": [ "node_modules" diff --git a/packages/utils/src/image.spec.ts b/packages/utils/src/image.spec.ts index 6d22a36..b8ce774 100644 --- a/packages/utils/src/image.spec.ts +++ b/packages/utils/src/image.spec.ts @@ -30,7 +30,7 @@ describe('image', function () { describe('getStoryboard', function () { this.timeout(1000*60*15) it('should accept a URL and return a path to image on disk', async function () { - const url = 'https://futureporn-b2.b-cdn.net/projektmelody-chaturbate-2024-09-27.mp4' + const url = 'https://futureporn-b2.b-cdn.net/projektmelody-chaturbate-2024-10-31.mp4' const imagePath = await getStoryboard(url) expect(imagePath).to.match(/\.png/) }) diff --git a/scripts/data-migrations/2024-10-07-from-strapi-to-postgrest.sql b/scripts/data-migrations/2024-10-07-from-strapi-to-postgrest.sql new file mode 100644 index 0000000..5c122d1 --- /dev/null +++ b/scripts/data-migrations/2024-10-07-from-strapi-to-postgrest.sql @@ -0,0 +1,350 @@ +SELECT dblink_connect( + 'old_db_conn', + 'dbname=futureporn_strapi_old user=postgres passfile=/tmp/.pgpass' +); + + +-- Temporary schema changes that I don't want to save in @futureporn/migrations +-- 1. ADD api.s3_files.id_old +-- 2. ADD api.vods.id_old +-- 3. ADD api.vods_s3_join.[id_old,vod_id_old,b_2_file_id_old] +-- 4. ADD api.vtubers.id_old +-- 5. ADD api.vods_s3_files_joins.id_old +ALTER TABLE IF EXISTS api.s3_files + ADD COLUMN IF NOT EXISTS id_old int; + +ALTER TABLE IF EXISTS api.vods + ADD COLUMN IF NOT EXISTS id_old int; + +ALTER TABLE api.vods_s3_files_joins + ADD COLUMN IF NOT EXISTS id_old int; + +ALTER TABLE api.vods_s3_files_joins + ADD COLUMN IF NOT EXISTS vod_id_old int; + +ALTER TABLE api.vods_s3_files_joins + ADD COLUMN IF NOT EXISTS b_2_file_id_old int; + +ALTER TABLE IF EXISTS api.vtubers + ADD COLUMN IF NOT EXISTS id_old int; + +ALTER TABLE api.vods_s3_files_joins + ADD COLUMN IF NOT EXISTS id_old int; + +ALTER TABLE api.vods_s3_files_joins + ADD COLUMN IF NOT EXISTS s3_file_id UUID; + +ALTER TABLE api.vods_s3_files_joins + ADD COLUMN IF NOT EXISTS s3_file_id_old int; + +CREATE TABLE IF NOT EXISTS api.a_temporary_vods ( + id integer, + video_src_hash character varying, + video_720_hash character varying, + video_480_hash character varying, + video_360_hash character varying, + video_240_hash character varying, + thin_hash character varying, + thicc_hash character varying, + announce_title character varying, + announce_url character varying, + note text, + date timestamp(6) without time zone, + spoilers text, + created_at timestamp(6) without time zone, + updated_at timestamp(6) without time zone, + published_at timestamp(6) without time zone, + created_by_id integer, + updated_by_id integer, + title character varying, + chat_log text, + date_2 character varying, + cuid character varying, + archive_status character varying +); + +-- Enable the dblink extension +-- this lets us copy data between two different databases +-- in our case, we are copying tables from futureporn_strapi_old.public.streams to futureporn.api.streams +CREATE EXTENSION IF NOT EXISTS dblink; + + +SELECT dblink_connect( + 'old_db_conn', + 'dbname=futureporn_strapi_old user=postgres passfile=/tmp/.pgpass' +); + + +-- Migrate vtubers table +INSERT INTO api.vtubers ( + id, + id_old, + chaturbate, + twitter, + patreon, + twitch, + tiktok, + onlyfans, + youtube, + linktree, + carrd, + fansly, + pornhub, + discord, + reddit, + throne, + instagram, + facebook, + merch, + slug, + image, + display_name, + description1, + description2, + created_at, + updated_at, + theme_color, + image_blur +) +SELECT DISTINCT + gen_random_uuid() AS id, + v.id AS id_old, + v.chaturbate, + v.twitter, + v.patreon, + v.twitch, + v.tiktok, + v.onlyfans, + v.youtube, + v.linktree, + v.carrd, + v.fansly, + v.pornhub, + v.discord, + v.reddit, + v.throne, + v.instagram, + v.facebook, + v.merch, + v.slug, + v.image, + v.display_name, + v.description_1, + v.description_2, + v.created_at, + v.updated_at, + v.theme_color, + v.image_blur +FROM dblink('old_db_conn', 'SELECT id, + chaturbate, + twitter, + patreon, + twitch, + tiktok, + onlyfans, + youtube, + linktree, + carrd, + fansly, + pornhub, + discord, + reddit, + throne, + instagram, + facebook, + merch, + slug, + image, + display_name, + description_1, + description_2, + created_at, + updated_at, + published_at, + created_by_id, + updated_by_id, + theme_color, + image_blur + FROM public.vtubers') +AS v( + id integer, + chaturbate character varying(255), + twitter character varying(255), + patreon character varying(255), + twitch character varying(255), + tiktok character varying(255), + onlyfans character varying(255), + youtube character varying(255), + linktree character varying(255), + carrd character varying(255), + fansly character varying(255), + pornhub character varying(255), + discord character varying(255), + reddit character varying(255), + throne character varying(255), + instagram character varying(255), + facebook character varying(255), + merch character varying(255), + slug character varying(255), + image character varying(255), + display_name character varying(255), + description_1 text, + description_2 text, + created_at timestamp(6) without time zone, + updated_at timestamp(6) without time zone, + published_at timestamp(6) without time zone, + created_by_id integer, + updated_by_id integer, + theme_color character varying(255), + image_blur character varying(255) +); + + + +-- Migrate streams table +-- here we are taking the pre-existing data from the strapi database +-- and copying it to the postgrest database. +-- some of the columns like vtuber need to be set to NULL because they are new and strapi streams table didn't contain that info +INSERT INTO api.streams (platform_notification_type, date, vtuber, tweet, archive_status, is_chaturbate_stream, is_fansly_stream) +SELECT DISTINCT + NULL AS platform_notification_type, + s.date, + NULL::UUID AS vtuber, + NULL AS tweet, + s.archive_status, + s.is_chaturbate_stream, + s.is_fansly_stream +FROM dblink('old_db_conn', 'SELECT date, archive_status, is_chaturbate_stream, is_fansly_stream FROM public.streams') +AS s( + date timestamp, + archive_status character varying, + is_chaturbate_stream boolean, + is_fansly_stream boolean +); + + +-- Migrate vods b2_files join table +-- previously public.vods_video_src_b_2_links +-- new api.vods_s3_join +INSERT INTO api.vods_s3_files_joins (id, id_old, vod_id, vod_id_old, s3_file_id, s3_file_id_old) +SELECT DISTINCT + gen_random_uuid() AS id, + old.id AS id_old, + NULL::UUID AS vod_id, + old.vod_id AS vod_id_old, + NULL::UUID AS s3_file_id, + old.b_2_file_id AS s3_file_id_old +FROM dblink('old_db_conn', 'SELECT id, vod_id, b_2_file_id FROM public.vods_video_src_b_2_links') +AS old( + id int, + vod_id int, + b_2_file_id int +); + + + + +-- Migrate B2 table +INSERT INTO api.s3_files ( + id, + id_old, + s3_id, + s3_key, + created_at, + updated_at, + bucket, + cdn_url +) +SELECT + gen_random_uuid()::UUID AS id, + b2_file.id::INT AS id_old, + b2_file.upload_id::TEXT AS s3_id, + b2_file.key::TEXT AS s3_key, + b2_file.created_at::TIMESTAMP(6) WITHOUT TIME ZONE AS created_at, + b2_file.updated_at::TIMESTAMP(6) WITHOUT TIME ZONE AS updated_at, + 'futureporn-b2'::TEXT AS bucket, + b2_file.cdn_url::TEXT AS cdn_url +FROM + dblink('old_db_conn', 'SELECT id, key, upload_id, created_at, updated_at, cdn_url FROM public.b2_files') AS b2_file ( + id integer, + key character varying(255), + upload_id character varying(255), + created_at timestamp(6) without time zone, + updated_at timestamp(6) without time zone, + cdn_url character varying(255) + ); + + +-- Migrate vods table +INSERT INTO api.vods ( + id, + id_old, + stream_id, + created_at, + updated_at, + title, + date, + note, + ipfs_cid, + s3_file, + announce_title, + announce_url, + status +) +SELECT + gen_random_uuid(), + vods.id, + NULL, + vods.created_at, + vods.updated_at, + vods.title, + vods.date::date, + vods.note, + vods.video_src_hash, + NULL, -- old vods doesn't contain this info-- the join table is needed + vods.announce_title, + vods.announce_url, + 'pending_recording' +FROM + dblink('old_db_conn', 'SELECT * FROM public.vods') AS vods ( + id integer, + video_src_hash character varying, + video_720_hash character varying, + video_480_hash character varying, + video_360_hash character varying, + video_240_hash character varying, + thin_hash character varying, + thicc_hash character varying, + announce_title character varying, + announce_url character varying, + note text, + date timestamp(6) without time zone, + spoilers text, + created_at timestamp(6) without time zone, + updated_at timestamp(6) without time zone, + published_at timestamp(6) without time zone, + created_by_id integer, + updated_by_id integer, + title character varying, + chat_log text, + date_2 character varying, + cuid character varying, + archive_status character varying + ) + LEFT JOIN ( + -- Fetching vods_vtuber_links from the old database + SELECT * + FROM dblink('old_db_conn', 'SELECT vod_id, vtuber_id FROM public.vods_vtuber_links') AS links ( + vod_id integer, + vtuber_id integer + ) + ) AS links ON vods.id = links.vod_id + LEFT JOIN api.vtubers AS vtubers + ON links.vtuber_id = vtubers.id_old; -- Map the old `vtuber_id` to the new `uuid` in `vtubers` + + + +-- Now we copy patron data from the old Strapi table up_user +-- Going forward we are changing how Patrons table is populated. + +-- FROM up_user diff --git a/scripts/data-migrations/2024-10-18-drupal.php b/scripts/data-migrations/2024-10-18-drupal.php new file mode 100644 index 0000000..d2cff86 --- /dev/null +++ b/scripts/data-migrations/2024-10-18-drupal.php @@ -0,0 +1,79 @@ +select('curling_games', 'g') + ->fields('g', [ + 'game_id', + 'title', + 'date', + 'time', + 'place', + ]); + return $query; + } + + /** + * {@inheritdoc} + */ + public function fields() { + $fields = [ + 'game_id' => $this->t('game_id' ), + 'title' => $this->t('title' ), + 'date' => $this->t('date'), + 'time' => $this->t('time'), + 'place' => $this->t('place' ), + ]; + return $fields; + } + + /** + * {@inheritdoc} + */ + public function getIds() { + return [ + 'game_id' => [ + 'type' => 'integer', + 'alias' => 'g', + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function prepareRow(Row $row) { + // This example shows how source properties can be added in + // prepareRow(). The source dates are stored as 2017-12-17 + // and times as 16:00. Drupal 8 saves date and time fields + // in ISO8601 format 2017-01-15T16:00:00 on UTC. + // We concatenate source date and time and add the seconds. + // The same result could also be achieved using the 'concat' + // and 'format_date' process plugins in the migration + // definition. + $date = $row->getSourceProperty('date'); + $time = $row->getSourceProperty('time'); + $datetime = $date . 'T' . $time . ':00'; + $row->setSourceProperty('datetime', $datetime); + return parent::prepareRow($row); + } +} diff --git a/scripts/data-migrations/2024-10-25-from-strapi-to-postgrest-mk2.sql b/scripts/data-migrations/2024-10-25-from-strapi-to-postgrest-mk2.sql new file mode 100644 index 0000000..fbf2f05 --- /dev/null +++ b/scripts/data-migrations/2024-10-25-from-strapi-to-postgrest-mk2.sql @@ -0,0 +1,80 @@ +-- Step 1, fetch data from strapi database and copy it to futureporn database via dblink +-- we store the data in futureporn database under public_strapi_old schema +-- We did this step manually using pgadmin4 so it's not part of this sql + + +-- Step 2, transform data from public_strapi_old to match the up-to-date api schema +-- There are a lot of deprecated tables in the Strapi db, so what we do is we copy and transform only what we need. +SELECT dblink_disconnect('old_db_conn'); +SELECT dblink_connect( + 'old_db_conn', + 'dbname=futureporn_strapi_old user=postgres passfile=/tmp/.pgpass' +); + + +-- Migrate vods table +INSERT INTO api.vods ( + id, + id_old, + stream_id, + created_at, + updated_at, + title, + date, + note, + ipfs_cid, + s3_file, + announce_title, + announce_url, + status +) +SELECT + gen_random_uuid(), + vods.id, + NULL, + vods.created_at, + vods.updated_at, + vods.title, + vods.date::date, + vods.note, + vods.video_src_hash, + NULL, -- old vods doesn't contain this info-- the join table is needed + vods.announce_title, + vods.announce_url, + 'pending_recording' +FROM + dblink('old_db_conn', 'SELECT * FROM public.vods') AS vods ( + id integer, + video_src_hash character varying, + video_720_hash character varying, + video_480_hash character varying, + video_360_hash character varying, + video_240_hash character varying, + thin_hash character varying, + thicc_hash character varying, + announce_title character varying, + announce_url character varying, + note text, + date timestamp(6) without time zone, + spoilers text, + created_at timestamp(6) without time zone, + updated_at timestamp(6) without time zone, + published_at timestamp(6) without time zone, + created_by_id integer, + updated_by_id integer, + title character varying, + chat_log text, + date_2 character varying, + cuid character varying, + archive_status character varying + ) + LEFT JOIN ( + -- Fetching vods_vtuber_links from the old database + SELECT * + FROM dblink('old_db_conn', 'SELECT vod_id, vtuber_id FROM public.vods_vtuber_links') AS links ( + vod_id integer, + vtuber_id integer + ) + ) AS links ON vods.id = links.vod_id + LEFT JOIN api.vtubers AS vtubers + ON links.vtuber_id = vtubers.id_old; -- Map the old `vtuber_id` to the new `uuid` in `vtubers` diff --git a/scripts/data-migrations/README.md b/scripts/data-migrations/README.md new file mode 100644 index 0000000..d1c6722 --- /dev/null +++ b/scripts/data-migrations/README.md @@ -0,0 +1,17 @@ +# Futureporn data migrations + +This directory is for data migrations ONLY. +For schema migrations, see ./services/migrations + + +## Usage + + $ a.migration.sh + +### Real-world Example + +Here we use dotenvx to load environment variables (specifically POSTGRES_PASSWORD is needed) and run the migration inside the postgres pod + + dotenvx run -f ./.env.development -- bash -x ./scripts/data-migrations/a.migration.sh ./scripts/data-migrations/2024-10-07-transfer-streams.sql + + diff --git a/scripts/data-migrations/a.migration.sh b/scripts/data-migrations/a.migration.sh new file mode 100755 index 0000000..ba4c8ce --- /dev/null +++ b/scripts/data-migrations/a.migration.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +postgres_pod_name=postgresql-primary-0 + +if [ -z $POSTGRES_PASSWORD ]; then + echo "POSTGRES_PASSWORD was missing in env. Please run using dotenvx or similar" + exit 5 +fi + + +if [ -z "$1" ] + then + echo "Usage: a.migration.sh /path/to/migraiton.sql" + exit 6 +fi + +echo "create .pgpass file inside pod" +kubectl -n futureporn exec -i ${postgres_pod_name} -- bash -c "echo *:5432:*:postgres:${POSTGRES_PASSWORD} | tee /tmp/.pgpass" +kubectl -n futureporn exec -i ${postgres_pod_name} -- chmod 0600 /tmp/.pgpass + +echo "Copying sql to pod" +kubectl -n futureporn cp ${1} ${postgres_pod_name}:/tmp/migration.sql + +echo "Running ${1} inside the pod" +kubectl -n futureporn exec -i ${postgres_pod_name} -- env PGPASSWORD=${POSTGRES_PASSWORD} psql -U postgres -d futureporn -f /tmp/migration.sql + +echo "rm .pgpass file" +kubectl -n futureporn exec -i ${postgres_pod_name} -- rm -rf /tmp/.pgpass \ No newline at end of file diff --git a/scripts/data-migrations/scratch.sql b/scripts/data-migrations/scratch.sql new file mode 100644 index 0000000..b71797c --- /dev/null +++ b/scripts/data-migrations/scratch.sql @@ -0,0 +1,14 @@ + + SELECT + gen_random_uuid() AS id, + vods.id AS id_old, + links.vod_id AS vod_id_old, + links.vtuber_id AS vtuber, + stream_links.stream_id AS stream + + FROM public_strapi_old.vods AS vods + LEFT JOIN public_strapi_old.vods_vtuber_links AS links + ON vods.id = links.vod_id + + LEFT JOIN public_strapi_old.vods_stream_links AS stream_links + ON vods.id = stream_links.vod_id \ No newline at end of file diff --git a/scripts/drupal-init-wrapper.sh b/scripts/drupal-init-wrapper.sh new file mode 100755 index 0000000..dd4c9f7 --- /dev/null +++ b/scripts/drupal-init-wrapper.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + +namespace=futureporn +pod_name=$(kubectl --namespace futureporn get pods -l app.kubernetes.io/name=drupal -o custom-columns=":metadata.name" --no-headers) + +kubectl -n "${namespace}" cp ./scripts/drupal-init.sh "${pod_name}:/tmp/drupal-init.sh" +kubectl -n "${namespace}" exec "${pod_name}" -- bash -c "/tmp/drupal-init.sh" diff --git a/scripts/drupal-init.sh b/scripts/drupal-init.sh new file mode 100755 index 0000000..e6bfc1e --- /dev/null +++ b/scripts/drupal-init.sh @@ -0,0 +1,24 @@ + +#!/bin/bash + +# maybe https://www.drupal.org/project/extlink +# maybe https://www.drupal.org/project/seckit +# maybe https://www.drupal.org/project/slick +# maybe https://www.drupal.org/project/fontawesome + +cd /opt/bitnami/drupal +composer require \ + 'drupal/bulma:^1.0' \ + 'drupal/file_uploader_uppy:^1.0' \ + 'drupal/backup_migrate:^5.0' \ + 'drupal/cdn:^4.1' \ + 'drupal/s3fs:^3.6' \ + 'drupal/video:^3.0' \ + 'league/commonmark ^1.0' \ + 'drupal/markdown:^3.0' \ + 'drupal/color_field:^3.0' \ + 'drupal/pathauto:^1.13' \ + 'drupal/extlink:^2.0' +drush updatedb +drush theme:install bulma +drush pm:install -y file_uploader_uppy backup_migrate cdn cdn_ui s3fs video markdown diff --git a/scripts/k8s-chisel.sh b/scripts/k8s-chisel.sh deleted file mode 100755 index 36c5bf0..0000000 --- a/scripts/k8s-chisel.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - - -if [ -z "${ENV}" ]; then \ - echo "Error: ENV variable is not defined. Please set to one of development|staging|production"; exit 1; \ -fi - -if [ "${ENV}" == "production" ]; then \ - echo "chisel is not used in production environment. Skipping." - exit 0 -fi - -kubectl apply -k 'https://github.com/FyraLabs/chisel-operator?ref=stable' \ No newline at end of file diff --git a/scripts/k8s-secrets.sh b/scripts/k8s-secrets.sh index 13f9269..a0b3ac8 100755 --- a/scripts/k8s-secrets.sh +++ b/scripts/k8s-secrets.sh @@ -42,10 +42,45 @@ EOF # --from-literal=b2Key=${UPPY_B2_KEY} \ # --from-literal=b2Secret=${UPPY_B2_SECRET}\ +kubectl --namespace futureporn delete secret traefik-dashboard-auth --ignore-not-found +kubectl --namespace futureporn create secret generic traefik-dashboard-auth \ +--type=kubernetes.io/basic-auth \ +--from-literal=password=${TRAEFIK_DASHBOARD_PASSWORD} \ +--from-literal=username=${TRAEFIK_DASHBOARD_USERNAME} + +kubectl --namespace futureporn delete secret logto --ignore-not-found +kubectl --namespace futureporn create secret generic logto \ +--from-literal=postgresqlUri=${LOGTO_POSTGRESQL_URI} \ +--from-literal=cookieSecret=${LOGTO_COOKIE_SECRET} \ +--from-literal=appSecret=${LOGTO_APP_SECRET} \ +--from-literal=appId=${LOGTO_APP_ID} + +kubectl --namespace futureporn delete secret supertokens --ignore-not-found +kubectl --namespace futureporn create secret generic supertokens \ +--from-literal=apiKeys=${SUPERTOKENS_API_KEYS} \ +--from-literal=postgresqlUri=${SUPERTOKENS_POSTGRESQL_URI} + +kubectl --namespace futureporn delete secret patreon --ignore-not-found +kubectl --namespace futureporn create secret generic patreon \ +--from-literal=creatorAccessToken=${PATREON_CREATOR_ACCESS_TOKEN} \ +--from-literal=creatorRefreshToken=${PATREON_CREATOR_REFRESH_TOKEN} \ +--from-literal=clientId=${PATREON_CLIENT_ID} \ +--from-literal=clientSecret=${PATREON_CLIENT_SECRET} + +kubectl --namespace futureporn delete secret mariadb --ignore-not-found +kubectl --namespace futureporn create secret generic mariadb \ +--from-literal=mariadb-root-password=${MARIADB_ROOT_PASSWORD} \ +--from-literal=mariadb-password=${MARIADB_PASSWORD} \ +--from-literal=mariadb-replication-password=${MARIADB_REPLICATION_PASSWORD} + +kubectl --namespace futureporn delete secret externaldb --ignore-not-found +kubectl --namespace futureporn create secret generic externaldb \ +--from-literal=db-password=${MARIADB_PASSWORD} kubectl --namespace futureporn delete secret chisel --ignore-not-found kubectl --namespace futureporn create secret generic chisel \ --from-literal=auth="${CHISEL_USERNAME}:${CHISEL_PASSWORD}" + kubectl --namespace chisel-operator-system delete secret chisel --ignore-not-found kubectl --namespace chisel-operator-system create secret generic chisel \ --from-literal=auth="${CHISEL_USERNAME}:${CHISEL_PASSWORD}" diff --git a/scripts/supertokens-seed.sh b/scripts/supertokens-seed.sh new file mode 100755 index 0000000..be5966f --- /dev/null +++ b/scripts/supertokens-seed.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +kubectl -n futureporn exec postgresql-primary-0 -- env PGPASSWORD=${POSTGRES_PASSWORD} psql -U postgres --command "CREATE DATABASE supertokens;" +echo "Done." \ No newline at end of file diff --git a/services/factory/.mocharc.json b/services/factory/.mocharc.json new file mode 100644 index 0000000..8c76e02 --- /dev/null +++ b/services/factory/.mocharc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/mocharc.json", + "extensions": ["ts"], + "spec": "./src/**/*.spec.ts", + "require": "tsx" +} \ No newline at end of file diff --git a/services/build/README.md b/services/factory/README.md similarity index 100% rename from services/build/README.md rename to services/factory/README.md diff --git a/services/factory/crontab b/services/factory/crontab new file mode 100644 index 0000000..1fc4461 --- /dev/null +++ b/services/factory/crontab @@ -0,0 +1,17 @@ +# @see https://worker.graphile.org/docs/cron +# +# ┌───────────── UTC minute (0 - 59) +# │ ┌───────────── UTC hour (0 - 23) +# │ │ ┌───────────── UTC day of the month (1 - 31) +# │ │ │ ┌───────────── UTC month (1 - 12) +# │ │ │ │ ┌───────────── UTC day of the week (0 - 6) (Sunday to Saturday) +# │ │ │ │ │ ┌───────────── task (identifier) to schedule +# │ │ │ │ │ │ ┌────────── optional scheduling options +# │ │ │ │ │ │ │ ┌────── optional payload to merge +# │ │ │ │ │ │ │ │ +# │ │ │ │ │ │ │ │ +# * * * * * task ?opts {payload} + + +## every 12 hours, we update the patrons table, synchronizing it with Patreon API. +* */12 * * * synchronize_patrons_list ?max=1 \ No newline at end of file diff --git a/services/build/package.json b/services/factory/package.json similarity index 87% rename from services/build/package.json rename to services/factory/package.json index b1bde55..da7b3c9 100644 --- a/services/build/package.json +++ b/services/factory/package.json @@ -1,11 +1,11 @@ { - "name": "@futureporn/build", + "name": "@futureporn/factory", "type": "module", "version": "2.0.0", "description": "", "main": "src/index.ts", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "mocha", "dev": "pnpm run dev.nodemon # yes this is crazy to have nodemon execute tsx, but it's the only way I have found to get live reloading in TS/ESM/docker with Graphile Worker's way of loading tasks", "dev.tsx": "tsx ./src/index.ts", "dev.nodemon": "nodemon --ext ts --exec \"pnpm run dev.tsx\"", @@ -28,8 +28,12 @@ "@futureporn/storage": "workspace:^", "@futureporn/utils": "workspace:^", "@paralleldrive/cuid2": "^2.2.2", + "@types/chai": "^4.3.19", + "@types/mocha": "^10.0.7", "@types/node": "^22.5.2", + "chai": "^5.1.1", "dotenv": "^16.4.5", + "graphile-config": "0.0.1-beta.9", "graphile-worker": "^0.16.6", "p-retry": "^6.2.0" }, diff --git a/services/build/pnpm-lock.yaml b/services/factory/pnpm-lock.yaml similarity index 97% rename from services/build/pnpm-lock.yaml rename to services/factory/pnpm-lock.yaml index 79281ba..7b4657b 100644 --- a/services/build/pnpm-lock.yaml +++ b/services/factory/pnpm-lock.yaml @@ -26,12 +26,24 @@ importers: '@paralleldrive/cuid2': specifier: ^2.2.2 version: 2.2.2 + '@types/chai': + specifier: ^4.3.19 + version: 4.3.20 + '@types/mocha': + specifier: ^10.0.7 + version: 10.0.9 '@types/node': specifier: ^22.5.2 version: 22.5.2 + chai: + specifier: ^5.1.1 + version: 5.1.2 dotenv: specifier: ^16.4.5 version: 16.4.5 + graphile-config: + specifier: 0.0.1-beta.9 + version: 0.0.1-beta.9 graphile-worker: specifier: ^0.16.6 version: 0.16.6(typescript@5.5.4) @@ -55,6 +67,34 @@ importers: specifier: ^4.19.0 version: 4.19.0 + ../..: {} + + ../../packages/fetchers: {} + + ../../packages/infra: {} + + ../../packages/storage: {} + + ../../packages/types: {} + + ../../packages/utils: {} + + ../bot: {} + + ../capture: {} + + ../mailbox: {} + + ../migrations: {} + + ../next: {} + + ../scout: {} + + ../strapi: {} + + ../uppy: {} + packages: '@aws-crypto/crc32@5.2.0': @@ -621,12 +661,18 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} '@types/interpret@1.1.3': resolution: {integrity: sha512-uBaBhj/BhilG58r64mtDb/BEdH51HIQLgP5bmWzc5qCtFMja8dCk/IOJmk36j0lbi9QHwI6sbtUNGuqXdKCAtQ==} + '@types/mocha@10.0.9': + resolution: {integrity: sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==} + '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} @@ -680,6 +726,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -717,6 +767,10 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -725,6 +779,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -777,6 +835,10 @@ packages: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -959,6 +1021,9 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -1023,6 +1088,10 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + pg-cloudflare@1.1.1: resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} @@ -2236,6 +2305,8 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@types/chai@4.3.20': {} + '@types/debug@4.1.12': dependencies: '@types/ms': 0.7.34 @@ -2244,6 +2315,8 @@ snapshots: dependencies: '@types/node': 22.5.2 + '@types/mocha@10.0.9': {} + '@types/ms@0.7.34': {} '@types/node@20.16.3': @@ -2291,6 +2364,8 @@ snapshots: argparse@2.0.1: {} + assertion-error@2.0.1: {} + balanced-match@1.0.2: {} base64-js@1.5.1: {} @@ -2323,6 +2398,14 @@ snapshots: camelcase@6.3.0: {} + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -2334,6 +2417,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + check-error@2.1.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -2401,6 +2486,8 @@ snapshots: decamelize@4.0.0: {} + deep-eql@5.0.2: {} + diff@4.0.2: {} diff@5.2.0: {} @@ -2583,6 +2670,8 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + loupe@3.1.2: {} + make-error@1.3.6: {} minimatch@3.1.2: @@ -2670,6 +2759,8 @@ snapshots: path-type@4.0.0: {} + pathval@2.0.0: {} + pg-cloudflare@1.1.1: optional: true diff --git a/services/build/src/config.ts b/services/factory/src/config.ts similarity index 80% rename from services/build/src/config.ts rename to services/factory/src/config.ts index 747ddc8..513ff14 100644 --- a/services/build/src/config.ts +++ b/services/factory/src/config.ts @@ -15,6 +15,8 @@ if (!process.env.S3_ENDPOINT) throw new Error('Missing S3_REGION env var'); if (!process.env.S3_MAIN_BUCKET) throw new Error('Missing S3_BUCKET env var'); if (!process.env.S3_USC_BUCKET) throw new Error('Missing S3_USC_BUCKET env var'); if (!process.env.CACHE_DIR) throw new Error('Missing CACHE_DIR env var'); +if (!process.env.PATREON_CREATOR_ACCESS_TOKEN) throw new Error('Missing PATREON_CREATOR_ACCESS_TOKEN env var'); +if (!process.env.PATREON_CREATOR_REFRESH_TOKEN) throw new Error('Missing PATREON_CREATOR_REFRESH_TOKEN env var'); const postgrestUrl = process.env.POSTGREST_URL! const automationUserJwt = process.env.AUTOMATION_USER_JWT! const connectionString = process.env.WORKER_CONNECTION_STRING! @@ -25,6 +27,8 @@ const s3SecretAccessKey = process.env.S3_SECRET_ACCESS_KEY! const s3MainBucket = process.env.S3_MAIN_BUCKET! const s3UscBucket = process.env.S3_USC_BUCKET! const cacheDir = process.env.CACHE_DIR! +const patreonCreatorAccessToken = process.env.PATREON_CREATOR_ACCESS_TOKEN! +const patreonCreatorRefreshToken = process.env.PATREON_CREATOR_REFRESH_TOKEN! export interface Config { postgrestUrl: string; @@ -37,6 +41,8 @@ export interface Config { s3UscBucket: string; s3MainBucket: string; cacheDir: string; + patreonCreatorAccessToken: string; + patreonCreatorRefreshToken: string; } @@ -51,4 +57,6 @@ export const configs: Config = { s3MainBucket, s3UscBucket, cacheDir, + patreonCreatorAccessToken, + patreonCreatorRefreshToken, } diff --git a/services/build/src/index.ts b/services/factory/src/index.ts similarity index 90% rename from services/build/src/index.ts rename to services/factory/src/index.ts index 3705630..e961f07 100644 --- a/services/build/src/index.ts +++ b/services/factory/src/index.ts @@ -1,5 +1,6 @@ -import type { RunnerOptions, GraphileConfig } from 'graphile-worker' +import type { RunnerOptions } from 'graphile-worker' +import type { GraphileConfig } from "graphile-config"; import { run } from 'graphile-worker' import { join, dirname } from 'node:path' import { fileURLToPath } from 'url' @@ -33,9 +34,6 @@ async function setupGraphileWorker() { } } - - - async function main() { await setupGraphileWorker() } diff --git a/services/build/src/tasks/combine_video_segments.ts b/services/factory/src/tasks/combine_video_segments.ts similarity index 100% rename from services/build/src/tasks/combine_video_segments.ts rename to services/factory/src/tasks/combine_video_segments.ts diff --git a/services/build/src/tasks/generate_thumbnail.ts b/services/factory/src/tasks/generate_thumbnail.ts similarity index 100% rename from services/build/src/tasks/generate_thumbnail.ts rename to services/factory/src/tasks/generate_thumbnail.ts diff --git a/services/build/src/tasks/process_video.ts b/services/factory/src/tasks/process_video.ts similarity index 100% rename from services/build/src/tasks/process_video.ts rename to services/factory/src/tasks/process_video.ts diff --git a/services/build/src/tasks/remux_video.ts b/services/factory/src/tasks/remux_video.ts similarity index 100% rename from services/build/src/tasks/remux_video.ts rename to services/factory/src/tasks/remux_video.ts diff --git a/services/factory/src/tasks/synchronize_patrons_list.ts b/services/factory/src/tasks/synchronize_patrons_list.ts new file mode 100644 index 0000000..68cc31b --- /dev/null +++ b/services/factory/src/tasks/synchronize_patrons_list.ts @@ -0,0 +1,252 @@ +import type { Task, Helpers } from "graphile-worker"; +import type { IPatron } from '@futureporn/types' +import { configs } from '../config.ts' + +interface Patron { + id: string; + full_name: string; +} + +type SimplePatron = { + id: string; // User ID of the patron + full_name: string; // Full name of the patron, pulled from included data + entitled_tier_ids: string[]; // List of tier IDs the patron is currently entitled to +}; + + +namespace Patreon { + export interface APIResponse { + data: { + id: string; + relationships: { + currently_entitled_tiers: { + data: { id: string; type: string }[]; + }; + user: { + data: { id: string; type: string }; + }; + }; + type: string; + }[]; + included: { + id: string; + type: string; + attributes: { + full_name?: string; + }; + }[]; + meta: { + count: number; + pagination: { + cursors: { + next?: string; + } + } + }; + } + + export interface Pledge { + id: string; + type: "pledge"; + attributes: { + amount_cents: number; + created_at: string; + declined_since: string | null; + patron_pays_fees: boolean; + pledge_cap_cents: number | null; + }; + relationships: { + patron: { + data: { + id: string; + type: "user"; + }; + links: { + related: string; + }; + }; + reward: { + data: { + id: string; + type: "reward"; + }; + links: { + related: string; + }; + }; + }; + } + + export interface User { + id: string; + type: "user"; + attributes: { + about: string; + created: string; + email: string; + facebook: string | null; + first_name: string; + full_name: string; + gender: number; + image_url: string; + is_email_verified: boolean; + last_name: string; + social_connections: SocialConnections; + thumb_url: string; + twitch: string | null; + twitter: string | null; + url: string; + vanity: string; + youtube: string | null; + }; + } + + export interface SocialConnections { + deviantart: string | null; + discord: string | null; + facebook: string | null; + reddit: string | null; + spotify: string | null; + twitch: string | null; + twitter: string | null; + youtube: string | null; + } + + export interface Reward { + id: string; + type: "reward"; + attributes: { + amount_cents: number; + created_at: string; + description: string; + discord_role_ids: any | null; + edited_at: string; + image_url: string | null; + patron_count: number; + post_count: number | null; + published: boolean; + published_at: string; + remaining: number | null; + requires_shipping: boolean; + title: string; + unpublished_at: string | null; + url: string; + user_limit: number | null; + }; + } +} + + + + +const tiers = { + free: '10620388', + archiveSupporter: '8154170', + stealthSupporter: '9561793', + tuneItUp: '9184994', + maxQ: '22529959', + archiveCollector: '8154171', + advancedArchiveSupporter: '8686045', + quantumSupporter: '8694826', + sneakyQuantumSupporter: '9560538', + luberPlusPlus: '8686022' +} + +async function fetchAllPages(url: string, headers: HeadersInit = {}): Promise { + const responses: Patreon.APIResponse[] = []; + let cursor: string | null = null; + + do { + const fetchUrl = cursor ? `${url}&page[cursor]=${cursor}` : url; + const response = await fetch(fetchUrl, { headers }); + const jsonResponse: Patreon.APIResponse = await response.json(); + + responses.push(jsonResponse); + cursor = jsonResponse.meta?.pagination?.cursors?.next || null; + } while (cursor); + + return responses; +} + + +function transformApiResponse(responses: Patreon.APIResponse[]): SimplePatron[] { + const usersMap: Record = {}; + + // Build a map of user ID -> full_name from the included data + responses.forEach(response => { + response.included + .filter(item => item.type === 'user') + .forEach(user => { + usersMap[user.id] = user.attributes.full_name || ''; + }); + }); + + // Map through `data` to create a unified array of SimplePatron + return responses.flatMap(response => + response.data.map(datum => ({ + id: datum.relationships.user.data.id, + full_name: usersMap[datum.relationships.user.data.id] || '', + entitled_tier_ids: datum.relationships.currently_entitled_tiers.data.map(tier => tier.id), + })) + ); +} + + +function filterActivePatrons(patrons: SimplePatron[]): SimplePatron[] { + const acceptedTiers = new Set(Object.values(tiers)) + acceptedTiers.delete(tiers.free); + return patrons.filter(patron => + patron.entitled_tier_ids.some(tierId => acceptedTiers.has(tierId)) + ); +} + + +async function getActivePatrons(url: string, headers: HeadersInit = {}): Promise { + // Step 1: Fetch all pages of raw data + const rawResponses = await fetchAllPages(url, headers); + + // Step 2: Transform raw responses into a unified data format + const allPatrons = transformApiResponse(rawResponses); + + // Step 3: Filter patrons by accepted tiers + return filterActivePatrons(allPatrons); +} + + + + +const updatePatronsTable = async function (patronsList: SimplePatron[]): Promise { + // @todo + console.log(`@todo Syncronizing ${patronsList.length} patrons to the db`) + const res = await fetch(`${configs.postgrestUrl}/patrons`, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${configs.automationUserJwt}`, + 'Prefer': 'return=representation', + 'Content-Type': 'application/json', + } + }) + const data = await res.json() +} + + +const synchronize_patrons_list: Task = async function (payload: unknown, helpers: Helpers) { + try { + + const patrons = await getActivePatrons( + 'https://api.patreon.com/api/oauth2/v2/campaigns/8012692/members?include=currently_entitled_tiers,user&fields[user]=full_name,vanity', + { 'Authorization': `Bearer ${configs.patreonCreatorAccessToken}` } + ) + + await updatePatronsTable(patrons) + + } catch (e) { + helpers.logger.error('failed to synchronize_patrons_list') + helpers.logger.error(JSON.stringify(e)) + + throw e + } +} + + +export default synchronize_patrons_list; \ No newline at end of file diff --git a/services/build/src/utils/importDirectory.ts b/services/factory/src/utils/importDirectory.ts similarity index 100% rename from services/build/src/utils/importDirectory.ts rename to services/factory/src/utils/importDirectory.ts diff --git a/services/build/tsconfig.json b/services/factory/tsconfig.json similarity index 100% rename from services/build/tsconfig.json rename to services/factory/tsconfig.json diff --git a/services/migrations/migrations/00079_stream_id-optional.sql b/services/migrations/migrations/00079_stream_id-optional.sql new file mode 100644 index 0000000..3d0a395 --- /dev/null +++ b/services/migrations/migrations/00079_stream_id-optional.sql @@ -0,0 +1,9 @@ + +-- data migrations are really difficult if api.vods.stream_id is required. Thus we make NULL allowed on stream_id + +ALTER TABLE api.vods + DROP COLUMN stream_id; + +ALTER TABLE api.vods + ADD COLUMN stream_id UUID REFERENCES api.streams(id); + diff --git a/services/migrations/migrations/00080_add-created_at-to-vtubers.sql b/services/migrations/migrations/00080_add-created_at-to-vtubers.sql new file mode 100644 index 0000000..d43464c --- /dev/null +++ b/services/migrations/migrations/00080_add-created_at-to-vtubers.sql @@ -0,0 +1,11 @@ +ALTER TABLE api.vtubers + ADD COLUMN created_at TIMESTAMP(6) WITHOUT TIME ZONE; + +ALTER TABLE api.vtubers + ADD COLUMN updated_at TIMESTAMP(6) WITHOUT TIME ZONE; + +ALTER TABLE api.vtubers + ALTER COLUMN created_at SET DEFAULT now(); + +ALTER TABLE api.vtubers + ALTER COLUMN updated_at SET DEFAULT now(); \ No newline at end of file diff --git a/services/migrations/migrations/00081_add-id_deprecated-to-vods.sql b/services/migrations/migrations/00081_add-id_deprecated-to-vods.sql new file mode 100644 index 0000000..e863384 --- /dev/null +++ b/services/migrations/migrations/00081_add-id_deprecated-to-vods.sql @@ -0,0 +1,3 @@ +-- for temporary data migration purposes, we add api.vods.id_deprecated which is an int and thus compatible with Strapi's IDs that we are importing +ALTER TABLE api.vtubers + ADD COLUMN id_deprecated int; diff --git a/services/migrations/migrations/00082_add-id_deprecated-to-s3_files.sql b/services/migrations/migrations/00082_add-id_deprecated-to-s3_files.sql new file mode 100644 index 0000000..4c778a3 --- /dev/null +++ b/services/migrations/migrations/00082_add-id_deprecated-to-s3_files.sql @@ -0,0 +1,3 @@ +-- for temporary data migration purposes, we add api.s3_files.id_deprecated which is an int and thus compatible with Strapi's IDs that we are importing +ALTER TABLE api.s3_files + ADD COLUMN id_deprecated int; diff --git a/services/migrations/migrations/00083_create_vods_s3_join.sql b/services/migrations/migrations/00083_create_vods_s3_join.sql new file mode 100644 index 0000000..735e8aa --- /dev/null +++ b/services/migrations/migrations/00083_create_vods_s3_join.sql @@ -0,0 +1,5 @@ +CREATE TABLE api.vods_s3_file_join ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + vod_id uuid, + s3_file_id uuid +); \ No newline at end of file diff --git a/services/migrations/migrations/00084_add-file_id-to-s3_files.sql b/services/migrations/migrations/00084_add-file_id-to-s3_files.sql new file mode 100644 index 0000000..fa08332 --- /dev/null +++ b/services/migrations/migrations/00084_add-file_id-to-s3_files.sql @@ -0,0 +1,2 @@ +ALTER TABLE api.s3_files + ADD COLUMN file_id TEXT; diff --git a/services/migrations/migrations/00085_sync-s3_files.sql b/services/migrations/migrations/00085_sync-s3_files.sql new file mode 100644 index 0000000..94493cf --- /dev/null +++ b/services/migrations/migrations/00085_sync-s3_files.sql @@ -0,0 +1,9 @@ +-- undo last because it was redundant. we don't need file_id because the same data is in s3_id +ALTER TABLE api.s3_files + DROP COLUMN file_id; + +-- add created_at and updated_at to match strapi data +ALTER TABLE api.s3_files + ADD COLUMN created_at timestamp(6) without time zone; +ALTER TABLE api.s3_files + ADD COLUMN updated_at timestamp(6) without time zone; \ No newline at end of file diff --git a/services/migrations/migrations/00086_add-cdn_url-to-s3_files.sql b/services/migrations/migrations/00086_add-cdn_url-to-s3_files.sql new file mode 100644 index 0000000..db2a82d --- /dev/null +++ b/services/migrations/migrations/00086_add-cdn_url-to-s3_files.sql @@ -0,0 +1,2 @@ +ALTER TABLE api.s3_files + ADD COLUMN cdn_url TEXT; \ No newline at end of file diff --git a/services/migrations/migrations/00087_remove-id_deprecated.sql b/services/migrations/migrations/00087_remove-id_deprecated.sql new file mode 100644 index 0000000..1c73d22 --- /dev/null +++ b/services/migrations/migrations/00087_remove-id_deprecated.sql @@ -0,0 +1,2 @@ +ALTER TABLE api.s3_files + DROP COLUMN id_deprecated; diff --git a/services/migrations/migrations/00088_remove-id_deprecated-from-vtubers.sql b/services/migrations/migrations/00088_remove-id_deprecated-from-vtubers.sql new file mode 100644 index 0000000..30cb5cb --- /dev/null +++ b/services/migrations/migrations/00088_remove-id_deprecated-from-vtubers.sql @@ -0,0 +1,2 @@ +ALTER TABLE api.vtubers + DROP COLUMN id_deprecated; diff --git a/services/migrations/migrations/00089_create-vods_s3_files_join.sql b/services/migrations/migrations/00089_create-vods_s3_files_join.sql new file mode 100644 index 0000000..1d7e59b --- /dev/null +++ b/services/migrations/migrations/00089_create-vods_s3_files_join.sql @@ -0,0 +1,10 @@ +-- vods_s3_files_join table schema +CREATE TABLE api.vods_s3_files_join ( + id UUID, + vod_id UUID, + s3_file UUID +); + +-- roles & permissions +GRANT all ON api.vods_s3_files_join TO automation; +GRANT SELECT ON api.vods_s3_files_join TO web_anon; \ No newline at end of file diff --git a/services/migrations/migrations/00090_rename-vods-s3-files-joins.sql b/services/migrations/migrations/00090_rename-vods-s3-files-joins.sql new file mode 100644 index 0000000..a154599 --- /dev/null +++ b/services/migrations/migrations/00090_rename-vods-s3-files-joins.sql @@ -0,0 +1,19 @@ +-- we are using joins instead of join because it matches all other table names being plural + +-- drop table +DROP TABLE api.vods_s3_files_join CASCADE; + + +-- vods_s3_files_joins table schema +CREATE TABLE api.vods_s3_files_joins ( + id UUID, + id_old INT, + vod_id UUID, + s3_file UUID +); + +-- roles & permissions +GRANT all ON api.vods_s3_files_joins TO automation; +GRANT SELECT ON api.vods_s3_files_joins TO web_anon; + + diff --git a/services/migrations/migrations/00091_drop-vods_s3_file_join.sql b/services/migrations/migrations/00091_drop-vods_s3_file_join.sql new file mode 100644 index 0000000..d56d214 --- /dev/null +++ b/services/migrations/migrations/00091_drop-vods_s3_file_join.sql @@ -0,0 +1,2 @@ +-- drop table +DROP TABLE api.vods_s3_file_join CASCADE; diff --git a/services/migrations/migrations/00092_use-s3_file_id.sql b/services/migrations/migrations/00092_use-s3_file_id.sql new file mode 100644 index 0000000..d852ed4 --- /dev/null +++ b/services/migrations/migrations/00092_use-s3_file_id.sql @@ -0,0 +1,5 @@ +ALTER TABLE api.vods_s3_files_joins + DROP COLUMN s3_file; + +ALTER TABLE api.vods_s3_files_joins + ADD COLUMN s3_file_id UUID; diff --git a/services/migrations/migrations/00093_enable-pg_trgm.sql b/services/migrations/migrations/00093_enable-pg_trgm.sql new file mode 100644 index 0000000..c77035b --- /dev/null +++ b/services/migrations/migrations/00093_enable-pg_trgm.sql @@ -0,0 +1,2 @@ +-- enabling pg_trgm for drupal +CREATE EXTENSION IF NOT EXISTS pg_trgm; diff --git a/services/migrations/migrations/00094_add-patrons-table.sql b/services/migrations/migrations/00094_add-patrons-table.sql new file mode 100644 index 0000000..44a4865 --- /dev/null +++ b/services/migrations/migrations/00094_add-patrons-table.sql @@ -0,0 +1,7 @@ +CREATE TABLE api.patrons ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + full_name TEXT NOT NULL, + link TEXT +); +GRANT all ON api.patrons TO automation; +GRANT SELECT ON api.patrons TO web_anon; diff --git a/services/migrations/migrations/00095_create-contributors.sql b/services/migrations/migrations/00095_create-contributors.sql new file mode 100644 index 0000000..1a6b312 --- /dev/null +++ b/services/migrations/migrations/00095_create-contributors.sql @@ -0,0 +1,7 @@ +CREATE TABLE api.contributors ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + full_name TEXT NOT NULL, + link TEXT +); +GRANT all ON api.contributors TO automation; +GRANT SELECT ON api.contributors TO web_anon; diff --git a/services/next/app/404.tsx b/services/next/app/404.tsx new file mode 100644 index 0000000..bf9ef9c --- /dev/null +++ b/services/next/app/404.tsx @@ -0,0 +1,3 @@ +export default function Custom404() { + return

404~~~~ - Page Not Found

+} \ No newline at end of file diff --git a/services/next/app/api/auth/[[...path]]/route.ts b/services/next/app/api/auth/[[...path]]/route.ts new file mode 100644 index 0000000..04b7e7d --- /dev/null +++ b/services/next/app/api/auth/[[...path]]/route.ts @@ -0,0 +1,39 @@ +import { getAppDirRequestHandler } from 'supertokens-node/nextjs'; +import { NextRequest, NextResponse } from 'next/server'; +import { ensureSuperTokensInit } from '../../../config/backend'; + +ensureSuperTokensInit(); + +const handleCall = getAppDirRequestHandler(); + +export async function GET(request: NextRequest) { + const res = await handleCall(request); + if (!res.headers.has('Cache-Control')) { + // This is needed for production deployments with Vercel + res.headers.set( + 'Cache-Control', + 'no-cache, no-store, max-age=0, must-revalidate' + ) + } + return res; +} + +export async function POST(request: NextRequest) { + return handleCall(request); +} + +export async function DELETE(request: NextRequest) { + return handleCall(request); +} + +export async function PUT(request: NextRequest) { + return handleCall(request); +} + +export async function PATCH(request: NextRequest) { + return handleCall(request); +} + +export async function HEAD(request: NextRequest) { + return handleCall(request); +} \ No newline at end of file diff --git a/services/next/app/auth/[[...path]]/page.tsx b/services/next/app/auth/[[...path]]/page.tsx new file mode 100644 index 0000000..269d945 --- /dev/null +++ b/services/next/app/auth/[[...path]]/page.tsx @@ -0,0 +1,27 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { redirectToAuth } from 'supertokens-auth-react'; +import SuperTokens from 'supertokens-auth-react/ui'; +import { ThirdPartyPreBuiltUI } from 'supertokens-auth-react/recipe/thirdparty/prebuiltui'; +// import { PasswordlessPreBuiltUI } from 'supertokens-auth-react/recipe/passwordless/prebuiltui'; + +export default function Auth() { + // if the user visits a page that is not handled by us (like /auth/random), then we redirect them back to the auth page. + const [loaded, setLoaded] = useState(false); + useEffect(() => { + if ( + SuperTokens.canHandleRoute([ThirdPartyPreBuiltUI]) === false + ) { + redirectToAuth({ redirectBack: false }); + } else { + setLoaded(true); + } + }, []); + + if (loaded) { + return SuperTokens.getRoutingComponent([ThirdPartyPreBuiltUI]); + } + + return null; +} \ No newline at end of file diff --git a/services/next/app/callback/route.ts b/services/next/app/callback/route.ts new file mode 100644 index 0000000..d927bfe --- /dev/null +++ b/services/next/app/callback/route.ts @@ -0,0 +1,11 @@ +import { handleSignIn } from '@logto/next/server-actions'; +import { redirect } from 'next/navigation'; +import { NextRequest } from 'next/server'; +import { logtoConfig } from '../logto'; + +export async function GET(request: NextRequest) { + const searchParams = request.nextUrl.searchParams; + await handleSignIn(logtoConfig, searchParams); + + redirect('/'); +} \ No newline at end of file diff --git a/services/next/app/components/auth.tsx b/services/next/app/components/auth.tsx index 6b17688..105e704 100644 --- a/services/next/app/components/auth.tsx +++ b/services/next/app/components/auth.tsx @@ -7,7 +7,7 @@ import { faPatreon } from '@fortawesome/free-brands-svg-icons'; import { useLocalStorageValue } from '@react-hookz/web'; import { faRightFromBracket } from '@fortawesome/free-solid-svg-icons'; import Skeleton from 'react-loading-skeleton'; -import { strapiUrl } from '@/app/lib/constants'; +import { strapiUrl } from '@/app/lib/constants'; // import NextAuth from 'next-auth'; // this is (pipedream) wishlist // import Providers from 'next-auth/providers'; @@ -124,10 +124,10 @@ export function LogoutButton() { ); } -export function useAuth(): IUseAuth { - const context = useContext(AuthContext); - if (!context) { - throw new Error('useAuth must be used within an AuthProvider'); - } - return context; -} +// export function useAuth(): IUseAuth { +// const context = useContext(AuthContext); +// if (!context) { +// throw new Error('useAuth must be used within an AuthProvider'); +// } +// return context; +// } diff --git a/services/next/app/components/navbar.tsx b/services/next/app/components/navbar.tsx index d419592..86d7a90 100644 --- a/services/next/app/components/navbar.tsx +++ b/services/next/app/components/navbar.tsx @@ -5,7 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons"; import { faUser, faUpload } from "@fortawesome/free-solid-svg-icons"; import Link from 'next/link' -import { LoginButton, useAuth } from '@/app/components/auth' +import { LoginButton } from '@/app/components/auth' export default function Navbar() { @@ -16,12 +16,12 @@ export default function Navbar() { setExpanded(!isExpanded); }; - const { authData } = useAuth() + // const { authData } = useAuth() - useEffect(() => { - if (!!authData?.accessToken && !!authData?.user?.username) setIsProfileButton(true) - else setIsProfileButton(false) - }, [authData]) + // useEffect(() => { + // if (!!authData?.accessToken && !!authData?.user?.username) setIsProfileButton(true) + // else setIsProfileButton(false) + // }, [authData]) return ( <> @@ -83,7 +83,8 @@ export default function Navbar() { icon={faUser} className="fas fa-user-large mr-1" > - { authData?.user?.username || 'profile' } + {/* { authData?.user?.username || 'profile' } */} + Profile ) : ( diff --git a/services/next/app/components/supertokensProvider.tsx b/services/next/app/components/supertokensProvider.tsx new file mode 100644 index 0000000..d5b58aa --- /dev/null +++ b/services/next/app/components/supertokensProvider.tsx @@ -0,0 +1,18 @@ +'use client'; +import React from 'react'; +import { SuperTokensWrapper } from 'supertokens-auth-react'; +import SuperTokensReact from 'supertokens-auth-react'; +import { frontendConfig, setRouter } from '../config/frontend'; +import { usePathname, useRouter } from 'next/navigation'; + +if (typeof window !== 'undefined') { + // we only want to call this init function on the frontend, so we check typeof window !== 'undefined' + SuperTokensReact.init(frontendConfig()); +} + +export const SuperTokensProvider: React.FC> = ({ + children, +}) => { + setRouter(useRouter(), usePathname() || window.location.pathname); + return {children}; +}; \ No newline at end of file diff --git a/services/next/app/components/tagger.tsx b/services/next/app/components/tagger.tsx index 8ec4874..e919a78 100644 --- a/services/next/app/components/tagger.tsx +++ b/services/next/app/components/tagger.tsx @@ -87,9 +87,11 @@ export function Tagger({ vod, setTimestamps }: ITaggerProps): React.JSX.Element async function getRandomSuggestions() { - const res = await fetch(`${strapiUrl}/api/tag/random`); - const tags = await res.json(); - setTagSuggestions(tags) + // @todo https://gitea.futureporn.net/futureporn/pm/issues/129 + setTagSuggestions([]) + // const res = await fetch(`${strapiUrl}/api/tag/random`); + // const tags = await res.json(); + // setTagSuggestions(tags) } async function search(value: string) { diff --git a/services/next/app/components/user-controls.tsx b/services/next/app/components/user-controls.tsx index 07f23ad..fb32c4c 100644 --- a/services/next/app/components/user-controls.tsx +++ b/services/next/app/components/user-controls.tsx @@ -46,6 +46,7 @@ export default function UserControls() { const [errors, setErrors] = useState([]) const [vanityLink, setVanityLink] = useState('') + return

@todo user-controls.tsx

const { authData, setAuthData } = useAuth() @@ -108,6 +109,7 @@ export function SaveButton({ errors, setErrors, }: ISaveButtonProps) { + return

@todo user-controls.tsx

const { authData } = useAuth(); const handleClick = async () => { if (!authData?.user) return; diff --git a/services/next/app/components/video-player.tsx b/services/next/app/components/video-player.tsx index 8b5bf34..3d00326 100644 --- a/services/next/app/components/video-player.tsx +++ b/services/next/app/components/video-player.tsx @@ -50,7 +50,7 @@ function hexToRgba(hex: string, alpha: number) { export const VideoPlayer = forwardRef(function VideoPlayer( props: IPlayerProps, ref: Ref ): React.JSX.Element { const { vod, setIsPlayerReady } = props const title: string = getVodTitle(vod); - const { authData } = useAuth(); + // const { authData } = useAuth(); const [selectedVideoSource, setSelectedVideoSource] = useState(''); const [isEntitledToCDN, setIsEntitledToCDN] = useState(false); const [hlsSource, setHlsSource] = useState(''); @@ -102,7 +102,7 @@ export const VideoPlayer = forwardRef(function VideoPlayer( props: IPlayerProps, setPlaybackId(''); setSrc(buildIpfsUrl(vod.attributes.video240Hash)) } - }, [selectedVideoSource, authData, vod, setHlsSource]); + }, [selectedVideoSource, vod, setHlsSource]); if (!isClient) return <> diff --git a/services/next/app/components/vod-card.tsx b/services/next/app/components/vod-card.tsx index 7798baf..7a3c03f 100644 --- a/services/next/app/components/vod-card.tsx +++ b/services/next/app/components/vod-card.tsx @@ -16,7 +16,7 @@ interface IVodCardProps { export default function VodCard({id, title, date, muxAsset, thumbnail = 'https://futureporn-b2.b-cdn.net/default-thumbnail.webp', vtuber}: IVodCardProps) { - if (!vtuber?.attributes?.slug) return

VOD {id} is missing VTuber

+ if (!vtuber?.attributes?.slug) return

VOD {id} is missing VTuber

return (
diff --git a/services/next/app/components/vod-page.tsx b/services/next/app/components/vod-page.tsx index ebd8b51..eed0735 100644 --- a/services/next/app/components/vod-page.tsx +++ b/services/next/app/components/vod-page.tsx @@ -13,7 +13,7 @@ import Thumbnail from './thumbnail'; export function getVodTitle(vod: IVod): string { // console.log('lets getVodTitle, ey?') // console.log(JSON.stringify(vod, null, 2)) - return vod.attributes?.title || vod.attributes?.announceTitle || `VOD ${vod.id}` + return vod.attributes?.title || vod.attributes?.announce_title || `VOD ${vod.id}` // return vod.attributes.title || vod.attributes.announceTitle || (vod.attributes?.date2 && vod.attributes?.vtuber?.data?.attributes?.displayName) ? `${vod.attributes.vtuber.data.attributes.displayName} ${vod.attributes.date2}` : `VOD ${vod.id}`; } diff --git a/services/next/app/config/appInfo.ts b/services/next/app/config/appInfo.ts new file mode 100644 index 0000000..b4e152c --- /dev/null +++ b/services/next/app/config/appInfo.ts @@ -0,0 +1,8 @@ +export const appInfo = { + // learn more about this on https://supertokens.com/docs/thirdpartyemailpassword/appinfo + appName: "futureporn", + apiDomain: "https://next.fp.sbtp.xyz", + websiteDomain: "https://next.fp.sbtp.xyz", + apiBasePath: "/api/auth", + websiteBasePath: "/auth" +} \ No newline at end of file diff --git a/services/next/app/config/backend.ts b/services/next/app/config/backend.ts new file mode 100644 index 0000000..ae97019 --- /dev/null +++ b/services/next/app/config/backend.ts @@ -0,0 +1,75 @@ +import SuperTokens from "supertokens-node"; +import ThirdPartyNode from "supertokens-node/recipe/thirdparty" +import SessionNode from 'supertokens-node/recipe/session' +import Dashboard from "supertokens-node/recipe/dashboard"; +import UserRoles from "supertokens-node/recipe/userroles" +import { appInfo } from './appInfo' +import { TypeInput } from "supertokens-node/types"; +import { configs } from './configs' + +const apiKey = configs.supertokensApiKeys.split(',').at(0) + +export const backendConfig = (): TypeInput => { + return { + framework: "custom", + supertokens: { + apiKey, + connectionURI: configs.supertokensUrl + }, + appInfo, + recipeList: [ + Dashboard.init({ + admins: [ + "cj@futureporn.net", + ], + }), + UserRoles.init(), + ThirdPartyNode.init({ + // We have provided you with development keys which you can use for testing. + // IMPORTANT: Please replace them with your own OAuth keys for production use. + signInAndUpFeature: { + providers: [{ + config: { + requireEmail: false, + authorizationEndpoint: 'https://www.patreon.com/oauth2/authorize', + tokenEndpoint: 'https://www.patreon.com/api/oauth2/token', + userInfoEndpoint: 'https://www.patreon.com/api/oauth2/v2/identity', + name: 'Patreon', + thirdPartyId: 'patreon', + clients: [{ + scope: ['identity', 'identity.memberships'], + clientId: configs.patreonClientId, + clientSecret: configs.patreonClientSecret + }], + userInfoEndpointQueryParams: { + // 'include': 'memberships,memberships.currently_entitled_tiers,memberships.currently_entitled_tiers.benefits,memberships.campaign', + 'fields[user]': 'full_name,email', + // 'fields[member]': 'full_name,is_follower,patron_status,currently_entitled_amount_cents,campaign_lifetime_support_cents', + // 'fields[tier]': 'title', + // 'fields[benefit]': 'title', + }, + userInfoMap: { + fromUserInfoAPI: { + userId: "data.id", // Maps to the "id" field under "data" + email: "data.attributes.email", // Maps to the "email" field in "data.attributes" + } + } + } + }, + ], + } + }), + SessionNode.init(), + ], + isInServerlessEnv: true, + } +} + +let initialized = false; +// This function is used in your APIs to make sure SuperTokens is initialised +export function ensureSuperTokensInit() { + if (!initialized) { + SuperTokens.init(backendConfig()); + initialized = true; + } +} \ No newline at end of file diff --git a/services/next/app/config/configs.ts b/services/next/app/config/configs.ts new file mode 100644 index 0000000..d2660ac --- /dev/null +++ b/services/next/app/config/configs.ts @@ -0,0 +1,43 @@ + +// if (!process.env.PATREON_CLIENT_ID) throw new Error("PATREON_CLIENT_ID was missing from env"); +// if (!process.env.PATREON_CLIENT_SECRET) throw new Error('Missing PATREON_CLIENT_SECRET env var'); +if (!process.env.NEXT_PUBLIC_API_DOMAIN) throw new Error('Missing NEXT_PUBLIC_API_DOMAIN env var'); +if (!process.env.NEXT_PUBLIC_WEBSITE_DOMAIN) throw new Error('Missing NEXT_PUBLIC_WEBSITE_DOMAIN env var'); +if (!process.env.SUPERTOKENS_API_KEYS) throw new Error('SUPERTOKENS_API_KEYS was undefined in env'); +if (!process.env.SUPERTOKENS_URL) throw new Error('SUPERTOKENS_URL missing in env'); +if (!process.env.PATREON_CLIENT_ID) throw new Error('PATREON_CLIENT_ID missing in env'); +if (!process.env.PATREON_CLIENT_SECRET) throw new Error('PATREON_CLIENT_SECRET missing in env'); + +const patreonClientId = process.env.PATREON_CLIENT_ID! +const patreonClientSecret = process.env.PATREON_CLIENT_SECRET! +const apiDomain = process.env.NEXT_PUBLIC_API_DOMAIN! +const websiteDomain = process.env.NEXT_PUBLIC_WEBSITE_DOMAIN! +const logtoCookieSecret = process.env.LOGTO_COOKIE_SECRET! +const logtoAppId = process.env.LOGTO_APP_ID! +const logtoAppSecret = process.env.LOGTO_APP_SECRET! +const supertokensApiKeys = process.env.SUPERTOKENS_API_KEYS! +const supertokensUrl = process.env.SUPERTOKENS_URL! + +export interface Config { + patreonClientId: string; + patreonClientSecret: string; + apiDomain: string; + websiteDomain: string; + logtoCookieSecret: string; + logtoAppSecret: string; + logtoAppId: string; + supertokensApiKeys: string; + supertokensUrl: string; +} + +export const configs: Config = { + patreonClientId, + patreonClientSecret, + apiDomain, + websiteDomain, + logtoCookieSecret, + logtoAppSecret, + logtoAppId, + supertokensApiKeys, + supertokensUrl, +} diff --git a/services/next/app/config/frontend.tsx b/services/next/app/config/frontend.tsx new file mode 100644 index 0000000..bd199f0 --- /dev/null +++ b/services/next/app/config/frontend.tsx @@ -0,0 +1,48 @@ +// import PasswordlessReact from 'supertokens-auth-react/recipe/passwordless' +import ThirdPartyReact from 'supertokens-auth-react/recipe/thirdparty' +import SessionReact from 'supertokens-auth-react/recipe/session' +import { appInfo } from './appInfo' +import { SuperTokensConfig } from 'supertokens-auth-react/lib/build/types' +import { useRouter } from "next/navigation"; +import { faPatreon } from '@fortawesome/free-brands-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +const routerInfo: { router?: ReturnType; pathName?: string } = {}; + +export function setRouter( + router: ReturnType, + pathName: string, +) { + routerInfo.router = router; + routerInfo.pathName = pathName; +} + +export const frontendConfig = (): SuperTokensConfig => { + return { + appInfo, + recipeList: [ + ThirdPartyReact.init({ + signInAndUpFeature: { + providers: [ + ThirdPartyReact.Github.init(), + { + id: 'patreon', + name: 'Patreon', + logo: , + } + ], + }, + }), + SessionReact.init(), + ], + windowHandler: (original) => ({ + ...original, + location: { + ...original.location, + getPathName: () => routerInfo.pathName!, + assign: (url) => routerInfo.router!.push(url.toString()), + setHref: (url) => routerInfo.router!.push(url.toString()), + }, + }), + } +} \ No newline at end of file diff --git a/services/next/app/layout.tsx b/services/next/app/layout.tsx index 2de8eaf..ea68f3f 100644 --- a/services/next/app/layout.tsx +++ b/services/next/app/layout.tsx @@ -7,6 +7,7 @@ import "@fortawesome/fontawesome-svg-core/styles.css"; import { AuthProvider } from './components/auth'; import type { Metadata } from 'next'; import NotificationCenter from './components/notification-center'; +import { SuperTokensProvider } from "./components/supertokensProvider"; // import { // QueryClientProvider, // QueryClient @@ -48,29 +49,32 @@ export default function RootLayout({ }: Props) { return ( - - {/* */} - - {/* */} - - -
- {children} -
-
- {/*
*/} -
- + + {/* */} + {/* */} + + {/* */} + {/* */} + + +
+ {children} + {/*
*/} +
+ {/*
*/} + {/*
*/} + + ) } diff --git a/services/next/app/lib/constants.ts b/services/next/app/lib/constants.ts index 18f163b..2261167 100644 --- a/services/next/app/lib/constants.ts +++ b/services/next/app/lib/constants.ts @@ -5,6 +5,9 @@ if (!process.env.NEXT_PUBLIC_UPPY_COMPANION_URL) throw new Error('NEXT_PUBLIC_UP export const companionUrl = ''+process.env.NEXT_PUBLIC_UPPY_COMPANION_URL export const siteUrl = ''+process.env.NEXT_PUBLIC_SITE_URL export const strapiUrl = ''+process.env.NEXT_PUBLIC_STRAPI_URL +export const postgrestUrl = ''+process.env.NEXT_PUBLIC_POSTGREST_URL +export const postgrestLocalUrl = 'http://postgrest.futureporn.svc.cluster.local:9000' +export const patreonCampaignId: string = '8012692' export const patreonSupporterBenefitId: string = '4760169' export const patreonQuantumSupporterId: string = '10663202' export const patreonVideoAccessBenefitId: string = '13462019' diff --git a/services/next/app/lib/dates.ts b/services/next/app/lib/dates.ts index 5d7c8ca..743ffcf 100644 --- a/services/next/app/lib/dates.ts +++ b/services/next/app/lib/dates.ts @@ -1,7 +1,6 @@ import { parse } from 'date-fns'; import { format } from 'date-fns-tz' -import utcToZonedTime from 'date-fns-tz/utcToZonedTime' -import zonedTimeToUtc from 'date-fns-tz/zonedTimeToUtc' +import { toZonedTime, fromZonedTime } from 'date-fns-tz' const safeDateFormatString: string = "yyyyMMdd'T'HHmmss'Z'" const localTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; @@ -11,7 +10,7 @@ export function getSafeDate(date: string | Date): string { let dateString: string; if (typeof date === 'string') { - const dateObject = utcToZonedTime(date, 'UTC'); + const dateObject = toZonedTime(date, 'UTC'); dateString = format(dateObject, safeDateFormatString, { timeZone: 'UTC' }); } else { dateString = format(date, safeDateFormatString, { timeZone: 'UTC' }); @@ -23,7 +22,7 @@ export function getSafeDate(date: string | Date): string { export function getDateFromSafeDate(safeDate: string): Date { const date = parse(safeDate, safeDateFormatString, new Date()) - const utcDate = zonedTimeToUtc(date, 'UTC') + const utcDate = fromZonedTime(date, 'UTC') return utcDate; } diff --git a/services/next/app/lib/fetch-api.ts b/services/next/app/lib/fetch-api.ts index 918d3bd..76bf82f 100644 --- a/services/next/app/lib/fetch-api.ts +++ b/services/next/app/lib/fetch-api.ts @@ -1,7 +1,7 @@ // greets https://github.com/strapi/nextjs-corporate-starter/blob/main/frontend/src/app/%5Blang%5D/utils/fetch-api.tsx#L4 import qs from "qs"; -import { strapiUrl } from "./constants"; +import { postgrestLocalUrl, strapiUrl } from "./constants"; export default async function fetchAPI( path: string, @@ -20,8 +20,8 @@ export default async function fetchAPI( // Build request URL const queryString = qs.stringify(urlParamsObject); - const requestUrl = `${strapiUrl}/api${path}${queryString ? `?${queryString}` : ""}`; - console.log(`fetching ${requestUrl}`) + const requestUrl = `${postgrestLocalUrl}${path}${queryString ? `?${queryString}` : ""}`; + console.log(`fetching--> ${requestUrl}`) // Trigger API call const response = await fetch(requestUrl, mergedOptions); diff --git a/services/next/app/lib/patreon.ts b/services/next/app/lib/patreon.ts index 7f40556..e13ae34 100644 --- a/services/next/app/lib/patreon.ts +++ b/services/next/app/lib/patreon.ts @@ -1,10 +1,6 @@ -import { strapiUrl, patreonVideoAccessBenefitId, giteaUrl } from './constants' +import { postgrestLocalUrl, patreonVideoAccessBenefitId, giteaUrl } from './constants' import { IAuthData } from '@/app/components/auth'; - -export interface IPatron { - username: string; - vanityLink?: string; -} +import { type IPatron } from '@futureporn/types' export interface ICampaign { @@ -32,15 +28,18 @@ export function isEntitledToPatronVideoAccess(authData: IAuthData): boolean { export async function getPatrons(): Promise { + let patrons = [] try { - const res = await fetch(`${strapiUrl}/api/patreon/patrons`); + const res = await fetch(`${postgrestLocalUrl}/patrons`); const data = await res.json(); - if (!data.data) throw new Error(`no patron data was available. ${JSON.stringify(data)}`); + if (!data) throw new Error(`no patron data was available. ${JSON.stringify(data)}`); + patrons = data.map((patron: IPatron) => patron.username) } catch (e) { - console.error('failed to get patrons list') + console.error('failed to get patrons~ list') console.error(e) return [] as IPatron[] } + return patrons } diff --git a/services/next/app/lib/vods.ts b/services/next/app/lib/vods.ts index ded8c94..9223efe 100644 --- a/services/next/app/lib/vods.ts +++ b/services/next/app/lib/vods.ts @@ -1,5 +1,5 @@ -import { strapiUrl, siteUrl } from './constants'; +import { postgrestLocalUrl, siteUrl } from './constants'; import { getDateFromSafeDate, getSafeDate } from './dates'; import { IVtuber, IVtuberResponse, IStream, IStreamResponse } from '@futureporn/types'; import qs from 'qs'; @@ -129,7 +129,7 @@ export async function getNextVod(vod: IVod): Promise { } } }) - const res = await fetch(`${strapiUrl}/api/vods?${query}`, fetchVodsOptions); + const res = await fetch(`${postgrestLocalUrl}/vods?${query}`, fetchVodsOptions); if (!res.ok) throw new Error('could not fetch next vod'); const json = await res.json(); const nextVod = json.data[0]; @@ -206,7 +206,7 @@ export async function getVodByCuid(cuid: string): Promise { }) try { - const res = await fetch(`${strapiUrl}/api/vods?${query}`, { cache: 'no-store', next: { tags: ['vods'] } }) + const res = await fetch(`${postgrestLocalUrl}/vods?${query}`, { cache: 'no-store', next: { tags: ['vods'] } }) if (!res.ok) { throw new Error('failed to fetch vodForDate') } @@ -258,7 +258,7 @@ export async function getVodForDate(date: Date): Promise { } } ) - const res = await fetch(`${strapiUrl}/api/vods?${query}`, { cache: 'no-store', next: { tags: ['vods'] } }) + const res = await fetch(`${postgrestLocalUrl}/vods?${query}`, { cache: 'no-store', next: { tags: ['vods'] } }) if (!res.ok) { throw new Error('failed to fetch vodForDate') } @@ -282,7 +282,7 @@ export async function getVod(id: number): Promise { } } ) - const res = await fetch(`${strapiUrl}/api/vods?${query}`, fetchVodsOptions); + const res = await fetch(`${postgrestLocalUrl}/vods?${query}`, fetchVodsOptions); if (!res.ok) return null; const data = await res.json(); return data; @@ -291,37 +291,38 @@ export async function getVod(id: number): Promise { export async function getVods(page: number = 1, pageSize: number = 25, sortDesc = true): Promise { const query = qs.stringify( { - populate: { - vtuber: { - fields: ['slug', 'displayName', 'image', 'imageBlur'] - }, - muxAsset: { - fields: ['playbackId', 'assetId'] - }, - thumbnail: { - fields: ['cdnUrl', 'url'] - }, - tagVodRelations: { - fields: ['tag'], - populate: ['tag'] - }, - videoSrcB2: { - fields: ['url', 'key', 'uploadId', 'cdnUrl'] - } - }, - sort: { - date: (sortDesc) ? 'desc' : 'asc' - }, - pagination: { - pageSize: pageSize, - page: page - } + // populate: { + // vtuber: { + // fields: ['slug', 'displayName', 'image', 'imageBlur'] + // }, + // muxAsset: { + // fields: ['playbackId', 'assetId'] + // }, + // thumbnail: { + // fields: ['cdnUrl', 'url'] + // }, + // tagVodRelations: { + // fields: ['tag'], + // populate: ['tag'] + // }, + // videoSrcB2: { + // fields: ['url', 'key', 'uploadId', 'cdnUrl'] + // } + // }, + // sort: { + // date: (sortDesc) ? 'desc' : 'asc' + // }, + // pagination: { + // pageSize: pageSize, + // page: page + // } } ) - const res = await fetch(`${strapiUrl}/api/vods?${query}`, fetchVodsOptions); + console.log(`postgrestLocalUrl=${postgrestLocalUrl} query=${query}`) + const res = await fetch(`${postgrestLocalUrl}/vods?${query}`, fetchVodsOptions); if (!res.ok) { - throw new Error('Failed to fetch vods'); + throw new Error(`Failed to fetch vods status=${res.status}, statusText=${res.statusText}`); } const json = await res.json() return json; @@ -366,7 +367,7 @@ export async function getAllVods(): Promise { }); try { - const response = await fetch(`${strapiUrl}/api/vods?${query}`, fetchVodsOptions); + const response = await fetch(`${postgrestLocalUrl}/vods?${query}`, fetchVodsOptions); if (!response.ok) { // Handle non-successful response (e.g., HTTP error) @@ -432,7 +433,7 @@ export async function getVodsForVtuber(vtuberId: number, page: number = 1, pageS } } ) - const res = await fetch(`${strapiUrl}/api/vods?${query}`, fetchVodsOptions) + const res = await fetch(`${postgrestLocalUrl}/vods?${query}`, fetchVodsOptions) if (!res.ok) return null; const data = await res.json() as IVodsResponse; return data; @@ -462,7 +463,7 @@ export async function getVodsForTag(tag: string): Promise { } } ) - const res = await fetch(`${strapiUrl}/api/vods?${query}`, fetchVodsOptions) + const res = await fetch(`${postgrestLocalUrl}/vods?${query}`, fetchVodsOptions) if (!res.ok) return null; const vods = await res.json() return vods; @@ -483,7 +484,7 @@ export async function getProgress(vtuberSlug: string): Promise<{ complete: numbe } } }) - const data = await fetch(`${strapiUrl}/api/vods?${query}`, fetchVodsOptions) + const data = await fetch(`${postgrestLocalUrl}/vods?${query}`, fetchVodsOptions) .then((res) => res.json()) .then((g) => { return g diff --git a/services/next/app/logto.ts b/services/next/app/logto.ts new file mode 100644 index 0000000..bc999e6 --- /dev/null +++ b/services/next/app/logto.ts @@ -0,0 +1,11 @@ +import { LogtoNextConfig } from "@logto/next"; +import { configs } from "./config/configs"; + +export const logtoConfig: LogtoNextConfig = { + endpoint: 'https://logto.fp.sbtp.xyz/', + appId: configs.logtoAppId, + appSecret: configs.logtoAppSecret, + baseUrl: configs.websiteDomain, + cookieSecret: configs.logtoCookieSecret, + cookieSecure: process.env.NODE_ENV === 'production', +}; \ No newline at end of file diff --git a/services/next/app/page.tsx b/services/next/app/page.tsx index 7f5b2ef..586cecb 100644 --- a/services/next/app/page.tsx +++ b/services/next/app/page.tsx @@ -9,15 +9,22 @@ import { getVtubers } from "./lib/vtubers"; import VTuberCard from "./components/vtuber-card"; import Link from 'next/link'; import { notFound } from "next/navigation"; +// import { getLogtoContext, signIn, signOut } from '@logto/next/server-actions'; +// import SignIn from './sign-in'; +// import SignOut from './sign-out'; +// import { logtoConfig } from './logto'; export default async function Page() { + + // const { isAuthenticated, claims } = await getLogtoContext(logtoConfig); + const vods = await getVods(1, 9, true); // console.log('vods as follows') // console.log(JSON.stringify(vods, null, 2)) const vtubers = await getVtubers(); - if (!vtubers) notFound(); + // if (!vtubers) notFound(); // console.log(`vtubers as follows`) // console.log(JSON.stringify(vtubers, null, 2)) @@ -26,7 +33,7 @@ export default async function Page() { // return ( //
   //     
-  //       {JSON.stringify(vods.data, null, 2)}
+  //       {JSON.stringify(vods, null, 2)}
   //     
   //   
// ) @@ -44,20 +51,27 @@ export default async function Page() { + Login +

Latest VODs

- {vods.data.map((vod: IVod) => ( + + {!vods?.data &&

Error: Failed to fetch VODs from the database

} + + + + {vods && vods.map((vod: IVod) => ( ))}
diff --git a/services/next/app/sign-in.tsx b/services/next/app/sign-in.tsx new file mode 100644 index 0000000..ae47881 --- /dev/null +++ b/services/next/app/sign-in.tsx @@ -0,0 +1,19 @@ +'use client'; + +type Props = { + onSignIn: () => Promise; +}; + +const SignIn = ({ onSignIn }: Props) => { + return ( +
{ + onSignIn(); + }} + > + Sign In +
+ ); +}; + +export default SignIn; \ No newline at end of file diff --git a/services/next/app/sign-out.tsx b/services/next/app/sign-out.tsx new file mode 100644 index 0000000..504b139 --- /dev/null +++ b/services/next/app/sign-out.tsx @@ -0,0 +1,19 @@ +'use client'; + +type Props = { + onSignOut: () => Promise; +}; + +const SignOut = ({ onSignOut }: Props) => { + return ( +
{ + onSignOut(); + }} + > + Sign Out +
+ ); +}; + +export default SignOut; \ No newline at end of file diff --git a/services/next/app/uppy.tsx b/services/next/app/uppy.tsx index 20a9401..1fdda93 100644 --- a/services/next/app/uppy.tsx +++ b/services/next/app/uppy.tsx @@ -4,7 +4,7 @@ import React, { useState, createContext, useContext, useEffect } from 'react'; import Uppy from '@uppy/core'; import AwsS3 from '@uppy/aws-s3'; import RemoteSources from '@uppy/remote-sources'; -import { useAuth } from './components/auth'; +// import { useAuth } from './components/auth'; import { companionUrl } from '@/app/lib/constants'; @@ -14,44 +14,44 @@ import { companionUrl } from '@/app/lib/constants'; export const UppyContext = createContext(new Uppy()); -export default function UppyProvider({ - children -}: { - children: React.ReactNode -}) { - const { authData } = useAuth(); - const uppy = new Uppy( - // const [uppy] = useState(() => new Uppy( - { - autoProceed: true, - debug: true, - logger: { - debug: console.info, - warn: console.log, - error: console.error - }, +// export default function UppyProvider({ +// children +// }: { +// children: React.ReactNode +// }) { +// // const { authData } = useAuth(); +// const uppy = new Uppy( +// // const [uppy] = useState(() => new Uppy( +// { +// autoProceed: true, +// debug: true, +// logger: { +// debug: console.info, +// warn: console.log, +// error: console.error +// }, - } - ) - .use(RemoteSources, { - companionUrl, - title: 'testing 123', - }) - .use(AwsS3, { - companionUrl, - shouldUseMultipart: true, - abortMultipartUpload: () => {}, // @see https://github.com/transloadit/uppy/issues/1197#issuecomment-491756118 - companionHeaders: { - 'authorization': `Bearer ${authData?.accessToken}` - } - }) - // ); +// } +// ) +// .use(RemoteSources, { +// companionUrl, +// title: 'testing 123', +// }) +// .use(AwsS3, { +// companionUrl, +// shouldUseMultipart: true, +// abortMultipartUpload: () => {}, // @see https://github.com/transloadit/uppy/issues/1197#issuecomment-491756118 +// companionHeaders: { +// 'authorization': `Bearer ${authData?.accessToken}` +// } +// }) +// // ); - return ( - - {children} - - ) -} +// return ( +// +// {children} +// +// ) +// } diff --git a/services/next/logto.ts b/services/next/logto.ts new file mode 100644 index 0000000..e2fc8fb --- /dev/null +++ b/services/next/logto.ts @@ -0,0 +1,13 @@ +import { UserScope } from '@logto/next'; + +export const logtoConfig = { + appId: process.env.APP_ID ?? '', + appSecret: process.env.APP_SECRET ?? '', + endpoint: process.env.ENDPOINT ?? 'http://localhost:3001', + baseUrl: process.env.BASE_URL ?? 'http://localhost:3000', + cookieSecret: process.env.COOKIE_SECRET ?? 'complex_password_at_least_32_characters_long', + cookieSecure: process.env.NODE_ENV === 'production', + // Optional fields for RBAC + resources: process.env.RESOURCES?.split(','), + scopes: process.env.SCOPES?.split(',') ?? [UserScope.Organizations, UserScope.OrganizationRoles], +}; \ No newline at end of file diff --git a/services/next/package.json b/services/next/package.json index 4bf62db..9d8bd34 100644 --- a/services/next/package.json +++ b/services/next/package.json @@ -20,6 +20,7 @@ "@futureporn/types": "workspace:*", "@hookform/error-message": "^2.0.1", "@hookform/resolvers": "^3.9.0", + "@logto/next": "^3.7.1", "@mux/blurhash": "^0.1.2", "@mux/mux-player": "^2.9.1", "@mux/mux-player-react": "^2.9.1", @@ -44,6 +45,7 @@ "date-fns": "^3.6.0", "date-fns-tz": "^3.1.3", "dayjs": "^1.11.13", + "dotenv": "^16.4.5", "feed": "^4.2.2", "gray-matter": "^4.0.3", "hls.js": "^1.5.15", @@ -52,6 +54,7 @@ "multiformats": "^13.2.2", "next": "14.2.7", "next-goatcounter": "^1.0.5", + "nextjs-cors": "^2.2.0", "nextjs-toploader": "^3.6.15", "plyr": "^3.7.8", "prism-react-renderer": "^2.4.0", @@ -66,6 +69,9 @@ "sharp": "^0.33.5", "slugify": "^1.6.6", "styled-components": "6.1.13", + "supertokens-auth-react": "^0.48.0", + "supertokens-node": "^21.0.0", + "supertokens-web-js": "^0.14.0", "yup": "^1.4.0" }, "devDependencies": { diff --git a/services/next/pnpm-lock.yaml b/services/next/pnpm-lock.yaml index d928ca0..adab63d 100644 --- a/services/next/pnpm-lock.yaml +++ b/services/next/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: '@hookform/resolvers': specifier: ^3.9.0 version: 3.9.0(react-hook-form@7.53.0(react@18.3.1)) + '@logto/next': + specifier: ^3.7.1 + version: 3.7.1(next@14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8)) '@mux/blurhash': specifier: ^0.1.2 version: 0.1.2 @@ -104,6 +107,9 @@ importers: dayjs: specifier: ^1.11.13 version: 1.11.13 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 feed: specifier: ^4.2.2 version: 4.2.2 @@ -128,6 +134,9 @@ importers: next-goatcounter: specifier: ^1.0.5 version: 1.0.5(next@14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nextjs-cors: + specifier: ^2.2.0 + version: 2.2.0(next@14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8)) nextjs-toploader: specifier: ^3.6.15 version: 3.6.15(next@14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -170,6 +179,15 @@ importers: styled-components: specifier: 6.1.13 version: 6.1.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + supertokens-auth-react: + specifier: ^0.48.0 + version: 0.48.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supertokens-web-js@0.14.0) + supertokens-node: + specifier: ^21.0.0 + version: 21.0.0 + supertokens-web-js: + specifier: ^0.14.0 + version: 0.14.0 yup: specifier: ^1.4.0 version: 1.4.0 @@ -187,8 +205,40 @@ importers: specifier: 5.5.4 version: 5.5.4 + ../..: {} + + ../../packages/fetchers: {} + + ../../packages/infra: {} + + ../../packages/storage: {} + + ../../packages/types: {} + + ../../packages/utils: {} + + ../bot: {} + + ../capture: {} + + ../factory: {} + + ../mailbox: {} + + ../migrations: {} + + ../scout: {} + + ../strapi: {} + + ../uppy: {} + packages: + '@edge-runtime/cookies@4.1.1': + resolution: {integrity: sha512-ATZLTOpnCUD9ZLNBIXhxOmP/UVx6BfhCjDy9P1YACpD8vrHb5Uw7YlG9RYUl1AMF7Y10TIIN3jhFbUSMiH2J7g==} + engines: {node: '>=16'} + '@emnapi/runtime@1.2.0': resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} @@ -382,6 +432,20 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@logto/client@2.8.1': + resolution: {integrity: sha512-tUQC36l9U3knrTicXFjd+FiBqwG1/KSGn1o3wx9DFn+5iSTQa66B+Y88GaXcxAYsgjzmSHrDY3qxuQg729mleQ==} + + '@logto/js@4.2.0': + resolution: {integrity: sha512-kse29kNKuM/tw30YcOf2eOQuFBlGPZTr4rKI/LpdTKhk0fLGM5ZJKPQWNPiPFZdBfTldERXVNtd17/bZLWc/OQ==} + + '@logto/next@3.7.1': + resolution: {integrity: sha512-ZMk+yszQV9N7y21oT+V0c1bE88ffDdJJKJtXxpFHAEwjwXFgIfxlpWnmXppb5v3Zkf/SISFEyFTGYqIB9l7rDg==} + peerDependencies: + next: '>=12' + + '@logto/node@2.5.8': + resolution: {integrity: sha512-QNVWIZf6sLAbF6rDT/wAG64S4IH5OQYk38fJvJYuIuMRHhUDf2VD+ENZ5BBwX3sOHFf6OM4rJVt2vWVJ8kTVow==} + '@mux/blurhash@0.1.2': resolution: {integrity: sha512-fWLOXHS2l3CGyPHF4NSRLqZx9DDAz1WYC4YXD3du24xxibIKUyBYzg7PDtx54z5QaQ12ln5oPFvhH5LhaLzeZg==} @@ -514,6 +578,10 @@ packages: '@rushstack/eslint-patch@1.10.4': resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} + '@silverhand/essentials@2.9.2': + resolution: {integrity: sha512-bD+82D9Dfa1F5xX1kfdR5ODIoJS41NOxTuHx4shVS5A4/ayEG+ZplpDDjB19fsa7kZXgSgD75R4sUCXjm88x6w==} + engines: {node: ^18.12.0 || ^20.9.0 || ^22.0.0, pnpm: ^9.0.0} + '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} @@ -753,6 +821,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -824,6 +896,9 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -832,6 +907,9 @@ packages: resolution: {integrity: sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g==} engines: {node: '>=4'} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + axobject-query@3.1.1: resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} @@ -861,9 +939,18 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browser-tabs-lock@1.3.0: + resolution: {integrity: sha512-g6nHaobTiT0eMZ7jh16YpD2kcjAp+PInbiVq3M1x6KKaEIVhT4v9oURNIpZLOZ3LQbQ3XYfNhMAb/9hzNLIWrw==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bulma@1.0.2: resolution: {integrity: sha512-D7GnDuF6seb6HkcnRMM9E739QpEY9chDzzeFrHMyEns/EXyDJuQ0XA0KxbBl/B2NTsKSoDomW61jFGFaAxhK5A==} @@ -879,6 +966,14 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camelcase-keys@7.0.2: + resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==} + engines: {node: '>=12'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} @@ -923,16 +1018,42 @@ packages: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + core-js@3.38.1: resolution: {integrity: sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==} + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + css-color-keywords@1.0.0: resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} engines: {node: '>=4'} @@ -1019,6 +1140,10 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + detect-libc@2.0.3: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} @@ -1031,9 +1156,16 @@ packages: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1259,6 +1391,15 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -1266,6 +1407,10 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -1362,6 +1507,10 @@ packages: hls.js@1.5.15: resolution: {integrity: sha512-6cD7xN6bycBHaXz2WyPIaHn/iXFizE5au2yvY5q9aC4wfihxAr16C9fUy4nxh2a3wOw0fEgLRa9dN6wsYjlpNg==} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1390,6 +1539,9 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} + intl-tel-input@17.0.21: + resolution: {integrity: sha512-TfyPxLe41QZPOf6RqBxRE2dpQ0FThB/PBD/gRbxVhGW7IuYg30QD90x/vjmEo4vkZw7j8etxpVcjIZVRcG+Otw==} + is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -1530,6 +1682,15 @@ packages: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} + jose@4.15.9: + resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + + jose@5.9.6: + resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} + + js-base64@3.7.7: + resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1554,10 +1715,20 @@ packages: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true + jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + + jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1576,6 +1747,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + libphonenumber-js@1.11.12: + resolution: {integrity: sha512-QkJn9/D7zZ1ucvT++TQSvZuSA2xAWeUytU+DiEQwbPKLyrDpvbul2AFs1CGbRAPpSCCk47aRAb5DX5mmcayp4g==} + loadjs@4.3.0: resolution: {integrity: sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ==} @@ -1583,9 +1757,30 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -1599,6 +1794,10 @@ packages: lunarphase-js@2.0.3: resolution: {integrity: sha512-zTr/UWbxQ1lyKgaBnyJ/DvKCPONhZQcwmQ8PuF2g2QwdkF8JkhgPe8QlDroxSjZrfpg/9x6jQ6lFtBkSXXf1oQ==} + map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + media-chrome@3.2.5: resolution: {integrity: sha512-tTsgS7x77Bn4p/wca/Si/7A+Q3z9DzKq0SOkroQvrNMXBVyQasMayDcsKg5Ur5NGsymZfttnJi7tXvVr/tPj8g==} @@ -1616,9 +1815,17 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + mime-match@1.0.2: resolution: {integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -1700,6 +1907,11 @@ packages: sass: optional: true + nextjs-cors@2.2.0: + resolution: {integrity: sha512-FZu/A+L59J4POJNqwXYyCPDvsLDeu5HjSBvytzS6lsrJeDz5cmnH45zV+VoNic0hjaeER9xGaiIjZIWzEHnxQg==} + peerDependencies: + next: ^8.1.1-canary.54 || ^9.0.0 || ^10.0.0-0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 + nextjs-toploader@3.6.15: resolution: {integrity: sha512-DMxO0BiT+NbGU7E9A8U2+0e7rRbG9qozbk19DFXhKRc9wuhgTPR/u8zr2TevsbFtVxDb9mf8YHFz+oBgjMC+HA==} peerDependencies: @@ -1714,6 +1926,19 @@ packages: node-addon-api@5.1.0: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + nodemailer@6.9.16: + resolution: {integrity: sha512-psAuZdTIRN08HKVd/E8ObdV6NO7NTBY3KsC30F7M4H1OnmLCUNaS56FpYxyb26zWLSyYF9Ozch9KYHhHegsiOQ==} + engines: {node: '>=6.0.0'} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -1784,6 +2009,9 @@ packages: resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==} engines: {node: '>=14.16'} + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1814,6 +2042,9 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + pkce-challenge@3.1.0: + resolution: {integrity: sha512-bQ/0XPZZ7eX+cdAkd61uYWpfMhakH3NeteUF1R8GNa+LMqX8QFAkbCLqq+AYAns1/ueACBu/BMWhrlKGrdvGZg==} + plyr@3.7.8: resolution: {integrity: sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==} @@ -1849,12 +2080,19 @@ packages: peerDependencies: react: '>=16.0.0' + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} property-expr@2.0.6: resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -1862,13 +2100,23 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qr.js@0.0.0: + resolution: {integrity: sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==} + qs@6.13.0: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + rangetouch@2.0.1: resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==} @@ -1901,6 +2149,11 @@ packages: peerDependencies: react: '>=16.8.0' + react-qr-code@2.0.15: + resolution: {integrity: sha512-MkZcjEXqVKqXEIMVE0mbcGgDpkfSdd8zhuzXEl9QzYeNcw8Hq2oVIzDLWuZN2PQBwM5PWjc2S31K8Q1UbcFMfw==} + peerDependencies: + react: '*' + react-toastify@10.0.5: resolution: {integrity: sha512-mNKt2jBXJg4O7pSdbNUfDdTsK9FIdikfsIE/yUCxbAEXl4HMyJaivrVFcn3Elvt5xvCQYhUZm+hqTIu1UXM3Pw==} peerDependencies: @@ -1927,6 +2180,9 @@ packages: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -1975,6 +2231,9 @@ packages: scheduler@0.23.2: resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + scmp@2.1.0: + resolution: {integrity: sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==} + section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} @@ -1988,6 +2247,9 @@ packages: engines: {node: '>=10'} hasBin: true + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2137,6 +2399,26 @@ packages: stylis@4.3.2: resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==} + supertokens-auth-react@0.48.0: + resolution: {integrity: sha512-JDahnvSKahso6LbD3Oe/e2Ifxz/dg7kMVGnlt+sZbz/kNSQAKk7yaTrxrCemcNDw5IDB9etheCVrLu7ye/ndmQ==} + engines: {node: '>=16.0.0', npm: '>=8'} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + supertokens-web-js: ^0.14.0 + + supertokens-js-override@0.0.4: + resolution: {integrity: sha512-r0JFBjkMIdep3Lbk3JA+MpnpuOtw4RSyrlRAbrzMcxwiYco3GFWl/daimQZ5b1forOiUODpOlXbSOljP/oyurg==} + + supertokens-node@21.0.0: + resolution: {integrity: sha512-2Ui7uoLEDXjk39rny/EONslZm4tc5ISS/bup93MNnCxY3BDOmn5f9Qyvori66jIDDOVbPD0kQLlE4RD61i8jtg==} + + supertokens-web-js@0.14.0: + resolution: {integrity: sha512-p4HZ580YX9UYFfY9Sv2VzBQOilqHnNzhrmHlOc45oMxqr/vqvqf+Ih7OXS1lx6RUVmQT8TAsLlFFKIWslIkbHA==} + + supertokens-website@20.1.5: + resolution: {integrity: sha512-2yN42BvHY41/pNIFdJTKSRW3sWZzfOY607i6cY+WWjHSAx7ppMgujyk8tKj+fiQ4MLWCk3HL6QsXZl0zLV4yEw==} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2162,6 +2444,13 @@ packages: tiny-case@1.0.3: resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==} + tldts-core@6.1.58: + resolution: {integrity: sha512-dR936xmhBm7AeqHIhCWwK765gZ7dFyL+IqLSFAjJbFlUXGMLCb8i2PzlzaOuWBuplBTaBYseSb565nk/ZEM0Bg==} + + tldts@6.1.58: + resolution: {integrity: sha512-MQJrJhjHOYGYb8DobR6Y4AdDbd4TYkyQ+KBDVc5ODzs1cbrvPpfN1IemYi9jfipJ/vR1YWvrDli0hg1y19VRoA==} + hasBin: true + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -2169,6 +2458,9 @@ packages: toposort@2.0.2: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + ts-api-utils@1.3.0: resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} @@ -2187,10 +2479,18 @@ packages: tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + twilio@4.23.0: + resolution: {integrity: sha512-LdNBQfOe0dY2oJH2sAsrxazpgfFQo5yXGxe96QA8UWB5uu+433PrUbkv8gQ5RmrRCqUTPQ0aOrIyAdBr1aB03Q==} + engines: {node: '>=14.0'} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} @@ -2225,6 +2525,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + url-polyfill@1.1.12: resolution: {integrity: sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==} @@ -2236,6 +2539,16 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -2278,6 +2591,10 @@ packages: resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} hasBin: true + xmlbuilder@13.0.2: + resolution: {integrity: sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==} + engines: {node: '>=6.0'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -2287,6 +2604,8 @@ packages: snapshots: + '@edge-runtime/cookies@4.1.1': {} + '@emnapi/runtime@1.2.0': dependencies: tslib: 2.7.0 @@ -2453,6 +2772,31 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@logto/client@2.8.1': + dependencies: + '@logto/js': 4.2.0 + '@silverhand/essentials': 2.9.2 + camelcase-keys: 7.0.2 + jose: 5.9.6 + + '@logto/js@4.2.0': + dependencies: + '@silverhand/essentials': 2.9.2 + camelcase-keys: 7.0.2 + + '@logto/next@3.7.1(next@14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))': + dependencies: + '@edge-runtime/cookies': 4.1.1 + '@logto/node': 2.5.8 + cookie: 0.6.0 + next: 14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) + + '@logto/node@2.5.8': + dependencies: + '@logto/client': 2.8.1 + '@silverhand/essentials': 2.9.2 + js-base64: 3.7.7 + '@mux/blurhash@0.1.2': dependencies: blurhash: 1.1.5 @@ -2555,6 +2899,8 @@ snapshots: '@rushstack/eslint-patch@1.10.4': {} + '@silverhand/essentials@2.9.2': {} + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.5': @@ -2860,6 +3206,12 @@ snapshots: acorn@8.12.1: {} + agent-base@6.0.2: + dependencies: + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -2961,12 +3313,22 @@ snapshots: ast-types-flow@0.0.8: {} + asynckit@0.4.0: {} + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 axe-core@4.10.0: {} + axios@1.7.7(debug@4.3.6): + dependencies: + follow-redirects: 1.15.9(debug@4.3.6) + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axobject-query@3.1.1: dependencies: deep-equal: 2.2.3 @@ -2998,11 +3360,22 @@ snapshots: dependencies: fill-range: 7.1.1 + browser-tabs-lock@1.3.0: + dependencies: + lodash: 4.17.21 + + buffer-equal-constant-time@1.0.1: {} + buffer@5.7.1: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bulma@1.0.2: {} busboy@1.6.0: @@ -3019,6 +3392,15 @@ snapshots: callsites@3.1.0: {} + camelcase-keys@7.0.2: + dependencies: + camelcase: 6.3.0 + map-obj: 4.3.0 + quick-lru: 5.1.1 + type-fest: 1.4.0 + + camelcase@6.3.0: {} + camelize@1.0.1: {} caniuse-lite@1.0.30001655: {} @@ -3068,16 +3450,39 @@ snapshots: color-convert: 2.0.1 color-string: 1.9.1 + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + concat-map@0.0.1: {} + content-type@1.0.5: {} + + cookie@0.6.0: {} + + cookie@0.7.2: {} + core-js@3.38.1: {} + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-fetch@3.1.8: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 + crypto-js@4.2.0: {} + css-color-keywords@1.0.0: {} css-to-react-native@3.2.0: @@ -3171,6 +3576,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delayed-stream@1.0.0: {} + detect-libc@2.0.3: {} dir-glob@3.0.1: @@ -3181,8 +3588,14 @@ snapshots: dependencies: esutils: 2.0.3 + dotenv@16.4.5: {} + eastasianwidth@0.2.0: {} + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -3310,7 +3723,7 @@ snapshots: eslint: 9.9.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@9.9.1))(eslint@9.9.1) - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3)(eslint@9.9.1) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@9.9.1))(eslint@9.9.1))(eslint@9.9.1) eslint-plugin-jsx-a11y: 6.9.0(eslint@9.9.1) eslint-plugin-react: 7.35.1(eslint@9.9.1) eslint-plugin-react-hooks: 4.6.2(eslint@9.9.1) @@ -3341,7 +3754,7 @@ snapshots: is-bun-module: 1.1.0 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3)(eslint@9.9.1) + eslint-plugin-import: 2.30.0(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@9.9.1))(eslint@9.9.1))(eslint@9.9.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node @@ -3359,7 +3772,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3)(eslint@9.9.1): + eslint-plugin-import@2.30.0(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@7.2.0(eslint@9.9.1)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.30.0(eslint@9.9.1))(eslint@9.9.1))(eslint@9.9.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -3553,6 +3966,10 @@ snapshots: flatted@3.3.1: {} + follow-redirects@1.15.9(debug@4.3.6): + optionalDependencies: + debug: 4.3.6 + for-each@0.3.3: dependencies: is-callable: 1.2.7 @@ -3562,6 +3979,12 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + fs-constants@1.0.0: {} fsevents@2.3.3: @@ -3665,6 +4088,13 @@ snapshots: hls.js@1.5.15: {} + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -3688,6 +4118,8 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 + intl-tel-input@17.0.21: {} + is-arguments@1.1.1: dependencies: call-bind: 1.0.7 @@ -3819,6 +4251,12 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jose@4.15.9: {} + + jose@5.9.6: {} + + js-base64@3.7.7: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -3840,6 +4278,19 @@ snapshots: dependencies: minimist: 1.2.8 + jsonwebtoken@9.0.2: + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.6.3 + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -3847,6 +4298,17 @@ snapshots: object.assign: 4.1.5 object.values: 1.2.0 + jwa@1.4.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@3.2.2: + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3864,14 +4326,30 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + libphonenumber-js@1.11.12: {} + loadjs@4.3.0: {} locate-path@6.0.0: dependencies: p-locate: 5.0.0 + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + lodash.merge@4.6.2: {} + lodash.once@4.1.1: {} + lodash@4.17.21: {} loose-envify@1.4.0: @@ -3882,6 +4360,8 @@ snapshots: lunarphase-js@2.0.3: {} + map-obj@4.3.0: {} + media-chrome@3.2.5: {} media-tracks@0.3.3: {} @@ -3895,10 +4375,16 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 + mime-db@1.52.0: {} + mime-match@1.0.2: dependencies: wildcard: 1.1.2 + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mimic-response@3.1.0: {} minimatch@3.1.2: @@ -3969,6 +4455,11 @@ snapshots: - '@babel/core' - babel-plugin-macros + nextjs-cors@2.2.0(next@14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8)): + dependencies: + cors: 2.8.5 + next: 14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) + nextjs-toploader@3.6.15(next@14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: next: 14.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.8) @@ -3983,6 +4474,12 @@ snapshots: node-addon-api@5.1.0: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + nodemailer@6.9.16: {} + normalize-path@3.0.0: {} nprogress@0.2.0: {} @@ -4064,6 +4561,8 @@ snapshots: p-timeout@6.1.2: {} + pako@2.1.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -4085,6 +4584,10 @@ snapshots: picomatch@2.3.1: {} + pkce-challenge@3.1.0: + dependencies: + crypto-js: 4.2.0 + plyr@3.7.8: dependencies: core-js: 3.38.1 @@ -4134,6 +4637,8 @@ snapshots: clsx: 2.1.1 react: 18.3.1 + process@0.11.10: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -4142,6 +4647,8 @@ snapshots: property-expr@2.0.6: {} + proxy-from-env@1.1.0: {} + pump@3.0.0: dependencies: end-of-stream: 1.4.4 @@ -4149,12 +4656,18 @@ snapshots: punycode@2.3.1: {} + qr.js@0.0.0: {} + qs@6.13.0: dependencies: side-channel: 1.0.6 + querystringify@2.2.0: {} + queue-microtask@1.2.3: {} + quick-lru@5.1.1: {} + rangetouch@2.0.1: {} rc@1.2.8: @@ -4186,6 +4699,12 @@ snapshots: dependencies: react: 18.3.1 + react-qr-code@2.0.15(react@18.3.1): + dependencies: + prop-types: 15.8.1 + qr.js: 0.0.0 + react: 18.3.1 + react-toastify@10.0.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: clsx: 2.1.1 @@ -4223,6 +4742,8 @@ snapshots: es-errors: 1.3.0 set-function-name: 2.0.2 + requires-port@1.0.0: {} + resolve-from@4.0.0: {} resolve-pkg-maps@1.0.0: {} @@ -4274,6 +4795,8 @@ snapshots: dependencies: loose-envify: 1.4.0 + scmp@2.1.0: {} + section-matter@1.0.0: dependencies: extend-shallow: 2.0.1 @@ -4283,6 +4806,8 @@ snapshots: semver@7.6.3: {} + set-cookie-parser@2.7.1: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -4478,6 +5003,49 @@ snapshots: stylis@4.3.2: {} + supertokens-auth-react@0.48.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supertokens-web-js@0.14.0): + dependencies: + intl-tel-input: 17.0.21 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-qr-code: 2.0.15(react@18.3.1) + supertokens-js-override: 0.0.4 + supertokens-web-js: 0.14.0 + + supertokens-js-override@0.0.4: {} + + supertokens-node@21.0.0: + dependencies: + buffer: 6.0.3 + content-type: 1.0.5 + cookie: 0.7.2 + cross-fetch: 3.1.8 + debug: 4.3.6 + jose: 4.15.9 + libphonenumber-js: 1.11.12 + nodemailer: 6.9.16 + pako: 2.1.0 + pkce-challenge: 3.1.0 + process: 0.11.10 + set-cookie-parser: 2.7.1 + supertokens-js-override: 0.0.4 + tldts: 6.1.58 + twilio: 4.23.0(debug@4.3.6) + transitivePeerDependencies: + - encoding + - supports-color + + supertokens-web-js@0.14.0: + dependencies: + supertokens-js-override: 0.0.4 + supertokens-website: 20.1.5 + + supertokens-website@20.1.5: + dependencies: + browser-tabs-lock: 1.3.0 + supertokens-js-override: 0.0.4 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -4505,12 +5073,20 @@ snapshots: tiny-case@1.0.3: {} + tldts-core@6.1.58: {} + + tldts@6.1.58: + dependencies: + tldts-core: 6.1.58 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 toposort@2.0.2: {} + tr46@0.0.3: {} + ts-api-utils@1.3.0(typescript@5.5.4): dependencies: typescript: 5.5.4 @@ -4530,10 +5106,26 @@ snapshots: dependencies: safe-buffer: 5.2.1 + twilio@4.23.0(debug@4.3.6): + dependencies: + axios: 1.7.7(debug@4.3.6) + dayjs: 1.11.13 + https-proxy-agent: 5.0.1 + jsonwebtoken: 9.0.2 + qs: 6.13.0 + scmp: 2.1.0 + url-parse: 1.5.10 + xmlbuilder: 13.0.2 + transitivePeerDependencies: + - debug + - supports-color + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 + type-fest@1.4.0: {} + type-fest@2.19.0: {} typed-array-buffer@1.0.2: @@ -4583,6 +5175,11 @@ snapshots: dependencies: punycode: 2.3.1 + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + url-polyfill@1.1.12: {} use-sync-external-store@1.2.2(react@18.3.1): @@ -4591,6 +5188,15 @@ snapshots: util-deprecate@1.0.2: {} + vary@1.1.2: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 @@ -4655,6 +5261,8 @@ snapshots: dependencies: sax: 1.4.1 + xmlbuilder@13.0.2: {} + yocto-queue@0.1.0: {} yup@1.4.0: diff --git a/services/strapi/database/migrations/2023.05.11T12.32.00.convert-to-video-src-b2.js.noexec b/services/strapi/database/migrations/2023.05.11T12.32.00.convert-to-video-src-b2.js.noexec index 41d8608..0ccaeb3 100644 --- a/services/strapi/database/migrations/2023.05.11T12.32.00.convert-to-video-src-b2.js.noexec +++ b/services/strapi/database/migrations/2023.05.11T12.32.00.convert-to-video-src-b2.js.noexec @@ -13,7 +13,7 @@ async function getFileDetailsFromUrl(url) { let retries = 10; while (retries) { - console.log(`fetching ${url}`); + console.log(`fetching~~ ${url}`); const timeoutId = setTimeout(() => { console.log('fetch timed out, aborting...'); controller.abort(); @@ -95,4 +95,4 @@ module.exports = { } } }, -}; \ No newline at end of file +};