From b2b8af670c8adbf057a679655597db3c81c1a96c Mon Sep 17 00:00:00 2001 From: TrueCharts-Bot Date: Sun, 13 Nov 2022 11:10:49 +0000 Subject: [PATCH] Commit new Chart releases for TrueCharts Signed-off-by: TrueCharts-Bot --- stable/traefik/15.1.0/CHANGELOG.md | 99 + stable/traefik/15.1.0/Chart.yaml | 31 + stable/traefik/15.1.0/README.md | 108 + stable/traefik/15.1.0/app-changelog.md | 9 + stable/traefik/15.1.0/app-readme.md | 8 + .../traefik/15.1.0/charts/common-10.9.7.tgz | Bin 0 -> 48224 bytes stable/traefik/15.1.0/ix_values.yaml | 406 +++ stable/traefik/15.1.0/questions.yaml | 2487 +++++++++++++++++ stable/traefik/15.1.0/templates/_args.tpl | 178 ++ stable/traefik/15.1.0/templates/_helpers.tpl | 22 + .../15.1.0/templates/_ingressclass.tpl | 24 + .../15.1.0/templates/_ingressroute.tpl | 25 + .../traefik/15.1.0/templates/_portalhook.tpl | 26 + .../traefik/15.1.0/templates/_tlsoptions.tpl | 12 + stable/traefik/15.1.0/templates/common.yaml | 24 + .../templates/middlewares/addPrefix.yaml | 17 + .../middlewares/basic-middleware.yaml | 62 + .../templates/middlewares/basicauth.yaml | 34 + .../15.1.0/templates/middlewares/chain.yaml | 21 + .../templates/middlewares/forwardauth.yaml | 34 + .../templates/middlewares/geoblock.yaml | 34 + .../templates/middlewares/ipwhitelist.yaml | 33 + .../templates/middlewares/ratelimit.yaml | 19 + .../15.1.0/templates/middlewares/real-ip.yaml | 21 + .../templates/middlewares/redirectScheme.yaml | 19 + .../templates/middlewares/redirectregex.yaml | 20 + .../middlewares/stripPrefixRegex.yaml | 20 + .../templates/middlewares/tc-chains.yaml | 29 + .../templates/middlewares/tc-headers.yaml | 62 + .../templates/middlewares/tc-nextcloud.yaml | 25 + .../templates/middlewares/theme-park.yaml | 26 + stable/traefik/15.1.0/values.yaml | 0 32 files changed, 3935 insertions(+) create mode 100644 stable/traefik/15.1.0/CHANGELOG.md create mode 100644 stable/traefik/15.1.0/Chart.yaml create mode 100644 stable/traefik/15.1.0/README.md create mode 100644 stable/traefik/15.1.0/app-changelog.md create mode 100644 stable/traefik/15.1.0/app-readme.md create mode 100644 stable/traefik/15.1.0/charts/common-10.9.7.tgz create mode 100644 stable/traefik/15.1.0/ix_values.yaml create mode 100644 stable/traefik/15.1.0/questions.yaml create mode 100644 stable/traefik/15.1.0/templates/_args.tpl create mode 100644 stable/traefik/15.1.0/templates/_helpers.tpl create mode 100644 stable/traefik/15.1.0/templates/_ingressclass.tpl create mode 100644 stable/traefik/15.1.0/templates/_ingressroute.tpl create mode 100644 stable/traefik/15.1.0/templates/_portalhook.tpl create mode 100644 stable/traefik/15.1.0/templates/_tlsoptions.tpl create mode 100644 stable/traefik/15.1.0/templates/common.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/addPrefix.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/basic-middleware.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/basicauth.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/chain.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/forwardauth.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/geoblock.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/ipwhitelist.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/ratelimit.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/real-ip.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/redirectScheme.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/redirectregex.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/stripPrefixRegex.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/tc-chains.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/tc-headers.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/tc-nextcloud.yaml create mode 100644 stable/traefik/15.1.0/templates/middlewares/theme-park.yaml create mode 100644 stable/traefik/15.1.0/values.yaml diff --git a/stable/traefik/15.1.0/CHANGELOG.md b/stable/traefik/15.1.0/CHANGELOG.md new file mode 100644 index 00000000000..f80fcb741ad --- /dev/null +++ b/stable/traefik/15.1.0/CHANGELOG.md @@ -0,0 +1,99 @@ +**Important:** +*for the complete changelog, please refer to the website* + + + + + +## [traefik-13.5.5](https://github.com/truecharts/charts/compare/traefik-13.5.2...traefik-13.5.5) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4349](https://github.com/truecharts/charts/issues/4349)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [traefik-13.5.4](https://github.com/truecharts/charts/compare/traefik-13.5.2...traefik-13.5.4) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [traefik-13.5.4](https://github.com/truecharts/charts/compare/traefik-13.5.2...traefik-13.5.4) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [traefik-13.5.4](https://github.com/truecharts/charts/compare/traefik-13.5.2...traefik-13.5.4) (2022-11-08) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4342](https://github.com/truecharts/charts/issues/4342)) + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [traefik-13.5.3](https://github.com/truecharts/charts/compare/traefik-13.5.2...traefik-13.5.3) (2022-11-07) + +### Chore + +- Auto-update chart README [skip ci] + - Auto-update chart README [skip ci] + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [traefik-13.5.3](https://github.com/truecharts/charts/compare/traefik-13.5.2...traefik-13.5.3) (2022-11-06) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4329](https://github.com/truecharts/charts/issues/4329)) + + + + +## [traefik-13.5.2](https://github.com/truecharts/charts/compare/traefik-13.5.1...traefik-13.5.2) (2022-11-06) + +### Chore + +- Auto-update chart README [skip ci] + - update helm general non-major ([#4317](https://github.com/truecharts/charts/issues/4317)) + + + + +## [traefik-13.5.1](https://github.com/truecharts/charts/compare/traefik-13.5.0...traefik-13.5.1) (2022-11-05) + diff --git a/stable/traefik/15.1.0/Chart.yaml b/stable/traefik/15.1.0/Chart.yaml new file mode 100644 index 00000000000..2763f4d899e --- /dev/null +++ b/stable/traefik/15.1.0/Chart.yaml @@ -0,0 +1,31 @@ +apiVersion: v2 +appVersion: "2.9.4" +dependencies: + - name: common + repository: https://library-charts.truecharts.org + version: 10.9.7 +deprecated: false +description: Traefik is a flexible reverse proxy and Ingress Provider. +home: https://truecharts.org/docs/charts/stable/traefik +icon: https://truecharts.org/img/hotlink-ok/chart-icons/traefik.png +keywords: + - traefik + - ingress +kubeVersion: ">=1.16.0-0" +maintainers: + - email: info@truecharts.org + name: TrueCharts + url: https://truecharts.org +name: traefik +sources: + - https://github.com/truecharts/charts/tree/master/charts/stable/traefik + - https://github.com/traefik/traefik + - https://github.com/traefik/traefik-helm-chart + - https://traefik.io/ +type: application +version: 15.1.0 +annotations: + truecharts.org/catagories: | + - network + truecharts.org/SCALE-support: "true" + truecharts.org/grade: U diff --git a/stable/traefik/15.1.0/README.md b/stable/traefik/15.1.0/README.md new file mode 100644 index 00000000000..ce7731c07fa --- /dev/null +++ b/stable/traefik/15.1.0/README.md @@ -0,0 +1,108 @@ +# traefik + +Traefik is a flexible reverse proxy and Ingress Provider. + +TrueCharts can be installed as both *normal* Helm Charts or as Apps on TrueNAS SCALE. + +This readme is just an automatically generated general guide on installing our Helm Charts and Apps. +For more information, please click here: [traefik](https://truecharts.org/docs/charts/stable/traefik) + +**This chart is not maintained by the upstream project and any issues with the chart should be raised [here](https://github.com/truecharts/charts/issues/new/choose)** + +## Source Code + +* +* +* +* + +## Requirements + +Kubernetes: `>=1.16.0-0` + +## Dependencies + +| Repository | Name | Version | +|------------|------|---------| +| https://library-charts.truecharts.org | common | 10.9.4 | + +## Installing the Chart + +### TrueNAS SCALE + +To install this Chart on TrueNAS SCALE check our [Quick-Start Guide](https://truecharts.org/docs/manual/SCALE%20Apps/Installing-an-App). + +### Helm + +To install the chart with the release name `traefik` + +```console +helm repo add TrueCharts https://charts.truecharts.org +helm repo update +helm install traefik TrueCharts/traefik +``` + +## Uninstall + +### TrueNAS SCALE + +**Upgrading, Rolling Back and Uninstalling the Chart** + +To upgrade, rollback or delete this Chart from TrueNAS SCALE check our [Quick-Start Guide](https://truecharts.org/docs/manual/SCALE%20Apps/Upgrade-rollback-delete-an-App). + +### Helm + +To uninstall the `traefik` deployment + +```console +helm uninstall traefik +``` + +## Configuration + +### Helm + +#### Available Settings + +Read through the values.yaml file. It has several commented out suggested values. +Other values may be used from the [values.yaml](https://github.com/truecharts/library-charts/tree/main/charts/stable/common/values.yaml) from the [common library](https://github.com/truecharts/library-charts/tree/main/charts/common). + +#### Configure using the command line + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +```console +helm install traefik \ + --set env.TZ="America/New York" \ + TrueCharts/traefik +``` + +#### Configure using a yaml file + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. + +```console +helm install traefik TrueCharts/traefik -f values.yaml +``` + +#### Connecting to other charts + +If you need to connect this Chart to other Charts on TrueNAS SCALE, please refer to our [Linking Charts Internally](https://truecharts.org/docs/manual/SCALE%20Apps/linking-apps) quick-start guide. + +## Support + +- Please check our [quick-start guides for TrueNAS SCALE](https://truecharts.org/docs/manual/SCALE%20Apps/Important-MUST-READ). +- See the [Website](https://truecharts.org) +- Check our [Discord](https://discord.gg/tVsPTHWTtr) +- Open a [issue](https://github.com/truecharts/apps/issues/new/choose) + +--- + +## Sponsor TrueCharts + +TrueCharts can only exist due to the incredible effort of our staff. +Please consider making a [donation](https://truecharts.org/sponsor) or contributing back to the project any way you can! + +--- + +All Rights Reserved - The TrueCharts Project diff --git a/stable/traefik/15.1.0/app-changelog.md b/stable/traefik/15.1.0/app-changelog.md new file mode 100644 index 00000000000..405a571be36 --- /dev/null +++ b/stable/traefik/15.1.0/app-changelog.md @@ -0,0 +1,9 @@ + + +## [traefik-15.1.0](https://github.com/truecharts/charts/compare/traefik-15.0.1...traefik-15.1.0) (2022-11-13) + +### Feat + +- add geoblock middleware ([#4396](https://github.com/truecharts/charts/issues/4396)) + + \ No newline at end of file diff --git a/stable/traefik/15.1.0/app-readme.md b/stable/traefik/15.1.0/app-readme.md new file mode 100644 index 00000000000..b76832bd9a2 --- /dev/null +++ b/stable/traefik/15.1.0/app-readme.md @@ -0,0 +1,8 @@ +Traefik is a flexible reverse proxy and Ingress Provider. + +This App is supplied by TrueCharts, for more information visit the manual: [https://truecharts.org/docs/charts/stable/traefik](https://truecharts.org/docs/charts/stable/traefik) + +--- + +TrueCharts can only exist due to the incredible effort of our staff. +Please consider making a [donation](https://truecharts.org/docs/about/sponsor) or contributing back to the project any way you can! diff --git a/stable/traefik/15.1.0/charts/common-10.9.7.tgz b/stable/traefik/15.1.0/charts/common-10.9.7.tgz new file mode 100644 index 0000000000000000000000000000000000000000..3bb192f016c53a80cb8ed717cf4b645c364ae158 GIT binary patch literal 48224 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ⅅYd0t0+#dLo`znMm@+FzD{NKt(3&5 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 literal 0 HcmV?d00001 diff --git a/stable/traefik/15.1.0/ix_values.yaml b/stable/traefik/15.1.0/ix_values.yaml new file mode 100644 index 00000000000..a85f8b10ab9 --- /dev/null +++ b/stable/traefik/15.1.0/ix_values.yaml @@ -0,0 +1,406 @@ +image: + repository: tccr.io/truecharts/traefik + # defaults to appVersion + tag: 2.9.4@sha256:7c5f07ef67ec092b66dd8bdb56279ed876965553ee5ec59b5aa7456def5ed1f3 + pullPolicy: IfNotPresent + +# -- Use ingressClass. Ignored if Traefik version < 2.3 / kubernetes < 1.18.x +ingressClass: + # true is not unit-testable yet, pending https://github.com/rancher/helm-unittest/pull/12 + enabled: false + isDefaultClass: false + # Use to force a networking.k8s.io API Version for certain CI/CD applications. E.g. "v1beta1" + fallbackApiVersion: "" + +# -- Create an IngressRoute for the dashboard +ingressRoute: + dashboard: + enabled: true + # Additional ingressRoute annotations (e.g. for kubernetes.io/ingress.class) + annotations: {} + # Additional ingressRoute labels (e.g. for filtering IngressRoute by custom labels) + labels: {} + +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/path: "/metrics" + prometheus.io/port: "9180" + +# +# -- Configure providers +providers: + kubernetesCRD: + enabled: true + namespaces: + [] + # - "default" + kubernetesIngress: + enabled: true + # labelSelector: environment=production,method=traefik + namespaces: + [] + # - "default" + # IP used for Kubernetes Ingress endpoints + publishedService: + enabled: true + # Published Kubernetes Service to copy status from. Format: namespace/servicename + # By default this Traefik service + # pathOverride: "" + +# -- Logs +# https://docs.traefik.io/observability/logs/ +logs: + # Traefik logs concern everything that happens to Traefik itself (startup, configuration, events, shutdown, and so on). + general: + # By default, the level is set to ERROR. Alternative logging levels are DEBUG, PANIC, FATAL, ERROR, WARN, and INFO. + level: ERROR + # -- Set the format of General Logs to be either Common Log Format or JSON. For more information: https://doc.traefik.io/traefik/observability/logs/#format + format: common + access: + # To enable access logs + enabled: false + # To write the logs in an asynchronous fashion, specify a bufferingSize option. + # This option represents the number of log lines Traefik will keep in memory before writing + # them to the selected output. In some cases, this option can greatly help performances. + # bufferingSize: 100 + # Filtering https://docs.traefik.io/observability/access-logs/#filtering + filters: + {} + # statuscodes: "200,300-302" + # retryattempts: true + # minduration: 10ms + # Fields + # https://docs.traefik.io/observability/access-logs/#limiting-the-fieldsincluding-headers + fields: + general: + defaultmode: keep + names: + {} + # Examples: + # ClientUsername: drop + headers: + defaultmode: drop + names: + {} + # Examples: + # User-Agent: redact + # Authorization: drop + # Content-Type: keep + # -- Set the format of Access Logs to be either Common Log Format or JSON. For more information: https://doc.traefik.io/traefik/observability/access-logs/#format + format: common + +metrics: + # datadog: + # address: 127.0.0.1:8125 + # influxdb: + # address: localhost:8089 + # protocol: udp + prometheus: + entryPoint: metrics + # statsd: + # address: localhost:8125 + +globalArguments: + - "--global.checknewversion" + +## +# -- Additional arguments to be passed at Traefik's binary +# All available options available on https://docs.traefik.io/reference/static-configuration/cli/ +## Use curly braces to pass values: `helm install --set="additionalArguments={--providers.kubernetesingress.ingressclass=traefik-internal,--log.level=DEBUG}"` +additionalArguments: + - "--metrics.prometheus" + - "--ping" + - "--serverstransport.insecureskipverify=true" + - "--providers.kubernetesingress.allowexternalnameservices=true" + +# -- TLS Options to be created as TLSOption CRDs +# https://doc.traefik.io/tccr.io/truecharts/https/tls/#tls-options +# Example: +tlsOptions: + default: + sniStrict: false + minVersion: VersionTLS12 + curvePreferences: + - CurveP521 + - CurveP384 + cipherSuites: + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + - TLS_AES_128_GCM_SHA256 + - TLS_AES_256_GCM_SHA384 + - TLS_CHACHA20_POLY1305_SHA256 + +# -- Options for the main traefik service, where the entrypoints traffic comes from +# from. +service: + main: + type: LoadBalancer + ports: + main: + port: 9000 + targetPort: 9000 + protocol: HTTP + # -- Forwarded Headers should never be enabled on Main entrypoint + forwardedHeaders: + enabled: false + # -- Proxy Protocol should never be enabled on Main entrypoint + proxyProtocol: + enabled: false + tcp: + enabled: true + type: LoadBalancer + ports: + web: + enabled: true + port: 9080 + protocol: HTTP + redirectTo: websecure + # Options: Empty, 0 (ingore), or positive int + # redirectPort: + # -- Configure (Forwarded Headers)[https://doc.traefik.io/traefik/routing/entrypoints/#forwarded-headers] Support + forwardedHeaders: + enabled: false + # -- List of trusted IP and CIDR references + trustedIPs: [] + # -- Trust all forwarded headers + insecureMode: false + # -- Configure (Proxy Protocol Headers)[https://doc.traefik.io/traefik/routing/entrypoints/#proxyprotocol] Support + proxyProtocol: + enabled: false + # -- Only IPs in trustedIPs will lead to remote client address replacement + trustedIPs: [] + # -- Trust every incoming connection + insecureMode: false + websecure: + enabled: true + port: 9443 + protocol: HTTPS + # -- Configure (Forwarded Headers)[https://doc.traefik.io/traefik/routing/entrypoints/#forwarded-headers] Support + forwardedHeaders: + enabled: false + # -- List of trusted IP and CIDR references + trustedIPs: [] + # -- Trust all forwarded headers + insecureMode: false + # -- Configure (Proxy Protocol Headers)[https://doc.traefik.io/traefik/routing/entrypoints/#proxyprotocol] Support + proxyProtocol: + enabled: false + # -- Only IPs in trustedIPs will lead to remote client address replacement + trustedIPs: [] + # -- Trust every incoming connection + insecureMode: false + # tcpexample: + # enabled: true + # targetPort: 9443 + # protocol: TCP + # tls: + # enabled: false + # # this is the name of a TLSOption definition + # options: "" + # certResolver: "" + # domains: [] + # # - main: example.com + # # sans: + # # - foo.example.com + # # - bar.example.com + metrics: + enabled: true + type: ClusterIP + ports: + metrics: + enabled: true + port: 9180 + targetPort: 9180 + protocol: HTTP + # -- Forwarded Headers should never be enabled on Metrics entrypoint + forwardedHeaders: + enabled: false + # -- Proxy Protocol should never be enabled on Metrics entrypoint + proxyProtocol: + enabled: false + udp: + enabled: false + +# probes: +# # -- Liveness probe configuration +# # @default -- See below +# liveness: +# # -- sets the probe type when not using a custom probe +# # @default -- "TCP" +# type: HTTP +# # -- If a HTTP probe is used (default for HTTP/HTTPS services) this path is used +# # @default -- "/" +# path: "/ping" + +# # -- Redainess probe configuration +# # @default -- See below +# readiness: +# # -- sets the probe type when not using a custom probe +# # @default -- "TCP" +# type: HTTP +# # -- If a HTTP probe is used (default for HTTP/HTTPS services) this path is used +# # @default -- "/" +# path: "/ping" + +# # -- Startup probe configuration +# # @default -- See below +# startup: +# # -- sets the probe type when not using a custom probe +# # @default -- "TCP" +# type: HTTP +# # -- If a HTTP probe is used (default for HTTP/HTTPS services) this path is used +# # @default -- "/" +# path: "/ping" + +# -- Whether Role Based Access Control objects like roles and rolebindings should be created +rbac: + main: + enabled: true + rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - extensions + - networking.k8s.io + resources: + - ingresses + - ingressclasses + verbs: + - get + - list + - watch + - apiGroups: + - extensions + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update + - apiGroups: + - traefik.containo.us + resources: + - ingressroutes + - ingressroutetcps + - ingressrouteudps + - middlewares + - middlewaretcps + - tlsoptions + - tlsstores + - traefikservices + - serverstransports + verbs: + - get + - list + - watch + +# -- The service account the pods will use to interact with the Kubernetes API +serviceAccount: + main: + enabled: true + +# -- SCALE Middleware Handlers +middlewares: + basicAuth: [] + # - name: basicauthexample + # users: + # - username: testuser + # password: testpassword + forwardAuth: [] + # - name: forwardAuthexample + # address: https://auth.example.com/ + # authResponseHeaders: + # - X-Secret + # - X-Auth-User + # authRequestHeaders: + # - "Accept" + # - "X-CustomHeader" + # authResponseHeadersRegex: "^X-" + # trustForwardHeader: true + chain: [] + # - name: chainname + # middlewares: + # - name: compress + redirectScheme: [] + # - name: redirectSchemeName + # scheme: https + # permanent: true + rateLimit: [] + # - name: rateLimitName + # average: 300 + # burst: 200 + redirectRegex: [] + # - name: redirectRegexName + # regex: putregexhere + # replacement: replacementurlhere + # permanent: false + stripPrefixRegex: [] + # - name: stripPrefixRegexName + # regex: [] + ipWhiteList: [] + # - name: ipWhiteListName + # sourceRange: [] + # ipStrategy: + # depth: 2 + # excludedIPs: [] + themeParkVersion: v1.2.2 + themePark: [] + # - name: themeParkName + # -- Supported apps, lower case name + # -- https://docs.theme-park.dev/themes + # app: appnamehere + # -- Supported themes, lower case name + # -- https://docs.theme-park.dev/themes/APPNAMEHERE + # -- https://docs.theme-park.dev/community-themes + # theme: themenamehere + # -- https://theme-park.dev or a self hosted url + # baseUrl: https://theme-park.dev + realIPVersion: v1.0.3 + # Sets X-Real-Ip with an IP from the X-Forwarded-For or + # Cf-Connecting-Ip (If from Cloudflare) + # Evaluation of those headers will go from last to first + realIP: [] + # - name: realIPName + # -- The real IP will be the first one that is + # -- not included in any of the CIDRs passed here + # excludedNetworks: + # - 1.1.1.1/24 + addPrefix: [] + # - name: addPrefixName + # prefix: "/foo" + geoBlockVersion: v0.2.3 + geoBlock: [] + # -- https://github.com/PascalMinder/geoblock + # - name: geoBlockName + # allowLocalRequests: true + # logLocalRequests: false + # logAllowedRequests: false + # logApiRequests: false + # api: https://get.geojs.io/v1/ip/country/{ip} + # apiTimeoutMs: 500 + # cacheSize: 25 + # forceMonthlyUpdate: true + # allowUnknownCountries: false + # unknownCountryApiResponse: nil + # countries: + # - RU + +portalhook: + enabled: true + +persistence: + plugins: + enabled: true + mountPath: "/plugins-storage" + type: emptyDir + +portal: + enabled: true diff --git a/stable/traefik/15.1.0/questions.yaml b/stable/traefik/15.1.0/questions.yaml new file mode 100644 index 00000000000..bc64ab449db --- /dev/null +++ b/stable/traefik/15.1.0/questions.yaml @@ -0,0 +1,2487 @@ +groups: + - name: Container Image + description: Image to be used for container + - name: General Settings + description: General Deployment Settings + - name: App Configuration + description: App Specific Config Options + - name: Networking and Services + description: Configure Network and Services for Container + - name: Storage and Persistence + description: Persist and Share Data that is Separate from the Container + - name: Ingress + description: Ingress Configuration + - name: Security and Permissions + description: Configure Security Context and Permissions + - name: Resources and Devices + description: "Specify Resources/Devices to be Allocated to Workload" + - name: Middlewares + description: Traefik Middlewares + - name: Metrics + description: Metrics + - name: VPN + description: VPN + - name: Addons + description: Addon Configuration + - name: Advanced + description: Advanced Configuration + - name: Documentation + description: Documentation +portals: + open: + protocols: + - "http" + host: + - "$kubernetes-resource_configmap_portal_host" + ports: + - "$kubernetes-resource_configmap_portal_port" + path: "/dashboard/" +questions: + - variable: global + label: Global Settings + group: "General Settings" + schema: + type: dict + hidden: true + attrs: + - variable: isSCALE + label: Flag this is SCALE + schema: + type: boolean + default: true + hidden: true + - variable: controller + group: "General Settings" + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: replicas + description: Number of desired pod replicas + label: Desired Replicas + schema: + type: int + required: true + default: 1 + - variable: customextraargs + group: "General Settings" + label: "Extra Args" + description: "Do not click this unless you know what you are doing" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: extraArgs + label: Extra Args + schema: + type: list + default: [] + items: + - variable: arg + label: Arg + schema: + type: string + - variable: TZ + label: Timezone + group: "General Settings" + schema: + type: string + default: "Etc/UTC" + $ref: + - "definitions/timezone" + - variable: envList + label: Extra Environment Variables + description: "Please be aware that some variables are set in the background, adding duplicates here might cause issues or prevent the app from starting..." + group: "General Settings" + schema: + type: list + default: [] + items: + - variable: envItem + label: Environment Variable + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + - variable: value + label: Value + schema: + type: string + - variable: ingressClass + label: "ingressClass" + group: "App Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: "Enable" + description: "When enabled, ingressClass will match the entered name of this app" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: isDefaultClass + label: "isDefaultClass" + schema: + type: boolean + default: false + - variable: logs + label: "Logs" + group: "App Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: general + label: "General Logs" + schema: + additional_attrs: true + type: dict + attrs: + - variable: level + label: "Log Level" + schema: + type: string + default: "ERROR" + enum: + - value: "INFO" + description: "Info" + - value: "WARN" + description: "Warnings" + - value: "ERROR" + description: "Errors" + - value: "FATAL" + description: "Fatal Errors" + - value: "PANIC" + description: "Panics" + - value: "DEBUG" + description: "Debug" + - variable: format + label: "General Log format" + schema: + type: string + default: "common" + enum: + - value: "common" + description: "Common Log Format" + - value: "json" + description: "JSON" + - variable: access + label: "Access Logs" + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: "Enable" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: enabledFilters + label: "Enable Filters" + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: filters + label: "Filters" + schema: + additional_attrs: true + type: dict + attrs: + - variable: statuscodes + label: "Status codes" + schema: + type: string + default: "200,300-302" + - variable: retryattempts + label: "retryattempts" + schema: + type: boolean + default: true + - variable: minduration + label: "minduration" + schema: + type: string + default: "10ms" + - variable: fields + label: "Fields" + schema: + additional_attrs: true + type: dict + attrs: + - variable: general + label: "General" + schema: + additional_attrs: true + type: dict + attrs: + - variable: defaultmode + label: "Default Mode" + schema: + type: string + default: "keep" + enum: + - value: "keep" + description: "Keep" + - value: "drop" + description: "Drop" + - variable: headers + label: "Headers" + schema: + additional_attrs: true + type: dict + attrs: + - variable: defaultmode + label: "Default Mode" + schema: + type: string + default: "drop" + enum: + - value: "keep" + description: "Keep" + - value: "drop" + description: "Drop" + - variable: format + label: "Access Log format" + schema: + type: string + default: "common" + enum: + - value: "common" + description: "Common Log Format" + - value: "json" + description: "JSON" + - variable: middlewares + label: "" + group: "Middlewares" + schema: + additional_attrs: true + type: dict + attrs: + - variable: basicAuth + label: basicAuth + schema: + type: list + default: [] + items: + - variable: basicAuthEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: users + label: Users + schema: + type: list + default: [] + items: + - variable: usersEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: username + label: Username + schema: + type: string + required: true + default: "" + - variable: password + label: Password + schema: + type: string + required: true + default: "" + - variable: forwardAuth + label: forwardAuth + schema: + type: list + default: [] + items: + - variable: basicAuthEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: address + label: Address + schema: + type: string + required: true + default: "" + - variable: trustForwardHeader + label: trustForwardHeader + schema: + type: boolean + default: false + - variable: tls + label: TLS + schema: + additional_attrs: true + type: dict + attrs: + - variable: insecureSkipVerify + label: insecureSkipVerify (expert) + description: >- + This disables all TLS certificate validation on communications with the authentication endpoint. + This could be a security risk and should only be used if you know what you are doing. + schema: + type: boolean + default: false + - variable: authResponseHeadersRegex + label: authResponseHeadersRegex + schema: + type: string + default: "" + - variable: authResponseHeaders + label: authResponseHeaders + schema: + type: list + default: [] + items: + - variable: authResponseHeadersEntry + label: "" + schema: + type: string + default: "" + - variable: authRequestHeaders + label: authRequestHeaders + schema: + type: list + default: [] + items: + - variable: authRequestHeadersEntry + label: "" + schema: + type: string + default: "" + - variable: chain + label: Chain + schema: + type: list + default: [] + items: + - variable: chainEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: middlewares + label: Middlewares to Chain + schema: + type: list + default: [] + items: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: redirectScheme + label: redirectScheme + schema: + type: list + default: [] + items: + - variable: redirectSchemeEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: scheme + label: Scheme + schema: + type: string + required: true + default: https + enum: + - value: https + description: https + - value: http + description: http + - variable: permanent + label: Permanent + schema: + type: boolean + default: false + - variable: rateLimit + label: rateLimit + schema: + type: list + default: [] + items: + - variable: rateLimitEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: average + label: Average + schema: + type: int + required: true + default: 300 + - variable: burst + label: Burst + schema: + type: int + required: true + default: 200 + - variable: redirectRegex + label: redirectRegex + schema: + type: list + default: [] + items: + - variable: redirectRegexEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: regex + label: Regex + schema: + type: string + required: true + default: "" + - variable: replacement + label: Replacement + schema: + type: string + required: true + default: "" + - variable: permanent + label: Permanent + schema: + type: boolean + default: false + - variable: stripPrefixRegex + label: stripPrefixRegex + schema: + type: list + default: [] + items: + - variable: stripPrefixRegexEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: regex + label: Regex + schema: + type: list + default: [] + items: + - variable: regexEntry + label: Regex + schema: + type: string + required: true + default: "" + - variable: ipWhiteList + label: ipWhiteList + schema: + type: list + default: [] + items: + - variable: ipWhiteListEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: sourceRange + label: Source Range + schema: + type: list + default: [] + items: + - variable: sourceRangeEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: ipStrategy + label: IP Strategy + schema: + additional_attrs: true + type: dict + attrs: + - variable: depth + label: Depth + schema: + type: int + required: true + - variable: excludedIPs + label: Excluded IPs + schema: + type: list + default: [] + items: + - variable: excludedIPsEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: themePark + label: theme.park + schema: + type: list + default: [] + items: + - variable: themeParkEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + description: This is a 3rd party plugin and not maintained by TrueCharts, + for more information go to traefik-themepark + schema: + type: string + required: true + default: "" + - variable: appName + label: App Name + description: Lower case, name of the app to be themed. +
Go to https://docs.theme-park.dev/themes/ to see supported apps. + schema: + type: string + required: true + default: "" + - variable: themeName + label: Theme Name + description: Lower case, name of the theme to be applied. +
Go to https://docs.theme-park.dev/theme-options/ to see supported themes. + schema: + type: string + required: true + default: "" + - variable: baseUrl + label: Base URL + description: Replace `https://theme-park.dev` URL for self-hosting reference. + schema: + type: string + required: true + default: https://theme-park.dev + - variable: addons + label: Addons + schema: + type: list + default: [] + items: + - variable: addonEntry + label: Addon + description: Currently only supports 'darker' and '4k-logo' for *arr apps. +
Go to https://docs.theme-park.dev/themes/addons/ for Addon information. +
Go to https://github.com/packruler/traefik-themepark for more context on plugin + schema: + type: string + required: true + default: "" + - variable: realIP + label: Real IP + schema: + type: list + default: [] + items: + - variable: realIPEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: excludedNetworks + label: Excluded Networks + schema: + type: list + default: [] + items: + - variable: excludedNetEntry + label: Excluded Network Entry + description: Network to exclude setting it to X-Real-Ip + schema: + type: string + required: true + default: "" + - variable: geoBlock + label: GeoBlock + schema: + type: list + default: [] + items: + - variable: geoBlockEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + description: This is a 3rd party plugin and not maintained by TrueCharts, + for more information go to geoblock + schema: + type: string + required: true + default: "" + - variable: allowLocalRequests + label: Allow Local Requests + description: If set to true, will not block request from Private IP Ranges + schema: + type: boolean + default: true + - variable: logLocalRequests + label: Log Local Requests + description: If set to true, will log every connection from any IP in the private IP range + schema: + type: boolean + default: false + - variable: logAllowedRequests + label: Log Allowed Requests + description: If set to true, will show a log message with the IP and the country of origin if a request is allowed. + schema: + type: boolean + default: false + - variable: logApiRequests + label: Log API Requests + description: If set to true, will show a log message for every API hit. + schema: + type: boolean + default: false + - variable: api + label: API + description: Defines the API URL for the IP to Country resolution. The IP to fetch can be added with {ip} to the URL. + schema: + type: string + required: true + default: https://get.geojs.io/v1/ip/country/{ip} + - variable: apiTimeoutMs + label: API Timeout in ms + description: Timeout for the call to the api uri. + schema: + type: int + required: true + default: 500 + - variable: cacheSize + label: Cache Size + description: Defines the max size of the LRU (least recently used) cache. + schema: + type: int + required: true + default: 25 + - variable: forceMonthlyUpdate + label: Force Monthly Update + description: Even if an IP stays in the cache for a period of a month (about 30 x 24 hours), it must be fetch again after a month. + schema: + type: boolean + default: true + - variable: allowUnknownCountries + label: Allow Unknown Countries + description: Some IP addresses have no country associated with them. If this option is set to true, all IPs with no associated country are also allowed. + schema: + type: boolean + default: false + - variable: unknownCountryApiResponse + label: Unknown Countries API Response + description: The API uri can be customized. This options allows to customize the response string of the API when a IP with no associated country is requested. + schema: + type: string + required: true + default: nil + - variable: countries + label: Blocked Countries + schema: + type: list + default: [] + items: + - variable: blockedCountryEntry + label: Blocked Country + description: Country codes (2 characters) from which connections to the service should be allowed. + schema: + type: string + required: true + # Allow only 2 Characters + valid_chars: '^[a-zA-Z]{2}$' + default: "" + - variable: addPrefix + label: Add Prefix + schema: + type: list + default: [] + items: + - variable: addPrefixEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: prefix + label: Prefix + schema: + type: string + required: true + default: "" + - variable: service + group: "Networking and Services" + label: "Configure Service Entrypoint" + schema: + additional_attrs: true + type: dict + attrs: + - variable: main + label: "Main Service" + description: "The Primary service on which the healthcheck runs, often the webUI" + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable the Service + schema: + type: boolean + default: true + hidden: true + - variable: type + label: Service Type + description: "ClusterIP's are only internally available and Loadbalancer exposes the service using the system loadbalancer" + schema: + type: string + default: LoadBalancer + enum: + - value: LoadBalancer + description: LoadBalancer (Expose Ports) + - value: ClusterIP + description: ClusterIP (Do Not Expose Ports) + - value: Simple + description: Deprecated CHANGE THIS + - variable: loadBalancerIP + label: LoadBalancer IP + description: "MetalLB Only: Selects the Loadbalancer IP to expose on. Required when using PortalButton with MetalLB" + schema: + show_if: [["type", "=", "LoadBalancer"]] + type: string + default: "" + - variable: ports + label: "Service's Port(s) Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: main + label: "Main Entrypoint Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: "Entrypoints Port" + schema: + type: int + default: 9000 + required: true + - variable: tcp + label: "TCP Service" + description: "The tcp Entrypoint service" + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable the Service + schema: + type: boolean + default: true + hidden: true + - variable: type + label: Service Type + description: "ClusterIP's are only internally available and Loadbalancer exposes the service using the system loadbalancer" + schema: + type: string + default: LoadBalancer + enum: + - value: LoadBalancer + description: LoadBalancer (Expose Ports) + - value: ClusterIP + description: ClusterIP (Do Not Expose Ports) + - value: Simple + description: Deprecated CHANGE THIS + - variable: loadBalancerIP + label: LoadBalancer IP + description: "MetalLB Only: Selects the Loadbalancer IP to expose on. Required when using PortalButton with MetalLB" + schema: + show_if: [["type", "=", "LoadBalancer"]] + type: string + default: "" + - variable: ports + label: "Service's Port(s) Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: web + label: "web Entrypoint Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: "Entrypoints Port" + schema: + type: int + default: 9080 + required: true + - variable: advanced + label: Show Advanced Settings + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: redirectPort + label: "Redirect to Port" + schema: + type: int + - variable: redirectTo + label: "Redirect to Entrypoint" + schema: + type: string + default: "websecure" + - variable: forwardedHeaders + label: Accept Forwarded Headers + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: trustedIPs + label: Trusted IPs + description: Trust Forwarded Headers from specific IPs. + schema: + type: list + default: [] + items: + - variable: trustedIPsEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: insecureMode + label: Insecure Mode + description: Always Trust Forwarded Headers + schema: + type: boolean + default: false + - variable: proxyProtocol + label: Accept Proxy Protocol connections + description: If Proxy Protocol header parsing is enabled for the entry point, this entry point can accept connections with or without Proxy Protocol headers. + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: trustedIPs + label: Trusted IPs + description: Only IPs in trustedIPs will lead to remote client address replacement + schema: + type: list + default: [] + items: + - variable: trustedIPsEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: insecureMode + label: Insecure Mode + description: Trust every incoming connection + schema: + type: boolean + default: false + - variable: websecure + label: "websecure Entrypoints Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: "Entrypoints Port" + schema: + type: int + default: 9443 + required: true + - variable: advanced + label: Show Advanced Settings + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: redirectPort + label: "Redirect to Port" + schema: + type: int + - variable: redirectTo + label: "Redirect to Entrypoint" + schema: + type: string + - variable: forwardedHeaders + label: Accept Forwarded Headers + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: trustedIPs + label: Trusted IPs + description: Trust Forwarded Headers from specific IPs. + schema: + type: list + default: [] + items: + - variable: trustedIPsEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: insecureMode + label: Insecure Mode + description: Always Trust Forwarded Headers + schema: + type: boolean + default: false + - variable: proxyProtocol + label: Accept Proxy Protocol connections + description: If Proxy Protocol header parsing is enabled for the entry point, this entry point can accept connections with or without Proxy Protocol headers. + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: trustedIPs + label: Trusted IPs + description: Only IPs in trustedIPs will lead to remote client address replacement + schema: + type: list + default: [] + items: + - variable: trustedIPsEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: insecureMode + label: Insecure Mode + description: Trust every incoming connection + schema: + type: boolean + default: false + - variable: tls + label: "websecure Entrypoints Configuration" + schema: + type: dict + hidden: true + attrs: + - variable: enabled + label: "Enabled" + schema: + type: boolean + default: true + hidden: true + - variable: portsList + label: "Additional TCP Entrypoints" + schema: + type: list + default: [] + items: + - variable: portsListEntry + label: "Custom Entrypoints" + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: "Enable the port" + schema: + type: boolean + default: true + hidden: true + - variable: name + label: "Entrypoints Name" + schema: + type: string + default: "" + - variable: protocol + label: "Entrypoints Type" + schema: + type: string + default: "TCP" + enum: + - value: HTTP + description: "HTTP" + - value: "HTTPS" + description: "HTTPS" + - value: TCP + description: "TCP" + - variable: port + label: "Port" + description: "This port exposes the container port on the service" + schema: + type: int + required: true + - variable: tls + label: "websecure Entrypoints Configuration" + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: "Enabled" + schema: + type: boolean + default: true + - variable: redirectPort + label: "Redirect to Port" + schema: + type: int + - variable: redirectTo + label: "Redirect to Entrypoint" + schema: + type: string + - variable: forwardedHeaders + label: Accept Forwarded Headers + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: trustedIPs + label: Trusted IPs + description: Trust Forwarded Headers from specific IPs. + schema: + type: list + default: [] + items: + - variable: trustedIPsEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: insecureMode + label: Insecure Mode + description: Always Trust Forwarded Headers + schema: + type: boolean + default: false + - variable: proxyProtocol + label: Accept Proxy Protocol connections + description: If Proxy Protocol header parsing is enabled for the entry point, this entry point can accept connections with or without Proxy Protocol headers. + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: trustedIPs + label: Trusted IPs + description: Only IPs in trustedIPs will lead to remote client address replacement + schema: + type: list + default: [] + items: + - variable: trustedIPsEntry + label: "" + schema: + type: string + required: true + default: "" + - variable: insecureMode + label: Insecure Mode + description: Trust every incoming connection + schema: + type: boolean + default: false + - variable: ingress + label: "" + group: Ingress + schema: + additional_attrs: true + type: dict + attrs: + - variable: main + label: "Main Ingress" + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable Ingress + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: hosts + label: Hosts + schema: + type: list + default: [] + items: + - variable: hostEntry + label: Host + schema: + additional_attrs: true + type: dict + attrs: + - variable: host + label: HostName + schema: + type: string + default: "" + required: true + - variable: paths + label: Paths + schema: + type: list + default: [] + items: + - variable: pathEntry + label: Host + schema: + additional_attrs: true + type: dict + attrs: + - variable: path + label: Path + schema: + type: string + required: true + default: "/" + - variable: pathType + label: Path Type + schema: + type: string + required: true + default: Prefix + - variable: tls + label: TLS-Settings + schema: + type: list + default: [] + items: + - variable: tlsEntry + label: Host + schema: + additional_attrs: true + type: dict + attrs: + - variable: hosts + label: Certificate Hosts + schema: + type: list + default: [] + items: + - variable: host + label: Host + schema: + type: string + default: "" + required: true + - variable: scaleCert + label: Select TrueNAS SCALE Certificate + schema: + type: int + $ref: + - "definitions/certificate" + - variable: entrypoint + label: (Advanced) Traefik Entrypoint + description: Entrypoint used by Traefik when using Traefik as Ingress Provider + schema: + type: string + default: websecure + required: true + - variable: ingressClassName + label: (Advanced/Optional) IngressClass Name + schema: + type: string + default: "" + - variable: middlewares + label: Traefik Middlewares + description: Add previously created Traefik Middlewares to this Ingress + schema: + type: list + default: [] + items: + - variable: name + label: Name + schema: + type: string + default: "" + required: true + - variable: ingressList + label: Add Manual Custom Ingresses + group: Ingress + schema: + type: list + default: [] + items: + - variable: ingressListEntry + label: Custom Ingress + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable Ingress + schema: + type: boolean + default: true + hidden: true + - variable: name + label: Name + schema: + type: string + default: "" + - variable: ingressClassName + label: IngressClass Name + schema: + type: string + default: "" + - variable: hosts + label: Hosts + schema: + type: list + default: [] + items: + - variable: hostEntry + label: Host + schema: + additional_attrs: true + type: dict + attrs: + - variable: host + label: HostName + schema: + type: string + default: "" + required: true + - variable: paths + label: Paths + schema: + type: list + default: [] + items: + - variable: pathEntry + label: Host + schema: + additional_attrs: true + type: dict + attrs: + - variable: path + label: Path + schema: + type: string + required: true + default: "/" + - variable: pathType + label: Path Type + schema: + type: string + required: true + default: Prefix + - variable: service + label: Linked Service + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Service Name + schema: + type: string + default: "" + - variable: port + label: Service Port + schema: + type: int + - variable: tls + label: TLS-Settings + schema: + type: list + default: [] + items: + - variable: tlsEntry + label: Host + schema: + additional_attrs: true + type: dict + attrs: + - variable: hosts + label: Certificate Hosts + schema: + type: list + default: [] + items: + - variable: host + label: Host + schema: + type: string + default: "" + required: true + - variable: scaleCert + label: Select TrueNAS SCALE Certificate + schema: + type: int + $ref: + - "definitions/certificate" + - variable: entrypoint + label: Traefik Entrypoint + description: Entrypoint used by Traefik when using Traefik as Ingress Provider + schema: + type: string + default: websecure + required: true + - variable: middlewares + label: Traefik Middlewares + description: Add previously created Traefik Middlewares to this Ingress + schema: + type: list + default: [] + items: + - variable: name + label: Name + schema: + type: string + default: "" + required: true + - variable: security + label: Container Security Settings + group: Security and Permissions + schema: + type: dict + additional_attrs: true + attrs: + - variable: editsecurity + label: Change PUID / UMASK values + description: By enabling this you override default set values. + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: PUID + label: Process User ID - PUID + description: When supported by the container, this sets the User ID running the Application Process. Not supported by all Apps + schema: + type: int + default: 568 + - variable: UMASK + label: UMASK + description: When supported by the container, this sets the UMASK for the App. Not supported by all Apps + schema: + type: string + default: "002" + - variable: advancedSecurity + label: Show Advanced Security Settings + group: Security and Permissions + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: securityContext + label: Security Context + schema: + additional_attrs: true + type: dict + attrs: + - variable: privileged + label: "Privileged mode" + schema: + type: boolean + default: false + - variable: readOnlyRootFilesystem + label: "ReadOnly Root Filesystem" + schema: + type: boolean + default: true + - variable: allowPrivilegeEscalation + label: "Allow Privilege Escalation" + schema: + type: boolean + default: false + - variable: runAsNonRoot + label: "runAsNonRoot" + schema: + type: boolean + default: true + - variable: podSecurityContext + group: Security and Permissions + label: Pod Security Context + schema: + additional_attrs: true + type: dict + attrs: + - variable: runAsUser + label: "runAsUser" + description: "The UserID of the user running the application" + schema: + type: int + default: 568 + - variable: runAsGroup + label: "runAsGroup" + description: "The groupID this App of the user running the application" + schema: + type: int + default: 568 + - variable: fsGroup + label: "fsGroup" + description: "The group that should own ALL storage." + schema: + type: int + default: 568 + - variable: fsGroupChangePolicy + label: "When should we take ownership?" + schema: + type: string + default: OnRootMismatch + enum: + - value: OnRootMismatch + description: OnRootMismatch + - value: Always + description: Always + - variable: supplementalGroups + label: Supplemental Groups + schema: + type: list + default: [] + items: + - variable: supplementalGroupsEntry + label: Supplemental Group + schema: + type: int + - variable: resources + group: Resources and Devices + label: "Resource Limits" + schema: + additional_attrs: true + type: dict + attrs: + - variable: limits + label: Advanced Limit Resource Consumption + schema: + additional_attrs: true + type: dict + attrs: + - variable: cpu + label: CPU + description: "1000m means 1 hyperthread. Detailed info: https://truecharts.org/docs/manual/SCALE%20Apps/indepth/validation" + schema: + type: string + default: 4000m + valid_chars: '^(?!^0(\.0|m|)$)([0-9]+)(\.[0-9]|m?)$' + - variable: memory + label: RAM + description: "1Gi means 1 Gibibyte RAM. Detailed info: https://truecharts.org/docs/manual/SCALE%20Apps/indepth/validation" + schema: + type: string + default: 8Gi + valid_chars: '^(?!^0(e[0-9]|[EPTGMK]i?|)$)([0-9]+)(|[EPTGMK]i?|e[0-9]+)$' + - variable: requests + label: "Minimum Resources Required (request)" + schema: + additional_attrs: true + type: dict + hidden: true + attrs: + - variable: cpu + label: CPU + description: "1000m means 1 hyperthread. Detailed info: https://truecharts.org/docs/manual/SCALE%20Apps/indepth/validation" + schema: + type: string + default: 10m + hidden: true + valid_chars: '^(?!^0(\.0|m|)$)([0-9]+)(\.[0-9]|m?)$' + - variable: memory + label: "RAM" + description: "1Gi means 1 Gibibyte RAM. Detailed info: https://truecharts.org/docs/manual/SCALE%20Apps/indepth/validation" + schema: + type: string + default: 50Mi + hidden: true + valid_chars: '^(?!^0(e[0-9]|[EPTGMK]i?|)$)([0-9]+)(|[EPTGMK]i?|e[0-9]+)$' + - variable: deviceList + label: Mount USB Devices + group: Resources and Devices + schema: + type: list + default: [] + items: + - variable: deviceListEntry + label: Device + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enable the Storage + schema: + type: boolean + default: true + - variable: type + label: (Advanced) Type of Storage + description: Sets the persistence type + schema: + type: string + default: hostPath + hidden: true + - variable: readOnly + label: readOnly + schema: + type: boolean + default: false + - variable: hostPath + label: Host Device Path + description: Path to the device on the host system + schema: + type: path + - variable: mountPath + label: Container Device Path + description: Path inside the container the device is mounted + schema: + type: string + default: "/dev/ttyACM0" + # Specify GPU configuration + - variable: scaleGPU + label: GPU Configuration + group: Resources and Devices + schema: + type: dict + $ref: + - "definitions/gpuConfiguration" + attrs: [] + - variable: horizontalPodAutoscaler + group: Advanced + label: (Advanced) Horizontal Pod Autoscaler + schema: + type: list + default: [] + items: + - variable: hpaEntry + label: HPA Entry + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: enabled + label: Enabled + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: target + label: Target + description: Deployment name, Defaults to Main Deployment + schema: + type: string + default: "" + - variable: minReplicas + label: Minimum Replicas + schema: + type: int + default: 1 + - variable: maxReplicas + label: Maximum Replicas + schema: + type: int + default: 5 + - variable: targetCPUUtilizationPercentage + label: Target CPU Utilization Percentage + schema: + type: int + default: 80 + - variable: targetMemoryUtilizationPercentage + label: Target Memory Utilization Percentage + schema: + type: int + default: 80 + - variable: networkPolicy + group: Advanced + label: (Advanced) Network Policy + schema: + type: list + default: [] + items: + - variable: netPolicyEntry + label: Network Policy Entry + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + default: "" + - variable: enabled + label: Enabled + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: policyType + label: Policy Type + schema: + type: string + default: "" + enum: + - value: "" + description: Default + - value: ingress + description: Ingress + - value: egress + description: Egress + - value: ingress-egress + description: Ingress and Egress + - variable: egress + label: Egress + schema: + type: list + default: [] + items: + - variable: egressEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: to + label: To + schema: + type: list + default: [] + items: + - variable: toEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: ipBlock + label: IP Block + schema: + additional_attrs: true + type: dict + attrs: + - variable: cidr + label: CIDR + schema: + type: string + default: "" + - variable: except + label: Except + schema: + type: list + default: [] + items: + - variable: exceptint + label: "" + schema: + type: string + - variable: namespaceSelector + label: Namespace Selector + schema: + additional_attrs: true + type: dict + attrs: + - variable: matchExpressions + label: Match Expressions + schema: + type: list + default: [] + items: + - variable: expressionEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: key + label: Key + schema: + type: string + - variable: operator + label: Operator + schema: + type: string + default: TCP + enum: + - value: In + description: In + - value: NotIn + description: NotIn + - value: Exists + description: Exists + - value: DoesNotExist + description: DoesNotExist + - variable: values + label: Values + schema: + type: list + default: [] + items: + - variable: value + label: "" + schema: + type: string + - variable: podSelector + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: matchExpressions + label: Match Expressions + schema: + type: list + default: [] + items: + - variable: expressionEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: key + label: Key + schema: + type: string + - variable: operator + label: Operator + schema: + type: string + default: TCP + enum: + - value: In + description: In + - value: NotIn + description: NotIn + - value: Exists + description: Exists + - value: DoesNotExist + description: DoesNotExist + - variable: values + label: Values + schema: + type: list + default: [] + items: + - variable: value + label: "" + schema: + type: string + - variable: ports + label: Ports + schema: + type: list + default: [] + items: + - variable: portsEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: Port + schema: + type: int + - variable: endPort + label: End Port + schema: + type: int + - variable: protocol + label: Protocol + schema: + type: string + default: TCP + enum: + - value: TCP + description: TCP + - value: UDP + description: UDP + - value: SCTP + description: SCTP + - variable: ingress + label: Ingress + schema: + type: list + default: [] + items: + - variable: ingressEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: from + label: From + schema: + type: list + default: [] + items: + - variable: fromEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: ipBlock + label: IP Block + schema: + additional_attrs: true + type: dict + attrs: + - variable: cidr + label: CIDR + schema: + type: string + default: "" + - variable: except + label: Except + schema: + type: list + default: [] + items: + - variable: exceptint + label: "" + schema: + type: string + - variable: namespaceSelector + label: Namespace Selector + schema: + additional_attrs: true + type: dict + attrs: + - variable: matchExpressions + label: Match Expressions + schema: + type: list + default: [] + items: + - variable: expressionEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: key + label: Key + schema: + type: string + - variable: operator + label: Operator + schema: + type: string + default: TCP + enum: + - value: In + description: In + - value: NotIn + description: NotIn + - value: Exists + description: Exists + - value: DoesNotExist + description: DoesNotExist + - variable: values + label: Values + schema: + type: list + default: [] + items: + - variable: value + label: "" + schema: + type: string + - variable: podSelector + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: matchExpressions + label: Match Expressions + schema: + type: list + default: [] + items: + - variable: expressionEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: key + label: Key + schema: + type: string + - variable: operator + label: Operator + schema: + type: string + default: TCP + enum: + - value: In + description: In + - value: NotIn + description: NotIn + - value: Exists + description: Exists + - value: DoesNotExist + description: DoesNotExist + - variable: values + label: Values + schema: + type: list + default: [] + items: + - variable: value + label: "" + schema: + type: string + - variable: ports + label: Ports + schema: + type: list + default: [] + items: + - variable: portsEntry + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: Port + schema: + type: int + - variable: endPort + label: End Port + schema: + type: int + - variable: protocol + label: Protocol + schema: + type: string + default: TCP + enum: + - value: TCP + description: TCP + - value: UDP + description: UDP + - value: SCTP + description: SCTP + - variable: addons + group: Addons + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: codeserver + label: Codeserver + schema: + additional_attrs: true + type: dict + attrs: + - variable: enabled + label: Enabled + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: git + label: Git Settings + schema: + additional_attrs: true + type: dict + attrs: + - variable: deployKey + description: Raw SSH Private Key + label: Deploy Key + schema: + type: string + - variable: deployKeyBase64 + description: Base64-encoded SSH private key. When both variables are set, the raw SSH key takes precedence + label: Deploy Key Base64 + schema: + type: string + - variable: service + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: type + label: Service Type + description: "ClusterIP's are only internally available and Loadbalancer exposes the service using the system loadbalancer" + schema: + type: string + default: LoadBalancer + enum: + - value: NodePort + description: Deprecated CHANGE THIS + - value: ClusterIP + description: ClusterIP + - value: LoadBalancer + description: LoadBalancer + - variable: loadBalancerIP + label: LoadBalancer IP + description: "MetalLB Only: Selects the Loadbalancer IP to expose on. Required when using PortalButton with MetalLB" + schema: + show_if: [["type", "=", "LoadBalancer"]] + type: string + default: "" + - variable: advancedsvcset + label: Show Advanced Service Settings + schema: + type: boolean + default: false + show_subquestions_if: true + subquestions: + - variable: externalIPs + label: "External IP's" + description: "External IP's" + schema: + type: list + default: [] + items: + - variable: externalIP + label: External IP + schema: + type: string + - variable: ipFamilyPolicy + label: IP Family Policy + description: Specify the IP Policy + schema: + type: string + default: SingleStack + enum: + - value: SingleStack + description: SingleStack + - value: PreferDualStack + description: PreferDualStack + - value: RequireDualStack + description: RequireDualStack + - variable: ipFamilies + label: IP Families + description: (Advanced) The IP Families that should be used + schema: + type: list + default: [] + items: + - variable: ipFamily + label: IP Family + schema: + type: string + - variable: ports + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: codeserver + label: "" + schema: + additional_attrs: true + type: dict + attrs: + - variable: port + label: Port + schema: + type: int + default: 36107 + - variable: nodePort + description: Leave Empty to Disable + label: nodePort DEPRECATED + schema: + type: int + default: 36107 + - variable: envList + label: Codeserver Environment Variables + schema: + type: list + show_if: [["type", "!=", "disabled"]] + default: [] + items: + - variable: envItem + label: Environment Variable + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: value + label: Value + schema: + type: string + required: true + - variable: vpn + label: VPN + schema: + additional_attrs: true + type: dict + attrs: + - variable: type + label: Type + schema: + type: string + default: disabled + enum: + - value: disabled + description: disabled + - value: openvpn + description: OpenVPN + - value: wireguard + description: Wireguard + - value: tailscale + description: Tailscale + - variable: openvpn + label: OpenVPN Settings + schema: + type: dict + show_if: [["type", "=", "openvpn"]] + attrs: + - variable: username + label: Authentication Username (Optional) + description: Authentication Username, Optional + schema: + type: string + default: "" + - variable: password + label: Authentication Password + description: Authentication Credentials + schema: + type: string + default: "" + required: true + - variable: tailscale + label: Tailscale Settings + schema: + type: dict + show_if: [["type", "=", "tailscale"]] + attrs: + - variable: authkey + label: Authentication Key + description: Provide an auth key to automatically authenticate the node as your user account. + schema: + type: string + private: true + default: "" + - variable: auth_once + label: Auth Once + description: Only attempt to log in if not already logged in. + schema: + type: boolean + default: true + - variable: accept_dns + label: Accept DNS + description: Accept DNS configuration from the admin console. + schema: + type: boolean + default: false + - variable: userspace + label: Userspace + description: Userspace Networking mode allows running Tailscale where you do not have access to create a VPN tunnel device. + schema: + type: boolean + default: false + - variable: routes + label: Routes + description: Expose physical subnet routes to your entire Tailscale network. + schema: + type: string + default: "" + - variable: dest_ip + label: Destination IP + description: Tells the DNAT mechanism which Destination IP to set in the IP header, and where to send packets that are matched. + schema: + type: string + default: "" + - variable: sock5_server + label: Sock5 Server + description: The address on which to listen for SOCKS5 proxying into the tailscale net. + schema: + type: string + default: "" + - variable: outbound_http_proxy_listen + label: Outbound HTTP Proxy Listen + description: The address on which to listen for HTTP proxying into the tailscale net. + schema: + type: string + default: "" + - variable: extra_args + label: Extra Args + description: Extra Args + schema: + type: string + default: "" + - variable: daemon_extra_args + label: Tailscale Daemon Extra Args + description: Tailscale Daemon Extra Args + schema: + type: string + default: "" + - variable: killSwitch + label: Enable Killswitch + schema: + type: boolean + show_if: [["type", "!=", "disabled"]] + default: true + - variable: excludedNetworks_IPv4 + label: Killswitch Excluded IPv4 networks + description: List of Killswitch Excluded IPv4 Addresses + schema: + type: list + show_if: [["type", "!=", "disabled"]] + default: [] + items: + - variable: networkv4 + label: IPv4 Network + schema: + type: string + required: true + - variable: excludedNetworks_IPv6 + label: Killswitch Excluded IPv6 networks + description: "List of Killswitch Excluded IPv6 Addresses" + schema: + type: list + show_if: [["type", "!=", "disabled"]] + default: [] + items: + - variable: networkv6 + label: IPv6 Network + schema: + type: string + required: true + - variable: configFile + label: VPN Config File Location + schema: + type: dict + show_if: [["type", "!=", "disabled"]] + attrs: + - variable: enabled + label: Enabled + schema: + type: boolean + default: true + hidden: true + - variable: type + label: Type + schema: + type: string + default: hostPath + hidden: true + - variable: hostPathType + label: hostPathType + schema: + type: string + default: File + hidden: true + - variable: noMount + label: noMount + schema: + type: boolean + default: true + hidden: true + - variable: hostPath + label: Full Path to File + description: "Path to your local VPN config file for example: /mnt/tank/vpn.conf or /mnt/tank/vpn.ovpn" + schema: + type: string + default: "" + - variable: envList + label: VPN Environment Variables + schema: + type: list + show_if: [["type", "!=", "disabled"]] + default: [] + items: + - variable: envItem + label: Environment Variable + schema: + additional_attrs: true + type: dict + attrs: + - variable: name + label: Name + schema: + type: string + required: true + - variable: value + label: Value + schema: + type: string + required: true + - variable: docs + group: Documentation + label: Please read the documentation at https://truecharts.org + description: Please read the documentation at +
https://truecharts.org + schema: + additional_attrs: true + type: dict + attrs: + - variable: confirmDocs + label: I have checked the documentation + schema: + type: boolean + default: true + - variable: donateNag + group: Documentation + label: Please consider supporting TrueCharts, see https://truecharts.org/sponsor + description: Please consider supporting TrueCharts, see +
https://truecharts.org/sponsor + schema: + additional_attrs: true + type: dict + attrs: + - variable: confirmDonate + label: I have considered donating + schema: + type: boolean + default: true + hidden: true diff --git a/stable/traefik/15.1.0/templates/_args.tpl b/stable/traefik/15.1.0/templates/_args.tpl new file mode 100644 index 00000000000..98cc63897b9 --- /dev/null +++ b/stable/traefik/15.1.0/templates/_args.tpl @@ -0,0 +1,178 @@ +{{/* Define the args */}} +{{- define "traefik.args" -}} +args: + {{/* merge all ports */}} + {{- $ports := dict }} + {{- range $.Values.service }} + {{- range $name, $value := .ports }} + {{- $_ := set $ports $name $value }} + {{- end }} + {{- end }} + {{/* start of actual arguments */}} + {{- with .Values.globalArguments }} + {{- range . }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- range $name, $config := $ports }} + {{- if $config }} + {{- if or ( eq $config.protocol "HTTP" ) ( eq $config.protocol "HTTPS" ) ( eq $config.protocol "TCP" ) }} + {{- $_ := set $config "protocol" "TCP" }} + {{- end }} + - "--entryPoints.{{$name}}.address=:{{ $config.port }}/{{ default "tcp" $config.protocol | lower }}" + {{- end }} + {{- end }} + - "--api.dashboard=true" + - "--ping=true" + {{- if .Values.metrics }} + {{- if .Values.metrics.datadog }} + - "--metrics.datadog=true" + - "--metrics.datadog.address={{ .Values.metrics.datadog.address }}" + {{- end }} + {{- if .Values.metrics.influxdb }} + - "--metrics.influxdb=true" + - "--metrics.influxdb.address={{ .Values.metrics.influxdb.address }}" + - "--metrics.influxdb.protocol={{ .Values.metrics.influxdb.protocol }}" + {{- end }} + {{- if .Values.metrics.prometheus }} + - "--metrics.prometheus=true" + - "--metrics.prometheus.entrypoint={{ .Values.metrics.prometheus.entryPoint }}" + {{- end }} + {{- if .Values.metrics.statsd }} + - "--metrics.statsd=true" + - "--metrics.statsd.address={{ .Values.metrics.statsd.address }}" + {{- end }} + {{- end }} + {{- if .Values.providers.kubernetesCRD.enabled }} + - "--providers.kubernetescrd" + {{- end }} + {{- if .Values.providers.kubernetesIngress.enabled }} + - "--providers.kubernetesingress" + {{- if .Values.providers.kubernetesIngress.publishedService.enabled }} + - "--providers.kubernetesingress.ingressendpoint.publishedservice={{ template "providers.kubernetesIngress.publishedServicePath" . }}" + {{- end }} + {{- if .Values.providers.kubernetesIngress.labelSelector }} + - "--providers.kubernetesingress.labelSelector={{ .Values.providers.kubernetesIngress.labelSelector }}" + {{- end }} + {{- end }} + {{- if and .Values.rbac.enabled .Values.rbac.namespaced }} + {{- if .Values.providers.kubernetesCRD.enabled }} + - "--providers.kubernetescrd.namespaces={{ template "providers.kubernetesCRD.namespaces" . }}" + {{- end }} + {{- if .Values.providers.kubernetesIngress.enabled }} + - "--providers.kubernetesingress.namespaces={{ template "providers.kubernetesIngress.namespaces" . }}" + {{- end }} + {{- end }} + {{- if .Values.ingressClass.enabled }} + - "--providers.kubernetesingress.ingressclass={{ .Release.Name }}" + {{- end }} + {{- range $entrypoint, $config := $ports }} + {{/* add args for proxyProtocol support */}} + {{- if $config.proxyProtocol }} + {{- if $config.proxyProtocol.enabled }} + {{- if $config.proxyProtocol.insecureMode }} + - "--entrypoints.{{ $entrypoint }}.proxyProtocol.insecure" + {{- end }} + {{- if not ( empty $config.proxyProtocol.trustedIPs ) }} + - "--entrypoints.{{ $entrypoint }}.proxyProtocol.trustedIPs={{ join "," $config.proxyProtocol.trustedIPs }}" + {{- end }} + {{- end }} + {{- end }} + {{/* add args for forwardedHeaders support */}} + {{- if $config.forwardedHeaders.enabled }} + {{- if not ( empty $config.forwardedHeaders.trustedIPs ) }} + - "--entrypoints.{{ $entrypoint }}.forwardedHeaders.trustedIPs={{ join "," $config.forwardedHeaders.trustedIPs }}" + {{- end }} + {{- if $config.forwardedHeaders.insecureMode }} + - "--entrypoints.{{ $entrypoint }}.forwardedHeaders.insecure" + {{- end }} + {{- end }} + {{/* end forwardedHeaders configuration */}} + {{- if $config.redirectTo }} + {{- $toPort := index $ports $config.redirectTo }} + - "--entrypoints.{{ $entrypoint }}.http.redirections.entryPoint.to=:{{ $toPort.port }}" + - "--entrypoints.{{ $entrypoint }}.http.redirections.entryPoint.scheme=https" + {{- else if $config.redirectPort }} + {{ if gt $config.redirectPort 0.0 }} + - "--entrypoints.{{ $entrypoint }}.http.redirections.entryPoint.to=:{{ $config.redirectPort }}" + - "--entrypoints.{{ $entrypoint }}.http.redirections.entryPoint.scheme=https" + {{- end }} + {{- end }} + {{- if or ( $config.tls ) ( eq $config.protocol "HTTPS" ) }} + {{- if or ( $config.tls.enabled ) ( eq $config.protocol "HTTPS" ) }} + - "--entrypoints.{{ $entrypoint }}.http.tls=true" + {{- if $config.tls.options }} + - "--entrypoints.{{ $entrypoint }}.http.tls.options={{ $config.tls.options }}" + {{- end }} + {{- if $config.tls.certResolver }} + - "--entrypoints.{{ $entrypoint }}.http.tls.certResolver={{ $config.tls.certResolver }}" + {{- end }} + {{- if $config.tls.domains }} + {{- range $index, $domain := $config.tls.domains }} + {{- if $domain.main }} + - "--entrypoints.{{ $entrypoint }}.http.tls.domains[{{ $index }}].main={{ $domain.main }}" + {{- end }} + {{- if $domain.sans }} + - "--entrypoints.{{ $entrypoint }}.http.tls.domains[{{ $index }}].sans={{ join "," $domain.sans }}" + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.logs }} + - "--log.format={{ .general.format }}" + {{- if ne .general.level "ERROR" }} + - "--log.level={{ .general.level | upper }}" + {{- end }} + {{- if .access.enabled }} + - "--accesslog=true" + - "--accesslog.format={{ .access.format }}" + {{- if .access.bufferingsize }} + - "--accesslog.bufferingsize={{ .access.bufferingsize }}" + {{- end }} + {{- if .access.filters }} + {{- if .access.filters.statuscodes }} + - "--accesslog.filters.statuscodes={{ .access.filters.statuscodes }}" + {{- end }} + {{- if .access.filters.retryattempts }} + - "--accesslog.filters.retryattempts" + {{- end }} + {{- if .access.filters.minduration }} + - "--accesslog.filters.minduration={{ .access.filters.minduration }}" + {{- end }} + {{- end }} + - "--accesslog.fields.defaultmode={{ .access.fields.general.defaultmode }}" + {{- range $fieldname, $fieldaction := .access.fields.general.names }} + - "--accesslog.fields.names.{{ $fieldname }}={{ $fieldaction }}" + {{- end }} + - "--accesslog.fields.headers.defaultmode={{ .access.fields.headers.defaultmode }}" + {{- range $fieldname, $fieldaction := .access.fields.headers.names }} + - "--accesslog.fields.headers.names.{{ $fieldname }}={{ $fieldaction }}" + {{- end }} + {{- end }} + {{- end }} + {{/* theme.park */}} + {{- if .Values.middlewares.themePark }} + - "--experimental.plugins.traefik-themepark.modulename=github.com/packruler/traefik-themepark" + - "--experimental.plugins.traefik-themepark.version={{ .Values.middlewares.themeParkVersion }}" + {{- end }} + {{/* End of theme.park */}} + {{/* GeoBlock */}} + {{- if .Values.middlewares.geoBlock }} + - "--experimental.plugins.GeoBlock.modulename=github.com/PascalMinder/geoblock" + - "--experimental.plugins.GeoBlock.version={{ .Values.middlewares.geoBlockVersion }}" + {{- end }} + {{/* End of GeoBlock */}} + {{/* RealIP */}} + {{- if .Values.middlewares.realIP }} + - "--experimental.plugins.traefik-real-ip.modulename=github.com/soulbalz/traefik-real-ip" + - "--experimental.plugins.traefik-real-ip.version={{ .Values.middlewares.realIPVersion }}" + {{- end }} + {{/* End of RealIP */}} + {{- with .Values.additionalArguments }} + {{- range . }} + - {{ . | quote }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/stable/traefik/15.1.0/templates/_helpers.tpl b/stable/traefik/15.1.0/templates/_helpers.tpl new file mode 100644 index 00000000000..ab55e4e7ec6 --- /dev/null +++ b/stable/traefik/15.1.0/templates/_helpers.tpl @@ -0,0 +1,22 @@ +{{/* +Construct the path for the providers.kubernetesingress.ingressendpoint.publishedservice. +By convention this will simply use the / to match the name of the +service generated. +Users can provide an override for an explicit service they want bound via `.Values.providers.kubernetesIngress.publishedService.pathOverride` +*/}} +{{- define "providers.kubernetesIngress.publishedServicePath" -}} +{{- $fullName := include "tc.common.names.fullname" . -}} +{{- $defServiceName := printf "%s/%s-tcp" .Release.Namespace $fullName -}} +{{- $servicePath := default $defServiceName .Values.providers.kubernetesIngress.publishedService.pathOverride }} +{{- print $servicePath | trimSuffix "-" -}} +{{- end -}} + +{{/* +Construct a comma-separated list of whitelisted namespaces +*/}} +{{- define "providers.kubernetesIngress.namespaces" -}} +{{- default .Release.Namespace (join "," .Values.providers.kubernetesIngress.namespaces) }} +{{- end -}} +{{- define "providers.kubernetesCRD.namespaces" -}} +{{- default .Release.Namespace (join "," .Values.providers.kubernetesCRD.namespaces) }} +{{- end -}} diff --git a/stable/traefik/15.1.0/templates/_ingressclass.tpl b/stable/traefik/15.1.0/templates/_ingressclass.tpl new file mode 100644 index 00000000000..909e249d6a5 --- /dev/null +++ b/stable/traefik/15.1.0/templates/_ingressclass.tpl @@ -0,0 +1,24 @@ +{{/* Define the ingressClass */}} +{{- define "traefik.ingressClass" -}} +--- +{{ if .Values.ingressClass.enabled }} + {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1/IngressClass" }} +apiVersion: networking.k8s.io/v1 + {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1/IngressClass" }} +apiVersion: networking.k8s.io/v1beta1 + {{- else if or (eq .Values.ingressClass.fallbackApiVersion "v1beta1") (eq .Values.ingressClass.fallbackApiVersion "v1") }} +apiVersion: {{ printf "networking.k8s.io/%s" .Values.ingressClass.fallbackApiVersion }} + {{- else }} + {{- fail "\n\n ERROR: You must have at least networking.k8s.io/v1beta1 to use ingressClass" }} + {{- end }} +kind: IngressClass +metadata: + annotations: + ingressclass.kubernetes.io/is-default-class: {{ .Values.ingressClass.isDefaultClass | quote }} + labels: + {{- include "tc.common.labels" . | nindent 4 }} + name: {{ .Release.Name }} +spec: + controller: traefik.io/ingress-controller +{{- end }} +{{- end }} diff --git a/stable/traefik/15.1.0/templates/_ingressroute.tpl b/stable/traefik/15.1.0/templates/_ingressroute.tpl new file mode 100644 index 00000000000..7f012c92350 --- /dev/null +++ b/stable/traefik/15.1.0/templates/_ingressroute.tpl @@ -0,0 +1,25 @@ +{{/* Define the ingressRoute */}} +{{- define "traefik.ingressRoute" -}} +{{ if .Values.ingressRoute.dashboard.enabled }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: {{ include "tc.common.names.fullname" . }}-dashboard + annotations: + {{- with .Values.ingressRoute.dashboard.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "tc.common.labels" . | nindent 4 }} +spec: + entryPoints: + - main + routes: + - match: PathPrefix(`/dashboard`) || PathPrefix(`/api`) + kind: Rule + services: + - name: api@internal + kind: TraefikService +{{ end }} +{{- end -}} diff --git a/stable/traefik/15.1.0/templates/_portalhook.tpl b/stable/traefik/15.1.0/templates/_portalhook.tpl new file mode 100644 index 00000000000..e3586c5d4e9 --- /dev/null +++ b/stable/traefik/15.1.0/templates/_portalhook.tpl @@ -0,0 +1,26 @@ +{{/* Define the portalHook */}} +{{- define "traefik.portalhook" -}} +{{- if .Values.portalhook.enabled }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: portalhook + namespace: {{ $namespace }} +data: + {{- $ports := dict }} + {{- range $.Values.service }} + {{- range $name, $value := .ports }} + {{- $_ := set $ports $name $value }} + {{- end }} + {{- end }} + {{- range $name, $value := $ports }} + {{ $name }}: {{ $value.port | quote }} + {{- end }} +{{- end }} +{{- end -}} diff --git a/stable/traefik/15.1.0/templates/_tlsoptions.tpl b/stable/traefik/15.1.0/templates/_tlsoptions.tpl new file mode 100644 index 00000000000..3e5aad3bee9 --- /dev/null +++ b/stable/traefik/15.1.0/templates/_tlsoptions.tpl @@ -0,0 +1,12 @@ +{{/* Define the tlsOptions */}} +{{- define "traefik.tlsOptions" -}} +{{- range $name, $config := .Values.tlsOptions }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: TLSOption +metadata: + name: {{ $name }} +spec: + {{- toYaml $config | nindent 2 }} +{{- end }} +{{- end -}} diff --git a/stable/traefik/15.1.0/templates/common.yaml b/stable/traefik/15.1.0/templates/common.yaml new file mode 100644 index 00000000000..c933a3d08e0 --- /dev/null +++ b/stable/traefik/15.1.0/templates/common.yaml @@ -0,0 +1,24 @@ +{{/* Make sure all variables are set properly */}} +{{- include "tc.common.loader.init" . }} + +{{- if .Values.metrics }} +{{- if .Values.metrics.prometheus }} +{{- $_ := set .Values.podAnnotations "prometheus.io/scrape" "true" -}} +{{- $_ := set .Values.podAnnotations "prometheus.io/path" "/metrics" -}} +{{- $_ := set .Values.podAnnotations "prometheus.io/port" "9180" -}} +{{- end }} +{{- end }} + +{{- $newArgs := (include "traefik.args" . | fromYaml) }} +{{- $_ := set .Values "newArgs" $newArgs -}} +{{- $mergedargs := concat .Values.args .Values.newArgs.args }} +{{- $_ := set .Values "args" $mergedargs -}} + +{{- include "traefik.portalhook" . }} +{{- include "traefik.tlsOptions" . }} +{{- include "traefik.ingressRoute" . }} +{{- include "traefik.ingressClass" . }} + + +{{/* Render the templates */}} +{{ include "tc.common.loader.apply" . }} diff --git a/stable/traefik/15.1.0/templates/middlewares/addPrefix.yaml b/stable/traefik/15.1.0/templates/middlewares/addPrefix.yaml new file mode 100644 index 00000000000..233b23834c3 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/addPrefix.yaml @@ -0,0 +1,17 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{- range $index, $middlewareData := .Values.middlewares.addPrefix }} + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + addPrefix: + prefix: {{ $middlewareData.prefix }} +{{- end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/basic-middleware.yaml b/stable/traefik/15.1.0/templates/middlewares/basic-middleware.yaml new file mode 100644 index 00000000000..9ba8e5c5d93 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/basic-middleware.yaml @@ -0,0 +1,62 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: compress + namespace: {{ $namespace }} +spec: + compress: {} +--- +# Here, an average of 300 requests per second is allowed. +# In addition, a burst of 200 requests is allowed. +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: basic-ratelimit + namespace: {{ $namespace }} +spec: + rateLimit: + average: 600 + burst: 400 +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: basic-secure-headers + namespace: {{ $namespace }} +spec: + headers: + accessControlAllowMethods: + - GET + - OPTIONS + - HEAD + - PUT + accessControlMaxAge: 100 + stsSeconds: 63072000 + # stsIncludeSubdomains: false + # stsPreload: false + forceSTSHeader: true + contentTypeNosniff: true + browserXssFilter: true + referrerPolicy: same-origin + customRequestHeaders: + X-Forwarded-Proto: "https" + customResponseHeaders: + server: '' +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: chain-basic + namespace: {{ $namespace }} +spec: + chain: + middlewares: + - name: basic-ratelimit + - name: basic-secure-headers + - name: compress diff --git a/stable/traefik/15.1.0/templates/middlewares/basicauth.yaml b/stable/traefik/15.1.0/templates/middlewares/basicauth.yaml new file mode 100644 index 00000000000..ccb541742f0 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/basicauth.yaml @@ -0,0 +1,34 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{ range $index, $middlewareData := .Values.middlewares.basicAuth }} +--- +{{- $users := list }} +{{ range $index, $userdata := $middlewareData.users }} + {{ $users = append $users ( htpasswd $userdata.username $userdata.password ) }} +{{ end }} + +apiVersion: v1 +kind: Secret +metadata: + name: {{printf "%v-%v" $middlewareData.name "secret" }} + namespace: {{ $namespace }} +type: Opaque +stringData: + users: | + {{- range $index, $user := $users }} + {{ printf "%s" $user }} + {{- end }} +--- +# Declaring the user list +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + basicAuth: + secret: {{printf "%v-%v" $middlewareData.name "secret" }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/chain.yaml b/stable/traefik/15.1.0/templates/middlewares/chain.yaml new file mode 100644 index 00000000000..f87994f7956 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/chain.yaml @@ -0,0 +1,21 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{ range $index, $middlewareData := .Values.middlewares.chain }} + +--- +# Declaring the user list +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + chain: + middlewares: + {{ range $index, $middleware := .middlewares }} + - name: {{ printf "%v-%v@%v" $namespace $middleware "kubernetescrd" }} + {{ end }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/forwardauth.yaml b/stable/traefik/15.1.0/templates/middlewares/forwardauth.yaml new file mode 100644 index 00000000000..4bdefbd5c01 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/forwardauth.yaml @@ -0,0 +1,34 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{ range $index, $middlewareData := .Values.middlewares.forwardAuth }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + forwardAuth: + address: {{ $middlewareData.address }} + {{- with $middlewareData.authResponseHeaders }} + authResponseHeaders: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $middlewareData.authRequestHeaders }} + authRequestHeaders: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $middlewareData.authResponseHeadersRegex }} + authResponseHeadersRegex: {{ $middlewareData.authResponseHeadersRegex }} + {{- end }} + {{- if $middlewareData.trustForwardHeader }} + trustForwardHeader: true + {{- end }} + {{- with $middlewareData.tls }} + tls: + insecureSkipVerify: {{ .insecureSkipVerify | default false }} + {{- end }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/geoblock.yaml b/stable/traefik/15.1.0/templates/middlewares/geoblock.yaml new file mode 100644 index 00000000000..1f0fb752769 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/geoblock.yaml @@ -0,0 +1,34 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{- range $index, $middlewareData := .Values.middlewares.geoBlock }} + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + plugin: + GeoBlock: + allowLocalRequests: {{ $middlewareData.allowLocalRequests }} + logLocalRequests: {{ $middlewareData.logLocalRequests }} + logAllowedRequests: {{ $middlewareData.logAllowedRequests }} + logApiRequests: {{ $middlewareData.logApiRequests }} + api: {{ $middlewareData.api }} + apiTimeoutMs: {{ $middlewareData.apiTimeoutMs }} + cacheSize: {{ $middlewareData.cacheSize }} + forceMonthlyUpdate: {{ $middlewareData.forceMonthlyUpdate }} + allowUnknownCountries: {{ $middlewareData.allowUnknownCountries }} + unknownCountryApiResponse: {{ $middlewareData.unknownCountryApiResponse }} + {{- if not $middlewareData.countries }} + {{- fail "You have to define at least one country..." }} + {{- end }} + countries: + {{- range $middlewareData.countries }} + - {{ . }} + {{- end }} +{{- end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/ipwhitelist.yaml b/stable/traefik/15.1.0/templates/middlewares/ipwhitelist.yaml new file mode 100644 index 00000000000..1179245017e --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/ipwhitelist.yaml @@ -0,0 +1,33 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{ range $index, $middlewareData := .Values.middlewares.ipWhiteList }} + +--- +# Declaring the user list +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + ipWhiteList: + sourceRange: + {{- range $middlewareData.sourceRange }} + - {{ . }} + {{- end }} + {{- if $middlewareData.ipStrategy }} + ipStrategy: + {{- if $middlewareData.ipStrategy.depth }} + depth: {{ $middlewareData.ipStrategy.depth }} + {{- end }} + {{- if $middlewareData.ipStrategy.excludedIPs }} + excludedIPs: + {{- range $middlewareData.ipStrategy.excludedIPs }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/ratelimit.yaml b/stable/traefik/15.1.0/templates/middlewares/ratelimit.yaml new file mode 100644 index 00000000000..144b9d8bf38 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/ratelimit.yaml @@ -0,0 +1,19 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{ range $index, $middlewareData := .Values.middlewares.rateLimit }} + +--- +# Declaring the user list +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + rateLimit: + average: {{ $middlewareData.average }} + burst: {{ $middlewareData.burst }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/real-ip.yaml b/stable/traefik/15.1.0/templates/middlewares/real-ip.yaml new file mode 100644 index 00000000000..2dd1ae030a4 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/real-ip.yaml @@ -0,0 +1,21 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{- range $index, $middlewareData := .Values.middlewares.realIP }} + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + plugin: + traefik-real-ip: + excludednets: + {{- range $middlewareData.excludedNetworks }} + - {{ . | quote }} + {{- end }} +{{- end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/redirectScheme.yaml b/stable/traefik/15.1.0/templates/middlewares/redirectScheme.yaml new file mode 100644 index 00000000000..f2413f84e19 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/redirectScheme.yaml @@ -0,0 +1,19 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{ range $index, $middlewareData := .Values.middlewares.redirectScheme }} + +--- +# Declaring the user list +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + redirectScheme: + scheme: {{ $middlewareData.scheme }} + permanent: {{ $middlewareData.permanent }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/redirectregex.yaml b/stable/traefik/15.1.0/templates/middlewares/redirectregex.yaml new file mode 100644 index 00000000000..46e3e724dd6 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/redirectregex.yaml @@ -0,0 +1,20 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{ range $index, $middlewareData := .Values.middlewares.redirectRegex }} + +--- +# Declaring the user list +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + redirectRegex: + regex: {{ $middlewareData.regex | quote }} + replacement: {{ $middlewareData.replacement | quote }} + permanent: {{ $middlewareData.permanent }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/stripPrefixRegex.yaml b/stable/traefik/15.1.0/templates/middlewares/stripPrefixRegex.yaml new file mode 100644 index 00000000000..007c166ff39 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/stripPrefixRegex.yaml @@ -0,0 +1,20 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} + +{{ range $index, $middlewareData := .Values.middlewares.stripPrefixRegex }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + stripPrefixRegex: + regex: + {{- range $middlewareData.regex }} + - {{ . | quote }} + {{- end }} +{{ end }} diff --git a/stable/traefik/15.1.0/templates/middlewares/tc-chains.yaml b/stable/traefik/15.1.0/templates/middlewares/tc-chains.yaml new file mode 100644 index 00000000000..409766daa89 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/tc-chains.yaml @@ -0,0 +1,29 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: tc-opencors-chain + namespace: {{ $namespace }} +spec: + chain: + middlewares: + - name: basic-ratelimit + - name: tc-opencors-headers + - name: compress +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: tc-closedcors-chain + namespace: {{ $namespace }} +spec: + chain: + middlewares: + - name: basic-ratelimit + - name: tc-closedcors-headers + - name: compress diff --git a/stable/traefik/15.1.0/templates/middlewares/tc-headers.yaml b/stable/traefik/15.1.0/templates/middlewares/tc-headers.yaml new file mode 100644 index 00000000000..a0462f1fd73 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/tc-headers.yaml @@ -0,0 +1,62 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: tc-opencors-headers + namespace: {{ $namespace }} +spec: + headers: + accessControlAllowHeaders: + - '*' + accessControlAllowMethods: + - GET + - OPTIONS + - HEAD + - PUT + - POST + accessControlAllowOriginList: + - '*' + accessControlMaxAge: 100 + browserXssFilter: true + contentTypeNosniff: true + customRequestHeaders: + X-Forwarded-Proto: https + customResponseHeaders: + server: "" + forceSTSHeader: true + referrerPolicy: same-origin + sslForceHost: true + sslRedirect: true + stsSeconds: 63072000 +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: tc-closedcors-headers + namespace: {{ $namespace }} +spec: + headers: + accessControlAllowMethods: + - GET + - OPTIONS + - HEAD + - PUT + accessControlMaxAge: 100 + sslRedirect: true + stsSeconds: 63072000 + # stsIncludeSubdomains: false + # stsPreload: false + forceSTSHeader: true + contentTypeNosniff: true + browserXssFilter: true + sslForceHost: true + referrerPolicy: same-origin + customRequestHeaders: + X-Forwarded-Proto: "https" + customResponseHeaders: + server: '' diff --git a/stable/traefik/15.1.0/templates/middlewares/tc-nextcloud.yaml b/stable/traefik/15.1.0/templates/middlewares/tc-nextcloud.yaml new file mode 100644 index 00000000000..6a3019d56c5 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/tc-nextcloud.yaml @@ -0,0 +1,25 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: tc-nextcloud-redirectregex-dav + namespace: {{ $namespace }} +spec: + redirectRegex: + regex: "https://(.*)/.well-known/(card|cal)dav" + replacement: "https://${1}/remote.php/dav/" +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: tc-nextcloud-chain + namespace: {{ $namespace }} +spec: + chain: + middlewares: + - name: tc-nextcloud-redirectregex-dav diff --git a/stable/traefik/15.1.0/templates/middlewares/theme-park.yaml b/stable/traefik/15.1.0/templates/middlewares/theme-park.yaml new file mode 100644 index 00000000000..92a4257e279 --- /dev/null +++ b/stable/traefik/15.1.0/templates/middlewares/theme-park.yaml @@ -0,0 +1,26 @@ +{{- $values := .Values }} +{{- $namespace := ( printf "ix-%s" .Release.Name ) }} +{{- if or ( not .Values.ingressClass.enabled ) ( and ( .Values.ingressClass.enabled ) ( .Values.ingressClass.isDefaultClass ) ) }} +{{- $namespace = "default" }} +{{- end }} +{{- range $index, $middlewareData := .Values.middlewares.themePark }} + +--- +apiVersion: traefik.containo.us/v1alpha1 +kind: Middleware +metadata: + name: {{ $middlewareData.name }} + namespace: {{ $namespace }} +spec: + plugin: + traefik-themepark: + app: {{ $middlewareData.appName }} + theme: {{ $middlewareData.themeName }} + baseUrl: {{ $middlewareData.baseUrl }} + {{- if $middlewareData.addons }} + addons: + {{- range $middlewareData.addons }} + - {{ . | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/stable/traefik/15.1.0/values.yaml b/stable/traefik/15.1.0/values.yaml new file mode 100644 index 00000000000..e69de29bb2d