Add support for Server Alias in Nginx
Adds support for server alias in nginx. Adds a new annotation which allows us to specify a server alias that will be appended to the server name.
This commit is contained in:
parent
198c926bb9
commit
ac504bdbc0
8 changed files with 146 additions and 4 deletions
|
@ -64,7 +64,7 @@ The following annotations are supported:
|
|||
|[ingress.kubernetes.io/upstream-max-fails](#custom-nginx-upstream-checks)|number|
|
||||
|[ingress.kubernetes.io/upstream-fail-timeout](#custom-nginx-upstream-checks)|number|
|
||||
|[ingress.kubernetes.io/whitelist-source-range](#whitelist-source-range)|CIDR|
|
||||
|
||||
|[ingress.kubernetes.io/server-alias](#server-alias)|string|
|
||||
|
||||
|
||||
#### Custom NGINX template
|
||||
|
@ -155,7 +155,7 @@ Please check the [tls-auth](/examples/auth/client-certs/nginx/README.md) example
|
|||
|
||||
### Configuration snippet
|
||||
|
||||
Using this annotion you can add additional configuration to the NGINX location. For example:
|
||||
Using this annotation you can add additional configuration to the NGINX location. For example:
|
||||
|
||||
```
|
||||
ingress.kubernetes.io/configuration-snippet: |
|
||||
|
@ -167,6 +167,17 @@ ingress.kubernetes.io/configuration-snippet: |
|
|||
To enable Cross-Origin Resource Sharing (CORS) in an Ingress rule add the annotation `ingress.kubernetes.io/enable-cors: "true"`. This will add a section in the server location enabling this functionality.
|
||||
For more information please check https://enable-cors.org/server_nginx.html
|
||||
|
||||
### Server Alias
|
||||
|
||||
To add Server Aliases to an Ingress rule add the annotation `ingress.kubernetes.io/server-alias: "<server-name_0>:<server-alias_0>;...;<server-name_n>:<server-alias_n>"`.
|
||||
This will append a server-alias to the end of the server_name in the NGINX server. A server-alias can accept wildcards, but
|
||||
it cannot accept port numbers.
|
||||
|
||||
The server-name must match a valid server within the ingress resource for it to append the server-alias. Multiple server-aliases
|
||||
can be added for multiple server-names using `;` as a delimiter.
|
||||
|
||||
For more information please see http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name
|
||||
|
||||
### External Authentication
|
||||
|
||||
To use an existing service that provides authentication the Ingress rule can be annotated with `ingress.kubernetes.io/auth-url` to indicate the URL where the HTTP request should be sent.
|
||||
|
|
|
@ -452,6 +452,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error {
|
|||
IP: svc.Spec.ClusterIP,
|
||||
Port: port,
|
||||
ProxyProtocol: false,
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ http {
|
|||
{{ $backlogSize := .BacklogSize }}
|
||||
{{ range $index, $server := .Servers }}
|
||||
server {
|
||||
server_name {{ $server.Hostname }};
|
||||
server_name {{ $server.Hostname }} {{ $server.Alias }};
|
||||
listen 80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{end}};
|
||||
{{ if $IsIPV6Enabled }}listen [::]:80{{ if $cfg.UseProxyProtocol }} proxy_protocol{{ end }}{{ if eq $server.Hostname "_"}} default_server reuseport backlog={{ $backlogSize }}{{ end }};{{ end }}
|
||||
set $proxy_upstream_name "-";
|
||||
|
|
42
core/pkg/ingress/annotations/alias/main.go
Normal file
42
core/pkg/ingress/annotations/alias/main.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package alias
|
||||
|
||||
import (
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
)
|
||||
|
||||
const (
|
||||
annotation = "ingress.kubernetes.io/server-alias"
|
||||
)
|
||||
|
||||
type alias struct {
|
||||
}
|
||||
|
||||
// NewParser creates a new CORS annotation parser
|
||||
func NewParser() parser.IngressAnnotation {
|
||||
return alias{}
|
||||
}
|
||||
|
||||
// Parse parses the annotations contained in the ingress rule
|
||||
// used to indicate if the location/s contains a fragment of
|
||||
// configuration to be included inside the paths of the rules
|
||||
func (a alias) Parse(ing *extensions.Ingress) (interface{}, error) {
|
||||
return parser.GetStringAnnotation(annotation, ing)
|
||||
}
|
60
core/pkg/ingress/annotations/alias/main_test.go
Normal file
60
core/pkg/ingress/annotations/alias/main_test.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package alias
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
api "k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
ap := NewParser()
|
||||
if ap == nil {
|
||||
t.Fatalf("expected a parser.IngressAnnotation but returned nil")
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
annotations map[string]string
|
||||
expected string
|
||||
}{
|
||||
{map[string]string{annotation: "www.example.com"}, "www.example.com"},
|
||||
{map[string]string{annotation: "*.example.com www.example.*"}, "*.example.com www.example.*"},
|
||||
{map[string]string{annotation: `~^www\d+\.example\.com$`}, `~^www\d+\.example\.com$`},
|
||||
{map[string]string{annotation: ""}, ""},
|
||||
{map[string]string{}, ""},
|
||||
{nil, ""},
|
||||
}
|
||||
|
||||
ing := &extensions.Ingress{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: extensions.IngressSpec{},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
ing.SetAnnotations(testCase.annotations)
|
||||
result, _ := ap.Parse(ing)
|
||||
if result != testCase.expected {
|
||||
t.Errorf("expected %v but returned %v, annotations: %s", testCase.expected, result, testCase.annotations)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import (
|
|||
"k8s.io/ingress/core/pkg/ingress/annotations/sslpassthrough"
|
||||
"k8s.io/ingress/core/pkg/ingress/errors"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/alias"
|
||||
)
|
||||
|
||||
type extractorConfig interface {
|
||||
|
@ -69,6 +70,7 @@ func newAnnotationExtractor(cfg extractorConfig) annotationExtractor {
|
|||
"SessionAffinity": sessionaffinity.NewParser(),
|
||||
"SSLPassthrough": sslpassthrough.NewParser(),
|
||||
"ConfigurationSnippet": snippet.NewParser(),
|
||||
"Alias": alias.NewParser(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +109,7 @@ const (
|
|||
sslPassthrough = "SSLPassthrough"
|
||||
sessionAffinity = "SessionAffinity"
|
||||
serviceUpstream = "ServiceUpstream"
|
||||
serverAlias = "Alias"
|
||||
)
|
||||
|
||||
func (e *annotationExtractor) ServiceUpstream(ing *extensions.Ingress) bool {
|
||||
|
@ -133,6 +136,11 @@ func (e *annotationExtractor) SSLPassthrough(ing *extensions.Ingress) bool {
|
|||
return val.(bool)
|
||||
}
|
||||
|
||||
func (e *annotationExtractor) Alias(ing *extensions.Ingress) string {
|
||||
val, _ := e.annotations[serverAlias].Parse(ing)
|
||||
return val.(string)
|
||||
}
|
||||
|
||||
func (e *annotationExtractor) SessionAffinity(ing *extensions.Ingress) *sessionaffinity.AffinityConfig {
|
||||
val, _ := e.annotations[sessionAffinity].Parse(ing)
|
||||
return val.(*sessionaffinity.AffinityConfig)
|
||||
|
|
|
@ -1055,19 +1055,37 @@ func (ic *GenericController) createServers(data []interface{},
|
|||
}
|
||||
}
|
||||
|
||||
// configure default location and SSL
|
||||
// configure default location, alias, and SSL
|
||||
for _, ingIf := range data {
|
||||
ing := ingIf.(*extensions.Ingress)
|
||||
if !class.IsValid(ing, ic.cfg.IngressClass, ic.cfg.DefaultIngressClass) {
|
||||
continue
|
||||
}
|
||||
|
||||
// setup server-aliases based on annotations
|
||||
aliasMap := map[string]string{}
|
||||
aliasAnnotation := ic.annotations.Alias(ing)
|
||||
|
||||
// Here we parse the annotation string in the following format:
|
||||
// ingress.kubernetes.io/server-alias: "host_0:alias_0;...;host_n:alias_n"
|
||||
aliases := strings.Split(aliasAnnotation, ";")
|
||||
for _, alias := range aliases {
|
||||
aliasParts := strings.Split(alias, ":")
|
||||
if len(aliasParts) == 2 {
|
||||
// aliasMap[host] = alias
|
||||
aliasMap[aliasParts[0]] = aliasParts[1]
|
||||
}
|
||||
}
|
||||
|
||||
for _, rule := range ing.Spec.Rules {
|
||||
host := rule.Host
|
||||
if host == "" {
|
||||
host = defServerName
|
||||
}
|
||||
|
||||
// setup server aliases
|
||||
servers[host].Alias = aliasMap[host]
|
||||
|
||||
// only add a certificate if the server does not have one previously configured
|
||||
if len(ing.Spec.TLS) == 0 || servers[host].SSLCertificate != "" {
|
||||
continue
|
||||
|
|
|
@ -220,6 +220,8 @@ type Server struct {
|
|||
SSLPemChecksum string `json:"sslPemChecksum"`
|
||||
// Locations list of URIs configured in the server.
|
||||
Locations []*Location `json:"locations,omitempty"`
|
||||
// return the alias of the server name
|
||||
Alias string `json:"alias,omitempty"`
|
||||
}
|
||||
|
||||
// Location describes an URI inside a server.
|
||||
|
|
Loading…
Reference in a new issue