Skip to content

Commit b4c2317

Browse files
authored
add additional mgmt config parameters (nginx#6921)
1 parent 14ac418 commit b4c2317

File tree

25 files changed

+643
-44
lines changed

25 files changed

+643
-44
lines changed

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"

internal/configs/config_params.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,22 @@ type Listener struct {
177177

178178
// MGMTSecrets holds mgmt block secret names
179179
type MGMTSecrets struct {
180-
License string
180+
License string
181+
ClientAuth string
182+
TrustedCert string
183+
TrustedCRL string
181184
}
182185

183186
// MGMTConfigParams holds mgmt block parameters.
184187
type MGMTConfigParams struct {
185188
Context context.Context
189+
SSLVerify *bool
190+
ResolverAddresses []string
191+
ResolverIPV6 *bool
192+
ResolverValid string
186193
EnforceInitialReport *bool
194+
Endpoint string
195+
Interval string
187196
Secrets MGMTSecrets
188197
}
189198

@@ -236,6 +245,7 @@ func NewDefaultConfigParams(ctx context.Context, isPlus bool) *ConfigParams {
236245
func NewDefaultMGMTConfigParams(ctx context.Context) *MGMTConfigParams {
237246
return &MGMTConfigParams{
238247
Context: ctx,
248+
SSLVerify: nil,
239249
EnforceInitialReport: nil,
240250
Secrets: MGMTSecrets{},
241251
}

0 commit comments

Comments
 (0)