Skip to content

Commit eb46c0e

Browse files
authored
Merge branch 'main' into chart-job-resources
2 parents db52000 + 2216b2a commit eb46c0e

File tree

9 files changed

+206
-18
lines changed

9 files changed

+206
-18
lines changed

.github/workflows/push_pr.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
- uses: actions/checkout@v5
4848
with:
4949
fetch-depth: 0
50-
- uses: helm/chart-testing-action@v2.7.0
50+
- uses: helm/chart-testing-action@v2.8.0
5151

5252
- name: Lint charts
5353
run: ct --config .github/ct.yaml lint --debug
@@ -127,7 +127,7 @@ jobs:
127127
# with:
128128
# auditOn: push
129129
- name: golangci-lint
130-
uses: golangci/golangci-lint-action@v8
130+
uses: golangci/golangci-lint-action@v9
131131
continue-on-error: ${{ github.event_name != 'pull_request' }}
132132
with:
133133
only-new-issues: true

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### enhancement
1111
- Added `jobImage.admissionCreate.resources` and `jobImage.admissionPatch.resources` configuration block @tviaud [#657](https://github.com/newrelic/k8s-metadata-injection/pull/657).
12+
### 🔒 Security
13+
- Allow pre-upgrade job pods to honor global security context settings @dpacheconr [#670](https://github.com/newrelic/k8s-metadata-injection/pull/670)
1214

1315
## v1.38.1 - 2025-10-20
1416

charts/nri-metadata-injection/templates/_helpers.tpl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
{{- include "newrelic.common.securityContext.pod" . -}}
77
{{- else -}}
88
fsGroup: 1001
9-
runAsUser: 1001
10-
runAsGroup: 1001
9+
runAsUser: 2000
10+
runAsGroup: 2000
11+
runAsNonRoot: true
1112
{{- end -}}
1213
{{- end -}}
1314

charts/nri-metadata-injection/templates/admission-webhooks/job-patch/job-createSecret.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ spec:
5555
{{- end }}
5656
restartPolicy: OnFailure
5757
serviceAccountName: {{ include "nri-metadata-injection.fullname.admission.serviceAccount" . }}
58+
{{- with include "nri-metadata-injection.securityContext.pod" . }}
5859
securityContext:
59-
runAsGroup: 2000
60-
runAsNonRoot: true
61-
runAsUser: 2000
60+
{{- . | nindent 8 }}
61+
{{- end }}
6262
nodeSelector:
6363
kubernetes.io/os: linux
6464
{{ include "newrelic.common.nodeSelector" . | nindent 8 }}

charts/nri-metadata-injection/templates/admission-webhooks/job-patch/job-patchWebhook.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ spec:
5555
{{- end }}
5656
restartPolicy: OnFailure
5757
serviceAccountName: {{ include "nri-metadata-injection.fullname.admission.serviceAccount" . }}
58+
{{- with include "nri-metadata-injection.securityContext.pod" . }}
5859
securityContext:
59-
runAsGroup: 2000
60-
runAsNonRoot: true
61-
runAsUser: 2000
60+
{{- . | nindent 8 }}
61+
{{- end }}
6262
nodeSelector:
6363
kubernetes.io/os: linux
6464
{{ include "newrelic.common.nodeSelector" . | nindent 8 }}

go.mod

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
module github.com/newrelic/k8s-metadata-injection
22

3-
go 1.25.3
3+
go 1.25.4
44

55
require (
66
github.com/fsnotify/fsnotify v1.9.0
77
github.com/kelseyhightower/envconfig v1.4.0
88
github.com/stretchr/testify v1.11.1
9-
go.uber.org/zap v1.27.0
10-
k8s.io/api v0.34.1
11-
k8s.io/apimachinery v0.34.1
9+
go.uber.org/zap v1.27.1
10+
k8s.io/api v0.34.2
11+
k8s.io/apimachinery v0.34.2
1212
)
1313

1414
require (
@@ -23,9 +23,9 @@ require (
2323
github.com/x448/float16 v0.8.4 // indirect
2424
go.uber.org/multierr v1.10.0 // indirect
2525
go.yaml.in/yaml/v2 v2.4.2 // indirect
26-
golang.org/x/net v0.43.0 // indirect
27-
golang.org/x/sys v0.36.0 // indirect
28-
golang.org/x/text v0.29.0 // indirect
26+
golang.org/x/net v0.46.0 // indirect
27+
golang.org/x/sys v0.38.0 // indirect
28+
golang.org/x/text v0.31.0 // indirect
2929
gopkg.in/inf.v0 v0.9.1 // indirect
3030
gopkg.in/yaml.v3 v3.0.1 // indirect
3131
k8s.io/klog/v2 v2.130.1 // indirect
@@ -37,4 +37,4 @@ require (
3737
)
3838

3939
// To avoid CVE-2022-27191 triggering a security scan
40-
replace golang.org/x/crypto => golang.org/x/crypto v0.42.0
40+
replace golang.org/x/crypto => golang.org/x/crypto v0.44.0

go.sum

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
5252
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
5353
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
5454
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
55+
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
56+
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
5557
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
5658
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
5759
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
5860
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
5961
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
62+
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
6063
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
6164
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
6265
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -68,6 +71,8 @@ golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
6871
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
6972
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
7073
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
74+
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
75+
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
7176
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
7277
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
7378
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -80,6 +85,9 @@ golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
8085
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
8186
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
8287
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
88+
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
89+
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
90+
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
8391
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8492
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8593
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -92,6 +100,7 @@ golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
92100
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
93101
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
94102
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
103+
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
95104
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
96105
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
97106
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -106,10 +115,15 @@ golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
106115
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
107116
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
108117
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
118+
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
119+
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
120+
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
109121
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
110122
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
111123
golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b/go.mod h1:4ZwOYna0/zsOKwuR5X/m0QFOJpSZvAxFfkQT+Erd9D4=
112124
golang.org/x/telemetry v0.0.0-20250807160809-1a19826ec488/go.mod h1:fGb/2+tgXXjhjHsTNdVEEMZNWA0quBnfrO+AfoDSAKw=
125+
golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE=
126+
golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE=
113127
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
114128
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
115129
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
@@ -118,6 +132,8 @@ golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
118132
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
119133
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
120134
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
135+
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
136+
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
121137
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
122138
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
123139
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
@@ -130,6 +146,9 @@ golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
130146
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
131147
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
132148
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
149+
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
150+
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
151+
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
133152
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
134153
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
135154
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -142,6 +161,8 @@ golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI
142161
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
143162
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
144163
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
164+
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
165+
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
145166
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
146167
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
147168
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -155,8 +176,12 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
155176
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
156177
k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
157178
k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
179+
k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY=
180+
k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw=
158181
k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
159182
k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
183+
k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4=
184+
k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
160185
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
161186
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
162187
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=

src/server/readiness_probe_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package server
22

33
import (
44
"crypto/tls"
5+
"errors"
56
"net/http"
67
"net/http/httptest"
78
"testing"
89

910
"github.com/stretchr/testify/assert"
11+
"go.uber.org/zap"
12+
"go.uber.org/zap/zaptest/observer"
1013
)
1114

1215
func TestTLSReadyReadinessProbe(t *testing.T) {
@@ -42,3 +45,81 @@ func TestTLSReadyReadinessProbe(t *testing.T) {
4245
})
4346
}
4447
}
48+
49+
// failingResponseWriter is a mock ResponseWriter that fails on Write().
50+
type failingResponseWriter struct {
51+
statusCode int
52+
header http.Header
53+
}
54+
55+
func (f *failingResponseWriter) Header() http.Header {
56+
if f.header == nil {
57+
f.header = http.Header{}
58+
}
59+
return f.header
60+
}
61+
62+
func (f *failingResponseWriter) Write([]byte) (int, error) {
63+
return 0, errors.New("mock write error") //nolint:err113
64+
}
65+
66+
func (f *failingResponseWriter) WriteHeader(statusCode int) {
67+
f.statusCode = statusCode
68+
}
69+
70+
func TestTLSReadyReadinessProbe_WriteErrorWithoutCert(t *testing.T) {
71+
t.Parallel()
72+
// Create an observer to capture log entries
73+
observedZapCore, observedLogs := observer.New(zap.ErrorLevel)
74+
observedLogger := zap.New(observedZapCore).Sugar()
75+
76+
webhook := &Webhook{
77+
Cert: nil,
78+
Logger: observedLogger,
79+
}
80+
81+
handler := TLSReadyReadinessProbe(webhook)
82+
req := httptest.NewRequest("GET", "/ready", nil)
83+
w := &failingResponseWriter{}
84+
85+
handler.ServeHTTP(w, req)
86+
87+
// Verify that WriteHeader was called with 503
88+
assert.Equal(t, 503, w.statusCode, "Should return 503 when certificate is not present")
89+
90+
// Verify that the error was logged
91+
logEntries := observedLogs.All()
92+
assert.Equal(t, 1, len(logEntries), "Should have logged one error")
93+
assert.Equal(t, "can't write response", logEntries[0].Message)
94+
assert.Equal(t, "Certificate not present", logEntries[0].ContextMap()["response"])
95+
assert.Contains(t, logEntries[0].ContextMap()["err"], "mock write error")
96+
}
97+
98+
func TestTLSReadyReadinessProbe_WriteErrorWithCert(t *testing.T) {
99+
t.Parallel()
100+
// Create an observer to capture log entries
101+
observedZapCore, observedLogs := observer.New(zap.ErrorLevel)
102+
observedLogger := zap.New(observedZapCore).Sugar()
103+
104+
webhook := &Webhook{
105+
Cert: &tls.Certificate{},
106+
Logger: observedLogger,
107+
}
108+
109+
handler := TLSReadyReadinessProbe(webhook)
110+
req := httptest.NewRequest("GET", "/ready", nil)
111+
w := &failingResponseWriter{}
112+
113+
handler.ServeHTTP(w, req)
114+
115+
// Verify that WriteHeader was not called (status 200 is implicit)
116+
// and that the handler completed without panicking despite Write() failing
117+
assert.Equal(t, 0, w.statusCode, "Should not explicitly set status code when cert is present (defaults to 200)")
118+
119+
// Verify that the error was logged
120+
logEntries := observedLogs.All()
121+
assert.Equal(t, 1, len(logEntries), "Should have logged one error")
122+
assert.Equal(t, "can't write response", logEntries[0].Message)
123+
assert.Equal(t, "OK", logEntries[0].ContextMap()["response"])
124+
assert.Contains(t, logEntries[0].ContextMap()["err"], "mock write error")
125+
}

src/server/webhook_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"testing"
1313

1414
"github.com/stretchr/testify/assert"
15+
"go.uber.org/zap"
1516
admissionv1 "k8s.io/api/admission/v1"
1617
corev1 "k8s.io/api/core/v1"
1718
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -201,3 +202,81 @@ func makeTestData(t testing.TB, namespace string) []byte {
201202
}
202203
return reviewJSON
203204
}
205+
206+
func TestUpdateContainer_WithExistingEnvVars(t *testing.T) {
207+
// This test covers the case where a container already has env vars
208+
t.Parallel()
209+
210+
whsvr := &Webhook{
211+
ClusterName: "test-cluster",
212+
Logger: zap.NewNop().Sugar(),
213+
}
214+
215+
pod := &corev1.Pod{
216+
ObjectMeta: metav1.ObjectMeta{
217+
Name: "test-pod",
218+
GenerateName: "test-deployment-abc-",
219+
Namespace: "default",
220+
OwnerReferences: []metav1.OwnerReference{{Kind: "ReplicaSet"}},
221+
},
222+
}
223+
224+
// Container with existing environment variables
225+
container := &corev1.Container{
226+
Name: "test-container",
227+
Image: "test-image:latest",
228+
Env: []corev1.EnvVar{
229+
{Name: "EXISTING_VAR_1", Value: "value1"},
230+
{Name: "EXISTING_VAR_2", Value: "value2"},
231+
{Name: "NEW_RELIC_METADATA_KUBERNETES_CLUSTER_NAME", Value: "existing-cluster"}, // Already exists
232+
},
233+
}
234+
235+
patches := whsvr.updateContainer(pod, 0, container)
236+
237+
// Should only add env vars that don't already exist
238+
// NEW_RELIC_METADATA_KUBERNETES_CLUSTER_NAME should not be added since it already exists
239+
assert.NotNil(t, patches)
240+
241+
// Verify that the existing cluster name env var is not in the patches
242+
for _, patch := range patches {
243+
if patch.Op == "add" {
244+
if envVar, ok := patch.Value.(corev1.EnvVar); ok {
245+
assert.NotEqual(t, "NEW_RELIC_METADATA_KUBERNETES_CLUSTER_NAME", envVar.Name,
246+
"Should not add env var that already exists")
247+
}
248+
}
249+
}
250+
}
251+
252+
func TestUpdateContainer_EmptyContainer(t *testing.T) {
253+
// This test covers the case where a container has no existing env vars
254+
t.Parallel()
255+
256+
whsvr := &Webhook{
257+
ClusterName: "test-cluster",
258+
Logger: zap.NewNop().Sugar(),
259+
}
260+
261+
pod := &corev1.Pod{
262+
ObjectMeta: metav1.ObjectMeta{
263+
Name: "test-pod",
264+
GenerateName: "test-deployment-abc-",
265+
Namespace: "default",
266+
OwnerReferences: []metav1.OwnerReference{{Kind: "ReplicaSet"}},
267+
},
268+
}
269+
270+
// Container with no existing environment variables
271+
container := &corev1.Container{
272+
Name: "test-container",
273+
Image: "test-image:latest",
274+
Env: []corev1.EnvVar{}, // Empty env vars
275+
}
276+
277+
patches := whsvr.updateContainer(pod, 0, container)
278+
279+
// Should add all New Relic env vars
280+
assert.NotEmpty(t, patches)
281+
assert.True(t, len(patches) > 0, "Should generate patches for empty container")
282+
}

0 commit comments

Comments
 (0)