diff --git a/pkg/api/types.go b/pkg/api/types.go index 385f1b2b22f..63adaf38c43 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -326,6 +326,7 @@ func (*ReplicationControllerList) IsAnAPIObject() {} type ReplicationController struct { JSONBase `json:",inline" yaml:",inline"` DesiredState ReplicationControllerState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"` + CurrentState ReplicationControllerState `json:"currentState,omitempty" yaml:"currentState,omitempty"` Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` } diff --git a/pkg/api/v1beta1/types.go b/pkg/api/v1beta1/types.go index f3f02480dda..d07128f3481 100644 --- a/pkg/api/v1beta1/types.go +++ b/pkg/api/v1beta1/types.go @@ -339,6 +339,7 @@ func (*ReplicationControllerList) IsAnAPIObject() {} type ReplicationController struct { JSONBase `json:",inline" yaml:",inline"` DesiredState ReplicationControllerState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"` + CurrentState ReplicationControllerState `json:"currentState,omitempty" yaml:"currentState,omitempty"` Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"` } diff --git a/pkg/registry/controller/rest.go b/pkg/registry/controller/rest.go index d7e6f19f3db..d494c7791af 100644 --- a/pkg/registry/controller/rest.go +++ b/pkg/registry/controller/rest.go @@ -92,6 +92,7 @@ func (rs *REST) Get(id string) (runtime.Object, error) { if err != nil { return nil, err } + rs.fillCurrentState(controller) return controller, err } @@ -104,6 +105,7 @@ func (rs *REST) List(selector labels.Selector) (runtime.Object, error) { filtered := []api.ReplicationController{} for _, controller := range controllers.Items { if selector.Matches(labels.Set(controller.Labels)) { + rs.fillCurrentState(&controller) filtered = append(filtered, controller) } } @@ -147,7 +149,11 @@ func (rs *REST) Watch(label, field labels.Selector, resourceVersion uint64) (wat } return watch.Filter(incoming, func(e watch.Event) (watch.Event, bool) { repController := e.Object.(*api.ReplicationController) - return e, label.Matches(labels.Set(repController.Labels)) + match := label.Matches(labels.Set(repController.Labels)) + if match { + rs.fillCurrentState(repController) + } + return e, match }), nil } @@ -164,3 +170,15 @@ func (rs *REST) waitForController(ctrl *api.ReplicationController) (runtime.Obje } return ctrl, nil } + +func (rs *REST) fillCurrentState(ctrl *api.ReplicationController) error { + if rs.podLister == nil { + return nil + } + list, err := rs.podLister.ListPods(labels.Set(ctrl.DesiredState.ReplicaSelector).AsSelector()) + if err != nil { + return err + } + ctrl.CurrentState.Replicas = len(list.Items) + return nil +} diff --git a/pkg/registry/controller/rest_test.go b/pkg/registry/controller/rest_test.go index 2332a1eecaa..d2f66810aa6 100644 --- a/pkg/registry/controller/rest_test.go +++ b/pkg/registry/controller/rest_test.go @@ -316,3 +316,44 @@ func TestControllerStorageValidatesUpdate(t *testing.T) { } } } + +type fakePodLister struct { + e error + l api.PodList + s labels.Selector +} + +func (f *fakePodLister) ListPods(s labels.Selector) (*api.PodList, error) { + f.s = s + return &f.l, f.e +} + +func TestFillCurrentState(t *testing.T) { + fakeLister := fakePodLister{ + l: api.PodList{ + Items: []api.Pod{ + {JSONBase: api.JSONBase{ID: "foo"}}, + {JSONBase: api.JSONBase{ID: "bar"}}, + }, + }, + } + mockRegistry := registrytest.ControllerRegistry{} + storage := REST{ + registry: &mockRegistry, + podLister: &fakeLister, + } + controller := api.ReplicationController{ + DesiredState: api.ReplicationControllerState{ + ReplicaSelector: map[string]string{ + "foo": "bar", + }, + }, + } + storage.fillCurrentState(&controller) + if controller.CurrentState.Replicas != 2 { + t.Errorf("expected 2, got: %d", controller.CurrentState.Replicas) + } + if !reflect.DeepEqual(fakeLister.s, labels.Set(controller.DesiredState.ReplicaSelector).AsSelector()) { + t.Errorf("unexpected output: %#v %#v", labels.Set(controller.DesiredState.ReplicaSelector).AsSelector(), fakeLister.s) + } +}