Rename client Minions->Nodes, select the correct path for v1beta3

Replaces the client public interface but leaves old references to "minions"
for a later refactor.  Selects the path "nodes" for v1beta3 and "minions"
for older versions.
pull/6/head
Clayton Coleman 2014-12-08 00:56:43 -05:00
parent d0087dfe62
commit d1d7505272
15 changed files with 103 additions and 62 deletions

View File

@ -126,6 +126,10 @@ kube::log::status "Testing kubectl(minions)"
"${kube_cmd[@]}" get minions "${kube_flags[@]}" "${kube_cmd[@]}" get minions "${kube_flags[@]}"
"${kube_cmd[@]}" get minions 127.0.0.1 "${kube_flags[@]}" "${kube_cmd[@]}" get minions 127.0.0.1 "${kube_flags[@]}"
kube::log::status "Testing kubectl(nodes)"
"${kube_cmd[@]}" get nodes "${kube_flags[@]}"
"${kube_cmd[@]}" describe nodes 127.0.0.1 "${kube_flags[@]}"
kube::log::status "TEST PASSED" kube::log::status "TEST PASSED"
# Start proxy # Start proxy

View File

@ -141,7 +141,7 @@ func TestMinionListConversionToNew(t *testing.T) {
oldMinion := func(id string) current.Minion { oldMinion := func(id string) current.Minion {
return current.Minion{TypeMeta: current.TypeMeta{ID: id}} return current.Minion{TypeMeta: current.TypeMeta{ID: id}}
} }
newMinion := func(id string) newer.Node { newNode := func(id string) newer.Node {
return newer.Node{ObjectMeta: newer.ObjectMeta{Name: id}} return newer.Node{ObjectMeta: newer.ObjectMeta{Name: id}}
} }
oldMinions := []current.Minion{ oldMinions := []current.Minion{
@ -149,8 +149,8 @@ func TestMinionListConversionToNew(t *testing.T) {
oldMinion("bar"), oldMinion("bar"),
} }
newMinions := []newer.Node{ newMinions := []newer.Node{
newMinion("foo"), newNode("foo"),
newMinion("bar"), newNode("bar"),
} }
table := []struct { table := []struct {
@ -188,7 +188,7 @@ func TestMinionListConversionToOld(t *testing.T) {
oldMinion := func(id string) current.Minion { oldMinion := func(id string) current.Minion {
return current.Minion{TypeMeta: current.TypeMeta{ID: id}} return current.Minion{TypeMeta: current.TypeMeta{ID: id}}
} }
newMinion := func(id string) newer.Node { newNode := func(id string) newer.Node {
return newer.Node{ObjectMeta: newer.ObjectMeta{Name: id}} return newer.Node{ObjectMeta: newer.ObjectMeta{Name: id}}
} }
oldMinions := []current.Minion{ oldMinions := []current.Minion{
@ -196,8 +196,8 @@ func TestMinionListConversionToOld(t *testing.T) {
oldMinion("bar"), oldMinion("bar"),
} }
newMinions := []newer.Node{ newMinions := []newer.Node{
newMinion("foo"), newNode("foo"),
newMinion("bar"), newNode("bar"),
} }
newML := &newer.NodeList{Items: newMinions} newML := &newer.NodeList{Items: newMinions}

View File

@ -32,7 +32,7 @@ type Interface interface {
ServicesNamespacer ServicesNamespacer
EndpointsNamespacer EndpointsNamespacer
VersionInterface VersionInterface
MinionsInterface NodesInterface
EventNamespacer EventNamespacer
} }
@ -40,8 +40,8 @@ func (c *Client) ReplicationControllers(namespace string) ReplicationControllerI
return newReplicationControllers(c, namespace) return newReplicationControllers(c, namespace)
} }
func (c *Client) Minions() MinionInterface { func (c *Client) Nodes() NodeInterface {
return newMinions(c) return newNodes(c, c.preV1Beta3)
} }
func (c *Client) Events(namespace string) EventInterface { func (c *Client) Events(namespace string) EventInterface {
@ -75,6 +75,9 @@ type APIStatus interface {
// Client is the implementation of a Kubernetes client. // Client is the implementation of a Kubernetes client.
type Client struct { type Client struct {
*RESTClient *RESTClient
// preV1Beta3 is true for v1beta1 and v1beta2
preV1Beta3 bool
} }
// ServerVersion retrieves and parses the server's version. // ServerVersion retrieves and parses the server's version.

View File

@ -28,6 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/resources" "github.com/GoogleCloudPlatform/kubernetes/pkg/resources"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -59,6 +60,7 @@ type testClient struct {
Response Response Response Response
Error bool Error bool
Created bool Created bool
Version string
server *httptest.Server server *httptest.Server
handler *util.FakeHandler handler *util.FakeHandler
// For query args, an optional function to validate the contents // For query args, an optional function to validate the contents
@ -77,9 +79,13 @@ func (c *testClient) Setup() *testClient {
} }
c.server = httptest.NewServer(c.handler) c.server = httptest.NewServer(c.handler)
if c.Client == nil { if c.Client == nil {
version := c.Version
if len(version) == 0 {
version = testapi.Version()
}
c.Client = NewOrDie(&Config{ c.Client = NewOrDie(&Config{
Host: c.server.URL, Host: c.server.URL,
Version: "v1beta1", Version: version,
}) })
} }
c.QueryValidator = map[string]func(string, string) bool{} c.QueryValidator = map[string]func(string, string) bool{}
@ -606,7 +612,7 @@ func TestListMinions(t *testing.T) {
Request: testRequest{Method: "GET", Path: "/minions"}, Request: testRequest{Method: "GET", Path: "/minions"},
Response: Response{StatusCode: 200, Body: &api.NodeList{ListMeta: api.ListMeta{ResourceVersion: "1"}}}, Response: Response{StatusCode: 200, Body: &api.NodeList{ListMeta: api.ListMeta{ResourceVersion: "1"}}},
} }
response, err := c.Setup().Minions().List() response, err := c.Setup().Nodes().List()
c.Validate(t, response, err) c.Validate(t, response, err)
} }
@ -615,7 +621,7 @@ func TestGetMinion(t *testing.T) {
Request: testRequest{Method: "GET", Path: "/minions/1"}, Request: testRequest{Method: "GET", Path: "/minions/1"},
Response: Response{StatusCode: 200, Body: &api.Node{ObjectMeta: api.ObjectMeta{Name: "minion-1"}}}, Response: Response{StatusCode: 200, Body: &api.Node{ObjectMeta: api.ObjectMeta{Name: "minion-1"}}},
} }
response, err := c.Setup().Minions().Get("1") response, err := c.Setup().Nodes().Get("1")
c.Validate(t, response, err) c.Validate(t, response, err)
} }
@ -641,7 +647,7 @@ func TestCreateMinion(t *testing.T) {
Body: requestMinion, Body: requestMinion,
}, },
} }
receivedMinion, err := c.Setup().Minions().Create(requestMinion) receivedMinion, err := c.Setup().Nodes().Create(requestMinion)
c.Validate(t, receivedMinion, err) c.Validate(t, receivedMinion, err)
} }
@ -650,6 +656,17 @@ func TestDeleteMinion(t *testing.T) {
Request: testRequest{Method: "DELETE", Path: "/minions/foo"}, Request: testRequest{Method: "DELETE", Path: "/minions/foo"},
Response: Response{StatusCode: 200}, Response: Response{StatusCode: 200},
} }
err := c.Setup().Minions().Delete("foo") err := c.Setup().Nodes().Delete("foo")
c.Validate(t, nil, err)
}
func TestNewMinionPath(t *testing.T) {
c := &testClient{
Request: testRequest{Method: "DELETE", Path: "/nodes/foo"},
Response: Response{StatusCode: 200},
}
cl := c.Setup()
cl.preV1Beta3 = false
err := cl.Nodes().Delete("foo")
c.Validate(t, nil, err) c.Validate(t, nil, err)
} }

View File

@ -49,8 +49,8 @@ func (c *Fake) ReplicationControllers(namespace string) ReplicationControllerInt
return &FakeReplicationControllers{Fake: c, Namespace: namespace} return &FakeReplicationControllers{Fake: c, Namespace: namespace}
} }
func (c *Fake) Minions() MinionInterface { func (c *Fake) Nodes() NodeInterface {
return &FakeMinions{Fake: c} return &FakeNodes{Fake: c}
} }
func (c *Fake) Events(namespace string) EventInterface { func (c *Fake) Events(namespace string) EventInterface {

View File

@ -18,30 +18,36 @@ package client
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
) )
// FakeMinions implements MinionInterface. Meant to be embedded into a struct to get a default // FakeNodes implements MinionInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier. // implementation. This makes faking out just the method you want to test easier.
type FakeMinions struct { type FakeNodes struct {
Fake *Fake Fake *Fake
} }
func (c *FakeMinions) Get(name string) (*api.Node, error) { func (c *FakeNodes) Get(name string) (*api.Node, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-minion", Value: name}) c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-minion", Value: name})
return &api.Node{}, nil for i := range c.Fake.MinionsList.Items {
if c.Fake.MinionsList.Items[i].Name == name {
return &c.Fake.MinionsList.Items[i], nil
}
}
return nil, errors.NewNotFound("Minions", name)
} }
func (c *FakeMinions) List() (*api.NodeList, error) { func (c *FakeNodes) List() (*api.NodeList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-minions", Value: nil}) c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-minions", Value: nil})
return &c.Fake.MinionsList, nil return &c.Fake.MinionsList, nil
} }
func (c *FakeMinions) Create(minion *api.Node) (*api.Node, error) { func (c *FakeNodes) Create(minion *api.Node) (*api.Node, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-minion", Value: minion}) c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-minion", Value: minion})
return &api.Node{}, nil return &api.Node{}, nil
} }
func (c *FakeMinions) Delete(id string) error { func (c *FakeNodes) Delete(id string) error {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-minion", Value: id}) c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-minion", Value: id})
return nil return nil
} }

View File

@ -87,7 +87,9 @@ func New(c *Config) (*Client, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &Client{client}, nil version := defaultVersionFor(&config)
isPreV1Beta3 := (version == "v1beta1" || version == "v1beta2")
return &Client{client, isPreV1Beta3}, nil
} }
// NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized. // NewOrDie creates a Kubernetes client and panics if the provided API version is not recognized.

View File

@ -18,49 +18,58 @@ package client
import "github.com/GoogleCloudPlatform/kubernetes/pkg/api" import "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
type MinionsInterface interface { type NodesInterface interface {
Minions() MinionInterface Nodes() NodeInterface
} }
type MinionInterface interface { type NodeInterface interface {
Get(id string) (result *api.Node, err error) Get(id string) (result *api.Node, err error)
Create(minion *api.Node) (*api.Node, error) Create(minion *api.Node) (*api.Node, error)
List() (*api.NodeList, error) List() (*api.NodeList, error)
Delete(id string) error Delete(id string) error
} }
// minions implements Minions interface // nodes implements NodesInterface
type minions struct { type nodes struct {
r *Client r *Client
preV1Beta3 bool
} }
// newMinions returns a minions // newNodes returns a nodes object. Uses "minions" as the
func newMinions(c *Client) *minions { // URL resource name for v1beta1 and v1beta2.
return &minions{c} func newNodes(c *Client, isPreV1Beta3 bool) *nodes {
return &nodes{c, isPreV1Beta3}
}
func (c *nodes) resourceName() string {
if c.preV1Beta3 {
return "minions"
}
return "nodes"
} }
// Create creates a new minion. // Create creates a new minion.
func (c *minions) Create(minion *api.Node) (*api.Node, error) { func (c *nodes) Create(minion *api.Node) (*api.Node, error) {
result := &api.Node{} result := &api.Node{}
err := c.r.Post().Path("minions").Body(minion).Do().Into(result) err := c.r.Post().Path(c.resourceName()).Body(minion).Do().Into(result)
return result, err return result, err
} }
// List lists all the minions in the cluster. // List lists all the nodes in the cluster.
func (c *minions) List() (*api.NodeList, error) { func (c *nodes) List() (*api.NodeList, error) {
result := &api.NodeList{} result := &api.NodeList{}
err := c.r.Get().Path("minions").Do().Into(result) err := c.r.Get().Path(c.resourceName()).Do().Into(result)
return result, err return result, err
} }
// Get gets an existing minion // Get gets an existing minion
func (c *minions) Get(id string) (*api.Node, error) { func (c *nodes) Get(id string) (*api.Node, error) {
result := &api.Node{} result := &api.Node{}
err := c.r.Get().Path("minions").Path(id).Do().Into(result) err := c.r.Get().Path(c.resourceName()).Path(id).Do().Into(result)
return result, err return result, err
} }
// Delete deletes an existing minion. // Delete deletes an existing minion.
func (c *minions) Delete(id string) error { func (c *nodes) Delete(id string) error {
return c.r.Delete().Path("minions").Path(id).Do().Error() return c.r.Delete().Path(c.resourceName()).Path(id).Do().Error()
} }

View File

@ -73,7 +73,7 @@ func (s *MinionController) SyncStatic(period time.Duration) error {
if registered.Has(minionID) { if registered.Has(minionID) {
continue continue
} }
_, err := s.kubeClient.Minions().Create(&api.Node{ _, err := s.kubeClient.Nodes().Create(&api.Node{
ObjectMeta: api.ObjectMeta{Name: minionID}, ObjectMeta: api.ObjectMeta{Name: minionID},
Spec: api.NodeSpec{ Spec: api.NodeSpec{
Capacity: s.staticResources.Capacity, Capacity: s.staticResources.Capacity,
@ -97,7 +97,7 @@ func (s *MinionController) SyncCloud() error {
if err != nil { if err != nil {
return err return err
} }
minions, err := s.kubeClient.Minions().List() minions, err := s.kubeClient.Nodes().List()
if err != nil { if err != nil {
return err return err
} }
@ -110,7 +110,7 @@ func (s *MinionController) SyncCloud() error {
for _, minion := range matches.Items { for _, minion := range matches.Items {
if _, ok := minionMap[minion.Name]; !ok { if _, ok := minionMap[minion.Name]; !ok {
glog.Infof("Create minion in registry: %s", minion.Name) glog.Infof("Create minion in registry: %s", minion.Name)
_, err = s.kubeClient.Minions().Create(&minion) _, err = s.kubeClient.Nodes().Create(&minion)
if err != nil { if err != nil {
glog.Errorf("Create minion error: %s", minion.Name) glog.Errorf("Create minion error: %s", minion.Name)
} }
@ -120,7 +120,7 @@ func (s *MinionController) SyncCloud() error {
for minionID := range minionMap { for minionID := range minionMap {
glog.Infof("Delete minion from registry: %s", minionID) glog.Infof("Delete minion from registry: %s", minionID)
err = s.kubeClient.Minions().Delete(minionID) err = s.kubeClient.Nodes().Delete(minionID)
if err != nil { if err != nil {
glog.Errorf("Delete minion error: %s", minionID) glog.Errorf("Delete minion error: %s", minionID)
} }

View File

@ -26,13 +26,13 @@ import (
fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake" fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake"
) )
func newMinion(name string) *api.Node { func newNode(name string) *api.Node {
return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}} return &api.Node{ObjectMeta: api.ObjectMeta{Name: name}}
} }
type FakeMinionHandler struct { type FakeMinionHandler struct {
client.Fake client.Fake
client.FakeMinions client.FakeNodes
// Input: Hooks determine if request is valid or not // Input: Hooks determine if request is valid or not
CreateHook func(*FakeMinionHandler, *api.Node) bool CreateHook func(*FakeMinionHandler, *api.Node) bool
@ -44,7 +44,7 @@ type FakeMinionHandler struct {
RequestCount int RequestCount int
} }
func (c *FakeMinionHandler) Minions() client.MinionInterface { func (c *FakeMinionHandler) Nodes() client.NodeInterface {
return c return c
} }
@ -75,7 +75,7 @@ func (m *FakeMinionHandler) List() (*api.NodeList, error) {
} }
func (m *FakeMinionHandler) Delete(id string) error { func (m *FakeMinionHandler) Delete(id string) error {
m.DeletedMinions = append(m.DeletedMinions, newMinion(id)) m.DeletedMinions = append(m.DeletedMinions, newNode(id))
m.RequestCount++ m.RequestCount++
return nil return nil
} }
@ -129,7 +129,7 @@ func TestSyncStaticCreateMinionWithError(t *testing.T) {
func TestSyncCloudCreateMinion(t *testing.T) { func TestSyncCloudCreateMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{ fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Node{newMinion("minion0")}, Existing: []*api.Node{newNode("minion0")},
} }
instances := []string{"minion0", "minion1"} instances := []string{"minion0", "minion1"}
fakeCloud := fake_cloud.FakeCloud{ fakeCloud := fake_cloud.FakeCloud{
@ -153,7 +153,7 @@ func TestSyncCloudCreateMinion(t *testing.T) {
func TestSyncCloudDeleteMinion(t *testing.T) { func TestSyncCloudDeleteMinion(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{ fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Node{newMinion("minion0"), newMinion("minion1")}, Existing: []*api.Node{newNode("minion0"), newNode("minion1")},
} }
instances := []string{"minion0"} instances := []string{"minion0"}
fakeCloud := fake_cloud.FakeCloud{ fakeCloud := fake_cloud.FakeCloud{
@ -177,7 +177,7 @@ func TestSyncCloudDeleteMinion(t *testing.T) {
func TestSyncCloudRegexp(t *testing.T) { func TestSyncCloudRegexp(t *testing.T) {
fakeMinionHandler := &FakeMinionHandler{ fakeMinionHandler := &FakeMinionHandler{
Existing: []*api.Node{newMinion("minion0")}, Existing: []*api.Node{newNode("minion0")},
} }
instances := []string{"minion0", "minion1", "node0"} instances := []string{"minion0", "minion1", "node0"}
fakeCloud := fake_cloud.FakeCloud{ fakeCloud := fake_cloud.FakeCloud{

View File

@ -176,7 +176,7 @@ type MinionDescriber struct {
} }
func (d *MinionDescriber) Describe(namespace, name string) (string, error) { func (d *MinionDescriber) Describe(namespace, name string) (string, error) {
mc := d.Minions() mc := d.Nodes()
minion, err := mc.Get(name) minion, err := mc.Get(name)
if err != nil { if err != nil {
return "", err return "", err

View File

@ -316,7 +316,7 @@ func (m *Master) init(c *Config) {
PodCache: podCache, PodCache: podCache,
PodInfoGetter: c.KubeletClient, PodInfoGetter: c.KubeletClient,
Registry: m.podRegistry, Registry: m.podRegistry,
Minions: m.client.Minions(), Nodes: m.client.Nodes(),
}), }),
"replicationControllers": controller.NewREST(m.controllerRegistry, m.podRegistry), "replicationControllers": controller.NewREST(m.controllerRegistry, m.podRegistry),
"services": service.NewREST(m.serviceRegistry, c.Cloud, m.minionRegistry, m.portalNet), "services": service.NewREST(m.serviceRegistry, c.Cloud, m.minionRegistry, m.portalNet),

View File

@ -60,7 +60,7 @@ type REST struct {
podInfoGetter client.PodInfoGetter podInfoGetter client.PodInfoGetter
podPollPeriod time.Duration podPollPeriod time.Duration
registry Registry registry Registry
minions client.MinionInterface nodes client.NodeInterface
ipCache ipCache ipCache ipCache
clock clock clock clock
} }
@ -70,7 +70,7 @@ type RESTConfig struct {
PodCache client.PodInfoGetter PodCache client.PodInfoGetter
PodInfoGetter client.PodInfoGetter PodInfoGetter client.PodInfoGetter
Registry Registry Registry Registry
Minions client.MinionInterface Nodes client.NodeInterface
} }
// NewREST returns a new REST. // NewREST returns a new REST.
@ -81,7 +81,7 @@ func NewREST(config *RESTConfig) *REST {
podInfoGetter: config.PodInfoGetter, podInfoGetter: config.PodInfoGetter,
podPollPeriod: time.Second * 10, podPollPeriod: time.Second * 10,
registry: config.Registry, registry: config.Registry,
minions: config.Minions, nodes: config.Nodes,
ipCache: ipCache{}, ipCache: ipCache{},
clock: realClock{}, clock: realClock{},
} }
@ -125,7 +125,7 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
} }
if rs.podCache != nil || rs.podInfoGetter != nil { if rs.podCache != nil || rs.podInfoGetter != nil {
rs.fillPodInfo(pod) rs.fillPodInfo(pod)
status, err := getPodStatus(pod, rs.minions) status, err := getPodStatus(pod, rs.nodes)
if err != nil { if err != nil {
return pod, err return pod, err
} }
@ -169,7 +169,7 @@ func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Obj
for i := range pods.Items { for i := range pods.Items {
pod := &pods.Items[i] pod := &pods.Items[i]
rs.fillPodInfo(pod) rs.fillPodInfo(pod)
status, err := getPodStatus(pod, rs.minions) status, err := getPodStatus(pod, rs.nodes)
if err != nil { if err != nil {
return pod, err return pod, err
} }

View File

@ -499,7 +499,7 @@ func TestMakePodStatus(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
if status, err := getPodStatus(test.pod, fakeClient.Minions()); status != test.status { if status, err := getPodStatus(test.pod, fakeClient.Nodes()); status != test.status {
t.Errorf("In test %s, expected %v, got %v", test.test, test.status, status) t.Errorf("In test %s, expected %v, got %v", test.test, test.status, status)
if err != nil { if err != nil {
t.Errorf("In test %s, unexpected error: %v", test.test, err) t.Errorf("In test %s, unexpected error: %v", test.test, err)

View File

@ -48,7 +48,7 @@ type ClientNodeInfo struct {
} }
func (nodes ClientNodeInfo) GetNodeInfo(nodeID string) (*api.Node, error) { func (nodes ClientNodeInfo) GetNodeInfo(nodeID string) (*api.Node, error) {
return nodes.Minions().Get(nodeID) return nodes.Nodes().Get(nodeID)
} }
func isVolumeConflict(volume api.Volume, pod *api.Pod) bool { func isVolumeConflict(volume api.Volume, pod *api.Pod) bool {