Add --disable-catch-all option to disable catch-all server
This commit is contained in:
parent
4e98666720
commit
1678d99a03
9 changed files with 172 additions and 10 deletions
|
@ -156,6 +156,9 @@ Feature backed by OpenResty Lua libraries. Requires that OCSP stapling is not en
|
||||||
sslProxyPort = flags.Int("ssl-passthrough-proxy-port", 442, `Port to use internally for SSL Passthrough.`)
|
sslProxyPort = flags.Int("ssl-passthrough-proxy-port", 442, `Port to use internally for SSL Passthrough.`)
|
||||||
defServerPort = flags.Int("default-server-port", 8181, `Port to use for exposing the default server (catch-all).`)
|
defServerPort = flags.Int("default-server-port", 8181, `Port to use for exposing the default server (catch-all).`)
|
||||||
healthzPort = flags.Int("healthz-port", 10254, "Port to use for the healthz endpoint.")
|
healthzPort = flags.Int("healthz-port", 10254, "Port to use for the healthz endpoint.")
|
||||||
|
|
||||||
|
disableCatchAll = flags.Bool("disable-catch-all", false,
|
||||||
|
`Disable support for catch-all Ingresses`)
|
||||||
)
|
)
|
||||||
|
|
||||||
flag.Set("logtostderr", "true")
|
flag.Set("logtostderr", "true")
|
||||||
|
@ -254,6 +257,7 @@ Feature backed by OpenResty Lua libraries. Requires that OCSP stapling is not en
|
||||||
SSLProxy: *sslProxyPort,
|
SSLProxy: *sslProxyPort,
|
||||||
Status: *statusPort,
|
Status: *statusPort,
|
||||||
},
|
},
|
||||||
|
DisableCatchAll: *disableCatchAll,
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, config, nil
|
return false, config, nil
|
||||||
|
|
|
@ -46,3 +46,4 @@ They are set in the container spec of the `nginx-ingress-controller` Deployment
|
||||||
| `--version` | Show release information about the NGINX Ingress controller and exit. |
|
| `--version` | Show release information about the NGINX Ingress controller and exit. |
|
||||||
| `--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 the controller watches for updates to Kubernetes objects. This includes Ingresses, Services and all configuration resources. All namespaces are watched if this parameter is left empty. |
|
| `--watch-namespace string` | Namespace the controller watches for updates to Kubernetes objects. This includes Ingresses, Services and all configuration resources. All namespaces are watched if this parameter is left empty. |
|
||||||
|
| `--disable-catch-all` | Disable support for catch-all Ingresses. |
|
||||||
|
|
|
@ -97,6 +97,8 @@ type Configuration struct {
|
||||||
SyncRateLimit float32
|
SyncRateLimit float32
|
||||||
|
|
||||||
DynamicCertificatesEnabled bool
|
DynamicCertificatesEnabled bool
|
||||||
|
|
||||||
|
DisableCatchAll bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPublishService returns the Service used to set the load-balancer status of Ingresses.
|
// GetPublishService returns the Service used to set the load-balancer status of Ingresses.
|
||||||
|
|
|
@ -915,7 +915,8 @@ func newNGINXController(t *testing.T) *NGINXController {
|
||||||
fs,
|
fs,
|
||||||
channels.NewRingChannel(10),
|
channels.NewRingChannel(10),
|
||||||
false,
|
false,
|
||||||
pod)
|
pod,
|
||||||
|
false)
|
||||||
|
|
||||||
config := &Configuration{
|
config := &Configuration{
|
||||||
ListenPorts: &ngx_config.ListenPorts{
|
ListenPorts: &ngx_config.ListenPorts{
|
||||||
|
|
|
@ -127,7 +127,8 @@ func NewNGINXController(config *Configuration, mc metric.Collector, fs file.File
|
||||||
fs,
|
fs,
|
||||||
n.updateCh,
|
n.updateCh,
|
||||||
config.DynamicCertificatesEnabled,
|
config.DynamicCertificatesEnabled,
|
||||||
pod)
|
pod,
|
||||||
|
config.DisableCatchAll)
|
||||||
|
|
||||||
n.syncQueue = task.NewTaskQueue(n.syncIngress)
|
n.syncQueue = task.NewTaskQueue(n.syncIngress)
|
||||||
|
|
||||||
|
|
|
@ -232,7 +232,8 @@ func New(checkOCSP bool,
|
||||||
fs file.Filesystem,
|
fs file.Filesystem,
|
||||||
updateCh *channels.RingChannel,
|
updateCh *channels.RingChannel,
|
||||||
isDynamicCertificatesEnabled bool,
|
isDynamicCertificatesEnabled bool,
|
||||||
pod *k8s.PodInfo) Storer {
|
pod *k8s.PodInfo,
|
||||||
|
disableCatchAll bool) Storer {
|
||||||
|
|
||||||
store := &k8sStore{
|
store := &k8sStore{
|
||||||
isOCSPCheckEnabled: checkOCSP,
|
isOCSPCheckEnabled: checkOCSP,
|
||||||
|
@ -310,6 +311,10 @@ func New(checkOCSP bool,
|
||||||
klog.Infof("ignoring add for ingress %v based on annotation %v with value %v", ing.Name, class.IngressKey, a)
|
klog.Infof("ignoring add for ingress %v based on annotation %v with value %v", ing.Name, class.IngressKey, a)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if ing.Spec.Backend != nil && disableCatchAll {
|
||||||
|
klog.Infof("ignoring add for catch-all ingress %v/%v because of --disable-catch-all", ing.Namespace, ing.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
recorder.Eventf(ing, corev1.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", ing.Namespace, ing.Name))
|
recorder.Eventf(ing, corev1.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", ing.Namespace, ing.Name))
|
||||||
|
|
||||||
store.syncIngress(ing)
|
store.syncIngress(ing)
|
||||||
|
@ -340,6 +345,10 @@ func New(checkOCSP bool,
|
||||||
klog.Infof("ignoring delete for ingress %v based on annotation %v", ing.Name, class.IngressKey)
|
klog.Infof("ignoring delete for ingress %v based on annotation %v", ing.Name, class.IngressKey)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if ing.Spec.Backend != nil && disableCatchAll {
|
||||||
|
klog.Infof("ignoring delete for catch-all ingress %v/%v because of --disable-catch-all", ing.Namespace, ing.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
recorder.Eventf(ing, corev1.EventTypeNormal, "DELETE", fmt.Sprintf("Ingress %s/%s", ing.Namespace, ing.Name))
|
recorder.Eventf(ing, corev1.EventTypeNormal, "DELETE", fmt.Sprintf("Ingress %s/%s", ing.Namespace, ing.Name))
|
||||||
|
|
||||||
store.listers.IngressWithAnnotation.Delete(ing)
|
store.listers.IngressWithAnnotation.Delete(ing)
|
||||||
|
@ -358,13 +367,27 @@ func New(checkOCSP bool,
|
||||||
validOld := class.IsValid(oldIng)
|
validOld := class.IsValid(oldIng)
|
||||||
validCur := class.IsValid(curIng)
|
validCur := class.IsValid(curIng)
|
||||||
if !validOld && validCur {
|
if !validOld && validCur {
|
||||||
|
if curIng.Spec.Backend != nil && disableCatchAll {
|
||||||
|
klog.Infof("ignoring update for catch-all ingress %v/%v because of --disable-catch-all", curIng.Namespace, curIng.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
klog.Infof("creating ingress %v based on annotation %v", curIng.Name, class.IngressKey)
|
klog.Infof("creating ingress %v based on annotation %v", curIng.Name, class.IngressKey)
|
||||||
recorder.Eventf(curIng, corev1.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", curIng.Namespace, curIng.Name))
|
recorder.Eventf(curIng, corev1.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", curIng.Namespace, curIng.Name))
|
||||||
} else if validOld && !validCur {
|
} else if validOld && !validCur {
|
||||||
klog.Infof("removing ingress %v based on annotation %v", curIng.Name, class.IngressKey)
|
klog.Infof("removing ingress %v based on annotation %v", curIng.Name, class.IngressKey)
|
||||||
|
// FIXME: this does not actually delete the Ingress resource.
|
||||||
|
// The existing one will be updated with latest changes and invalid ingress.class will be missed.
|
||||||
recorder.Eventf(curIng, corev1.EventTypeNormal, "DELETE", fmt.Sprintf("Ingress %s/%s", curIng.Namespace, curIng.Name))
|
recorder.Eventf(curIng, corev1.EventTypeNormal, "DELETE", fmt.Sprintf("Ingress %s/%s", curIng.Namespace, curIng.Name))
|
||||||
} else if validCur && !reflect.DeepEqual(old, cur) {
|
} else if validCur && !reflect.DeepEqual(old, cur) {
|
||||||
recorder.Eventf(curIng, corev1.EventTypeNormal, "UPDATE", fmt.Sprintf("Ingress %s/%s", curIng.Namespace, curIng.Name))
|
if curIng.Spec.Backend != nil && disableCatchAll {
|
||||||
|
klog.Infof("ignoring update for catch-all ingress %v/%v because of --disable-catch-all", curIng.Namespace, curIng.Name)
|
||||||
|
// FIXME: this does not actually delete the Ingress resource.
|
||||||
|
// The existing one will be updated with latest changes.
|
||||||
|
recorder.Eventf(curIng, corev1.EventTypeNormal, "DELETE", fmt.Sprintf("Ingress %s/%s", curIng.Namespace, curIng.Name))
|
||||||
|
} else {
|
||||||
|
recorder.Eventf(curIng, corev1.EventTypeNormal, "UPDATE", fmt.Sprintf("Ingress %s/%s", curIng.Namespace, curIng.Name))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
klog.Infof("ignoring ingress %v based on annotation %v", curIng.Name, class.IngressKey)
|
klog.Infof("ignoring ingress %v based on annotation %v", curIng.Name, class.IngressKey)
|
||||||
return
|
return
|
||||||
|
|
|
@ -82,7 +82,8 @@ func TestStore(t *testing.T) {
|
||||||
fs,
|
fs,
|
||||||
updateCh,
|
updateCh,
|
||||||
false,
|
false,
|
||||||
pod)
|
pod,
|
||||||
|
false)
|
||||||
|
|
||||||
storer.Run(stopCh)
|
storer.Run(stopCh)
|
||||||
|
|
||||||
|
@ -163,7 +164,8 @@ func TestStore(t *testing.T) {
|
||||||
fs,
|
fs,
|
||||||
updateCh,
|
updateCh,
|
||||||
false,
|
false,
|
||||||
pod)
|
pod,
|
||||||
|
false)
|
||||||
|
|
||||||
storer.Run(stopCh)
|
storer.Run(stopCh)
|
||||||
|
|
||||||
|
@ -316,7 +318,8 @@ func TestStore(t *testing.T) {
|
||||||
fs,
|
fs,
|
||||||
updateCh,
|
updateCh,
|
||||||
false,
|
false,
|
||||||
pod)
|
pod,
|
||||||
|
false)
|
||||||
|
|
||||||
storer.Run(stopCh)
|
storer.Run(stopCh)
|
||||||
|
|
||||||
|
@ -424,7 +427,8 @@ func TestStore(t *testing.T) {
|
||||||
fs,
|
fs,
|
||||||
updateCh,
|
updateCh,
|
||||||
false,
|
false,
|
||||||
pod)
|
pod,
|
||||||
|
false)
|
||||||
|
|
||||||
storer.Run(stopCh)
|
storer.Run(stopCh)
|
||||||
|
|
||||||
|
@ -514,7 +518,8 @@ func TestStore(t *testing.T) {
|
||||||
fs,
|
fs,
|
||||||
updateCh,
|
updateCh,
|
||||||
false,
|
false,
|
||||||
pod)
|
pod,
|
||||||
|
false)
|
||||||
|
|
||||||
storer.Run(stopCh)
|
storer.Run(stopCh)
|
||||||
|
|
||||||
|
@ -627,7 +632,8 @@ func TestStore(t *testing.T) {
|
||||||
fs,
|
fs,
|
||||||
updateCh,
|
updateCh,
|
||||||
false,
|
false,
|
||||||
pod)
|
pod,
|
||||||
|
false)
|
||||||
|
|
||||||
storer.Run(stopCh)
|
storer.Run(stopCh)
|
||||||
|
|
||||||
|
|
|
@ -352,6 +352,21 @@ func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateIngress runs the given updateFunc on the ingress
|
||||||
|
func UpdateIngress(kubeClientSet kubernetes.Interface, namespace string, name string, updateFunc func(d *extensions.Ingress) error) error {
|
||||||
|
ingress, err := kubeClientSet.ExtensionsV1beta1().Ingresses(namespace).Get(name, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := updateFunc(ingress); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = kubeClientSet.ExtensionsV1beta1().Ingresses(namespace).Update(ingress)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// NewSingleIngressWithTLS creates a simple ingress rule with TLS spec included
|
// NewSingleIngressWithTLS creates a simple ingress rule with TLS spec included
|
||||||
func NewSingleIngressWithTLS(name, path, host, ns, service string, port int, annotations *map[string]string) *extensions.Ingress {
|
func NewSingleIngressWithTLS(name, path, host, ns, service string, port int, annotations *map[string]string) *extensions.Ingress {
|
||||||
return newSingleIngressWithRules(name, path, host, ns, service, port, annotations, true)
|
return newSingleIngressWithRules(name, path, host, ns, service, port, annotations, true)
|
||||||
|
|
109
test/e2e/settings/disable_catch_all.go
Normal file
109
test/e2e/settings/disable_catch_all.go
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
Copyright 2018 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 settings
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||||
|
|
||||||
|
"k8s.io/ingress-nginx/test/e2e/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = framework.IngressNginxDescribe("Disabled catch-all", func() {
|
||||||
|
f := framework.NewDefaultFramework("disabled-catch-all")
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
f.NewEchoDeploymentWithReplicas(1)
|
||||||
|
|
||||||
|
framework.UpdateDeployment(f.KubeClientSet, f.IngressController.Namespace, "nginx-ingress-controller", 1,
|
||||||
|
func(deployment *appsv1beta1.Deployment) error {
|
||||||
|
args := deployment.Spec.Template.Spec.Containers[0].Args
|
||||||
|
args = append(args, "--disable-catch-all=true")
|
||||||
|
deployment.Spec.Template.Spec.Containers[0].Args = args
|
||||||
|
_, err := f.KubeClientSet.AppsV1beta1().Deployments(f.IngressController.Namespace).Update(deployment)
|
||||||
|
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should ignore catch all Ingress", func() {
|
||||||
|
host := "foo"
|
||||||
|
|
||||||
|
ing := framework.NewSingleCatchAllIngress("catch-all", f.IngressController.Namespace, "http-svc", 80, nil)
|
||||||
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
ing = framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil)
|
||||||
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
f.WaitForNginxServer(host, func(cfg string) bool {
|
||||||
|
return strings.Contains(cfg, "server_name foo")
|
||||||
|
})
|
||||||
|
|
||||||
|
f.WaitForNginxServer("_", func(cfg string) bool {
|
||||||
|
return strings.Contains(cfg, `set $ingress_name ""`) &&
|
||||||
|
strings.Contains(cfg, `set $proxy_upstream_name "upstream-default-backend"`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// FIXME: This test doesn't work because of a bug in Ingress update handle in store package.
|
||||||
|
// It("should delete Ingress updated to catch-all", func() {
|
||||||
|
// host := "foo"
|
||||||
|
|
||||||
|
// ing := framework.NewSingleIngress(host, "/", host, f.IngressController.Namespace, "http-svc", 80, nil)
|
||||||
|
// f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
// f.WaitForNginxServer(host,
|
||||||
|
// func(server string) bool {
|
||||||
|
// return strings.Contains(server, "server_name foo")
|
||||||
|
// })
|
||||||
|
|
||||||
|
// resp, _, errs := gorequest.New().
|
||||||
|
// Get(f.IngressController.HTTPURL).
|
||||||
|
// Set("Host", host).
|
||||||
|
// End()
|
||||||
|
// Expect(errs).To(BeNil())
|
||||||
|
// Expect(resp.StatusCode).Should(Equal(http.StatusOK))
|
||||||
|
|
||||||
|
// err := framework.UpdateIngress(f.KubeClientSet, f.IngressController.Namespace, host, func(ingress *extensions.Ingress) error {
|
||||||
|
// ingress.Spec.Rules = nil
|
||||||
|
// ingress.Spec.Backend = &extensions.IngressBackend{
|
||||||
|
// ServiceName: "http-svc",
|
||||||
|
// ServicePort: intstr.FromInt(80),
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
// })
|
||||||
|
// Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// f.WaitForNginxConfiguration(func(cfg string) bool {
|
||||||
|
// return !strings.Contains(cfg, "server_name foo") &&
|
||||||
|
// !strings.Contains(cfg, `set $ingress_name "foo"`) &&
|
||||||
|
// !strings.Contains(cfg, `set $service_name "http-svc"`)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// resp, _, errs = gorequest.New().
|
||||||
|
// Get(f.IngressController.HTTPURL).
|
||||||
|
// Set("Host", host).
|
||||||
|
// End()
|
||||||
|
// Expect(errs).To(BeNil())
|
||||||
|
// Expect(resp.StatusCode).Should(Equal(http.StatusNotFound))
|
||||||
|
// })
|
||||||
|
})
|
Loading…
Reference in a new issue