Add support for services running ssl

This commit is contained in:
Manuel de Brito Fontes 2016-06-01 14:47:37 -04:00
parent ae52257c3a
commit 74b66beda9
8 changed files with 172 additions and 259 deletions

View file

@ -34,6 +34,7 @@ type IngressConfig struct {
type Upstream struct {
Name string
Backends []UpstreamServer
Secure bool
}
// UpstreamByNameServers sorts upstreams by name
@ -91,12 +92,13 @@ func (c ServerByName) Less(i, j int) bool {
// Location describes an NGINX location
type Location struct {
Path string
IsDefBackend bool
Upstream Upstream
Auth auth.Nginx
RateLimit ratelimit.RateLimit
Redirect rewrite.Redirect
Path string
IsDefBackend bool
Upstream Upstream
Auth auth.Nginx
RateLimit ratelimit.RateLimit
Redirect rewrite.Redirect
SecureUpstream bool
}
// LocationByPath sorts location by path

View file

@ -0,0 +1,50 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 secureupstream
import (
"errors"
"strconv"
"k8s.io/kubernetes/pkg/apis/extensions"
)
const (
secureUpstream = "ingress.kubernetes.io/secure-upstream"
)
type ingAnnotations map[string]string
func (a ingAnnotations) secureUpstream() bool {
val, ok := a[secureUpstream]
if ok {
if b, err := strconv.ParseBool(val); err == nil {
return b
}
}
return false
}
// ParseAnnotations parses the annotations contained in the ingress
// rule used to indicate if the upstream servers should use SSL
func ParseAnnotations(ing *extensions.Ingress) (bool, error) {
if ing.GetAnnotations() == nil {
return false, errors.New("no annotations present")
}
return ingAnnotations(ing.GetAnnotations()).secureUpstream(), nil
}

View file

@ -0,0 +1,80 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
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 secureupstream
import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/util/intstr"
)
func buildIngress() *extensions.Ingress {
defaultBackend := extensions.IngressBackend{
ServiceName: "default-backend",
ServicePort: intstr.FromInt(80),
}
return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Namespace: api.NamespaceDefault,
},
Spec: extensions.IngressSpec{
Backend: &extensions.IngressBackend{
ServiceName: "default-backend",
ServicePort: intstr.FromInt(80),
},
Rules: []extensions.IngressRule{
{
Host: "foo.bar.com",
IngressRuleValue: extensions.IngressRuleValue{
HTTP: &extensions.HTTPIngressRuleValue{
Paths: []extensions.HTTPIngressPath{
{
Path: "/foo",
Backend: defaultBackend,
},
},
},
},
},
},
},
}
}
func TestAnnotations(t *testing.T) {
ing := buildIngress()
data := map[string]string{}
data[secureUpstream] = "true"
ing.SetAnnotations(data)
su := ingAnnotations(ing.GetAnnotations()).secureUpstream()
if !su {
t.Errorf("Expected true in secure-upstgream but %v was returned", su)
}
}
func TestWithoutAnnotations(t *testing.T) {
ing := buildIngress()
_, err := ParseAnnotations(ing)
if err == nil {
t.Error("Expected error with ingress without annotations")
}
}

View file

@ -139,8 +139,12 @@ func buildProxyPass(input interface{}) string {
path := location.Path
proto := "http"
if location.SecureUpstream {
proto = "https"
}
// defProxyPass returns the default proxy_pass, just the name of the upstream
defProxyPass := fmt.Sprintf("proxy_pass http://%s;", location.Upstream.Name)
defProxyPass := fmt.Sprintf("proxy_pass %s://%s;", proto, location.Upstream.Name)
// if the path in the ingress rule is equals to the target: no special rewrite
if path == location.Redirect.Target {
return defProxyPass
@ -169,14 +173,14 @@ func buildProxyPass(input interface{}) string {
return fmt.Sprintf(`
rewrite %s / break;
rewrite %s(.*) /$1 break;
proxy_pass http://%s;
%v`, location.Path, path, location.Upstream.Name, abu)
proxy_pass %s://%s;
%v`, location.Path, path, proto, location.Upstream.Name, abu)
}
return fmt.Sprintf(`
rewrite %s(.*) %s/$1 break;
proxy_pass http://%s;
%v`, path, location.Redirect.Target, location.Upstream.Name, abu)
proxy_pass %s://%s;
%v`, path, location.Redirect.Target, proto, location.Upstream.Name, abu)
}
// default proxy_pass