Skip to content

Commit

Permalink
Add SSL services annotation
Browse files Browse the repository at this point in the history
If an application in a container requires HTTPS, one needs to set the
'proxy_path https://...' instead of 'proxy_pass http://...'. With this
patch one can use the annotation:

  'nginx.org/ssl-services: "service1[,service2,...]"'

to specify, which services require HTTPS.

Fixes #61
  • Loading branch information
Julian Strobl committed Nov 3, 2016
1 parent ea9571b commit 8354d4e
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 8 deletions.
34 changes: 34 additions & 0 deletions examples/ssl-services/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SSL Services Support

To load balance an application that requires HTTPS with NGINX Ingress controllers, you need to add the **nginx.org/ssl-services** annotation to your Ingress resource definition. The annotation specifies which services are SSL services. The annotation syntax is as follows:
```
nginx.org/ssl-services: "service1[,service2,...]"
```

In the following example we load balance three applications, one of which requires HTTPS:
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.org/ssl-services: "ssl-svc"
spec:
rules:
- host: cafe.example.com
http:
paths:
- path: /tea
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee
backend:
serviceName: coffee-svc
servicePort: 80
- path: /ssl
backend:
serviceName: ssl-svc
servicePort: 443
```
*ssl-svc* is a service for an HTTPS application. The service becomes available at the `/ssl` path. Note how we used the **nginx.org/ssl-services** annotation.
22 changes: 18 additions & 4 deletions nginx-controller/nginx/configurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
upstreams := make(map[string]Upstream)

wsServices := getWebsocketServices(ingEx)
sslServices := getSSLServices(ingEx)

if ingEx.Ingress.Spec.Backend != nil {
name := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
Expand Down Expand Up @@ -119,7 +120,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
upstreams[upsName] = upstream
}

loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName])
loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName], sslServices[path.Backend.ServiceName])
locations = append(locations, loc)

if loc.Path == "/" {
Expand All @@ -129,7 +130,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri

if rootLocation == false && ingEx.Ingress.Spec.Backend != nil {
upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
locations = append(locations, loc)
}

Expand All @@ -150,7 +151,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri

upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)

loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
locations = append(locations, loc)

server.Locations = locations
Expand Down Expand Up @@ -187,14 +188,27 @@ func getWebsocketServices(ingEx *IngressEx) map[string]bool {
return wsServices
}

func createLocation(path string, upstream Upstream, cfg *Config, websocket bool) Location {
func getSSLServices(ingEx *IngressEx) map[string]bool {
sslServices := make(map[string]bool)

if services, exists := ingEx.Ingress.Annotations["nginx.org/ssl-services"]; exists {
for _, svc := range strings.Split(services, ",") {
sslServices[svc] = true
}
}

return sslServices
}

func createLocation(path string, upstream Upstream, cfg *Config, websocket bool, ssl bool) Location {
loc := Location{
Path: path,
Upstream: upstream,
ProxyConnectTimeout: cfg.ProxyConnectTimeout,
ProxyReadTimeout: cfg.ProxyReadTimeout,
ClientMaxBodySize: cfg.ClientMaxBodySize,
Websocket: websocket,
SSL: ssl,
}

return loc
Expand Down
4 changes: 4 additions & 0 deletions nginx-controller/nginx/ingress.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ server {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
{{if $location.SSL}}
proxy_pass https://{{$location.Upstream.Name}};
{{else}}
proxy_pass http://{{$location.Upstream.Name}};
{{end}}
}{{end}}
}{{end}}
1 change: 1 addition & 0 deletions nginx-controller/nginx/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Location struct {
ProxyReadTimeout string
ClientMaxBodySize string
Websocket bool
SSL bool
}

// NginxMainConfig describe the main NGINX configuration file
Expand Down
22 changes: 18 additions & 4 deletions nginx-plus-controller/nginx/configurator.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri

wsServices := getWebsocketServices(ingEx)
spServices := getSessionPersistenceServices(ingEx)
sslServices := getSSLServices(ingEx)

if ingEx.Ingress.Spec.Backend != nil {
name := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
Expand Down Expand Up @@ -128,7 +129,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri
upstreams[upsName] = upstream
}

loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName])
loc := createLocation(pathOrDefault(path.Path), upstreams[upsName], &ingCfg, wsServices[path.Backend.ServiceName], sslServices[path.Backend.ServiceName])
locations = append(locations, loc)

if loc.Path == "/" {
Expand All @@ -138,7 +139,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri

if rootLocation == false && ingEx.Ingress.Spec.Backend != nil {
upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
locations = append(locations, loc)
}

Expand All @@ -163,7 +164,7 @@ func (cnf *Configurator) generateNginxCfg(ingEx *IngressEx, pems map[string]stri

upsName := getNameForUpstream(ingEx.Ingress, emptyHost, ingEx.Ingress.Spec.Backend.ServiceName)

loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName])
loc := createLocation(pathOrDefault("/"), upstreams[upsName], &ingCfg, wsServices[ingEx.Ingress.Spec.Backend.ServiceName], sslServices[ingEx.Ingress.Spec.Backend.ServiceName])
locations = append(locations, loc)

server.Locations = locations
Expand Down Expand Up @@ -200,6 +201,18 @@ func getWebsocketServices(ingEx *IngressEx) map[string]bool {
return wsServices
}

func getSSLServices(ingEx *IngressEx) map[string]bool {
sslServices := make(map[string]bool)

if services, exists := ingEx.Ingress.Annotations["nginx.org/ssl-services"]; exists {
for _, svc := range strings.Split(services, ",") {
sslServices[svc] = true
}
}

return sslServices
}

func getSessionPersistenceServices(ingEx *IngressEx) map[string]string {
spServices := make(map[string]string)

Expand Down Expand Up @@ -231,14 +244,15 @@ func parseStickyService(service string) (serviceName string, stickyCookie string
return svcNameParts[1], parts[1], nil
}

func createLocation(path string, upstream Upstream, cfg *Config, websocket bool) Location {
func createLocation(path string, upstream Upstream, cfg *Config, websocket bool, ssl bool) Location {
loc := Location{
Path: path,
Upstream: upstream,
ProxyConnectTimeout: cfg.ProxyConnectTimeout,
ProxyReadTimeout: cfg.ProxyReadTimeout,
ClientMaxBodySize: cfg.ClientMaxBodySize,
Websocket: websocket,
SSL: ssl,
}

return loc
Expand Down
4 changes: 4 additions & 0 deletions nginx-plus-controller/nginx/ingress.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ server {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Proto $scheme;
{{if $location.SSL}}
proxy_pass https://{{$location.Upstream.Name}};
{{else}}
proxy_pass http://{{$location.Upstream.Name}};
{{end}}
}{{end}}
}{{end}}
1 change: 1 addition & 0 deletions nginx-plus-controller/nginx/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type Location struct {
ProxyReadTimeout string
ClientMaxBodySize string
Websocket bool
SSL bool
}

// NginxMainConfig describe the main NGINX configuration file
Expand Down

0 comments on commit 8354d4e

Please sign in to comment.