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
|
--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-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
|
--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")
|
--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.
|
--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")
|
--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
|
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.
|
--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.
|
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
|
-v, --v Level log level for V logs
|
||||||
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
|
--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
|
--watch-namespace string Namespace to watch for Ingress. Default is to watch all namespaces
|
||||||
|
|
|
@ -130,6 +130,7 @@ type Configuration struct {
|
||||||
// optional
|
// optional
|
||||||
UDPConfigMapName string
|
UDPConfigMapName string
|
||||||
DefaultSSLCertificate string
|
DefaultSSLCertificate string
|
||||||
|
AlwaysEnableTLS bool
|
||||||
DefaultHealthzURL string
|
DefaultHealthzURL string
|
||||||
DefaultIngressClass string
|
DefaultIngressClass string
|
||||||
// optional
|
// optional
|
||||||
|
@ -340,7 +341,7 @@ func (ic GenericController) GetDefaultBackend() defaults.Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRecorder returns the event recorder
|
// GetRecorder returns the event recorder
|
||||||
func (ic GenericController) GetRecoder() record.EventRecorder {
|
func (ic GenericController) GetRecorder() record.EventRecorder {
|
||||||
return ic.recorder
|
return ic.recorder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,76 +1065,80 @@ func (ic *GenericController) createServers(data []interface{},
|
||||||
},
|
},
|
||||||
}, SSLPassthrough: sslpt}
|
}, SSLPassthrough: sslpt}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// configure default location and SSL
|
ic.configureTLSforIng(ing, servers, defaultPemFileName, defaultPemSHA)
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return servers
|
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.
|
// getEndpoints returns a list of <endpoint ip>:<port> for a given service/target port combination.
|
||||||
func (ic *GenericController) getEndpoints(
|
func (ic *GenericController) getEndpoints(
|
||||||
s *api.Service,
|
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
|
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`)
|
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
|
defHealthzURL = flags.String("health-check-path", "/healthz", `Defines
|
||||||
the URL to be used as health check inside in the default server in NGINX.`)
|
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,
|
TCPConfigMapName: *tcpConfigMapName,
|
||||||
UDPConfigMapName: *udpConfigMapName,
|
UDPConfigMapName: *udpConfigMapName,
|
||||||
DefaultSSLCertificate: *defSSLCertificate,
|
DefaultSSLCertificate: *defSSLCertificate,
|
||||||
|
AlwaysEnableTLS: *defAlwaysEnableTLS,
|
||||||
DefaultHealthzURL: *defHealthzURL,
|
DefaultHealthzURL: *defHealthzURL,
|
||||||
PublishService: *publishSvc,
|
PublishService: *publishSvc,
|
||||||
Backend: backend,
|
Backend: backend,
|
||||||
|
|
Loading…
Reference in a new issue