diff --git a/pkg/controller/daemon/controller.go b/pkg/controller/daemon/controller.go index 50a5293deaa70..83e4970ecdcf3 100644 --- a/pkg/controller/daemon/controller.go +++ b/pkg/controller/daemon/controller.go @@ -627,7 +627,7 @@ func (dsc *DaemonSetsController) syncDaemonSet(key string) error { everything := unversioned.LabelSelector{} if reflect.DeepEqual(ds.Spec.Selector, &everything) { - dsc.eventRecorder.Eventf(ds, api.EventTypeWarning, "SelectingAll", "This controller is selecting all pods. Skipping sync.") + dsc.eventRecorder.Eventf(ds, api.EventTypeWarning, "SelectingAll", "This daemon set is selecting all pods. A non-empty selector is required.") return nil } diff --git a/pkg/controller/deployment/deployment_controller.go b/pkg/controller/deployment/deployment_controller.go index c81df83793dd3..e02112dbaa8c3 100644 --- a/pkg/controller/deployment/deployment_controller.go +++ b/pkg/controller/deployment/deployment_controller.go @@ -426,6 +426,11 @@ func (dc *DeploymentController) syncDeployment(key string) error { } d := obj.(*extensions.Deployment) + everything := unversioned.LabelSelector{} + if reflect.DeepEqual(d.Spec.Selector, &everything) { + dc.eventRecorder.Eventf(d, api.EventTypeWarning, "SelectingAll", "This deployment is selecting all pods. A non-empty selector is required.") + return nil + } if d.Spec.Paused { // TODO: Implement scaling for paused deployments. diff --git a/pkg/controller/deployment/deployment_controller_test.go b/pkg/controller/deployment/deployment_controller_test.go index 648e7e633e6e3..dcab9a73b70c8 100644 --- a/pkg/controller/deployment/deployment_controller_test.go +++ b/pkg/controller/deployment/deployment_controller_test.go @@ -789,3 +789,28 @@ func TestSyncDeploymentCreatesReplicaSet(t *testing.T) { f.run(getKey(d, t)) } + +// issue: https://github.com/kubernetes/kubernetes/issues/23218 +func TestDeploymentController_dontSyncDeploymentsWithEmptyPodSelector(t *testing.T) { + fake := &fake.Clientset{} + controller := NewDeploymentController(fake, controller.NoResyncPeriodFunc) + + controller.eventRecorder = &record.FakeRecorder{} + controller.rsStoreSynced = alwaysReady + controller.podStoreSynced = alwaysReady + + d := newDeployment(1, nil) + empty := unversioned.LabelSelector{} + d.Spec.Selector = &empty + controller.dStore.Store.Add(d) + // We expect the deployment controller to not take action here since it's configuration + // is invalid, even though no replicasets exist that match it's selector. + controller.syncDeployment(fmt.Sprintf("%s/%s", d.ObjectMeta.Namespace, d.ObjectMeta.Name)) + if len(fake.Actions()) == 0 { + return + } + for _, action := range fake.Actions() { + t.Logf("unexpected action: %#v", action) + } + t.Errorf("expected deployment controller to not take action") +}