diff --git a/pkg/api/helper.go b/pkg/api/helper.go index b4fe0c42d92..d4bd0425db0 100644 --- a/pkg/api/helper.go +++ b/pkg/api/helper.go @@ -34,6 +34,8 @@ func init() { ReplicationController{}, ServiceList{}, Service{}, + MinionList{}, + Minion{}, Status{}, ) } diff --git a/pkg/api/types.go b/pkg/api/types.go index fdbd8eb90a7..a9d15a3f47b 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -175,6 +175,20 @@ type Endpoints struct { Endpoints []string } +// Information about a single Minion; the name of the minion according to etcd +// is in JSONBase.ID. +type Minion struct { + JSONBase `json:",inline" yaml:",inline"` + // Queried from cloud provider, if available. + HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"` +} + +// A list of minions. +type MinionList struct { + JSONBase `json:",inline" yaml:",inline"` + Minions []Minion `json:"minions,omitempty" yaml:"minions,omitempty"` +} + // Status is a return value for calls that don't return other objects. // Arguably, this could go in apiserver, but I'm including it here so clients needn't // import both. diff --git a/pkg/registry/minion_registry.go b/pkg/registry/minion_registry.go index 38f3c282631..99e46674646 100644 --- a/pkg/registry/minion_registry.go +++ b/pkg/registry/minion_registry.go @@ -17,11 +17,11 @@ limitations under the License. package registry import ( - "encoding/json" "fmt" "sort" "sync" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" ) @@ -71,7 +71,7 @@ type minionList struct { func (m *minionList) List() (currentMinions []string, err error) { m.lock.Lock() defer m.lock.Unlock() - // Make a copy to avoid any threading issues + // Convert from map to []string for minion := range m.minions { currentMinions = append(currentMinions, minion) } @@ -110,8 +110,20 @@ func MakeMinionRegistryStorage(m MinionRegistry) apiserver.RESTStorage { } } +func (storage *MinionRegistryStorage) toApiMinion(name string) api.Minion { + return api.Minion{JSONBase: api.JSONBase{ID: name}} +} + func (storage *MinionRegistryStorage) List(selector labels.Selector) (interface{}, error) { - return storage.registry.List() + nameList, err := storage.registry.List() + if err != nil { + return nil, err + } + var list api.MinionList + for _, name := range nameList { + list.Minions = append(list.Minions, storage.toApiMinion(name)) + } + return list, nil } func (storage *MinionRegistryStorage) Get(id string) (interface{}, error) { @@ -119,17 +131,17 @@ func (storage *MinionRegistryStorage) Get(id string) (interface{}, error) { if !exists { return nil, ErrDoesNotExist } - return id, err + return storage.toApiMinion(id), err } -func (storage *MinionRegistryStorage) Extract(body string) (interface{}, error) { - var minion string - err := json.Unmarshal([]byte(body), &minion) +func (storage *MinionRegistryStorage) Extract(body []byte) (interface{}, error) { + var minion api.Minion + err := api.DecodeInto(body, &minion) return minion, err } func (storage *MinionRegistryStorage) Create(minion interface{}) (<-chan interface{}, error) { - return apiserver.MakeAsync(func() interface{} { return minion }), storage.registry.Insert(minion.(string)) + return apiserver.MakeAsync(func() interface{} { return minion }), storage.registry.Insert(minion.(api.Minion).ID) } func (storage *MinionRegistryStorage) Update(minion interface{}) (<-chan interface{}, error) { @@ -144,5 +156,5 @@ func (storage *MinionRegistryStorage) Delete(id string) (<-chan interface{}, err if err != nil { return nil, err } - return apiserver.MakeAsync(func() interface{} { return apiserver.Status{Success: true} }), storage.registry.Delete(id) + return apiserver.MakeAsync(func() interface{} { return api.Status{Status: api.StatusSuccess} }), storage.registry.Delete(id) } diff --git a/pkg/registry/minion_registry_test.go b/pkg/registry/minion_registry_test.go index fbad64426f1..a46936f2289 100644 --- a/pkg/registry/minion_registry_test.go +++ b/pkg/registry/minion_registry_test.go @@ -13,12 +13,14 @@ 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 registry import ( "reflect" "testing" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" ) @@ -61,20 +63,20 @@ func TestMinionRegistryStorage(t *testing.T) { m := MakeMinionRegistry([]string{"foo", "bar"}) ms := MakeMinionRegistryStorage(m) - if obj, err := ms.Get("foo"); err != nil || obj.(string) != "foo" { + if obj, err := ms.Get("foo"); err != nil || obj.(api.Minion).ID != "foo" { t.Errorf("missing expected object") } - if obj, err := ms.Get("bar"); err != nil || obj.(string) != "bar" { + if obj, err := ms.Get("bar"); err != nil || obj.(api.Minion).ID != "bar" { t.Errorf("missing expected object") } if _, err := ms.Get("baz"); err != ErrDoesNotExist { t.Errorf("has unexpected object") } - if _, err := ms.Create("baz"); err != nil { + if _, err := ms.Create(api.Minion{JSONBase: api.JSONBase{ID: "baz"}}); err != nil { t.Errorf("insert failed") } - if obj, err := ms.Get("baz"); err != nil || obj.(string) != "baz" { + if obj, err := ms.Get("baz"); err != nil || obj.(api.Minion).ID != "baz" { t.Errorf("insert didn't actually insert") } @@ -92,7 +94,14 @@ func TestMinionRegistryStorage(t *testing.T) { if err != nil { t.Errorf("got error calling List") } - if !reflect.DeepEqual(list.([]string), []string{"baz", "foo"}) { + expect := []api.Minion{ + { + JSONBase: api.JSONBase{ID: "baz"}, + }, { + JSONBase: api.JSONBase{ID: "foo"}, + }, + } + if !reflect.DeepEqual(list.(api.MinionList).Minions, expect) { t.Errorf("Unexpected list value: %#v", list) } }