From 601e54a0837ed4428df97c3a10938b23908e75fd Mon Sep 17 00:00:00 2001 From: Afzal Ansari Date: Mon, 5 Sep 2022 09:20:58 +0000 Subject: [PATCH] feat: add support for http headers on liveness/readiness probes --- assets/auto-deploy-app/Chart.yaml | 2 +- assets/auto-deploy-app/README.md | 9 + .../auto-deploy-app/templates/deployment.yaml | 23 ++- .../templates/worker-deployment.yaml | 14 ++ .../test/templates/deployment_test.go | 40 +++- .../test/templates/workerdeployment_test.go | 187 ++++++++++++------ assets/auto-deploy-app/values.yaml | 9 + 7 files changed, 213 insertions(+), 71 deletions(-) diff --git a/assets/auto-deploy-app/Chart.yaml b/assets/auto-deploy-app/Chart.yaml index 5546405..cbea7ec 100644 --- a/assets/auto-deploy-app/Chart.yaml +++ b/assets/auto-deploy-app/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 description: GitLab's Auto-deploy Helm Chart name: auto-deploy-app -version: 2.34.0 +version: 2.35.0 icon: https://gitlab.com/gitlab-com/gitlab-artwork/raw/master/logo/logo-square.png diff --git a/assets/auto-deploy-app/README.md b/assets/auto-deploy-app/README.md index ab254ec..1d75bcd 100644 --- a/assets/auto-deploy-app/README.md +++ b/assets/auto-deploy-app/README.md @@ -77,12 +77,18 @@ | ingress.annotations | Ingress annotations | See [`_ingress-annotations.yaml`](./templates/_ingress-annotations.yaml) | | livenessProbe.path | Path to access on the HTTP server on periodic probe of container liveness. | `/` | | livenessProbe.scheme | Scheme to access the HTTP server (HTTP or HTTPS). | `HTTP` | +| livenessProbe.httpHeaders | List of additional custom headers to send on the server | `[]` | +| livenessProbe.httpHeaders.name | Name of the custom header | `nil` | +| livenessProbe.httpHeaders.value | Value of the header | `nil` | | livenessProbe.initialDelaySeconds | # of seconds after the container has started before liveness probes are initiated. | `15` | | livenessProbe.timeoutSeconds | # of seconds after which the liveness probe times out. | `15` | | livenessProbe.probeType | Type of [liveness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes) to use. | `httpGet` | livenessProbe.command | Commands for use with probe type 'exec'. | `{}` | readinessProbe.path | Path to access on the HTTP server on periodic probe of container readiness. | `/` | | readinessProbe.scheme | Scheme to access the HTTP server (HTTP or HTTPS). | `HTTP` | +| readinessProbe.httpHeaders | List of additional custom headers to send on the server | `[]` | +| readinessProbe.httpHeaders.name | Name of the custom header | `nil` | +| readinessProbe.httpHeaders.value | Value of the header | `nil` | | readinessProbe.initialDelaySeconds | # of seconds after the container has started before readiness probes are initiated. | `5` | | readinessProbe.timeoutSeconds | # of seconds after which the readiness probe times out. | `3` | | readinessProbe.probeType | Type of [readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes) to use. | `httpGet` @@ -90,6 +96,9 @@ | startupProbe.enabled | If true, enables startup probe. | `/` | | startupProbe.path | Path to access on the HTTP server on periodic probe of container startup. | `/` | | startupProbe.scheme | Scheme to access the HTTP server (HTTP or HTTPS). | `HTTP` | +| startUpProbe.httpHeaders | List of additional custom headers to send on the server | `[]` | +| startUpProbe.httpHeaders.name | Name of the custom header | `nil` | +| startUpProbe.httpHeaders.value | Value of the header | `nil` | | startupProbe.initialDelaySeconds | # of seconds after the container has started before startup probes are initiated. | `5` | | startupProbe.timeoutSeconds | # of seconds after which the startup probe times out. | `3` | | startupProbe.failureThreshold | # of times, Kubernetes will retry failed probes before giving up. | `30` | diff --git a/assets/auto-deploy-app/templates/deployment.yaml b/assets/auto-deploy-app/templates/deployment.yaml index d45c979..0809c2e 100644 --- a/assets/auto-deploy-app/templates/deployment.yaml +++ b/assets/auto-deploy-app/templates/deployment.yaml @@ -148,6 +148,13 @@ spec: path: {{ .Values.livenessProbe.path }} scheme: {{ .Values.livenessProbe.scheme }} port: {{ .Values.livenessProbe.port | default .Values.service.internalPort }} +{{- if .Values.livenessProbe.httpHeaders }} + httpHeaders: +{{- range $httpHeader := .Values.livenessProbe.httpHeaders }} + - name: {{ $httpHeader.name }} + value: {{ $httpHeader.value }} +{{- end }} +{{- end }} {{- else if eq .Values.livenessProbe.probeType "tcpSocket" }} tcpSocket: port: {{ .Values.livenessProbe.port | default .Values.service.internalPort }} @@ -164,6 +171,13 @@ spec: path: {{ .Values.readinessProbe.path }} scheme: {{ .Values.readinessProbe.scheme }} port: {{ .Values.readinessProbe.port | default .Values.service.internalPort }} +{{- if .Values.readinessProbe.httpHeaders }} + httpHeaders: +{{- range $httpHeader := .Values.readinessProbe.httpHeaders }} + - name: {{ $httpHeader.name }} + value: {{ $httpHeader.value }} +{{- end }} +{{- end }} {{- else if eq .Values.readinessProbe.probeType "tcpSocket" }} tcpSocket: port: {{ .Values.readinessProbe.port | default .Values.service.internalPort }} @@ -181,7 +195,14 @@ spec: path: {{ .Values.startupProbe.path }} scheme: {{ .Values.startupProbe.scheme }} port: {{ .Values.startupProbe.port | default .Values.service.internalPort }} -{{- else if eq .Values.startupProbe.probeType "tcpSocket" }} +{{- if .Values.startupProbe.httpHeaders }} + httpHeaders: +{{- range $httpHeader := .Values.startupProbe.httpHeaders }} + - name: {{ $httpHeader.name }} + value: {{ $httpHeader.value }} +{{- end }} +{{- end }} +{{- else if eq .Values.readinessProbe.probeType "tcpSocket" }} tcpSocket: port: {{ .Values.startupProbe.port | default .Values.service.internalPort }} {{- else if eq .Values.startupProbe.probeType "exec" }} diff --git a/assets/auto-deploy-app/templates/worker-deployment.yaml b/assets/auto-deploy-app/templates/worker-deployment.yaml index 0e34b75..1e170c1 100644 --- a/assets/auto-deploy-app/templates/worker-deployment.yaml +++ b/assets/auto-deploy-app/templates/worker-deployment.yaml @@ -117,6 +117,13 @@ items: path: {{ $livenessProbeConfig.path }} scheme: {{ $livenessProbeConfig.scheme }} port: {{ $livenessProbeConfig.port | default $.Values.service.internalPort }} +{{- if $livenessProbeConfig.httpHeaders }} + httpHeaders: +{{- range $httpHeader := $livenessProbeConfig.httpHeaders }} + - name: {{ $httpHeader.name }} + value: {{ $httpHeader.value }} +{{- end }} +{{- end }} {{- else if eq $livenessProbeConfig.probeType "tcpSocket" }} tcpSocket: port: {{ $livenessProbeConfig.port | default $.Values.service.internalPort }} @@ -137,6 +144,13 @@ items: path: {{ $readinessProbeConfig.path }} scheme: {{ $readinessProbeConfig.scheme }} port: {{ $readinessProbeConfig.port | default $.Values.service.internalPort }} +{{- if $readinessProbeConfig.httpHeaders }} + httpHeaders: +{{- range $httpHeader := $readinessProbeConfig.httpHeaders }} + - name: {{ $httpHeader.name }} + value: {{ $httpHeader.value }} +{{- end }} +{{- end }} {{- else if eq $readinessProbeConfig.probeType "tcpSocket" }} tcpSocket: port: {{ $readinessProbeConfig.port | default $.Values.service.internalPort }} diff --git a/assets/auto-deploy-app/test/templates/deployment_test.go b/assets/auto-deploy-app/test/templates/deployment_test.go index fd46086..d8d6de5 100644 --- a/assets/auto-deploy-app/test/templates/deployment_test.go +++ b/assets/auto-deploy-app/test/templates/deployment_test.go @@ -404,20 +404,22 @@ func TestDeploymentTemplate(t *testing.T) { ExpectedLivenessProbe *coreV1.Probe ExpectedReadinessProbe *coreV1.Probe - ExpectedStartupProbe *coreV1.Probe + ExpectedStartupProbe *coreV1.Probe }{ { CaseName: "defaults", Release: "production", ExpectedLivenessProbe: defaultLivenessProbe(), ExpectedReadinessProbe: defaultReadinessProbe(), - ExpectedStartupProbe: nil, + ExpectedStartupProbe: nil, }, { CaseName: "custom liveness probe", Release: "production", Values: map[string]string{ - "livenessProbe.port": "1234", + "livenessProbe.port": "1234", + "livenessProbe.httpHeaders[0].name": "custom-header", + "livenessProbe.httpHeaders[0].value": "awesome", }, ExpectedLivenessProbe: &coreV1.Probe{ Handler: coreV1.Handler{ @@ -425,19 +427,27 @@ func TestDeploymentTemplate(t *testing.T) { Path: "/", Port: intstr.FromInt(1234), Scheme: coreV1.URISchemeHTTP, + HTTPHeaders: []coreV1.HTTPHeader{ + coreV1.HTTPHeader{ + Name: "custom-header", + Value: "awesome", + }, + }, }, }, InitialDelaySeconds: 15, TimeoutSeconds: 15, }, ExpectedReadinessProbe: defaultReadinessProbe(), - ExpectedStartupProbe: nil, + ExpectedStartupProbe: nil, }, { CaseName: "custom readiness probe", Release: "production", Values: map[string]string{ - "readinessProbe.port": "2345", + "readinessProbe.port": "2345", + "readinessProbe.httpHeaders[0].name": "custom-header", + "readinessProbe.httpHeaders[0].value": "awesome", }, ExpectedLivenessProbe: defaultLivenessProbe(), ExpectedReadinessProbe: &coreV1.Probe{ @@ -446,6 +456,12 @@ func TestDeploymentTemplate(t *testing.T) { Path: "/", Port: intstr.FromInt(2345), Scheme: coreV1.URISchemeHTTP, + HTTPHeaders: []coreV1.HTTPHeader{ + coreV1.HTTPHeader{ + Name: "custom-header", + Value: "awesome", + }, + }, }, }, InitialDelaySeconds: 5, @@ -457,10 +473,12 @@ func TestDeploymentTemplate(t *testing.T) { CaseName: "custom startup probe", Release: "production", Values: map[string]string{ - "startupProbe.enabled": "true", - "startupProbe.port": "2345", + "startupProbe.enabled": "true", + "startupProbe.port": "2345", + "startupProbe.httpHeaders[0].name": "custom-header", + "startupProbe.httpHeaders[0].value": "awesome", }, - ExpectedLivenessProbe: defaultLivenessProbe(), + ExpectedLivenessProbe: defaultLivenessProbe(), ExpectedReadinessProbe: defaultReadinessProbe(), ExpectedStartupProbe: &coreV1.Probe{ Handler: coreV1.Handler{ @@ -468,6 +486,12 @@ func TestDeploymentTemplate(t *testing.T) { Path: "/", Port: intstr.FromInt(2345), Scheme: coreV1.URISchemeHTTP, + HTTPHeaders: []coreV1.HTTPHeader{ + coreV1.HTTPHeader{ + Name: "custom-header", + Value: "awesome", + }, + }, }, }, InitialDelaySeconds: 5, diff --git a/assets/auto-deploy-app/test/templates/workerdeployment_test.go b/assets/auto-deploy-app/test/templates/workerdeployment_test.go index 47d940b..eef65d1 100644 --- a/assets/auto-deploy-app/test/templates/workerdeployment_test.go +++ b/assets/auto-deploy-app/test/templates/workerdeployment_test.go @@ -11,8 +11,9 @@ import ( "github.com/stretchr/testify/require" appsV1 "k8s.io/api/apps/v1" coreV1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) func TestWorkerDeploymentTemplate(t *testing.T) { @@ -675,28 +676,60 @@ func TestWorkerDeploymentTemplate(t *testing.T) { CaseName: "enableWorkerLivenessProbe", Release: "production", Values: map[string]string{ - "workers.worker1.command[0]": "echo", - "workers.worker1.command[1]": "worker1", - "workers.worker1.livenessProbe.path": "/worker", - "workers.worker1.livenessProbe.scheme": "HTTP", - "workers.worker1.livenessProbe.probeType": "httpGet", - "workers.worker2.command[0]": "echo", - "workers.worker2.command[1]": "worker2", - "workers.worker2.livenessProbe.path": "/worker", - "workers.worker2.livenessProbe.scheme": "HTTP", - "workers.worker2.livenessProbe.probeType": "httpGet", + "workers.worker1.command[0]": "echo", + "workers.worker1.command[1]": "worker1", + "workers.worker1.livenessProbe.path": "/worker", + "workers.worker1.livenessProbe.scheme": "HTTP", + "workers.worker1.livenessProbe.probeType": "httpGet", + "workers.worker1.livenessProbe.httpHeaders[0].name": "custom-header", + "workers.worker1.livenessProbe.httpHeaders[0].value": "awesome", + "workers.worker2.command[0]": "echo", + "workers.worker2.command[1]": "worker2", + "workers.worker2.livenessProbe.path": "/worker", + "workers.worker2.livenessProbe.scheme": "HTTP", + "workers.worker2.livenessProbe.probeType": "httpGet", + "workers.worker2.livenessProbe.httpHeaders[0].name": "custom-header", + "workers.worker2.livenessProbe.httpHeaders[0].value": "awesome", }, ExpectedDeployments: []workerDeploymentTestCase{ { - ExpectedName: "production-worker1", - ExpectedCmd: []string{"echo", "worker1"}, - ExpectedLivenessProbe: workerLivenessProbe(), + ExpectedName: "production-worker1", + ExpectedCmd: []string{"echo", "worker1"}, + ExpectedLivenessProbe: &coreV1.Probe{ + Handler: coreV1.Handler{ + HTTPGet: &coreV1.HTTPGetAction{ + Path: "/worker", + Port: intstr.FromInt(5000), + Scheme: coreV1.URISchemeHTTP, + HTTPHeaders: []coreV1.HTTPHeader{ + coreV1.HTTPHeader{ + Name: "custom-header", + Value: "awesome", + }, + }, + }, + }, + }, ExpectedReadinessProbe: defaultReadinessProbe(), }, { - ExpectedName: "production-worker2", - ExpectedCmd: []string{"echo", "worker2"}, - ExpectedLivenessProbe: workerLivenessProbe(), + ExpectedName: "production-worker2", + ExpectedCmd: []string{"echo", "worker2"}, + ExpectedLivenessProbe: &coreV1.Probe{ + Handler: coreV1.Handler{ + HTTPGet: &coreV1.HTTPGetAction{ + Path: "/worker", + Port: intstr.FromInt(5000), + Scheme: coreV1.URISchemeHTTP, + HTTPHeaders: []coreV1.HTTPHeader{ + coreV1.HTTPHeader{ + Name: "custom-header", + Value: "awesome", + }, + }, + }, + }, + }, ExpectedReadinessProbe: defaultReadinessProbe(), }, }, @@ -705,29 +738,61 @@ func TestWorkerDeploymentTemplate(t *testing.T) { CaseName: "enableWorkerReadinessProbe", Release: "production", Values: map[string]string{ - "workers.worker1.command[0]": "echo", - "workers.worker1.command[1]": "worker1", - "workers.worker1.readinessProbe.path": "/worker", - "workers.worker1.readinessProbe.scheme": "HTTP", - "workers.worker1.readinessProbe.probeType": "httpGet", - "workers.worker2.command[0]": "echo", - "workers.worker2.command[1]": "worker2", - "workers.worker2.readinessProbe.path": "/worker", - "workers.worker2.readinessProbe.scheme": "HTTP", - "workers.worker2.readinessProbe.probeType": "httpGet", + "workers.worker1.command[0]": "echo", + "workers.worker1.command[1]": "worker1", + "workers.worker1.readinessProbe.path": "/worker", + "workers.worker1.readinessProbe.scheme": "HTTP", + "workers.worker1.readinessProbe.probeType": "httpGet", + "workers.worker1.readinessProbe.httpHeaders[0].name": "custom-header", + "workers.worker1.readinessProbe.httpHeaders[0].value": "awesome", + "workers.worker2.command[0]": "echo", + "workers.worker2.command[1]": "worker2", + "workers.worker2.readinessProbe.path": "/worker", + "workers.worker2.readinessProbe.scheme": "HTTP", + "workers.worker2.readinessProbe.probeType": "httpGet", + "workers.worker2.readinessProbe.httpHeaders[0].name": "custom-header", + "workers.worker2.readinessProbe.httpHeaders[0].value": "awesome", }, ExpectedDeployments: []workerDeploymentTestCase{ { - ExpectedName: "production-worker1", - ExpectedCmd: []string{"echo", "worker1"}, - ExpectedLivenessProbe: defaultLivenessProbe(), - ExpectedReadinessProbe: workerReadinessProbe(), + ExpectedName: "production-worker1", + ExpectedCmd: []string{"echo", "worker1"}, + ExpectedLivenessProbe: defaultLivenessProbe(), + ExpectedReadinessProbe: &coreV1.Probe{ + Handler: coreV1.Handler{ + HTTPGet: &coreV1.HTTPGetAction{ + Path: "/worker", + Port: intstr.FromInt(5000), + Scheme: coreV1.URISchemeHTTP, + HTTPHeaders: []coreV1.HTTPHeader{ + coreV1.HTTPHeader{ + Name: "custom-header", + Value: "awesome", + }, + }, + }, + }, + }, }, { - ExpectedName: "production-worker2", - ExpectedCmd: []string{"echo", "worker2"}, - ExpectedLivenessProbe: defaultLivenessProbe(), - ExpectedReadinessProbe: workerReadinessProbe(), + ExpectedName: "production-worker2", + ExpectedCmd: []string{"echo", "worker2"}, + ExpectedLivenessProbe: defaultLivenessProbe(), + ExpectedReadinessProbe: &coreV1.Probe{ + Handler: coreV1.Handler{ + HTTPGet: &coreV1.HTTPGetAction{ + Path: "/worker", + Port: intstr.FromInt(5000), + Scheme: coreV1.URISchemeHTTP, + HTTPHeaders: []coreV1.HTTPHeader{ + coreV1.HTTPHeader{ + Name: "custom-header", + Value: "awesome", + }, + }, + }, + }, + }, }, }, }, @@ -784,16 +849,16 @@ func TestWorkerDeploymentTemplate(t *testing.T) { }, ExpectedDeployments: []workerDeploymentTestCase{ { - ExpectedName: "production-worker1", - ExpectedCmd: []string{"echo", "worker1"}, - ExpectedResources: coreV1.ResourceRequirements{ + ExpectedName: "production-worker1", + ExpectedCmd: []string{"echo", "worker1"}, + ExpectedResources: coreV1.ResourceRequirements{ Requests: coreV1.ResourceList{}, }, }, { - ExpectedName: "production-worker2", - ExpectedCmd: []string{"echo", "worker2"}, - ExpectedResources: coreV1.ResourceRequirements{ + ExpectedName: "production-worker2", + ExpectedCmd: []string{"echo", "worker2"}, + ExpectedResources: coreV1.ResourceRequirements{ Requests: coreV1.ResourceList{}, }, }, @@ -811,18 +876,18 @@ func TestWorkerDeploymentTemplate(t *testing.T) { }, ExpectedDeployments: []workerDeploymentTestCase{ { - ExpectedName: "production-worker1", - ExpectedCmd: []string{"echo", "worker1"}, - ExpectedResources: coreV1.ResourceRequirements{ + ExpectedName: "production-worker1", + ExpectedCmd: []string{"echo", "worker1"}, + ExpectedResources: coreV1.ResourceRequirements{ Requests: coreV1.ResourceList{ "memory": resource.MustParse("250M"), }, }, }, { - ExpectedName: "production-worker2", - ExpectedCmd: []string{"echo", "worker2"}, - ExpectedResources: coreV1.ResourceRequirements{ + ExpectedName: "production-worker2", + ExpectedCmd: []string{"echo", "worker2"}, + ExpectedResources: coreV1.ResourceRequirements{ Requests: coreV1.ResourceList{}, }, }, @@ -832,29 +897,29 @@ func TestWorkerDeploymentTemplate(t *testing.T) { CaseName: "override workers limits resources", Release: "production", Values: map[string]string{ - "workers.worker1.command[0]": "echo", - "workers.worker1.command[1]": "worker1", - "workers.worker1.resources.limits.memory": "500m", - "workers.worker1.resources.limits.storage": "8Gi", - "workers.worker2.command[0]": "echo", - "workers.worker2.command[1]": "worker2", - "workers.worker2.resources.limits.storage": "16Gi", + "workers.worker1.command[0]": "echo", + "workers.worker1.command[1]": "worker1", + "workers.worker1.resources.limits.memory": "500m", + "workers.worker1.resources.limits.storage": "8Gi", + "workers.worker2.command[0]": "echo", + "workers.worker2.command[1]": "worker2", + "workers.worker2.resources.limits.storage": "16Gi", }, ExpectedDeployments: []workerDeploymentTestCase{ { - ExpectedName: "production-worker1", - ExpectedCmd: []string{"echo", "worker1"}, - ExpectedResources: coreV1.ResourceRequirements{ + ExpectedName: "production-worker1", + ExpectedCmd: []string{"echo", "worker1"}, + ExpectedResources: coreV1.ResourceRequirements{ Limits: coreV1.ResourceList{ - "memory": resource.MustParse("500m"), + "memory": resource.MustParse("500m"), "storage": resource.MustParse("8Gi"), }, }, }, { - ExpectedName: "production-worker2", - ExpectedCmd: []string{"echo", "worker2"}, - ExpectedResources: coreV1.ResourceRequirements{ + ExpectedName: "production-worker2", + ExpectedCmd: []string{"echo", "worker2"}, + ExpectedResources: coreV1.ResourceRequirements{ Limits: coreV1.ResourceList{ "storage": resource.MustParse("16Gi"), }, diff --git a/assets/auto-deploy-app/values.yaml b/assets/auto-deploy-app/values.yaml index faa6335..c71cf55 100644 --- a/assets/auto-deploy-app/values.yaml +++ b/assets/auto-deploy-app/values.yaml @@ -108,12 +108,14 @@ livenessProbe: timeoutSeconds: 15 scheme: "HTTP" probeType: "httpGet" + httpHeaders: [] readinessProbe: path: "/" initialDelaySeconds: 5 timeoutSeconds: 3 scheme: "HTTP" probeType: "httpGet" + httpHeaders: [] startupProbe: enabled: false path: "/" @@ -123,6 +125,7 @@ startupProbe: periodSeconds: 10 scheme: "HTTP" probeType: "httpGet" + httpHeaders: [] #hostAliases: #- ip: X.X.X.X @@ -225,12 +228,18 @@ workers: {} # timeoutSeconds: 15 # scheme: "HTTP" # probeType: "httpGet" + # httpHeader: + # - name: "custum-header" + # value: "awesome" # readinessProbe: # path: "/" # initialDelaySeconds: 5 # timeoutSeconds: 3 # scheme: "HTTP" # probeType: "httpGet" + # httpHeader: + # - name: "custum-header" + # value: "awesome" # lifecycle: # preStop: # exec: -- GitLab