From af088dac32191798bc3f886b07b850db5f2b0eb1 Mon Sep 17 00:00:00 2001 From: Dean Coakley Date: Mon, 6 Jul 2020 15:39:46 +0100 Subject: [PATCH 1/2] Add VirtualServer custom template support --- .../configmap-resource.md | 4 +++ .../global-configuration/custom-templates.md | 2 +- .../custom-templates/README.md | 3 ++ examples/custom-templates/README.md | 31 ++++++++++++++++--- internal/configs/config_params.go | 5 +-- internal/configs/configmaps.go | 4 +++ internal/configs/configurator.go | 7 +++++ .../configs/version2/template_executor.go | 11 +++++++ 8 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 examples-of-custom-resources/custom-templates/README.md diff --git a/docs-web/configuration/global-configuration/configmap-resource.md b/docs-web/configuration/global-configuration/configmap-resource.md index 7ddb73806c..e127ff8c48 100644 --- a/docs-web/configuration/global-configuration/configmap-resource.md +++ b/docs-web/configuration/global-configuration/configmap-resource.md @@ -382,6 +382,10 @@ See the doc about [VirtualServer and VirtualServerRoute resources](/nginx-ingres - Sets the NGINX configuration template for an Ingress resource. - By default the template is read from the file on the container. - `Custom Templates `_. + * - ``virtualserver-template`` + - Sets the NGINX configuration template for an VirtualServer resource. + - By default the template is read from the file on the container. + - `Custom Templates `_. ``` ### Modules diff --git a/docs-web/configuration/global-configuration/custom-templates.md b/docs-web/configuration/global-configuration/custom-templates.md index 2b55df272b..6ab8cdcb0a 100644 --- a/docs-web/configuration/global-configuration/custom-templates.md +++ b/docs-web/configuration/global-configuration/custom-templates.md @@ -1,3 +1,3 @@ # Custom Templates -The Ingress Controller uses templates to generate NGINX configuration for Ingress resources and the main NGINX configuration file. You can customize the templates and apply them via the ConfigMap. See the [corresponding example](https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/custom-templates). +The Ingress Controller uses templates to generate NGINX configuration for Ingress resources, VirtualServer resources and the main NGINX configuration file. You can customize the templates and apply them via the ConfigMap. See the [corresponding example](https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/custom-templates). diff --git a/examples-of-custom-resources/custom-templates/README.md b/examples-of-custom-resources/custom-templates/README.md new file mode 100644 index 0000000000..39c4faa23e --- /dev/null +++ b/examples-of-custom-resources/custom-templates/README.md @@ -0,0 +1,3 @@ +# Custom Templates + +The Ingress Controller uses templates to generate NGINX configuration for VirtualServer resources and the main NGINX configuration file. You can customize the templates and apply them via the ConfigMap. See the [corresponding example](../../examples/custom-templates/README.md). diff --git a/examples/custom-templates/README.md b/examples/custom-templates/README.md index 24bbd50dc6..ad0e979203 100644 --- a/examples/custom-templates/README.md +++ b/examples/custom-templates/README.md @@ -1,10 +1,11 @@ # Custom Templates -The Ingress controller allows you to customize your templates through a [ConfigMap](https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/) via the following keys: +The Ingress controller allows you to customize your templates through a [ConfigMap](https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/#snippets-and-custom-templates) via the following keys: * `main-template` - Sets the main NGINX configuration template. * `ingress-template` - Sets the Ingress NGINX configuration template for an Ingress resource. +* `virtualserver-template` - Sets the NGINX configuration template for an VirtualServer resource. -## Example +## Ingress Example ```yaml kind: ConfigMap apiVersion: v1 @@ -13,7 +14,6 @@ metadata: namespace: nginx-ingress data: main-template: | - user nginx; worker_processes {{.WorkerProcesses}}; ... include /etc/nginx/conf.d/*.conf; @@ -25,9 +25,32 @@ data: ... }{{end}} ``` + +## VirtualServer Example +```yaml +kind: ConfigMap +apiVersion: v1 +metadata: + name: nginx-config + namespace: nginx-ingress +data: + main-template: | + worker_processes {{.WorkerProcesses}}; + ... + include /etc/nginx/conf.d/*.conf; + } + virtualserver-template: | + {{ range $u := .Upstreams }} + upstream {{ $u.Name }} { + {{ if ne $u.UpstreamZoneSize "0" }}zone {{ $u.Name }} {{ $u.UpstreamZoneSize }};{{ end }} + ... + } + {{ end }} +``` + **Notes:** * The templates are truncated for the clarity of the example. -* The templates for NGINX (the main `nginx.tmpl` and the Ingress `nginx.ingress.tmpl`) and NGINX Plus (the main `nginx-plus.tmpl` and the Ingress `nginx-plus.ingress.tmpl`) are located at [internal/configs/templates](../../internal/configs/version1/). +* The templates for NGINX (the main `nginx.tmpl` and the Ingress `nginx.ingress.tmpl`) and NGINX Plus (the main `nginx-plus.tmpl` and the Ingress `nginx-plus.ingress.tmpl`) are located at [internal/configs/version1](../../internal/configs/version1/). The VirtualServer templates for NGINX (`nginx.virtualserver.tmpl`) and NGINX Plus (`nginx-plus.virtualserver.tmpl`) are located at [internal/configs/version2](../../internal/configs/version2/). ## Troubleshooting * If a custom template contained within the ConfigMap is invalid on startup, the Ingress controller will fail to start, the error will be reported in the Ingress controller logs. diff --git a/internal/configs/config_params.go b/internal/configs/config_params.go index 7040a54e0a..0992065375 100644 --- a/internal/configs/config_params.go +++ b/internal/configs/config_params.go @@ -84,8 +84,9 @@ type ConfigParams struct { MainServerSSLPreferServerCiphers bool MainServerSSLProtocols string - IngressTemplate *string - MainTemplate *string + IngressTemplate *string + VirtualServerTemplate *string + MainTemplate *string JWTKey string JWTLoginURL string diff --git a/internal/configs/configmaps.go b/internal/configs/configmaps.go index 272274f86e..88076a5bb1 100644 --- a/internal/configs/configmaps.go +++ b/internal/configs/configmaps.go @@ -353,6 +353,10 @@ func ParseConfigMap(cfgm *v1.ConfigMap, nginxPlus bool, hasAppProtect bool) *Con cfgParams.IngressTemplate = &ingressTemplate } + if virtualServerTemplate, exists := cfgm.Data["virtualserver-template"]; exists { + cfgParams.VirtualServerTemplate = &virtualServerTemplate + } + if mainStreamSnippets, exists, err := GetMapKeyAsStringSlice(cfgm.Data, "stream-snippets", cfgm, "\n"); exists { if err != nil { glog.Error(err) diff --git a/internal/configs/configurator.go b/internal/configs/configurator.go index b99198f356..cba6a97c4b 100644 --- a/internal/configs/configurator.go +++ b/internal/configs/configurator.go @@ -769,6 +769,13 @@ func (cnf *Configurator) UpdateConfig(cfgParams *ConfigParams, ingExes []*Ingres } } + if cfgParams.VirtualServerTemplate != nil { + err := cnf.templateExecutorV2.UpdateVirtualServerTemplate(cfgParams.VirtualServerTemplate) + if err != nil { + return allWarnings, fmt.Errorf("Error when parsing the VirtualServer template: %v", err) + } + } + mainCfg := GenerateNginxMainConfig(cnf.staticCfgParams, cfgParams) mainCfgContent, err := cnf.templateExecutor.ExecuteMainConfigTemplate(mainCfg) if err != nil { diff --git a/internal/configs/version2/template_executor.go b/internal/configs/version2/template_executor.go index 5fb39f88a3..2ea044897c 100644 --- a/internal/configs/version2/template_executor.go +++ b/internal/configs/version2/template_executor.go @@ -45,6 +45,17 @@ func NewTemplateExecutor(virtualServerTemplatePath string, transportServerTempla }, nil } +// UpdateVirtualServerTemplate updates the VirtualServer template. +func (te *TemplateExecutor) UpdateVirtualServerTemplate(templateString *string) error { + newTemplate, err := template.New("virtualServerTemplate").Parse(*templateString) + if err != nil { + return err + } + te.virtualServerTemplate = newTemplate + + return nil +} + // ExecuteVirtualServerTemplate generates the content of an NGINX configuration file for a VirtualServer resource. func (te *TemplateExecutor) ExecuteVirtualServerTemplate(cfg *VirtualServerConfig) ([]byte, error) { var configBuffer bytes.Buffer From c6515415a3d152eec350ec3846b958c2fbdeb011 Mon Sep 17 00:00:00 2001 From: Dean Coakley Date: Mon, 6 Jul 2020 18:51:40 +0100 Subject: [PATCH 2/2] PR feedback --- .../custom-templates/README.md | 2 +- examples/custom-templates/README.md | 17 +---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/examples-of-custom-resources/custom-templates/README.md b/examples-of-custom-resources/custom-templates/README.md index 39c4faa23e..38f83d6e6b 100644 --- a/examples-of-custom-resources/custom-templates/README.md +++ b/examples-of-custom-resources/custom-templates/README.md @@ -1,3 +1,3 @@ # Custom Templates -The Ingress Controller uses templates to generate NGINX configuration for VirtualServer resources and the main NGINX configuration file. You can customize the templates and apply them via the ConfigMap. See the [corresponding example](../../examples/custom-templates/README.md). +The Ingress Controller uses a template to generate NGINX configuration for VirtualServer resources. You can customize the template and apply it via the ConfigMap. See the [combined custom templates](../../examples/custom-templates/README.md) example, which shows how to customize the template for the VirtualServer resource as well as the other templates used by the Ingress Controller. diff --git a/examples/custom-templates/README.md b/examples/custom-templates/README.md index ad0e979203..582340228a 100644 --- a/examples/custom-templates/README.md +++ b/examples/custom-templates/README.md @@ -5,7 +5,7 @@ The Ingress controller allows you to customize your templates through a [ConfigM * `ingress-template` - Sets the Ingress NGINX configuration template for an Ingress resource. * `virtualserver-template` - Sets the NGINX configuration template for an VirtualServer resource. -## Ingress Example +## Example ```yaml kind: ConfigMap apiVersion: v1 @@ -24,21 +24,6 @@ data: {{if $upstream.LBMethod }}{{$upstream.LBMethod}};{{end}} ... }{{end}} -``` - -## VirtualServer Example -```yaml -kind: ConfigMap -apiVersion: v1 -metadata: - name: nginx-config - namespace: nginx-ingress -data: - main-template: | - worker_processes {{.WorkerProcesses}}; - ... - include /etc/nginx/conf.d/*.conf; - } virtualserver-template: | {{ range $u := .Upstreams }} upstream {{ $u.Name }} {