diff --git a/parcellab/common/Chart.yaml b/parcellab/common/Chart.yaml index d408d3b..704b01d 100644 --- a/parcellab/common/Chart.yaml +++ b/parcellab/common/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: common description: A Helm chart library for parcelLab charts type: library -version: 1.3.0 +version: 1.3.1 maintainers: - name: parcelLab email: engineering@parcellab.com diff --git a/parcellab/common/templates/_backendtrafficpolicy.tpl b/parcellab/common/templates/_backendtrafficpolicy.tpl new file mode 100644 index 0000000..77a6008 --- /dev/null +++ b/parcellab/common/templates/_backendtrafficpolicy.tpl @@ -0,0 +1,79 @@ +{{/* vim: set filetype=mustache: */}} +{{/* + Common BackendTrafficPolicy definition: + {{ include "common.backendtrafficpolicy" ( + dict + "Values" "the values scope" + "Release" .Release + "route" "the current HTTPRoute object" + "index" "the httpRoutes index" + "routeName" "the rendered HTTPRoute name" + "globalLabels" "common labels" + ) }} +*/}} + +{{- define "common.backendtrafficpolicy" -}} +{{- $route := .route | default dict -}} +{{- $index := .index | default 0 -}} +{{- $routeName := .routeName | default "" -}} +{{- $globalLabels := .globalLabels | default dict -}} +{{- $serviceNamespace := .Release.Namespace -}} +{{- $backendTrafficPolicy := $route.backendTrafficPolicy -}} +{{- if $backendTrafficPolicy }} +{{- $btpEnabled := default true $backendTrafficPolicy.enabled -}} +{{- if $btpEnabled -}} +{{- $btpName := default (printf "%s-backend-traffic-policy" $routeName) $backendTrafficPolicy.name -}} +{{- $btpLabels := $backendTrafficPolicy.labels | default dict -}} +{{- $btpAnnotations := $backendTrafficPolicy.annotations | default dict -}} +{{- $btpTargetRefs := $backendTrafficPolicy.targetRefs | default list -}} +{{- $btpSpec := $backendTrafficPolicy.spec | default dict -}} +{{- if eq (len $btpSpec) 0 -}} +{{- $btpSpec = deepCopy $backendTrafficPolicy -}} +{{- $_ := unset $btpSpec "enabled" -}} +{{- $_ := unset $btpSpec "name" -}} +{{- $_ := unset $btpSpec "labels" -}} +{{- $_ := unset $btpSpec "annotations" -}} +{{- $_ := unset $btpSpec "targetRefs" -}} +{{- $_ := unset $btpSpec "spec" -}} +{{- end -}} +{{- $btpSpecHasTargetRefs := hasKey $btpSpec "targetRefs" -}} +{{- if gt (len $btpTargetRefs) 0 -}} +{{- if $btpSpecHasTargetRefs -}} +{{- $_ := unset $btpSpec "targetRefs" -}} +{{- $btpSpecHasTargetRefs = false -}} +{{- end -}} +{{- end -}} +{{- if and (eq (len $btpSpec) 0) (eq (len $btpTargetRefs) 0) (not $btpSpecHasTargetRefs) -}} +{{- fail (printf "envoy.httpRoutes[%d].backendTrafficPolicy requires spec or fields" $index) -}} +{{- end -}} +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: BackendTrafficPolicy +metadata: + name: {{ $btpName }} + namespace: {{ $serviceNamespace }} + labels: + {{- $globalLabels | nindent 4 }} + {{- with $btpLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $btpAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if gt (len $btpTargetRefs) 0 }} + targetRefs: + {{- toYaml $btpTargetRefs | nindent 4 }} + {{- else if not $btpSpecHasTargetRefs }} + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: {{ $routeName }} + {{- end }} + {{- if gt (len $btpSpec) 0 }} + {{- toYaml $btpSpec | nindent 2 }} + {{- end }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/parcellab/common/templates/_clienttrafficpolicy.tpl b/parcellab/common/templates/_clienttrafficpolicy.tpl new file mode 100644 index 0000000..7a5cc78 --- /dev/null +++ b/parcellab/common/templates/_clienttrafficpolicy.tpl @@ -0,0 +1,79 @@ +{{/* vim: set filetype=mustache: */}} +{{/* + Common ClientTrafficPolicy definition: + {{ include "common.clienttrafficpolicy" ( + dict + "Values" "the values scope" + "Release" .Release + "route" "the current HTTPRoute object" + "index" "the httpRoutes index" + "routeName" "the rendered HTTPRoute name" + "globalLabels" "common labels" + ) }} +*/}} + +{{- define "common.clienttrafficpolicy" -}} +{{- $route := .route | default dict -}} +{{- $index := .index | default 0 -}} +{{- $routeName := .routeName | default "" -}} +{{- $globalLabels := .globalLabels | default dict -}} +{{- $serviceNamespace := .Release.Namespace -}} +{{- $clientTrafficPolicy := $route.clientTrafficPolicy -}} +{{- if $clientTrafficPolicy }} +{{- $ctpEnabled := default true $clientTrafficPolicy.enabled -}} +{{- if $ctpEnabled -}} +{{- $ctpName := default (printf "%s-client-traffic-policy" $routeName) $clientTrafficPolicy.name -}} +{{- $ctpLabels := $clientTrafficPolicy.labels | default dict -}} +{{- $ctpAnnotations := $clientTrafficPolicy.annotations | default dict -}} +{{- $ctpTargetRefs := $clientTrafficPolicy.targetRefs | default list -}} +{{- $ctpSpec := $clientTrafficPolicy.spec | default dict -}} +{{- if eq (len $ctpSpec) 0 -}} +{{- $ctpSpec = deepCopy $clientTrafficPolicy -}} +{{- $_ := unset $ctpSpec "enabled" -}} +{{- $_ := unset $ctpSpec "name" -}} +{{- $_ := unset $ctpSpec "labels" -}} +{{- $_ := unset $ctpSpec "annotations" -}} +{{- $_ := unset $ctpSpec "targetRefs" -}} +{{- $_ := unset $ctpSpec "spec" -}} +{{- end -}} +{{- $ctpSpecHasTargetRefs := hasKey $ctpSpec "targetRefs" -}} +{{- if gt (len $ctpTargetRefs) 0 -}} +{{- if $ctpSpecHasTargetRefs -}} +{{- $_ := unset $ctpSpec "targetRefs" -}} +{{- $ctpSpecHasTargetRefs = false -}} +{{- end -}} +{{- end -}} +{{- if and (eq (len $ctpSpec) 0) (eq (len $ctpTargetRefs) 0) (not $ctpSpecHasTargetRefs) -}} +{{- fail (printf "envoy.httpRoutes[%d].clientTrafficPolicy requires spec or fields" $index) -}} +{{- end -}} +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: ClientTrafficPolicy +metadata: + name: {{ $ctpName }} + namespace: {{ $serviceNamespace }} + labels: + {{- $globalLabels | nindent 4 }} + {{- with $ctpLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $ctpAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if gt (len $ctpTargetRefs) 0 }} + targetRefs: + {{- toYaml $ctpTargetRefs | nindent 4 }} + {{- else if not $ctpSpecHasTargetRefs }} + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: {{ $routeName }} + {{- end }} + {{- if gt (len $ctpSpec) 0 }} + {{- toYaml $ctpSpec | nindent 2 }} + {{- end }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/parcellab/common/templates/_httproutes.tpl b/parcellab/common/templates/_httproutes.tpl index 9d539ce..d31f029 100644 --- a/parcellab/common/templates/_httproutes.tpl +++ b/parcellab/common/templates/_httproutes.tpl @@ -5,6 +5,7 @@ */}} {{- define "common.httproutes" -}} +{{- $root := . -}} {{- $envoy := .Values.envoy | default dict -}} {{- if $envoy.enabled -}} {{- $gateway := default (dict "name" "gateway-api" "namespace" "envoy-gateway") $envoy.gateway -}} @@ -15,6 +16,7 @@ {{- $security := default dict $envoy.security -}} {{- $securityEnabled := default false $security.enabled -}} {{- $securityLabelKey := printf "%s/security-required" (include "common.parcellabtagsdomain" .) -}} +{{- $rolloutServices := include "common.rolloutServicesMap" (dict "root" $root "baseName" $baseName) | fromJson -}} {{- range $index, $route := $httproutes }} {{- $hosts := required (printf "envoy.httpRoutes[%d].hosts is required" $index) $route.hosts -}} @@ -50,8 +52,25 @@ spec: {{- end }} {{- with $route.rules }} rules: - {{ toYaml . | nindent 4 }} - {{ end }} + {{- range $rule := . }} + {{- $ruleCopy := deepCopy $rule -}} + {{- if $ruleCopy.backendRefs }} + {{- range $backend := $ruleCopy.backendRefs }} + {{- $backendKind := default "Service" $backend.kind -}} + {{- $backendGroup := default "" $backend.group -}} + {{- if and (eq $backendKind "Service") (eq $backendGroup "") }} + {{- $backendName := $backend.name -}} + {{- if and $backendName (hasKey $rolloutServices $backendName) (not (hasSuffix "-rollout" $backendName)) -}} + {{- $_ := set $backend "name" (printf "%s-rollout" $backendName) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- toYaml (list $ruleCopy) | nindent 4 }} + {{- end }} + {{- end }} +{{ include "common.backendtrafficpolicy" (dict "Values" $root.Values "Release" $root.Release "route" $route "index" $index "routeName" $routeName "globalLabels" $globalLabels) }} +{{ include "common.clienttrafficpolicy" (dict "Values" $root.Values "Release" $root.Release "route" $route "index" $index "routeName" $routeName "globalLabels" $globalLabels) }} {{ end }} {{- end }} {{- end }} diff --git a/parcellab/common/templates/_ingress.tpl b/parcellab/common/templates/_ingress.tpl index ed85440..fb8dd44 100644 --- a/parcellab/common/templates/_ingress.tpl +++ b/parcellab/common/templates/_ingress.tpl @@ -7,11 +7,12 @@ ) }} */}} {{- define "common.ingress" -}} +{{- $root := . -}} {{- $ingress := .Values.ingress -}} {{- $defaultServicePort := .Values.service.port -}} {{- if $ingress.enabled -}} {{- $name := include "common.fullname" . }} -{{- $argoRollout := .Values.argoRollout | default dict -}} +{{- $rolloutServices := include "common.rolloutServicesMap" (dict "root" $root "baseName" $name) | fromJson -}} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: @@ -52,12 +53,16 @@ spec: pathType: {{ .pathType }} {{- end }} {{- if .backend }} + {{- $backendCopy := deepCopy .backend -}} + {{- if and $backendCopy.service $backendCopy.service.name (hasKey $rolloutServices $backendCopy.service.name) (not (hasSuffix "-rollout" $backendCopy.service.name)) -}} + {{- $_ := set $backendCopy.service "name" (printf "%s-rollout" $backendCopy.service.name) -}} + {{- end }} backend: - {{- toYaml .backend | nindent 14 }} + {{- toYaml $backendCopy | nindent 14 }} {{- else }} backend: service: - name: {{ if $argoRollout.enabled }} {{ $name }}-rollout {{ else }} {{ $name }} {{ end }} + name: {{ if (hasKey $rolloutServices $name) }}{{ $name }}-rollout{{ else }}{{ $name }}{{ end }} port: number: {{ $defaultServicePort }} {{- end }} diff --git a/parcellab/common/templates/_rollout.tpl b/parcellab/common/templates/_rollout.tpl index 63b21a9..4e29122 100644 --- a/parcellab/common/templates/_rollout.tpl +++ b/parcellab/common/templates/_rollout.tpl @@ -1,4 +1,27 @@ {{/* vim: set filetype=mustache: */}} +{{/* +Builds the map of service names that should target their -rollout counterpart. +Returns JSON so callers can deserialise with fromJson. +Usage: + {{- $rolloutServices := include "common.rolloutServicesMap" (dict "root" . "baseName" $baseName) | fromJson -}} +*/}} +{{- define "common.rolloutServicesMap" -}} +{{- $root := .root -}} +{{- $baseName := .baseName -}} +{{- $rolloutServices := dict -}} +{{- $globalRollout := $root.Values.argoRollout | default dict -}} +{{- if $globalRollout.enabled -}} +{{- $_ := set $rolloutServices $baseName true -}} +{{- end -}} +{{- range $root.Values.extraServices | default list -}} +{{- if and .argoRollout .argoRollout.enabled -}} +{{- $svcName := include "common.componentname" (merge (deepCopy $root) (dict "component" .name)) -}} +{{- $_ := set $rolloutServices $svcName true -}} +{{- end -}} +{{- end -}} +{{- $rolloutServices | toJson -}} +{{- end -}} + {{/* Keys and quoted values generated from a given dict: {{ include "common.argorollout" ( diff --git a/parcellab/cronjob/Chart.yaml b/parcellab/cronjob/Chart.yaml index 3ba4d4c..481808c 100644 --- a/parcellab/cronjob/Chart.yaml +++ b/parcellab/cronjob/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: cronjob description: Single cron job -version: 0.4.2 +version: 0.4.3 dependencies: - name: common version: "*" diff --git a/parcellab/microservice/Chart.yaml b/parcellab/microservice/Chart.yaml index dfd2797..b32100f 100644 --- a/parcellab/microservice/Chart.yaml +++ b/parcellab/microservice/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: microservice description: Simple microservice -version: 0.5.0 +version: 0.5.1 dependencies: - name: common version: "*" diff --git a/parcellab/microservice/README.md b/parcellab/microservice/README.md index a53956d..a9de888 100644 --- a/parcellab/microservice/README.md +++ b/parcellab/microservice/README.md @@ -32,7 +32,7 @@ needs. - `hpa` - Horizontal automatic scaling rules of pods. Can be defined with the `autoscaling` setting. - `envoy` - - Envoy Gateway resources (HTTPRoute, ReferenceGrant). Defined under `envoy.*`. + - Envoy Gateway resources (HTTPRoute, ReferenceGrant, BackendTrafficPolicy, ClientTrafficPolicy). Defined under `envoy.*`. - `ingress` - Rules to open external access to the workload. Can be defined with `ingress`. - `poddisruptionbudget` diff --git a/parcellab/microservice/values.yaml b/parcellab/microservice/values.yaml index e55fb28..65e740c 100644 --- a/parcellab/microservice/values.yaml +++ b/parcellab/microservice/values.yaml @@ -80,6 +80,28 @@ envoy: # port: 5000 # group: "" # kind: Service + # backendTrafficPolicy: + # # enabled: true + # # name: my-app-policy + # # labels: {} + # # annotations: {} + # # targetRefs: [] # default: the HTTPRoute above + # # loadBalancer: + # # type: LeastRequest + # # timeout: + # # tcp: + # # connectTimeout: 5s + # # http: + # # connectionIdleTimeout: 60s + # # requestTimeout: 30s + # clientTrafficPolicy: + # # enabled: true + # # name: my-app-client-policy + # # labels: {} + # # annotations: {} + # # targetRefs: [] # default: the HTTPRoute above + # # tls: + # # sni: "my-app.example.com" # labels: # foo: bar # optional security: diff --git a/parcellab/monolith/Chart.yaml b/parcellab/monolith/Chart.yaml index 1de13c6..5d5baf8 100644 --- a/parcellab/monolith/Chart.yaml +++ b/parcellab/monolith/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: monolith description: Application that may define multiple services and cronjobs -version: 0.5.0 +version: 0.5.1 dependencies: - name: common version: "*" diff --git a/parcellab/monolith/README.md b/parcellab/monolith/README.md index 465e252..582c6ed 100644 --- a/parcellab/monolith/README.md +++ b/parcellab/monolith/README.md @@ -32,7 +32,7 @@ needs. - `hpa` - Horizontal automatic scaling rules of pods. Can be defined with the `autoscaling` setting. - `envoy` - - Envoy Gateway resources (HTTPRoute, ReferenceGrant, SecurityPolicy). Defined under `envoy.*`. + - Envoy Gateway resources (HTTPRoute, ReferenceGrant, SecurityPolicy, BackendTrafficPolicy, ClientTrafficPolicy). Defined under `envoy.*`. - `ingress` - Rules to open external access to the workload. Can be defined with `ingress`. - `poddisruptionbudget` diff --git a/parcellab/monolith/values.yaml b/parcellab/monolith/values.yaml index 71a3b98..7929514 100644 --- a/parcellab/monolith/values.yaml +++ b/parcellab/monolith/values.yaml @@ -109,6 +109,28 @@ envoy: # port: 5000 # group: "" # kind: Service + # backendTrafficPolicy: + # # enabled: true + # # name: my-app-policy + # # labels: {} + # # annotations: {} + # # targetRefs: [] # default: the HTTPRoute above + # # loadBalancer: + # # type: LeastRequest + # # timeout: + # # tcp: + # # connectTimeout: 5s + # # http: + # # connectionIdleTimeout: 60s + # # requestTimeout: 30s + # clientTrafficPolicy: + # # enabled: true + # # name: my-app-client-policy + # # labels: {} + # # annotations: {} + # # targetRefs: [] # default: the HTTPRoute above + # # tls: + # # sni: "my-app.example.com" # labels: # foo: bar # optional security: diff --git a/parcellab/worker-group/Chart.yaml b/parcellab/worker-group/Chart.yaml index da9c592..1e3e70d 100644 --- a/parcellab/worker-group/Chart.yaml +++ b/parcellab/worker-group/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: worker-group description: Set of workers that do not expose a service -version: 0.3.2 +version: 0.3.3 dependencies: - name: common version: "*"