Merge branch 'upstream' into nginx/extauth_headers

This commit is contained in:
rsafronov 2017-03-24 20:25:18 -04:00
commit 6d07d32003
63 changed files with 1075 additions and 218 deletions

View file

@ -28,6 +28,7 @@ const (
addBaseURL = "ingress.kubernetes.io/add-base-url"
sslRedirect = "ingress.kubernetes.io/ssl-redirect"
forceSSLRedirect = "ingress.kubernetes.io/force-ssl-redirect"
appRoot = "ingress.kubernetes.io/app-root"
)
// Redirect describes the per location redirect config
@ -41,6 +42,8 @@ type Redirect struct {
SSLRedirect bool `json:"sslRedirect"`
// ForceSSLRedirect indicates if the location section is accessible SSL only
ForceSSLRedirect bool `json:"forceSSLRedirect"`
// AppRoot defines the Application Root that the Controller must redirect if it's not in '/' context
AppRoot string `json:"appRoot"`
}
type rewrite struct {
@ -65,10 +68,12 @@ func (a rewrite) Parse(ing *extensions.Ingress) (interface{}, error) {
fSslRe = a.backendResolver.GetDefaultBackend().ForceSSLRedirect
}
abu, _ := parser.GetBoolAnnotation(addBaseURL, ing)
ar, _ := parser.GetStringAnnotation(appRoot, ing)
return &Redirect{
Target: rt,
AddBaseURL: abu,
SSLRedirect: sslRe,
ForceSSLRedirect: fSslRe,
AppRoot: ar,
}, nil
}

View file

@ -158,3 +158,20 @@ func TestForceSSLRedirect(t *testing.T) {
t.Errorf("Expected true but returned false")
}
}
func TestAppRoot(t *testing.T) {
ing := buildIngress()
data := map[string]string{}
data[appRoot] = "/app1"
ing.SetAnnotations(data)
i, _ := NewParser(mockBackend{true}).Parse(ing)
redirect, ok := i.(*Redirect)
if !ok {
t.Errorf("expected a App Context")
}
if redirect.AppRoot != "/app1" {
t.Errorf("Unexpected value got in AppRoot")
}
}

View file

@ -17,8 +17,11 @@ limitations under the License.
package controller
import (
"fmt"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
@ -47,11 +50,13 @@ type extractorConfig interface {
}
type annotationExtractor struct {
annotations map[string]parser.IngressAnnotation
secretResolver resolver.Secret
annotations map[string]parser.IngressAnnotation
}
func newAnnotationExtractor(cfg extractorConfig) annotationExtractor {
return annotationExtractor{
cfg,
map[string]parser.IngressAnnotation{
"BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg),
"ExternalAuth": authreq.NewParser(),
@ -104,6 +109,7 @@ const (
healthCheck = "HealthCheck"
sslPassthrough = "SSLPassthrough"
sessionAffinity = "SessionAffinity"
certificateAuth = "CertificateAuth"
)
func (e *annotationExtractor) SecureUpstream(ing *extensions.Ingress) bool {
@ -125,3 +131,17 @@ func (e *annotationExtractor) SessionAffinity(ing *extensions.Ingress) *sessiona
val, _ := e.annotations[sessionAffinity].Parse(ing)
return val.(*sessionaffinity.AffinityConfig)
}
func (e *annotationExtractor) ContainsCertificateAuth(ing *extensions.Ingress) bool {
val, _ := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
return val != ""
}
func (e *annotationExtractor) CertificateAuthSecret(ing *extensions.Ingress) (*api.Secret, error) {
val, _ := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
if val == "" {
return nil, fmt.Errorf("ingress rule %v/%v does not contains the auth-tls-secret annotation", ing.Namespace, ing.Name)
}
return e.secretResolver.GetSecret(val)
}

View file

@ -18,6 +18,7 @@ package controller
import (
"fmt"
"reflect"
"strings"
"time"
@ -68,13 +69,18 @@ func (ic *GenericController) syncSecret(k interface{}) error {
}
// create certificates and add or update the item in the store
_, exists = ic.sslCertTracker.Get(key)
cur, exists := ic.sslCertTracker.Get(key)
if exists {
glog.V(3).Infof("updating secret %v/%v in the store ", sec.Namespace, sec.Name)
s := cur.(*ingress.SSLCert)
if reflect.DeepEqual(s, cert) {
// no need to update
return nil
}
glog.Infof("updating secret %v/%v in the local store", sec.Namespace, sec.Name)
ic.sslCertTracker.Update(key, cert)
return nil
}
glog.V(3).Infof("adding secret %v/%v to the store ", sec.Namespace, sec.Name)
glog.Infof("adding secret %v/%v to the local store", sec.Namespace, sec.Name)
ic.sslCertTracker.Add(key, cert)
return nil
}
@ -84,10 +90,10 @@ func (ic *GenericController) syncSecret(k interface{}) error {
func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLCert, error) {
secretInterface, exists, err := ic.secrLister.Store.GetByKey(secretName)
if err != nil {
return nil, fmt.Errorf("error retriveing secret %v: %v", secretName, err)
return nil, fmt.Errorf("error retrieving secret %v: %v", secretName, err)
}
if !exists {
return nil, fmt.Errorf("secret named %v does not exists", secretName)
return nil, fmt.Errorf("secret named %v does not exist", secretName)
}
secret := secretInterface.(*api.Secret)
@ -100,13 +106,13 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC
var s *ingress.SSLCert
if okcert && okkey {
glog.V(3).Infof("Found certificate and private key, configuring %v as a TLS Secret", secretName)
glog.Infof("found certificate and private key, configuring %v as a TLS Secret", secretName)
s, err = ssl.AddOrUpdateCertAndKey(nsSecName, cert, key, ca)
} else if ca != nil {
glog.V(3).Infof("Found only ca.crt, configuring %v as an Certificate Authentication secret", secretName)
glog.Infof("found only ca.crt, configuring %v as an Certificate Authentication secret", secretName)
s, err = ssl.AddCertAuth(nsSecName, ca)
} else {
return nil, fmt.Errorf("No keypair or CA cert could be found in %v", secretName)
return nil, fmt.Errorf("ko keypair or CA cert could be found in %v", secretName)
}
if err != nil {
@ -122,10 +128,14 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC
func (ic *GenericController) secrReferenced(name, namespace string) bool {
for _, ingIf := range ic.ingLister.Store.List() {
ing := ingIf.(*extensions.Ingress)
str, err := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
if err == nil && str == fmt.Sprintf("%v/%v", namespace, name) {
return true
if ic.annotations.ContainsCertificateAuth(ing) {
str, _ := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
if str == fmt.Sprintf("%v/%v", namespace, name) {
return true
}
}
if ing.Namespace != namespace {
continue
}

View file

@ -111,7 +111,7 @@ type GenericController struct {
// Configuration contains all the settings required by an Ingress controller
type Configuration struct {
Client *clientset.Clientset
Client clientset.Interface
ResyncPeriod time.Duration
DefaultService string
@ -170,6 +170,12 @@ func newIngressController(config *Configuration) *GenericController {
}
ic.recorder.Eventf(addIng, api.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", addIng.Namespace, addIng.Name))
ic.syncQueue.Enqueue(obj)
if ic.annotations.ContainsCertificateAuth(addIng) {
s, err := ic.annotations.CertificateAuthSecret(addIng)
if err == nil {
ic.syncSecret(fmt.Sprintf("%v/%v", s.Namespace, s.Name))
}
}
},
DeleteFunc: func(obj interface{}) {
delIng := obj.(*extensions.Ingress)
@ -209,6 +215,13 @@ func newIngressController(config *Configuration) *GenericController {
}()
}
}
if ic.annotations.ContainsCertificateAuth(upIng) {
s, err := ic.annotations.CertificateAuthSecret(upIng)
if err == nil {
ic.syncSecret(fmt.Sprintf("%v/%v", s.Namespace, s.Name))
}
}
ic.syncQueue.Enqueue(cur)
}
},
@ -280,11 +293,11 @@ func newIngressController(config *Configuration) *GenericController {
&api.Endpoints{}, ic.cfg.ResyncPeriod, eventHandler)
ic.secrLister.Store, ic.secrController = cache.NewInformer(
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "secrets", ic.cfg.Namespace, fields.Everything()),
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "secrets", api.NamespaceAll, fields.Everything()),
&api.Secret{}, ic.cfg.ResyncPeriod, secrEventHandler)
ic.mapLister.Store, ic.mapController = cache.NewInformer(
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", ic.cfg.Namespace, fields.Everything()),
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", api.NamespaceAll, fields.Everything()),
&api.ConfigMap{}, ic.cfg.ResyncPeriod, mapEventHandler)
ic.svcLister.Indexer, ic.svcController = cache.NewIndexerInformer(
@ -551,7 +564,7 @@ func (ic *GenericController) getDefaultUpstream() *ingress.Backend {
}
if !svcExists {
glog.Warningf("service %v does not exists", svcKey)
glog.Warningf("service %v does not exist", svcKey)
upstream.Endpoints = append(upstream.Endpoints, newDefaultServer())
return upstream
}
@ -693,7 +706,7 @@ func (ic GenericController) GetAuthCertificate(secretName string) (*resolver.Aut
bc, exists := ic.sslCertTracker.Get(secretName)
if !exists {
return &resolver.AuthSSLCert{}, fmt.Errorf("secret %v does not exists", secretName)
return &resolver.AuthSSLCert{}, fmt.Errorf("secret %v does not exist", secretName)
}
cert := bc.(*ingress.SSLCert)
return &resolver.AuthSSLCert{
@ -792,7 +805,7 @@ func (ic *GenericController) serviceEndpoints(svcKey, backendPort string,
}
if !svcExists {
err = fmt.Errorf("service %v does not exists", svcKey)
err = fmt.Errorf("service %v does not exist", svcKey)
return upstreams, err
}
@ -947,6 +960,12 @@ func (ic *GenericController) createServers(data []interface{},
}
}
if tlsSecretName == "" {
glog.Warningf("ingress rule %v/%v for host %v does not contains a matching tls host", ing.Namespace, ing.Name, host)
glog.V(2).Infof("%v", ing.Spec.TLS)
continue
}
key := fmt.Sprintf("%v/%v", ing.Namespace, tlsSecretName)
bc, exists := ic.sslCertTracker.Get(key)
if exists {
@ -954,7 +973,11 @@ func (ic *GenericController) createServers(data []interface{},
if isHostValid(host, cert) {
servers[host].SSLCertificate = cert.PemFileName
servers[host].SSLPemChecksum = cert.PemSHA
} else {
glog.Warningf("ssl certificate %v does not contains a common name for host %v", key, host)
}
} else {
glog.Warningf("ssl certificate \"%v\" does not exist in local store", key)
}
}
}
@ -978,6 +1001,11 @@ func (ic *GenericController) getEndpoints(
upsServers := []ingress.Endpoint{}
// avoid duplicated upstream servers when the service
// contains multiple port definitions sharing the same
// targetport.
adus := make(map[string]bool, 0)
for _, ss := range ep.Subsets {
for _, epPort := range ss.Ports {
@ -1018,6 +1046,10 @@ func (ic *GenericController) getEndpoints(
}
for _, epAddress := range ss.Addresses {
ep := fmt.Sprintf("%v:%v", epAddress.IP, targetPort)
if _, exists := adus[ep]; exists {
continue
}
ups := ingress.Endpoint{
Address: epAddress.IP,
Port: fmt.Sprintf("%v", targetPort),
@ -1025,6 +1057,7 @@ func (ic *GenericController) getEndpoints(
FailTimeout: hz.FailTimeout,
}
upsServers = append(upsServers, ups)
adus[ep] = true
}
}
}

View file

@ -128,10 +128,12 @@ func NewIngressController(backend ingress.Controller) *GenericController {
glog.Infof("service %v validated as source of Ingress status", *publishSvc)
}
if *configMap != "" {
_, _, err = k8s.ParseNameNS(*configMap)
if *watchNamespace != "" {
_, err = k8s.IsValidNamespace(kubeClient, *watchNamespace)
if err != nil {
glog.Fatalf("configmap error: %v", err)
glog.Fatalf("no watchNamespace with name %v found: %v", *watchNamespace, err)
}
}

View file

@ -32,13 +32,13 @@ import (
)
// checkSvcForUpdate verifies if one of the running pods for a service contains
// named port. If the annotation in the service does not exists or is not equals
// named port. If the annotation in the service does not exist or is not equals
// to the port mapping obtained from the pod the service must be updated to reflect
// the current state
func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
// get the pods associated with the service
// TODO: switch this to a watch
pods, err := ic.cfg.Client.Pods(svc.Namespace).List(api.ListOptions{
pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(api.ListOptions{
LabelSelector: labels.Set(svc.Spec.Selector).AsSelector(),
})
@ -82,7 +82,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) {
data, _ := json.Marshal(namedPorts)
newSvc, err := ic.cfg.Client.Services(svc.Namespace).Get(svc.Name)
newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name)
if err != nil {
return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err)
}
@ -93,7 +93,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
newSvc.ObjectMeta.Annotations[service.NamedPortAnnotation] = string(data)
glog.Infof("updating service %v with new named port mappings", svc.Name)
_, err = ic.cfg.Client.Services(svc.Namespace).Update(newSvc)
_, err = ic.cfg.Client.Core().Services(svc.Namespace).Update(newSvc)
if err != nil {
return fmt.Errorf("error syncing service %v/%v: %v", svc.Namespace, svc.Name, err)
}

View file

@ -0,0 +1,191 @@
/*
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 controller
import (
"reflect"
"testing"
"k8s.io/ingress/core/pkg/ingress/annotations/service"
"k8s.io/kubernetes/pkg/api"
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/util/intstr"
)
func buildSimpleClientSet() *testclient.Clientset {
return testclient.NewSimpleClientset(
&api.PodList{Items: []api.Pod{
{
ObjectMeta: api.ObjectMeta{
Name: "foo1",
Namespace: api.NamespaceDefault,
Labels: map[string]string{
"lable_sig": "foo_pod",
},
},
Spec: api.PodSpec{
NodeName: "foo_node_1",
Containers: []api.Container{
{
Ports: []api.ContainerPort{
{
Name: "foo1_named_port_c1",
Protocol: api.ProtocolTCP,
ContainerPort: 80,
},
},
},
},
},
},
{
ObjectMeta: api.ObjectMeta{
Name: "foo1",
Namespace: api.NamespaceSystem,
Labels: map[string]string{
"lable_sig": "foo_pod",
},
},
},
}},
&api.ServiceList{Items: []api.Service{
{
ObjectMeta: api.ObjectMeta{
Namespace: api.NamespaceDefault,
Name: "named_port_test_service",
},
},
}},
)
}
func buildGenericController() *GenericController {
return &GenericController{
cfg: &Configuration{
Client: buildSimpleClientSet(),
},
}
}
func buildService() *api.Service {
return &api.Service{
ObjectMeta: api.ObjectMeta{
Namespace: api.NamespaceSystem,
Name: "named_port_test_service",
},
Spec: api.ServiceSpec{
ClusterIP: "10.10.10.10",
},
}
}
func TestCheckSvcForUpdate(t *testing.T) {
foos := []struct {
n string
ns string
sps []api.ServicePort
sl map[string]string
er string
}{
{
"pods_have_not_been_found_in_this_namespace",
api.NamespaceSystem,
[]api.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"",
},
{
"ports_have_not_been_found_in_this_pod",
api.NamespaceDefault,
[]api.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"",
},
{
"ports_fixed",
api.NamespaceDefault,
[]api.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(80)},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"",
},
{
"nil_selector",
api.NamespaceDefault,
[]api.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
},
nil,
"{\"foo1_named_port_c1\":\"80\"}",
},
{
"normal_update",
api.NamespaceDefault,
[]api.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
},
map[string]string{
"lable_sig": "foo_pod",
},
"{\"foo1_named_port_c1\":\"80\"}",
},
}
for _, foo := range foos {
t.Run(foo.n, func(t *testing.T) {
gc := buildGenericController()
s := buildService()
s.SetNamespace(foo.ns)
s.Spec.Ports = foo.sps
s.Spec.Selector = foo.sl
err := gc.checkSvcForUpdate(s)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service")
rr := rs.ObjectMeta.Annotations[service.NamedPortAnnotation]
if !reflect.DeepEqual(rr, foo.er) {
t.Errorf("Returned %s, but expected %s for %s", rr, foo.er, foo.n)
}
})
}
}

View file

@ -46,7 +46,7 @@ func isHostValid(host string, cert *ingress.SSLCert) bool {
return false
}
for _, cn := range cert.CN {
if matchHostnames(cn, host) {
if matchHostnames(cn, strings.ToLower(host)) {
return true
}
}

View file

@ -6,6 +6,8 @@ import "net"
// The reason of this requirements is the annotations are generic. If some implementation do not supports
// one or more annotations it just can provides defaults
type Backend struct {
// AppRoot contains the AppRoot for apps that doesn't exposes its content in the 'root' context
AppRoot string `json:"app-root"`
// enables which HTTP codes should be passed for processing with the error_page directive
// http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors

View file

@ -252,7 +252,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
continue
}
go func(wg *sync.WaitGroup) {
go func(wg *sync.WaitGroup, ing *extensions.Ingress) {
defer wg.Done()
ingClient := s.Client.Extensions().Ingresses(ing.Namespace)
currIng, err := ingClient.Get(ing.Name)
@ -274,7 +274,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
if err != nil {
glog.Warningf("error updating ingress rule: %v", err)
}
}(&wg)
}(&wg, ing)
}
wg.Wait()

View file

@ -34,6 +34,30 @@ func IsValidService(kubeClient clientset.Interface, name string) (*api.Service,
return kubeClient.Core().Services(ns).Get(name)
}
// isValidConfigMap check if exists a configmap with the specified name
func IsValidConfigMap(kubeClient clientset.Interface, fullName string) (*api.ConfigMap, error) {
ns, name, err := ParseNameNS(fullName)
if err != nil {
return nil, err
}
configMap, err := kubeClient.Core().ConfigMaps(ns).Get(name)
if err != nil {
return nil, fmt.Errorf("configmap not found: %v", err)
}
return configMap, nil
}
// isValidNamespace chck if exists a namespace with the specified name
func IsValidNamespace(kubeClient clientset.Interface, name string) (*api.Namespace, error) {
return kubeClient.Core().Namespaces().Get(name)
}
// IsValidSecret checks if exists a secret with the specified name
func IsValidSecret(kubeClient clientset.Interface, name string) (*api.Secret, error) {
ns, name, err := ParseNameNS(name)

View file

@ -85,6 +85,64 @@ func TestIsValidService(t *testing.T) {
}
}
func TestIsValidNamespace(t *testing.T) {
fk := testclient.NewSimpleClientset(&api.Namespace{
ObjectMeta: api.ObjectMeta{
Name: "default",
},
})
_, err := IsValidNamespace(fk, "empty")
if err == nil {
t.Errorf("expected error but return nill")
}
ns, err := IsValidNamespace(fk, "default")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if ns == nil {
t.Errorf("expected a configmap but returned nil")
}
}
func TestIsValidConfigMap(t *testing.T) {
fk := testclient.NewSimpleClientset(&api.ConfigMap{
ObjectMeta: api.ObjectMeta{
Namespace: api.NamespaceDefault,
Name: "demo",
},
})
_, err := IsValidConfigMap(fk, "")
if err == nil {
t.Errorf("expected error but return nill")
}
s, err := IsValidConfigMap(fk, "default/demo")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if s == nil {
t.Errorf("expected a configmap but returned nil")
}
fk = testclient.NewSimpleClientset()
s, err = IsValidConfigMap(fk, "default/demo")
if err == nil {
t.Errorf("expected an error but returned nil")
}
if s != nil {
t.Errorf("unexpected Configmap returned: %v", s)
}
}
func TestIsValidSecret(t *testing.T) {
fk := testclient.NewSimpleClientset(&api.Secret{
ObjectMeta: api.ObjectMeta{

View file

@ -43,10 +43,10 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
tempPemFile, err := ioutil.TempFile(ingress.DefaultSSLDirectory, pemName)
glog.V(3).Infof("Creating temp file %v for Keypair: %v", tempPemFile.Name(), pemName)
if err != nil {
return nil, fmt.Errorf("could not create temp pem file %v: %v", pemFileName, err)
}
glog.V(3).Infof("Creating temp file %v for Keypair: %v", tempPemFile.Name(), pemName)
_, err = tempPemFile.Write(cert)
if err != nil {
@ -75,13 +75,13 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
pemBlock, _ := pem.Decode(pemCerts)
if pemBlock == nil {
_ = os.Remove(tempPemFile.Name())
return nil, fmt.Errorf("No valid PEM formatted block found")
return nil, fmt.Errorf("no valid PEM formatted block found")
}
// If the file does not start with 'BEGIN CERTIFICATE' it's invalid and must not be used.
if pemBlock.Type != "CERTIFICATE" {
_ = os.Remove(tempPemFile.Name())
return nil, fmt.Errorf("Certificate %v contains invalid data, and must be created with 'kubectl create secret tls'", name)
return nil, fmt.Errorf("certificate %v contains invalid data, and must be created with 'kubectl create secret tls'", name)
}
pemCert, err := x509.ParseCertificate(pemBlock.Bytes)
@ -115,7 +115,7 @@ func AddOrUpdateCertAndKey(name string, cert, key, ca []byte) (*ingress.SSLCert,
caFile, err := os.OpenFile(pemFileName, os.O_RDWR|os.O_APPEND, 0600)
if err != nil {
return nil, fmt.Errorf("Could not open file %v for writing additional CA chains: %v", pemFileName, err)
return nil, fmt.Errorf("could not open file %v for writing additional CA chains: %v", pemFileName, err)
}
defer caFile.Close()
@ -150,11 +150,11 @@ func AddCertAuth(name string, ca []byte) (*ingress.SSLCert, error) {
pemCABlock, _ := pem.Decode(ca)
if pemCABlock == nil {
return nil, fmt.Errorf("No valid PEM formatted block found")
return nil, fmt.Errorf("no valid PEM formatted block found")
}
// If the first certificate does not start with 'BEGIN CERTIFICATE' it's invalid and must not be used.
if pemCABlock.Type != "CERTIFICATE" {
return nil, fmt.Errorf("CA File %v contains invalid data, and must be created only with PEM formated certificates", name)
return nil, fmt.Errorf("CA file %v contains invalid data, and must be created only with PEM formated certificates", name)
}
_, err := x509.ParseCertificate(pemCABlock.Bytes)
@ -206,13 +206,13 @@ func AddOrUpdateDHParam(name string, dh []byte) (string, error) {
pemBlock, _ := pem.Decode(pemCerts)
if pemBlock == nil {
_ = os.Remove(tempPemFile.Name())
return "", fmt.Errorf("No valid PEM formatted block found")
return "", fmt.Errorf("no valid PEM formatted block found")
}
// If the file does not start with 'BEGIN DH PARAMETERS' it's invalid and must not be used.
if pemBlock.Type != "DH PARAMETERS" {
_ = os.Remove(tempPemFile.Name())
return "", fmt.Errorf("Certificate %v contains invalid data", name)
return "", fmt.Errorf("certificate %v contains invalid data", name)
}
err = os.Rename(tempPemFile.Name(), pemFileName)