add traefik integration

This commit is contained in:
Stavros kois
2023-12-06 22:18:33 +02:00
parent 6eb51ca7fc
commit 796ed60b62
6 changed files with 688 additions and 64 deletions

View File

@@ -18,6 +18,9 @@ tests:
operator: &operator
verify:
enabled: false
global:
traefik:
addIngressAnnotations: false
ingress:
my-ingress1:
enabled: true

View File

@@ -14,6 +14,8 @@ tests:
annotation1: annotation1
annotation2: global_annotation2
global:
traefik:
addIngressAnnotations: false
labels:
g_label1: global_label1
g_label2: "{{ .Values.label2 }}"

View File

@@ -0,0 +1,495 @@
suite: ingress - traefik metadata test
templates:
- common.yaml
chart:
appVersion: &appVer v9.9.9
release:
name: test-release-name
namespace: test-release-namespace
tests:
- it: should pass with ingress created with annotations from traefik by default
set:
operator: &operator
verify:
enabled: false
ingress:
my-ingress:
enabled: true
primary: true
asserts:
- documentIndex: &ingressDoc 0
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-tc-system@kubernetescrd
- documentIndex: *ingressDoc
equal:
path: metadata.namespace
value: test-release-namespace
- it: should pass with ingress created without traefik annotations when traefik false
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: false
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
isNull:
path: metadata.annotations
- it: should replace local fixedMiddlewares when allowCors true
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
allowCors: true
fixedMiddlewares:
- some-fixed-middleware
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: tc-opencors-chain-tc-system@kubernetescrd
- it: should replace global fixedMiddlewares when allowCors true
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
allowCors: true
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: tc-opencors-chain-tc-system@kubernetescrd
- it: should replace global fixedMiddlewares when local fixedMiddlewares is defined
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
fixedMiddlewares:
- some-fixed-middleware
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: some-fixed-middleware-tc-system@kubernetescrd
- it: should override default entrypoint(s)
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints:
- web
- websecure
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-tc-system@kubernetescrd
- it: should not contain fixed middlewares when global is disabled
set:
operator: *operator
global:
traefik:
enableFixedMiddlewares: false
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
- it: should not contain fixed middlewares when local is disabled
set:
operator: *operator
global:
traefik:
enableFixedMiddlewares: true
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
enableFixedMiddlewares: false
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
- it: should set correct namespace when operator is registered
set:
operator:
verify:
enabled: false
traefik:
namespace: some-ns
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints:
- web
- websecure
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-some-ns@kubernetescrd
- it: should set correct namespace when ingressClassName is defined regardless of operator
set:
operator:
verify:
enabled: false
traefik:
namespace: some-ns
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
ingressClassName: some-class
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-some-class@kubernetescrd
- it: should set correct namespace when ingressClassName is defined in SCALE regardless of operator
set:
operator:
verify:
enabled: false
traefik:
namespace: some-ns
global:
ixChartContext:
imNotEmpty: true
namespace: ix-namespace
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
ingressClassName: some-class
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-ix-some-class@kubernetescrd
- it: should add the defined middlewares to the ingress
set:
operator: *operator
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
middlewares:
- some-middleware
- some-other-middleware
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-tc-system@kubernetescrd,some-middleware-tc-system@kubernetescrd,some-other-middleware-tc-system@kubernetescrd
- it: should disable traefik annotations in ingress
set:
operator: *operator
global:
traefik:
addIngressAnnotations: false
ingress:
my-ingress:
enabled: true
primary: true
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
isNull:
path: metadata.annotations
- it: should override global disable for traefik annotations in ingress
set:
operator: *operator
global:
traefik:
addIngressAnnotations: false
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: true
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
equal:
path: metadata.annotations
value:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: chain-basic-tc-system@kubernetescrd
- it: should override global disable for traefik annotations in ingress
set:
operator: *operator
global:
traefik:
addIngressAnnotations: true
ingress:
my-ingress:
enabled: true
primary: true
integrations:
traefik:
enabled: false
asserts:
- documentIndex: *ingressDoc
isKind:
of: Ingress
- documentIndex: *ingressDoc
equal:
path: metadata.name
value: test-release-name-common-test
- documentIndex: *ingressDoc
isNull:
path: metadata.annotations
# Failures
- it: should fail with entrypoint not a slice
set:
operator: *operator
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints: "not a string"
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.traefik.entrypoints] to be a [slice], but got [string]
- it: should fail with middlewares not a slice
set:
operator: *operator
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
middlewares: "not a slice"
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.traefik.middlewares] to be a [slice], but got [string]
- it: should fail with fixedMiddlewares not a slice
set:
operator: *operator
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
fixedMiddlewares: "not a slice"
asserts:
- failedTemplate:
errorMessage: Ingress - Expected [integrations.traefik.fixedMiddlewares] to be a [slice], but got [string]
- it: should fail with duplicate middlewares
set:
operator: *operator
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
middlewares:
- chain-basic
asserts:
- failedTemplate:
errorMessage: Ingress - Combined traefik middlewares contain duplicates [chain-basic, chain-basic]
- it: should fail with duplicate entrypoints
set:
operator: *operator
ingress:
my-ingress1:
enabled: true
primary: true
integrations:
traefik:
enabled: true
entrypoints:
- websecure
- websecure
asserts:
- failedTemplate:
errorMessage: Ingress - Combined traefik entrypoints contain duplicates [websecure, websecure]

View File

@@ -20,7 +20,7 @@ objectData: The object data to be used to render the Ingress.
{{- $_ := set $objectData "annotations" dict -}}
{{- end -}}
{{- include "tc.v1.common.lib.ingress.integration.certManager" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- /* include "tc.v1.common.lib.ingress.integration.certManager" (dict "rootCtx" $rootCtx "objectData" $objectData) */ -}}
{{- include "tc.v1.common.lib.ingress.integration.traefik" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{- include "tc.v1.common.lib.ingress.integration.homepage" (dict "rootCtx" $rootCtx "objectData" $objectData) -}}
{{/* TODO: fix last - */}}

View File

@@ -0,0 +1,121 @@
{{- define "tc.v1.common.lib.ingress.integration.traefik" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- $traefik := $objectData.integrations.traefik -}}
{{- $enabled := false -}}
{{- if (hasKey $rootCtx.Values.global "traefik") -}}
{{- $enabled = $rootCtx.Values.global.traefik.addIngressAnnotations -}}
{{- end -}}
{{- if and $traefik (kindIs "bool" $traefik.enabled) -}}
{{- $enabled = $traefik.enabled -}}
{{- end -}}
{{- if $enabled -}}
{{- include "tc.v1.common.lib.ingress.integration.traefik.validate" (dict "objectData" $objectData) -}}
{{- $fixedMiddlewares := list -}}
{{- $enableFixed := false -}}
{{- if (hasKey $rootCtx.Values.global "traefik") -}}
{{- $fixedMiddlewares = $rootCtx.Values.global.traefik.fixedMiddlewares -}}
{{- $enableFixed = $rootCtx.Values.global.traefik.enableFixedMiddlewares -}}
{{- end -}}
{{/* Override global (enable)fixedMiddlewares with local */}}
{{- if $traefik.fixedMiddlewares -}}
{{- $fixedMiddlewares = $traefik.fixedMiddlewares -}}
{{- end -}}
{{/* Replace global fixed with local fixed */}}
{{- if and (hasKey $traefik "enableFixedMiddlewares") (kindIs "bool" $traefik.enableFixedMiddlewares) -}}
{{- $enableFixed = $traefik.enableFixedMiddlewares -}}
{{- end -}}
{{/* Replace global and local fixed middlewares with the opencors-chain */}}
{{- if $traefik.allowCors -}}
{{- $fixedMiddlewares = list "tc-opencors-chain" -}}
{{- end -}}
{{- $entrypoints := $traefik.entrypoints | default (list "websecure") -}}
{{- $middlewares := list -}}
{{/* Add the fixedMiddlewares */}}
{{- if and $enableFixed $fixedMiddlewares -}}
{{- $middlewares = concat $middlewares $fixedMiddlewares -}}
{{- end -}}
{{/* Add the user middlewares */}}
{{- if $traefik.middlewares -}}
{{- $middlewares = concat $middlewares $traefik.middlewares -}}
{{- end -}}
{{/* Make sure we dont have dupes */}}
{{- if $middlewares -}}
{{- if not (deepEqual (mustUniq $middlewares) $middlewares) -}}
{{- fail (printf "Ingress - Combined traefik middlewares contain duplicates [%s]" (join ", " $middlewares)) -}}
{{- end -}}
{{- end -}}
{{- if not (deepEqual (mustUniq $entrypoints) $entrypoints) -}}
{{- fail (printf "Ingress - Combined traefik entrypoints contain duplicates [%s]" (join ", " $entrypoints)) -}}
{{- end -}}
{{- $midNamespace := "tc-system" -}}
{{/* If our hook has set operator.traefik.namespace, use that */}}
{{- if (hasKey $rootCtx.Values.operator "traefik") -}}
{{- if $rootCtx.Values.operator.traefik.namespace -}}
{{- $midNamespace = $rootCtx.Values.operator.traefik.namespace -}}
{{- end -}}
{{- end -}}
{{- if $traefik.ingressClassName -}}
{{- $midNamespace = $traefik.ingressClassName -}}
{{/* On SCALE prepend with ix- */}}
{{- if $rootCtx.Values.global.ixChartContext -}}
{{- $midNamespace = (printf "ix-%s" $midNamespace) -}}
{{- end -}}
{{- end -}}
{{/* Format middlewares */}}
{{- $formMiddlewares := list -}}
{{- range $mid := $middlewares -}}
{{- $formMiddlewares = mustAppend $formMiddlewares (printf "%s-%s@kubernetescrd" $mid $midNamespace) -}}
{{- end -}}
{{- $_ := set $objectData.annotations "traefik.ingress.kubernetes.io/router.entrypoints" (join "," $entrypoints) -}}
{{- if $formMiddlewares -}}
{{- $_ := set $objectData.annotations "traefik.ingress.kubernetes.io/router.middlewares" (join "," $formMiddlewares) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "tc.v1.common.lib.ingress.integration.traefik.validate" -}}
{{- $objectData := .objectData -}}
{{- $traefik := $objectData.integrations.traefik -}}
{{- if $traefik -}}
{{- if $traefik.entrypoints -}}
{{- if not (kindIs "slice" $traefik.entrypoints) -}}
{{- fail (printf "Ingress - Expected [integrations.traefik.entrypoints] to be a [slice], but got [%s]" (kindOf $traefik.entrypoints)) -}}
{{- end -}}
{{- end -}}
{{- if $traefik.middlewares -}}
{{- if not (kindIs "slice" $traefik.middlewares) -}}
{{- fail (printf "Ingress - Expected [integrations.traefik.middlewares] to be a [slice], but got [%s]" (kindOf $traefik.middlewares)) -}}
{{- end -}}
{{- end -}}
{{- if $traefik.fixedMiddlewares -}}
{{- if not (kindIs "slice" $traefik.fixedMiddlewares) -}}
{{- fail (printf "Ingress - Expected [integrations.traefik.fixedMiddlewares] to be a [slice], but got [%s]" (kindOf $traefik.fixedMiddlewares)) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -13,6 +13,8 @@ global:
traefik:
# -- Adds traefik annotations to services (when needed)
addServiceAnnotations: true
# -- Enable or disable traefik ingress integration, can be overruled per ingress
addIngressAnnotations: true
# Enables or disables the fixed middlewares on all ingresses
# Can be overrided per ingress
enableFixedMiddlewares: true
@@ -532,77 +534,23 @@ ingress:
main:
# -- Enables or disables the ingress
enabled: false
# -- Adds integrations to ingress
# integration:
# homepage:
# enabled: true
# # Default: chart name
# name: somename
# # Default: chart description
# description: some description
# group: somegroup
# # Default: chart icon
# icon: icon.png
# pod-selector: ""
# widget:
# # Default: chartname
# type: "sometype"
# # Default: host-path of first ingress
# url: "https://example.com"
# custom:
# - somesetting: some value
# -- Make this the primary ingress (used in probes, notes, etc...).
# If there is more than 1 ingress, make sure that only 1 ingress is marked as primary.
primary: true
# -- Ensure this ingress is always enabled.
required: false
# -- Override the name suffix that is used for this ingress.
nameOverride:
# -- Autolink the ingress to a service and port, both with the same name as the ingress.
autoLink: false
# -- disable to ignore any default middlwares
enableFixedMiddlewares: true
# -- set the Cert-Manager clusterissuer for this ingress
clusterIssuer: ""
# -- List of middlewares in the traefikmiddlewares k8s namespace to add automatically
# Creates an annotation with the middlewares and appends k8s and traefik namespaces to the middleware names
# Primarily used for TrueNAS SCALE to add additional (seperate) middlewares without exposing them to the end-user
# -- Additional List of middlewares in the traefikmiddlewares k8s namespace to add automatically
# Creates an annotation with the middlewares and appends k8s and traefik namespaces to the middleware names
middlewares: []
annotationsList: []
# - name: somename
# value: somevalue
# -- Provide additional annotations which may be required.
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
labelsList: []
# - name: somename
# value: somevalue
# -- Set labels on the deployment/statefulset/daemonset
# -- Provide additional labels which may be required.
expandObjectName: false
# -- Provide additional labels which may be required.
labels: {}
# -- Provide additional annotations which may be required.
annotations: {}
# -- Set the ingressClass that is used for this ingress.
# Requires Kubernetes >=1.19
ingressClassName: # "nginx"
# Enable or disable CORS Requests to the ingress
allowCors: false
# Defaults to primary service and primary port
# targetSelector:
# # service: port
# main: main
## Configure the hosts for the ingress
hosts:
- # -- Host address. Helm template can be passed.
@@ -613,12 +561,12 @@ ingress:
path: /
# -- Ignored if not kubeVersion >= 1.14-0
pathType: Prefix
service:
# -- Overrides the service reference for this path, by default the selector is honored
overrideService:
# -- Overrides the service name reference for this path
name:
# -- Overrides the service port reference for this path
port:
# -- Configure TLS for the ingress. Both secretName and hosts can process a Helm template.
# Gets ignored when clusterIssuer is filled
tls: []
@@ -629,6 +577,61 @@ ingress:
# scaleCert: ""
# hosts:
# - chart-example.local
integrations:
traefik:
enabled: true
# Default to websecure
entrypoints:
- websecure
enableFixedMiddlewares: true
# Drops both global and local fixedMiddlewares when enabled
allowCors: false
fixedMiddlewares:
- chain-basic
middlewares: []
certManager:
enabled: true
clusterIssuer: ""
# -- Adds integrations to ingress
integration:
homepage:
# enabled: true
# # Default: chart name
# name: somename
# # Default: chart description
# description: some description
# # Default: no group
# group: somegroup
# # Default: chart icon
# icon: icon.png
# widget:
# # Default: chartname
# type: "sometype"
# # Default to ingress host 0
# url: "https://example.com"
# custom:
# - somesetting: some value
traefik:
# -- Enables or disables the traefik integration (enabled if not defined)
enabled: true
# -- List of entrypoints to add, Defaults to websecure
entrypoints:
- websecure
# -- disable to ignore any default middelwares
enableFixedMiddlewares: true
# -- Additional List of middlewares in the traefik middlewares k8s namespace to add automatically
# Creates an annotation with the middlewares and appends k8s and traefik namespaces to the middleware names
middlewares: []
# Replaces global fixed middlewares
fixedMiddlewares: []
# Enable or disable CORS Requests to the ingress
# Drops both global and local fixedMiddlewares when enabled
allowCors: false
certManager:
# -- Enables or disables the cert-manager integration (enabled if not defined)
enabled: true
# -- set the Cert-Manager clusterissuer for this ingress
clusterIssuer: ""
# -- BETA: Configure the gateway routes for the chart here.
# Additional routes can be added by adding a dictionary key similar to the 'main' route.