Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add VirtualServer custom template support #1036

Merged
merged 2 commits into from
Jul 7, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 </nginx-ingress-controller/configuration/global-configuration/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 </nginx-ingress-controller/configuration/global-configuration/custom-templates>`_.
```

### Modules
Expand Down
Original file line number Diff line number Diff line change
@@ -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).
3 changes: 3 additions & 0 deletions examples-of-custom-resources/custom-templates/README.md
Original file line number Diff line number Diff line change
@@ -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).
Dean-Coakley marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 27 additions & 4 deletions examples/custom-templates/README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -13,7 +14,6 @@ metadata:
namespace: nginx-ingress
data:
main-template: |
user nginx;
worker_processes {{.WorkerProcesses}};
...
include /etc/nginx/conf.d/*.conf;
Expand All @@ -25,9 +25,32 @@ data:
...
}{{end}}
```

## VirtualServer Example
Dean-Coakley marked this conversation as resolved.
Show resolved Hide resolved
```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.
Expand Down
5 changes: 3 additions & 2 deletions internal/configs/config_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions internal/configs/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions internal/configs/configurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
11 changes: 11 additions & 0 deletions internal/configs/version2/template_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down