diff --git a/docs/user-guide/cli-arguments.md b/docs/user-guide/cli-arguments.md index ab483b1cd..4379d0b34 100644 --- a/docs/user-guide/cli-arguments.md +++ b/docs/user-guide/cli-arguments.md @@ -18,6 +18,7 @@ They are set in the container spec of the `ingress-nginx-controller` Deployment | `--disable-catch-all` | Disable support for catch-all Ingresses. (default false) | | `--disable-full-test` | Disable full test of all merged ingresses at the admission stage and tests the template of the ingress being created or updated (full test of all ingresses is enabled by default). | | `--disable-svc-external-name` | Disable support for Services of type ExternalName. (default false) | +| `--disable-sync-events` | Disables the creation of 'Sync' Event resources, but still logs them | | `--dynamic-configuration-retries` | Number of times to retry failed dynamic configuration before failing to sync an ingress. (default 15) | | `--election-id` | Election id to use for Ingress status updates. (default "ingress-controller-leader") | | `--enable-metrics` | Enables the collection of NGINX metrics. (default true) | diff --git a/internal/ingress/controller/controller.go b/internal/ingress/controller/controller.go index 8eee56647..010eba162 100644 --- a/internal/ingress/controller/controller.go +++ b/internal/ingress/controller/controller.go @@ -129,6 +129,8 @@ type Configuration struct { DeepInspector bool DynamicConfigurationRetries int + + DisableSyncEvents bool } // GetPublishService returns the Service used to set the load-balancer status of Ingresses. diff --git a/internal/ingress/controller/controller_test.go b/internal/ingress/controller/controller_test.go index da9f10e45..796012cd3 100644 --- a/internal/ingress/controller/controller_test.go +++ b/internal/ingress/controller/controller_test.go @@ -2404,6 +2404,7 @@ func newNGINXController(t *testing.T) *NGINXController { Controller: "k8s.io/ingress-nginx", AnnotationValue: "nginx", }, + false, ) sslCert := ssl.GetFakeSSLCert() @@ -2468,7 +2469,8 @@ func newDynamicNginxController(t *testing.T, setConfigMap func(string) *v1.Confi &ingressclass.IngressClassConfiguration{ Controller: "k8s.io/ingress-nginx", AnnotationValue: "nginx", - }) + }, + false) sslCert := ssl.GetFakeSSLCert() config := &Configuration{ diff --git a/internal/ingress/controller/nginx.go b/internal/ingress/controller/nginx.go index 4b543ea2f..5575009ea 100644 --- a/internal/ingress/controller/nginx.go +++ b/internal/ingress/controller/nginx.go @@ -136,7 +136,8 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro n.updateCh, config.DisableCatchAll, config.DeepInspector, - config.IngressClassConfiguration) + config.IngressClassConfiguration, + config.DisableSyncEvents) n.syncQueue = task.NewTaskQueue(n.syncIngress) diff --git a/internal/ingress/controller/store/store.go b/internal/ingress/controller/store/store.go index 7f493bd8a..13af28137 100644 --- a/internal/ingress/controller/store/store.go +++ b/internal/ingress/controller/store/store.go @@ -251,7 +251,8 @@ func New( updateCh *channels.RingChannel, disableCatchAll bool, deepInspector bool, - icConfig *ingressclass.IngressClassConfiguration) Storer { + icConfig *ingressclass.IngressClassConfiguration, + disableSyncEvents bool) Storer { store := &k8sStore{ informers: &Informer{}, @@ -267,9 +268,11 @@ func New( eventBroadcaster := record.NewBroadcaster() eventBroadcaster.StartLogging(klog.Infof) - eventBroadcaster.StartRecordingToSink(&clientcorev1.EventSinkImpl{ - Interface: client.CoreV1().Events(namespace), - }) + if !disableSyncEvents { + eventBroadcaster.StartRecordingToSink(&clientcorev1.EventSinkImpl{ + Interface: client.CoreV1().Events(namespace), + }) + } recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{ Component: "nginx-ingress-controller", }) diff --git a/internal/ingress/controller/store/store_test.go b/internal/ingress/controller/store/store_test.go index 9b8947f9c..9fe6e37bb 100644 --- a/internal/ingress/controller/store/store_test.go +++ b/internal/ingress/controller/store/store_test.go @@ -125,7 +125,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) @@ -206,7 +207,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) ic := createIngressClass(clientSet, t, "not-k8s.io/not-ingress-nginx") @@ -310,7 +312,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) validSpec := commonIngressSpec @@ -426,7 +429,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - ingressClassconfig) + ingressClassconfig, + false) storer.Run(stopCh) @@ -556,7 +560,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - ingressClassconfig) + ingressClassconfig, + false) storer.Run(stopCh) validSpec := commonIngressSpec @@ -656,7 +661,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) @@ -750,7 +756,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) invalidSpec := commonIngressSpec @@ -836,7 +843,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) @@ -932,7 +940,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) @@ -1056,7 +1065,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) @@ -1177,7 +1187,8 @@ func TestStore(t *testing.T) { updateCh, false, true, - DefaultClassConfig) + DefaultClassConfig, + false) storer.Run(stopCh) diff --git a/pkg/flags/flags.go b/pkg/flags/flags.go index 65b5fbcdc..6e183289c 100644 --- a/pkg/flags/flags.go +++ b/pkg/flags/flags.go @@ -214,6 +214,8 @@ Takes the form ":port". If not provided, no admission controller is starte deepInspector = flags.Bool("deep-inspect", true, "Enables ingress object security deep inspector") dynamicConfigurationRetries = flags.Int("dynamic-configuration-retries", 15, "Number of times to retry failed dynamic configuration before failing to sync an ingress.") + + disableSyncEvents = flags.Bool("disable-sync-events", false, "Disables the creation of 'Sync' event resources") ) flags.StringVar(&nginx.MaxmindMirror, "maxmind-mirror", "", `Maxmind mirror url (example: http://geoip.local/databases.`) @@ -364,6 +366,7 @@ https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-g ValidationWebhookCertPath: *validationWebhookCert, ValidationWebhookKeyPath: *validationWebhookKey, InternalLoggerAddress: *internalLoggerAddress, + DisableSyncEvents: *disableSyncEvents, } if *apiserverHost != "" { diff --git a/test/e2e/settings/disable_sync_events.go b/test/e2e/settings/disable_sync_events.go new file mode 100644 index 000000000..7d1298087 --- /dev/null +++ b/test/e2e/settings/disable_sync_events.go @@ -0,0 +1,107 @@ +/* +Copyright 2022 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 ( + "context" + "fmt" + "strings" + + "github.com/onsi/ginkgo/v2" + "github.com/stretchr/testify/assert" + appsv1 "k8s.io/api/apps/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "k8s.io/ingress-nginx/test/e2e/framework" +) + +var _ = framework.IngressNginxDescribe("[Flag] disable-sync-events", func() { + f := framework.NewDefaultFramework("disable-sync-events") + + ginkgo.It("should create sync events (default)", func() { + host := "sync-events-default" + f.NewEchoDeployment(framework.WithDeploymentReplicas(1)) + + ing := framework.NewSingleIngressWithIngressClass(host, "/", host, f.Namespace, framework.EchoService, f.IngressClass, 80, nil) + ing = f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("server_name %v", host)) + }) + + events, err := f.KubeClientSet.CoreV1().Events(ing.Namespace).List(context.TODO(), metav1.ListOptions{FieldSelector: "reason=Sync,involvedObject.name=" + host}) + assert.Nil(ginkgo.GinkgoT(), err, "listing events") + + assert.NotEmpty(ginkgo.GinkgoT(), events.Items, "got events") + }) + + ginkgo.It("should create sync events", func() { + host := "disable-sync-events-false" + f.NewEchoDeployment(framework.WithDeploymentReplicas(1)) + + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--disable-sync-events=false") + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") + + ing := framework.NewSingleIngressWithIngressClass(host, "/", host, f.Namespace, framework.EchoService, f.IngressClass, 80, nil) + ing = f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("server_name %v", host)) + }) + + events, err := f.KubeClientSet.CoreV1().Events(ing.Namespace).List(context.TODO(), metav1.ListOptions{FieldSelector: "reason=Sync,involvedObject.name=" + host}) + assert.Nil(ginkgo.GinkgoT(), err, "listing events") + + assert.NotEmpty(ginkgo.GinkgoT(), events.Items, "got events") + }) + + ginkgo.It("should not create sync events", func() { + host := "disable-sync-events-true" + f.NewEchoDeployment(framework.WithDeploymentReplicas(1)) + + err := f.UpdateIngressControllerDeployment(func(deployment *appsv1.Deployment) error { + args := deployment.Spec.Template.Spec.Containers[0].Args + args = append(args, "--disable-sync-events=true") + deployment.Spec.Template.Spec.Containers[0].Args = args + _, err := f.KubeClientSet.AppsV1().Deployments(f.Namespace).Update(context.TODO(), deployment, metav1.UpdateOptions{}) + return err + }) + assert.Nil(ginkgo.GinkgoT(), err, "updating ingress controller deployment flags") + + ing := framework.NewSingleIngressWithIngressClass(host, "/", host, f.Namespace, framework.EchoService, f.IngressClass, 80, nil) + ing = f.EnsureIngress(ing) + + f.WaitForNginxServer(host, + func(server string) bool { + return strings.Contains(server, fmt.Sprintf("server_name %v", host)) + }) + + events, err := f.KubeClientSet.CoreV1().Events(ing.Namespace).List(context.TODO(), metav1.ListOptions{FieldSelector: "reason=Sync,involvedObject.name=" + host}) + assert.Nil(ginkgo.GinkgoT(), err, "listing events") + + assert.Empty(ginkgo.GinkgoT(), events.Items, "got events") + }) + +})