Merge 4ea8bceb09
into ad723a7028
This commit is contained in:
commit
fbce22d626
4 changed files with 149 additions and 66 deletions
|
@ -50,6 +50,8 @@ Usage of :
|
|||
--configmap string Name of the ConfigMap that contains the custom configuration use
|
||||
--default-backend-service string Service used to serve a 404 page for the default backend. Takes the form namespace/name. The controller uses the first node port of this Service for the default backend.
|
||||
--default-ssl-certificate string Name of the secret that contains a SSL certificate to be used as default for a HTTPS catch-all server
|
||||
--always-enable-tls bool Enable tls using the default-ssl-certificate even if no tls section is defined
|
||||
for the ingress.
|
||||
--election-id string Election id to use for status update. (default "ingress-controller-leader")
|
||||
--force-namespace-isolation Force namespace isolation. This flag is required to avoid the reference of secrets or configmaps located in a different namespace than the specified in the flag --watch-namespace.
|
||||
--health-check-path string Defines the URL to be used as health check inside in the default server in NGINX. (default "/healthz")
|
||||
|
@ -68,7 +70,7 @@ Usage of :
|
|||
The ports 80 and 443 are not allowed as external ports. This ports are reserved for the backend
|
||||
--udp-services-configmap string Name of the ConfigMap that contains the definition of the UDP services to expose.
|
||||
The key in the map indicates the external port to be used. The value is the name of the service with the format namespace/serviceName and the port of the service could be a number of the name of the port.
|
||||
--update-status Indicates if the ingress controller should update the Ingress status IP/hostname. Default is true (default true)
|
||||
--update-status bool Indicates if the ingress controller should update the Ingress status IP/hostname. Default is true (default true)
|
||||
-v, --v Level log level for V logs
|
||||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
|
||||
--watch-namespace string Namespace to watch for Ingress. Default is to watch all namespaces
|
||||
|
|
|
@ -130,6 +130,7 @@ type Configuration struct {
|
|||
// optional
|
||||
UDPConfigMapName string
|
||||
DefaultSSLCertificate string
|
||||
AlwaysEnableTLS bool
|
||||
DefaultHealthzURL string
|
||||
DefaultIngressClass string
|
||||
// optional
|
||||
|
@ -340,7 +341,7 @@ func (ic GenericController) GetDefaultBackend() defaults.Backend {
|
|||
}
|
||||
|
||||
// GetRecorder returns the event recorder
|
||||
func (ic GenericController) GetRecoder() record.EventRecorder {
|
||||
func (ic GenericController) GetRecorder() record.EventRecorder {
|
||||
return ic.recorder
|
||||
}
|
||||
|
||||
|
@ -1064,76 +1065,80 @@ func (ic *GenericController) createServers(data []interface{},
|
|||
},
|
||||
}, SSLPassthrough: sslpt}
|
||||
}
|
||||
}
|
||||
|
||||
// configure default location and SSL
|
||||
for _, ingIf := range data {
|
||||
ing := ingIf.(*extensions.Ingress)
|
||||
if !class.IsValid(ing, ic.cfg.IngressClass, ic.cfg.DefaultIngressClass) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, rule := range ing.Spec.Rules {
|
||||
host := rule.Host
|
||||
if host == "" {
|
||||
host = defServerName
|
||||
}
|
||||
|
||||
// only add a certificate if the server does not have one previously configured
|
||||
if len(ing.Spec.TLS) == 0 || servers[host].SSLCertificate != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
tlsSecretName := ""
|
||||
found := false
|
||||
for _, tls := range ing.Spec.TLS {
|
||||
if sets.NewString(tls.Hosts...).Has(host) {
|
||||
tlsSecretName = tls.SecretName
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// the current ing.Spec.Rules[].Host doesn't have an entry at
|
||||
// ing.Spec.TLS[].Hosts[] skipping to the next Rule
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
if tlsSecretName == "" {
|
||||
glog.V(3).Infof("host %v is listed on tls section but secretName is empty. Using default cert", host)
|
||||
servers[host].SSLCertificate = defaultPemFileName
|
||||
servers[host].SSLPemChecksum = defaultPemSHA
|
||||
continue
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%v/%v", ing.Namespace, tlsSecretName)
|
||||
bc, exists := ic.sslCertTracker.Get(key)
|
||||
if !exists {
|
||||
glog.Infof("ssl certificate \"%v\" does not exist in local store", key)
|
||||
continue
|
||||
}
|
||||
|
||||
cert := bc.(*ingress.SSLCert)
|
||||
err = cert.Certificate.VerifyHostname(host)
|
||||
if err != nil {
|
||||
glog.Warningf("ssl certificate %v does not contain a Common Name or Subject Alternative Name for host %v", key, host)
|
||||
continue
|
||||
}
|
||||
|
||||
servers[host].SSLCertificate = cert.PemFileName
|
||||
servers[host].SSLPemChecksum = cert.PemSHA
|
||||
servers[host].SSLExpireTime = cert.ExpireTime
|
||||
|
||||
if cert.ExpireTime.Before(time.Now().Add(240 * time.Hour)) {
|
||||
glog.Warningf("ssl certificate for host %v is about to expire in 10 days", host)
|
||||
}
|
||||
}
|
||||
ic.configureTLSforIng(ing, servers, defaultPemFileName, defaultPemSHA)
|
||||
}
|
||||
|
||||
return servers
|
||||
}
|
||||
|
||||
func (ic *GenericController) configureTLSforIng(ing *extensions.Ingress, servers map[string]*ingress.Server, defaultPemFileName string, defaultPemSHA string) {
|
||||
for _, rule := range ing.Spec.Rules {
|
||||
host := rule.Host
|
||||
if host == "" {
|
||||
host = defServerName
|
||||
}
|
||||
|
||||
// only add a certificate if the server does not have one previously configured
|
||||
if servers[host].SSLCertificate != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
tlsForHost := getTLSForHost(ing.Spec.TLS, host)
|
||||
|
||||
if tlsForHost == nil && ic.cfg.AlwaysEnableTLS {
|
||||
glog.V(3).Infof("no tls host defined for %v but EnforceTLS is true. Using default cert", host)
|
||||
servers[host].SSLCertificate = defaultPemFileName
|
||||
servers[host].SSLPemChecksum = defaultPemSHA
|
||||
continue
|
||||
}
|
||||
|
||||
// the current ing.Spec.Rules[].Host doesn't have an entry at
|
||||
// ing.Spec.TLS[].Hosts[] skipping to the next Rule
|
||||
if tlsForHost == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if tlsForHost.SecretName == "" {
|
||||
glog.V(3).Infof("host %v is listed on tls section but secretName is empty. Using default cert", host)
|
||||
servers[host].SSLCertificate = defaultPemFileName
|
||||
servers[host].SSLPemChecksum = defaultPemSHA
|
||||
continue
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%v/%v", ing.Namespace, tlsForHost.SecretName)
|
||||
bc, exists := ic.sslCertTracker.Get(key)
|
||||
if !exists {
|
||||
glog.Infof("ssl certificate \"%v\" does not exist in local store", key)
|
||||
continue
|
||||
}
|
||||
|
||||
cert := bc.(*ingress.SSLCert)
|
||||
err := cert.Certificate.VerifyHostname(host)
|
||||
if err != nil {
|
||||
glog.Warningf("ssl certificate %v does not contain a Common Name or Subject Alternative Name for host %v", key, host)
|
||||
continue
|
||||
}
|
||||
|
||||
servers[host].SSLCertificate = cert.PemFileName
|
||||
servers[host].SSLPemChecksum = cert.PemSHA
|
||||
servers[host].SSLExpireTime = cert.ExpireTime
|
||||
|
||||
if cert.ExpireTime.Before(time.Now().Add(240 * time.Hour)) {
|
||||
glog.Warningf("ssl certificate for host %v is about to expire in 10 days", host)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getTLSForHost(ingressTLS []extensions.IngressTLS, host string) *extensions.IngressTLS {
|
||||
for _, tls := range ingressTLS {
|
||||
if sets.NewString(tls.Hosts...).Has(host) {
|
||||
return &tls
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// getEndpoints returns a list of <endpoint ip>:<port> for a given service/target port combination.
|
||||
func (ic *GenericController) getEndpoints(
|
||||
s *api.Service,
|
||||
|
|
72
core/pkg/ingress/controller/controller_test.go
Normal file
72
core/pkg/ingress/controller/controller_test.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/ingress/core/pkg/ingress"
|
||||
)
|
||||
|
||||
func buildGenericControllerForCertTest() *GenericController {
|
||||
return &GenericController{
|
||||
cfg: &Configuration{},
|
||||
}
|
||||
}
|
||||
|
||||
func buildTestIngressRuleForCertTest() extensions.Ingress {
|
||||
return extensions.Ingress{
|
||||
Spec: extensions.IngressSpec{
|
||||
Rules: []extensions.IngressRule{
|
||||
extensions.IngressRule{
|
||||
Host: "hostWithTLS",
|
||||
},
|
||||
extensions.IngressRule{
|
||||
Host: "hostWithoutTLS",
|
||||
},
|
||||
},
|
||||
TLS: []extensions.IngressTLS{
|
||||
extensions.IngressTLS{
|
||||
Hosts: []string{"hostWithTLS"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func buildTestServersForCertTest() map[string]*ingress.Server {
|
||||
return map[string]*ingress.Server{
|
||||
"hostWithTLS": &ingress.Server{
|
||||
Hostname: "hostWithTLS",
|
||||
},
|
||||
"hostWithoutTLS": &ingress.Server{
|
||||
Hostname: "hostWithoutTLS",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigureTLSforIng(t *testing.T) {
|
||||
ic := buildGenericControllerForCertTest()
|
||||
|
||||
testIng := buildTestIngressRuleForCertTest()
|
||||
testServers := buildTestServersForCertTest()
|
||||
|
||||
defaultPemFileName := "defaultPemFileName"
|
||||
defaultPemSHA := "defaultPemSHA"
|
||||
|
||||
ic.configureTLSforIng(&testIng, testServers, defaultPemFileName, defaultPemSHA)
|
||||
if testServers["hostWithTLS"].SSLCertificate != defaultPemFileName {
|
||||
t.Errorf("SSLCertificate set to %s instead of %s", testServers["hostWithTLS"].SSLCertificate, defaultPemFileName)
|
||||
}
|
||||
if testServers["hostWithoutTLS"].SSLCertificate != "" {
|
||||
t.Errorf("SSLCertificate set to %s instead of being empty", testServers["hostWithoutTLS"].SSLCertificate)
|
||||
}
|
||||
|
||||
ic.cfg.AlwaysEnableTLS = true
|
||||
ic.configureTLSforIng(&testIng, testServers, defaultPemFileName, defaultPemSHA)
|
||||
if testServers["hostWithTLS"].SSLCertificate != defaultPemFileName {
|
||||
t.Errorf("SSLCertificate set to %s instead of %s", testServers["hostWithTLS"].SSLCertificate, defaultPemFileName)
|
||||
}
|
||||
if testServers["hostWithoutTLS"].SSLCertificate != defaultPemFileName {
|
||||
t.Errorf("SSLCertificate set to %s instead of %s", testServers["hostWithoutTLS"].SSLCertificate, defaultPemFileName)
|
||||
}
|
||||
}
|
|
@ -78,6 +78,9 @@ func NewIngressController(backend ingress.Controller) *GenericController {
|
|||
defSSLCertificate = flags.String("default-ssl-certificate", "", `Name of the secret
|
||||
that contains a SSL certificate to be used as default for a HTTPS catch-all server`)
|
||||
|
||||
defAlwaysEnableTLS = flags.Bool("always-enable-tls", false, `Enable tls using the default-ssl-certificate even if no tls section is defined
|
||||
for the ingress.`)
|
||||
|
||||
defHealthzURL = flags.String("health-check-path", "/healthz", `Defines
|
||||
the URL to be used as health check inside in the default server in NGINX.`)
|
||||
|
||||
|
@ -171,6 +174,7 @@ func NewIngressController(backend ingress.Controller) *GenericController {
|
|||
TCPConfigMapName: *tcpConfigMapName,
|
||||
UDPConfigMapName: *udpConfigMapName,
|
||||
DefaultSSLCertificate: *defSSLCertificate,
|
||||
AlwaysEnableTLS: *defAlwaysEnableTLS,
|
||||
DefaultHealthzURL: *defHealthzURL,
|
||||
PublishService: *publishSvc,
|
||||
Backend: backend,
|
||||
|
|
Loading…
Reference in a new issue