Skip to content

Commit b6347ac

Browse files
authored
Merge branch 'main' into dependabot/github_actions/actions-033e808f89
2 parents 164bb12 + 7fffc20 commit b6347ac

File tree

32 files changed

+681
-124
lines changed

32 files changed

+681
-124
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ your links to the correct versions:
145145

146146
| Version | Description | Image for NGINX | Image for NGINX Plus | Installation Manifests and Helm Chart | Documentation and Examples |
147147
| ------- | ----------- | --------------- | -------------------- | ---------------------------------------| -------------------------- |
148-
| Latest stable release | For production use | Use the 3.7.2 images from [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/), [GitHub Container](https://github.com/nginxinc/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress) or [build your own image](https://docs.nginx.com/nginx-ingress-controller/installation/build-ingress-controller-image/). | Use the 3.7.2 images from the [F5 Container Registry](https://docs.nginx.com/nginx-ingress-controller/installation/pulling-ingress-controller-image/) or the [AWS Marketplace](https://aws.amazon.com/marketplace/search/?CREATOR=741df81b-dfdc-4d36-b8da-945ea66b522c&FULFILLMENT_OPTION_TYPE=CONTAINER&filters=CREATOR%2CFULFILLMENT_OPTION_TYPE) or [Build your own image](https://docs.nginx.com/nginx-ingress-controller/installation/build-nginx-ingress-controller/). | [Manifests](https://github.com/nginxinc/kubernetes-ingress/tree/v3.7.2/deployments). [Helm chart](https://github.com/nginxinc/kubernetes-ingress/tree/v3.7.2/charts/nginx-ingress). | [Documentation](https://docs.nginx.com/nginx-ingress-controller/). [Examples](https://docs.nginx.com/nginx-ingress-controller/configuration/configuration-examples/). |
148+
| Latest stable release | For production use | Use the 3.7.2 images from [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/), [GitHub Container](https://github.com/nginxinc/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress) or [build your own image](https://docs.nginx.com/nginx-ingress-controller/installation/build-ingress-controller-image/). | Use the 3.7.2 images from the [F5 Container Registry](https://docs.nginx.com/nginx-ingress-controller/installation/pulling-ingress-controller-image/) or [Build your own image](https://docs.nginx.com/nginx-ingress-controller/installation/build-nginx-ingress-controller/). | [Manifests](https://github.com/nginxinc/kubernetes-ingress/tree/v3.7.2/deployments). [Helm chart](https://github.com/nginxinc/kubernetes-ingress/tree/v3.7.2/charts/nginx-ingress). | [Documentation](https://docs.nginx.com/nginx-ingress-controller/). [Examples](https://docs.nginx.com/nginx-ingress-controller/configuration/configuration-examples/). |
149149
| Edge/Nightly | For testing and experimenting | Use the edge or nightly images from [DockerHub](https://hub.docker.com/r/nginx/nginx-ingress/), [GitHub Container](https://github.com/nginxinc/kubernetes-ingress/pkgs/container/kubernetes-ingress), [Amazon ECR Public Gallery](https://gallery.ecr.aws/nginx/nginx-ingress) or [Quay.io](https://quay.io/repository/nginx/nginx-ingress) or [build your own image](https://docs.nginx.com/nginx-ingress-controller/installation/build-nginx-ingress-controller/). | [Build your own image](https://docs.nginx.com/nginx-ingress-controller/installation/build-nginx-ingress-controller/). | [Manifests](https://github.com/nginxinc/kubernetes-ingress/tree/main/deployments). [Helm chart](https://github.com/nginxinc/kubernetes-ingress/tree/main/charts/nginx-ingress). | [Documentation](https://github.com/nginxinc/kubernetes-ingress/tree/main/site/content). [Examples](https://github.com/nginxinc/kubernetes-ingress/tree/main/examples). |
150150

151151
## SBOM (Software Bill of Materials)

build/scripts/common.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ if [ -z "${BUILD_OS##*plus*}" ]; then
88
cp -a /code/internal/configs/oidc/* /etc/nginx/oidc/
99
mkdir -p /etc/nginx/state_files/
1010
mkdir -p /etc/nginx/reporting/
11+
mkdir -p /etc/nginx/secrets/mgmt/
1112
PLUS=-plus
1213
fi
1314

charts/nginx-ingress/templates/_helpers.tpl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ Expand the name of the configmap used for NGINX Agent.
116116
Expand the name of the mgmt configmap.
117117
*/}}
118118
{{- define "nginx-ingress.mgmtConfigName" -}}
119-
{{- if .Values.controller.mgmt.customConfigMap -}}
120-
{{ .Values.controller.mgmt.customConfigMap }}
119+
{{- if .Values.controller.mgmt.configMapName -}}
120+
{{ .Values.controller.mgmt.configMapName }}
121121
{{- else -}}
122122
{{- default (printf "%s-mgmt" (include "nginx-ingress.fullname" .)) -}}
123123
{{- end -}}
@@ -127,7 +127,11 @@ Expand the name of the mgmt configmap.
127127
Expand license token secret name.
128128
*/}}
129129
{{- define "nginx-ingress.licenseTokenSecretName" -}}
130+
{{- if hasKey .Values.controller.mgmt "licenseTokenSecretName" -}}
130131
{{- .Values.controller.mgmt.licenseTokenSecretName -}}
132+
{{- else }}
133+
{{- fail "Error: When using Nginx Plus, 'controller.mgmt.licenseTokenSecretName' must be set." }}
134+
{{- end -}}
131135
{{- end -}}
132136

133137
{{/*
@@ -393,7 +397,6 @@ volumeMounts:
393397
{{ include "nginx-ingress.volumeMountEntries" . }}
394398
{{- end -}}
395399
{{- end -}}
396-
397400
{{- define "nginx-ingress.volumeMountEntries" -}}
398401
{{- if eq (include "nginx-ingress.readOnlyRootFilesystem" .) "true" }}
399402
- mountPath: /etc/nginx

charts/nginx-ingress/templates/controller-configmap.yaml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ data:
3131
{{ include "nginx-ingress.agentConfiguration" . | indent 4 }}
3232
{{- end }}
3333
---
34-
{{- if and .Values.controller.nginxplus (eq (.Values.controller.mgmt.customConfigMap | default "") "") }}
34+
{{- if .Values.controller.nginxplus }}
3535
apiVersion: v1
3636
kind: ConfigMap
3737
metadata:
@@ -44,8 +44,36 @@ metadata:
4444
{{ toYaml .Values.controller.config.annotations | indent 4 }}
4545
{{- end }}
4646
data:
47-
license-token-secret-name: {{ include "nginx-ingress.licenseTokenSecretName" . }}
47+
license-token-secret-name: {{ required "When using Nginx Plus, 'controller.mgmt.licenseTokenSecretName' cannot be empty " (include "nginx-ingress.licenseTokenSecretName" . ) }}
48+
{{- if hasKey .Values.controller.mgmt "sslVerify" }}
49+
ssl-verify: {{ quote .Values.controller.mgmt.sslVerify }}
50+
{{- end }}
4851
{{- if hasKey .Values.controller.mgmt "enforceInitialReport" }}
4952
enforce-initial-report: {{ quote .Values.controller.mgmt.enforceInitialReport }}
5053
{{- end }}
54+
{{- if hasKey .Values.controller.mgmt "usageReport" }}
55+
{{- if hasKey .Values.controller.mgmt.usageReport "endpoint" }}
56+
usage-report-endpoint: {{ quote .Values.controller.mgmt.usageReport.endpoint }}
57+
{{- end }}
58+
{{- if hasKey .Values.controller.mgmt.usageReport "interval" }}
59+
usage-report-interval: {{ quote .Values.controller.mgmt.usageReport.interval }}
60+
{{- end }}
61+
{{- end }}
62+
{{- if hasKey .Values.controller.mgmt "sslTrustedCertificateSecretName" }}
63+
ssl-trusted-certificate-secret-name: {{ quote .Values.controller.mgmt.sslTrustedCertificateSecretName }}
64+
{{- end }}
65+
{{- if hasKey .Values.controller.mgmt "sslCertificateSecretName" }}
66+
ssl-certificate-secret-name: {{ quote .Values.controller.mgmt.sslCertificateSecretName}}
67+
{{- end }}
68+
{{- if hasKey .Values.controller.mgmt "resolver" }}
69+
{{- if hasKey .Values.controller.mgmt.resolver "addresses" }}
70+
resolver-addresses: {{ join "," .Values.controller.mgmt.resolver.addresses | quote }}
71+
{{- end }}
72+
{{- if hasKey .Values.controller.mgmt.resolver "ipv6" }}
73+
resolver-ipv6: {{ quote .Values.controller.mgmt.resolver.ipv6 }}
74+
{{- end }}
75+
{{- if hasKey .Values.controller.mgmt.resolver "valid" }}
76+
resolver-valid: {{ quote .Values.controller.mgmt.resolver.valid }}
77+
{{- end }}
78+
{{- end }}
5179
{{- end }}

charts/nginx-ingress/values.schema.json

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,42 @@
109109
"license"
110110
]
111111
},
112+
"sslCertificateSecretName": {
113+
"type": "string",
114+
"default": "",
115+
"title": "The sslCertificateSecretName Schema",
116+
"examples": [
117+
"ssl-certificate"
118+
]
119+
},
120+
"usageReport": {
121+
"type": "object",
122+
"default": {},
123+
"title": "The usageReport Schema",
124+
"properties": {
125+
"endpoint": {
126+
"type": "string",
127+
"title": "The endpoint of the usageReport",
128+
"default": "",
129+
"examples": [
130+
"",
131+
"product.connect.nginx.com",
132+
"nginx-mgmt.local"
133+
]
134+
},
135+
"interval": {
136+
"type": "string",
137+
"pattern": "^[0-9]+[mhd]$",
138+
"default": "1h",
139+
"title": "The usage report interval Schema",
140+
"examples": [
141+
"1m",
142+
"1h",
143+
"24h"
144+
]
145+
}
146+
}
147+
},
112148
"enforceInitialReport": {
113149
"type": "boolean",
114150
"default": false,
@@ -117,6 +153,58 @@
117153
true,
118154
false
119155
]
156+
},
157+
"sslVerify": {
158+
"type": "boolean",
159+
"default": true,
160+
"title": "The sslVerify Schema",
161+
"examples": [
162+
true,
163+
false
164+
]
165+
},
166+
"resolver": {
167+
"type": "object",
168+
"default": {},
169+
"title": "The resolver Schema",
170+
"properties": {
171+
"addresses": {
172+
"type": "array",
173+
"default": [],
174+
"title": "List of resolver addresses/fqdns"
175+
},
176+
"valid": {
177+
"type": "string",
178+
"pattern": "^[0-9]+[smhdwMy]$",
179+
"title": "A valid nginx time",
180+
"examples": [
181+
"1m",
182+
"5d"
183+
]
184+
},
185+
"ipv6": {
186+
"type": "boolean",
187+
"title": "turn on or off ipv6 support",
188+
"default": false
189+
}
190+
}
191+
},
192+
"sslTrustedCertificateSecretName": {
193+
"type": "string",
194+
"default": "ssl-trusted-cert",
195+
"title": "The sslTrustedCertificateSecretName Schema",
196+
"examples": [
197+
"ssl-trusted-cert",
198+
"certificate-secret"
199+
]
200+
},
201+
"configMapName": {
202+
"type": "string",
203+
"default": "",
204+
"title": "The configMap Schema",
205+
"examples": [
206+
""
207+
]
120208
}
121209
},
122210
"examples": [

charts/nginx-ingress/values.yaml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,31 @@ controller:
2222
## Enables the 180-day grace period for sending the initial usage report
2323
# enforceInitialReport: false
2424

25+
# usageReport:
26+
# endpoint: "product.connect.nginx.com" # Endpoint for usage report
27+
# interval: 1h
28+
29+
## Configures the ssl_verify directive in the mgmt block
30+
# sslVerify: true
31+
32+
## Configures the resolver directive in the mgmt block
33+
# resolver:
34+
# ipv6: true
35+
# valid: 1s
36+
# addresses:
37+
# - kube-dns.kube-system.svc.cluster.local
38+
39+
## Secret containing TLS client certificate
40+
# sslCertificateSecretName: ssl-certificate # kubernetes.io/tls secret type
41+
42+
## Secret containing trusted CA certificate
43+
# sslTrustedCertificateSecretName: ssl-trusted-cert
44+
45+
# configMapName allows changing the name of the MGMT config map
46+
# the name should not include a namespace
47+
# configMapName: ""
48+
49+
2550
## Timeout in milliseconds which the Ingress Controller will wait for a successful NGINX reload after a change or at the initial start.
2651
nginxReloadTimeout: 60000
2752

cmd/nginx-ingress/main.go

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ func main() {
153153
if err := processLicenseSecret(kubeClient, nginxManager, mgmtCfgParams, controllerNamespace); err != nil {
154154
logEventAndExit(ctx, eventRecorder, pod, secretErrorReason, err)
155155
}
156+
157+
if err := processTrustedCertSecret(kubeClient, nginxManager, mgmtCfgParams, controllerNamespace); err != nil {
158+
logEventAndExit(ctx, eventRecorder, pod, secretErrorReason, err)
159+
}
160+
161+
if err := processClientAuthSecret(kubeClient, nginxManager, mgmtCfgParams, controllerNamespace); err != nil {
162+
logEventAndExit(ctx, eventRecorder, pod, secretErrorReason, err)
163+
}
164+
156165
}
157166

158167
templateExecutor, templateExecutorV2 := createTemplateExecutors(ctx)
@@ -204,7 +213,7 @@ func main() {
204213
AppProtectBundlePath: appProtectBundlePath,
205214
}
206215

207-
mustProcessNginxConfig(staticCfgParams, cfgParams, mgmtCfgParams, templateExecutor, nginxManager)
216+
mustWriteNginxMainConfig(staticCfgParams, cfgParams, mgmtCfgParams, templateExecutor, nginxManager)
208217

209218
if *enableTLSPassthrough {
210219
var emptyFile []byte
@@ -323,6 +332,44 @@ func main() {
323332
}
324333
}
325334

335+
func processClientAuthSecret(kubeClient *kubernetes.Clientset, nginxManager nginx.Manager, mgmtCfgParams *configs.MGMTConfigParams, controllerNamespace string) error {
336+
if mgmtCfgParams.Secrets.ClientAuth == "" {
337+
return nil
338+
}
339+
340+
clientAuthSecretNsName := controllerNamespace + "/" + mgmtCfgParams.Secrets.ClientAuth
341+
342+
secret, err := getAndValidateSecret(kubeClient, clientAuthSecretNsName, api_v1.SecretTypeTLS)
343+
if err != nil {
344+
return fmt.Errorf("error trying to get the client auth secret %v: %w", clientAuthSecretNsName, err)
345+
}
346+
347+
bytes := configs.GenerateCertAndKeyFileContent(secret)
348+
nginxManager.CreateSecret(fmt.Sprintf("mgmt/%s", configs.ClientAuthCertSecretFileName), bytes, nginx.ReadWriteOnlyFileMode)
349+
return nil
350+
}
351+
352+
func processTrustedCertSecret(kubeClient *kubernetes.Clientset, nginxManager nginx.Manager, mgmtCfgParams *configs.MGMTConfigParams, controllerNamespace string) error {
353+
if mgmtCfgParams.Secrets.TrustedCert == "" {
354+
return nil
355+
}
356+
357+
trustedCertSecretNsName := controllerNamespace + "/" + mgmtCfgParams.Secrets.TrustedCert
358+
359+
secret, err := getAndValidateSecret(kubeClient, trustedCertSecretNsName, secrets.SecretTypeCA)
360+
if err != nil {
361+
return fmt.Errorf("error trying to get the trusted cert secret %v: %w", trustedCertSecretNsName, err)
362+
}
363+
364+
caBytes, crlBytes := configs.GenerateCAFileContent(secret)
365+
nginxManager.CreateSecret(fmt.Sprintf("mgmt/%s", configs.CACrtKey), caBytes, nginx.ReadWriteOnlyFileMode)
366+
if _, hasCRL := secret.Data[configs.CACrlKey]; hasCRL {
367+
mgmtCfgParams.Secrets.TrustedCRL = secret.Name
368+
nginxManager.CreateSecret(fmt.Sprintf("mgmt/%s", configs.CACrlKey), crlBytes, nginx.ReadWriteOnlyFileMode)
369+
}
370+
return nil
371+
}
372+
326373
func mustCreateConfigAndKubeClient(ctx context.Context) (*rest.Config, *kubernetes.Clientset) {
327374
l := nl.LoggerFromContext(ctx)
328375
var config *rest.Config
@@ -666,9 +713,9 @@ func createGlobalConfigurationValidator() *cr_validation.GlobalConfigurationVali
666713
return cr_validation.NewGlobalConfigurationValidator(forbiddenListenerPorts)
667714
}
668715

669-
// mustProcessNginxConfig calls internally os.Exit
716+
// mustWriteNginxMainConfig calls internally os.Exit
670717
// if can't generate a valid NGINX config.
671-
func mustProcessNginxConfig(staticCfgParams *configs.StaticConfigParams, cfgParams *configs.ConfigParams, mgmtCfgParams *configs.MGMTConfigParams, templateExecutor *version1.TemplateExecutor, nginxManager nginx.Manager) {
718+
func mustWriteNginxMainConfig(staticCfgParams *configs.StaticConfigParams, cfgParams *configs.ConfigParams, mgmtCfgParams *configs.MGMTConfigParams, templateExecutor *version1.TemplateExecutor, nginxManager nginx.Manager) {
672719
l := nl.LoggerFromContext(cfgParams.Context)
673720
ngxConfig := configs.GenerateNginxMainConfig(staticCfgParams, cfgParams, mgmtCfgParams)
674721
content, err := templateExecutor.ExecuteMainConfigTemplate(ngxConfig)
@@ -701,7 +748,6 @@ func getSocketClient(sockPath string) *http.Client {
701748
}
702749

703750
// getAndValidateSecret gets and validates a secret.
704-
// nolint:unparam
705751
func getAndValidateSecret(kubeClient *kubernetes.Clientset, secretNsName string, secretType api_v1.SecretType) (secret *api_v1.Secret, err error) {
706752
ns, name, err := k8s.ParseNamespaceName(secretNsName)
707753
if err != nil {
@@ -722,7 +768,13 @@ func getAndValidateSecret(kubeClient *kubernetes.Clientset, secretNsName string,
722768
if err != nil {
723769
return nil, err
724770
}
771+
case secrets.SecretTypeCA:
772+
err = secrets.ValidateCASecret(secret)
773+
if err != nil {
774+
return nil, err
775+
}
725776
}
777+
726778
return secret, nil
727779
}
728780

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# NGINX Plus Secret
2+
3+
Refer to the [Create License Secret](https://docs.nginx.com/nginx-ingress-controller/installation/installing-nic/create-license-secret/) docs to download and create a License Secret
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: nginx-config-mgmt
5+
namespace: nginx-ingress
6+
data:
7+
license-token-secret-name: "license-token"

go.mod

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
module github.com/nginxinc/kubernetes-ingress
22

3-
go 1.23.3
3+
go 1.23.4
44

55
require (
6-
github.com/aws/aws-sdk-go-v2/config v1.28.5
7-
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.25.6
6+
github.com/aws/aws-sdk-go-v2/config v1.28.6
7+
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.25.7
88
github.com/cert-manager/cert-manager v1.16.2
99
github.com/dlclark/regexp2 v1.11.4
1010
github.com/gkampitakis/go-snaps v0.5.7
@@ -35,17 +35,17 @@ require (
3535
github.com/BurntSushi/toml v1.3.2 // indirect
3636
github.com/Microsoft/go-winio v0.6.2 // indirect
3737
github.com/aws/aws-sdk-go v1.44.122 // indirect
38-
github.com/aws/aws-sdk-go-v2 v1.32.5 // indirect
39-
github.com/aws/aws-sdk-go-v2/credentials v1.17.46 // indirect
40-
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect
41-
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect
42-
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect
38+
github.com/aws/aws-sdk-go-v2 v1.32.6 // indirect
39+
github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect
40+
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect
41+
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect
42+
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect
4343
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
4444
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
45-
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 // indirect
46-
github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect
47-
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect
48-
github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect
45+
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect
46+
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect
47+
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect
48+
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect
4949
github.com/aws/smithy-go v1.22.1 // indirect
5050
github.com/beorn7/perks v1.0.1 // indirect
5151
github.com/blang/semver/v4 v4.0.0 // indirect

0 commit comments

Comments
 (0)