Merge pull request #1937 from derekwaynecarr/update_client_interface

Rework client.Interface
This commit is contained in:
Daniel Smith 2014-10-24 16:26:16 -07:00
commit dc7e3d6601
35 changed files with 1053 additions and 574 deletions

View File

@ -40,9 +40,8 @@ var (
func waitForPodRunning(c *client.Client, id string) { func waitForPodRunning(c *client.Client, id string) {
for { for {
ctx := api.NewContext()
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
pod, err := c.GetPod(ctx, id) pod, err := c.Pods(api.NamespaceDefault).Get(id)
if err != nil { if err != nil {
glog.Warningf("Get pod failed: %v", err) glog.Warningf("Get pod failed: %v", err)
continue continue
@ -100,26 +99,26 @@ func loadClientOrDie() *client.Client {
} }
func TestPodUpdate(c *client.Client) bool { func TestPodUpdate(c *client.Client) bool {
ctx := api.NewContext() podClient := c.Pods(api.NamespaceDefault)
pod := loadPodOrDie("./api/examples/pod.json") pod := loadPodOrDie("./api/examples/pod.json")
value := strconv.Itoa(time.Now().Nanosecond()) value := strconv.Itoa(time.Now().Nanosecond())
pod.Labels["time"] = value pod.Labels["time"] = value
_, err := c.CreatePod(ctx, pod) _, err := podClient.Create(pod)
if err != nil { if err != nil {
glog.Errorf("Failed to create pod: %v", err) glog.Errorf("Failed to create pod: %v", err)
return false return false
} }
defer c.DeletePod(ctx, pod.Name) defer podClient.Delete(pod.Name)
waitForPodRunning(c, pod.Name) waitForPodRunning(c, pod.Name)
pods, err := c.ListPods(ctx, labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) pods, err := podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
if len(pods.Items) != 1 { if len(pods.Items) != 1 {
glog.Errorf("Failed to find the correct pod") glog.Errorf("Failed to find the correct pod")
return false return false
} }
podOut, err := c.GetPod(ctx, pod.Name) podOut, err := podClient.Get(pod.Name)
if err != nil { if err != nil {
glog.Errorf("Failed to get pod: %v", err) glog.Errorf("Failed to get pod: %v", err)
return false return false
@ -128,13 +127,13 @@ func TestPodUpdate(c *client.Client) bool {
pod.Labels["time"] = value pod.Labels["time"] = value
pod.ResourceVersion = podOut.ResourceVersion pod.ResourceVersion = podOut.ResourceVersion
pod.DesiredState.Manifest.UUID = podOut.DesiredState.Manifest.UUID pod.DesiredState.Manifest.UUID = podOut.DesiredState.Manifest.UUID
pod, err = c.UpdatePod(ctx, pod) pod, err = podClient.Update(pod)
if err != nil { if err != nil {
glog.Errorf("Failed to update pod: %v", err) glog.Errorf("Failed to update pod: %v", err)
return false return false
} }
waitForPodRunning(c, pod.Name) waitForPodRunning(c, pod.Name)
pods, err = c.ListPods(ctx, labels.SelectorFromSet(labels.Set(map[string]string{"time": value}))) pods, err = podClient.List(labels.SelectorFromSet(labels.Set(map[string]string{"time": value})))
if len(pods.Items) != 1 { if len(pods.Items) != 1 {
glog.Errorf("Failed to find the correct pod after update.") glog.Errorf("Failed to find the correct pod after update.")
return false return false

View File

@ -201,9 +201,9 @@ func podsOnMinions(c *client.Client, pods api.PodList) wait.ConditionFunc {
} }
} }
func endpointsSet(c *client.Client, ctx api.Context, serviceID string, endpointCount int) wait.ConditionFunc { func endpointsSet(c *client.Client, serviceNamespace, serviceID string, endpointCount int) wait.ConditionFunc {
return func() (bool, error) { return func() (bool, error) {
endpoints, err := c.GetEndpoints(ctx, serviceID) endpoints, err := c.Endpoints(serviceNamespace).Get(serviceID)
if err != nil { if err != nil {
return false, nil return false, nil
} }
@ -211,15 +211,14 @@ func endpointsSet(c *client.Client, ctx api.Context, serviceID string, endpointC
} }
} }
func podExists(c *client.Client, ctx api.Context, podID string) wait.ConditionFunc { func podExists(c *client.Client, podNamespace string, podID string) wait.ConditionFunc {
return func() (bool, error) { return func() (bool, error) {
_, err := c.GetPod(ctx, podID) _, err := c.Pods(podNamespace).Get(podID)
return err == nil, nil return err == nil, nil
} }
} }
func runReplicationControllerTest(c *client.Client) { func runReplicationControllerTest(c *client.Client) {
ctx := api.NewDefaultContext()
data, err := ioutil.ReadFile("api/examples/controller.json") data, err := ioutil.ReadFile("api/examples/controller.json")
if err != nil { if err != nil {
glog.Fatalf("Unexpected error: %#v", err) glog.Fatalf("Unexpected error: %#v", err)
@ -230,7 +229,7 @@ func runReplicationControllerTest(c *client.Client) {
} }
glog.Infof("Creating replication controllers") glog.Infof("Creating replication controllers")
if _, err := c.CreateReplicationController(ctx, &controllerRequest); err != nil { if _, err := c.ReplicationControllers(api.NamespaceDefault).Create(&controllerRequest); err != nil {
glog.Fatalf("Unexpected error: %#v", err) glog.Fatalf("Unexpected error: %#v", err)
} }
glog.Infof("Done creating replication controllers") glog.Infof("Done creating replication controllers")
@ -241,7 +240,7 @@ func runReplicationControllerTest(c *client.Client) {
} }
// wait for minions to indicate they have info about the desired pods // wait for minions to indicate they have info about the desired pods
pods, err := c.ListPods(ctx, labels.Set(controllerRequest.DesiredState.ReplicaSelector).AsSelector()) pods, err := c.Pods(api.NamespaceDefault).List(labels.Set(controllerRequest.DesiredState.ReplicaSelector).AsSelector())
if err != nil { if err != nil {
glog.Fatalf("FAILED: unable to get pods to list: %v", err) glog.Fatalf("FAILED: unable to get pods to list: %v", err)
} }
@ -333,7 +332,6 @@ func runAtomicPutTest(c *client.Client) {
} }
func runServiceTest(client *client.Client) { func runServiceTest(client *client.Client) {
ctx := api.NewDefaultContext()
pod := api.Pod{ pod := api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
@ -359,11 +357,11 @@ func runServiceTest(client *client.Client) {
PodIP: "1.2.3.4", PodIP: "1.2.3.4",
}, },
} }
_, err := client.CreatePod(ctx, &pod) _, err := client.Pods(api.NamespaceDefault).Create(&pod)
if err != nil { if err != nil {
glog.Fatalf("Failed to create pod: %v, %v", pod, err) glog.Fatalf("Failed to create pod: %v, %v", pod, err)
} }
if err := wait.Poll(time.Second, time.Second*20, podExists(client, ctx, pod.Name)); err != nil { if err := wait.Poll(time.Second, time.Second*20, podExists(client, pod.Namespace, pod.Name)); err != nil {
glog.Fatalf("FAILED: pod never started running %v", err) glog.Fatalf("FAILED: pod never started running %v", err)
} }
svc1 := api.Service{ svc1 := api.Service{
@ -373,11 +371,11 @@ func runServiceTest(client *client.Client) {
}, },
Port: 8080, Port: 8080,
} }
_, err = client.CreateService(ctx, &svc1) _, err = client.Services(api.NamespaceDefault).Create(&svc1)
if err != nil { if err != nil {
glog.Fatalf("Failed to create service: %v, %v", svc1, err) glog.Fatalf("Failed to create service: %v, %v", svc1, err)
} }
if err := wait.Poll(time.Second, time.Second*20, endpointsSet(client, ctx, svc1.Name, 1)); err != nil { if err := wait.Poll(time.Second, time.Second*20, endpointsSet(client, svc1.Namespace, svc1.Name, 1)); err != nil {
glog.Fatalf("FAILED: unexpected endpoints: %v", err) glog.Fatalf("FAILED: unexpected endpoints: %v", err)
} }
// A second service with the same port. // A second service with the same port.
@ -388,11 +386,11 @@ func runServiceTest(client *client.Client) {
}, },
Port: 8080, Port: 8080,
} }
_, err = client.CreateService(ctx, &svc2) _, err = client.Services(api.NamespaceDefault).Create(&svc2)
if err != nil { if err != nil {
glog.Fatalf("Failed to create service: %v, %v", svc2, err) glog.Fatalf("Failed to create service: %v, %v", svc2, err)
} }
if err := wait.Poll(time.Second, time.Second*20, endpointsSet(client, ctx, svc2.Name, 1)); err != nil { if err := wait.Poll(time.Second, time.Second*20, endpointsSet(client, svc2.Namespace, svc2.Name, 1)); err != nil {
glog.Fatalf("FAILED: unexpected endpoints: %v", err) glog.Fatalf("FAILED: unexpected endpoints: %v", err)
} }
glog.Info("Service test passed.") glog.Info("Service test passed.")

View File

@ -21,6 +21,7 @@ import (
"net" "net"
"time" "time"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy" "github.com/GoogleCloudPlatform/kubernetes/pkg/proxy"
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/config" "github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/config"
@ -63,7 +64,8 @@ func main() {
glog.Fatalf("Invalid API configuration: %v", err) glog.Fatalf("Invalid API configuration: %v", err)
} }
config.NewSourceAPI( config.NewSourceAPI(
client, client.Services(api.NamespaceAll),
client.Endpoints(api.NamespaceAll),
30*time.Second, 30*time.Second,
serviceConfig.Channel("api"), serviceConfig.Channel("api"),
endpointsConfig.Channel("api"), endpointsConfig.Channel("api"),

View File

@ -21,64 +21,42 @@ import (
"fmt" "fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/version" "github.com/GoogleCloudPlatform/kubernetes/pkg/version"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
// Interface holds the methods for clients of Kubernetes, // Interface holds the methods for clients of Kubernetes,
// an interface to allow mock testing. // an interface to allow mock testing.
// TODO: these should return/take pointers.
type Interface interface { type Interface interface {
PodInterface PodsNamespacer
ReplicationControllerInterface ReplicationControllersNamespacer
ServiceInterface ServicesNamespacer
VersionInterface VersionInterface
MinionInterface MinionsInterface
EventsInterface
} }
// PodInterface has methods to work with Pod resources. func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface {
type PodInterface interface { return newReplicationControllers(c, namespace)
ListPods(ctx api.Context, selector labels.Selector) (*api.PodList, error)
GetPod(ctx api.Context, id string) (*api.Pod, error)
DeletePod(ctx api.Context, id string) error
CreatePod(ctx api.Context, pod *api.Pod) (*api.Pod, error)
UpdatePod(ctx api.Context, pod *api.Pod) (*api.Pod, error)
} }
// ReplicationControllerInterface has methods to work with ReplicationController resources. func (c *Client) Minions() MinionInterface {
type ReplicationControllerInterface interface { return newMinions(c)
ListReplicationControllers(ctx api.Context, selector labels.Selector) (*api.ReplicationControllerList, error)
GetReplicationController(ctx api.Context, id string) (*api.ReplicationController, error)
CreateReplicationController(ctx api.Context, ctrl *api.ReplicationController) (*api.ReplicationController, error)
UpdateReplicationController(ctx api.Context, ctrl *api.ReplicationController) (*api.ReplicationController, error)
DeleteReplicationController(ctx api.Context, id string) error
WatchReplicationControllers(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error)
} }
// ServiceInterface has methods to work with Service resources. func (c *Client) Events() EventInterface {
type ServiceInterface interface { return newEvents(c)
ListServices(ctx api.Context, selector labels.Selector) (*api.ServiceList, error)
GetService(ctx api.Context, id string) (*api.Service, error)
CreateService(ctx api.Context, srv *api.Service) (*api.Service, error)
UpdateService(ctx api.Context, srv *api.Service) (*api.Service, error)
DeleteService(ctx api.Context, id string) error
WatchServices(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error)
} }
// EndpointsInterface has methods to work with Endpoints resources func (c *Client) Endpoints(namespace string) EndpointsInterface {
type EndpointsInterface interface { return newEndpoints(c, namespace)
ListEndpoints(ctx api.Context, selector labels.Selector) (*api.EndpointsList, error)
GetEndpoints(ctx api.Context, id string) (*api.Endpoints, error)
WatchEndpoints(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error)
} }
// EventInterface has methods to work with Event resources func (c *Client) Pods(namespace string) PodInterface {
type EventInterface interface { return newPods(c, namespace)
CreateEvent(event *api.Event) (*api.Event, error) }
ListEvents(selector labels.Selector) (*api.EventList, error)
GetEvent(id string) (*api.Event, error) func (c *Client) Services(namespace string) ServiceInterface {
WatchEvents(label, field labels.Selector, resourceVersion string) (watch.Interface, error) return newServices(c, namespace)
} }
// VersionInterface has a method to retrieve the server version. // VersionInterface has a method to retrieve the server version.
@ -86,12 +64,6 @@ type VersionInterface interface {
ServerVersion() (*version.Info, error) ServerVersion() (*version.Info, error)
} }
type MinionInterface interface {
CreateMinion(minion *api.Minion) (*api.Minion, error)
ListMinions() (*api.MinionList, error)
DeleteMinion(id string) error
}
// APIStatus is exposed by errors that can be converted to an api.Status object // APIStatus is exposed by errors that can be converted to an api.Status object
// for finer grained details. // for finer grained details.
type APIStatus interface { type APIStatus interface {
@ -103,190 +75,6 @@ type Client struct {
*RESTClient *RESTClient
} }
// ListPods takes a selector, and returns the list of pods that match that selector.
func (c *Client) ListPods(ctx api.Context, selector labels.Selector) (result *api.PodList, err error) {
result = &api.PodList{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("pods").SelectorParam("labels", selector).Do().Into(result)
return
}
// GetPod takes the id of the pod, and returns the corresponding Pod object, and an error if it occurs
func (c *Client) GetPod(ctx api.Context, id string) (result *api.Pod, err error) {
result = &api.Pod{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("pods").Path(id).Do().Into(result)
return
}
// DeletePod takes the id of the pod, and returns an error if one occurs
func (c *Client) DeletePod(ctx api.Context, id string) error {
return c.Delete().Namespace(api.Namespace(ctx)).Path("pods").Path(id).Do().Error()
}
// CreatePod takes the representation of a pod. Returns the server's representation of the pod, and an error, if it occurs.
func (c *Client) CreatePod(ctx api.Context, pod *api.Pod) (result *api.Pod, err error) {
result = &api.Pod{}
err = c.Post().Namespace(api.Namespace(ctx)).Path("pods").Body(pod).Do().Into(result)
return
}
// UpdatePod takes the representation of a pod to update. Returns the server's representation of the pod, and an error, if it occurs.
func (c *Client) UpdatePod(ctx api.Context, pod *api.Pod) (result *api.Pod, err error) {
result = &api.Pod{}
if len(pod.ResourceVersion) == 0 {
err = fmt.Errorf("invalid update object, missing resource version: %v", pod)
return
}
err = c.Put().Namespace(api.Namespace(ctx)).Path("pods").Path(pod.Name).Body(pod).Do().Into(result)
return
}
// ListReplicationControllers takes a selector, and returns the list of replication controllers that match that selector.
func (c *Client) ListReplicationControllers(ctx api.Context, selector labels.Selector) (result *api.ReplicationControllerList, err error) {
result = &api.ReplicationControllerList{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("replicationControllers").SelectorParam("labels", selector).Do().Into(result)
return
}
// GetReplicationController returns information about a particular replication controller.
func (c *Client) GetReplicationController(ctx api.Context, id string) (result *api.ReplicationController, err error) {
result = &api.ReplicationController{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("replicationControllers").Path(id).Do().Into(result)
return
}
// CreateReplicationController creates a new replication controller.
func (c *Client) CreateReplicationController(ctx api.Context, controller *api.ReplicationController) (result *api.ReplicationController, err error) {
result = &api.ReplicationController{}
err = c.Post().Namespace(api.Namespace(ctx)).Path("replicationControllers").Body(controller).Do().Into(result)
return
}
// UpdateReplicationController updates an existing replication controller.
func (c *Client) UpdateReplicationController(ctx api.Context, controller *api.ReplicationController) (result *api.ReplicationController, err error) {
result = &api.ReplicationController{}
if len(controller.ResourceVersion) == 0 {
err = fmt.Errorf("invalid update object, missing resource version: %v", controller)
return
}
err = c.Put().Namespace(api.Namespace(ctx)).Path("replicationControllers").Path(controller.Name).Body(controller).Do().Into(result)
return
}
// DeleteReplicationController deletes an existing replication controller.
func (c *Client) DeleteReplicationController(ctx api.Context, id string) error {
return c.Delete().Namespace(api.Namespace(ctx)).Path("replicationControllers").Path(id).Do().Error()
}
// WatchReplicationControllers returns a watch.Interface that watches the requested controllers.
func (c *Client) WatchReplicationControllers(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.Get().
Namespace(api.Namespace(ctx)).
Path("watch").
Path("replicationControllers").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}
// ListServices takes a selector, and returns the list of services that match that selector
func (c *Client) ListServices(ctx api.Context, selector labels.Selector) (result *api.ServiceList, err error) {
result = &api.ServiceList{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("services").SelectorParam("labels", selector).Do().Into(result)
return
}
// GetService returns information about a particular service.
func (c *Client) GetService(ctx api.Context, id string) (result *api.Service, err error) {
result = &api.Service{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("services").Path(id).Do().Into(result)
return
}
// CreateService creates a new service.
func (c *Client) CreateService(ctx api.Context, svc *api.Service) (result *api.Service, err error) {
result = &api.Service{}
err = c.Post().Namespace(api.Namespace(ctx)).Path("services").Body(svc).Do().Into(result)
return
}
// UpdateService updates an existing service.
func (c *Client) UpdateService(ctx api.Context, svc *api.Service) (result *api.Service, err error) {
result = &api.Service{}
if len(svc.ResourceVersion) == 0 {
err = fmt.Errorf("invalid update object, missing resource version: %v", svc)
return
}
err = c.Put().Namespace(api.Namespace(ctx)).Path("services").Path(svc.Name).Body(svc).Do().Into(result)
return
}
// DeleteService deletes an existing service.
func (c *Client) DeleteService(ctx api.Context, id string) error {
return c.Delete().Namespace(api.Namespace(ctx)).Path("services").Path(id).Do().Error()
}
// WatchServices returns a watch.Interface that watches the requested services.
func (c *Client) WatchServices(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.Get().
Namespace(api.Namespace(ctx)).
Path("watch").
Path("services").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}
// ListEndpoints takes a selector, and returns the list of endpoints that match that selector
func (c *Client) ListEndpoints(ctx api.Context, selector labels.Selector) (result *api.EndpointsList, err error) {
result = &api.EndpointsList{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("endpoints").SelectorParam("labels", selector).Do().Into(result)
return
}
// GetEndpoints returns information about the endpoints for a particular service.
func (c *Client) GetEndpoints(ctx api.Context, id string) (result *api.Endpoints, err error) {
result = &api.Endpoints{}
err = c.Get().Namespace(api.Namespace(ctx)).Path("endpoints").Path(id).Do().Into(result)
return
}
// WatchEndpoints returns a watch.Interface that watches the requested endpoints for a service.
func (c *Client) WatchEndpoints(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.Get().
Namespace(api.Namespace(ctx)).
Path("watch").
Path("endpoints").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}
// CreateEndpoints creates a new endpoint.
func (c *Client) CreateEndpoints(ctx api.Context, endpoints *api.Endpoints) (*api.Endpoints, error) {
result := &api.Endpoints{}
err := c.Post().Namespace(api.Namespace(ctx)).Path("endpoints").Body(endpoints).Do().Into(result)
return result, err
}
// UpdateEndpoints updates an existing endpoint.
func (c *Client) UpdateEndpoints(ctx api.Context, endpoints *api.Endpoints) (*api.Endpoints, error) {
result := &api.Endpoints{}
if len(endpoints.ResourceVersion) == 0 {
return nil, fmt.Errorf("invalid update object, missing resource version: %v", endpoints)
}
err := c.Put().
Namespace(api.Namespace(ctx)).
Path("endpoints").
Path(endpoints.Name).
Body(endpoints).
Do().
Into(result)
return result, err
}
// ServerVersion retrieves and parses the server's version. // ServerVersion retrieves and parses the server's version.
func (c *Client) ServerVersion() (*version.Info, error) { func (c *Client) ServerVersion() (*version.Info, error) {
body, err := c.Get().AbsPath("/version").Do().Raw() body, err := c.Get().AbsPath("/version").Do().Raw()
@ -300,66 +88,3 @@ func (c *Client) ServerVersion() (*version.Info, error) {
} }
return &info, nil return &info, nil
} }
// CreateMinion creates a new minion.
func (c *Client) CreateMinion(minion *api.Minion) (*api.Minion, error) {
result := &api.Minion{}
err := c.Post().Path("minions").Body(minion).Do().Into(result)
return result, err
}
// ListMinions lists all the minions in the cluster.
func (c *Client) ListMinions() (*api.MinionList, error) {
result := &api.MinionList{}
err := c.Get().Path("minions").Do().Into(result)
return result, err
}
// GetMinion returns information about a particular minion.
func (c *Client) GetMinion(id string) (*api.Minion, error) {
result := &api.Minion{}
err := c.Get().Path("minions").Path(id).Do().Into(result)
return result, err
}
// DeleteMinion deletes an existing minion.
func (c *Client) DeleteMinion(id string) error {
return c.Delete().Path("minions").Path(id).Do().Error()
}
// CreateEvent makes a new event. Returns the copy of the event the server returns, or an error.
func (c *Client) CreateEvent(event *api.Event) (*api.Event, error) {
result := &api.Event{}
err := c.Post().Path("events").Body(event).Do().Into(result)
return result, err
}
// ListEvents returns a list of events matching the selectors.
func (c *Client) ListEvents(label, field labels.Selector) (*api.EventList, error) {
result := &api.EventList{}
err := c.Get().
Path("events").
SelectorParam("labels", label).
SelectorParam("fields", field).
Do().
Into(result)
return result, err
}
// GetEvent returns the given event, or an error.
func (c *Client) GetEvent(id string) (*api.Event, error) {
result := &api.Event{}
err := c.Get().Path("events").Path(id).Do().Into(result)
return result, err
}
// WatchEvents starts watching for events matching the given selectors.
func (c *Client) WatchEvents(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.Get().
Path("watch").
Path("events").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}

View File

@ -146,17 +146,17 @@ func (c *testClient) ValidateCommon(t *testing.T, err error) {
} }
func TestListEmptyPods(t *testing.T) { func TestListEmptyPods(t *testing.T) {
ctx := api.NewContext() ns := api.NamespaceDefault
c := &testClient{ c := &testClient{
Request: testRequest{Method: "GET", Path: "/pods"}, Request: testRequest{Method: "GET", Path: "/pods"},
Response: Response{StatusCode: 200, Body: &api.PodList{}}, Response: Response{StatusCode: 200, Body: &api.PodList{}},
} }
podList, err := c.Setup().ListPods(ctx, labels.Everything()) podList, err := c.Setup().Pods(ns).List(labels.Everything())
c.Validate(t, podList, err) c.Validate(t, podList, err)
} }
func TestListPods(t *testing.T) { func TestListPods(t *testing.T) {
ctx := api.NewDefaultContext() ns := api.NamespaceDefault
c := &testClient{ c := &testClient{
Request: testRequest{Method: "GET", Path: "/pods"}, Request: testRequest{Method: "GET", Path: "/pods"},
Response: Response{StatusCode: 200, Response: Response{StatusCode: 200,
@ -177,7 +177,7 @@ func TestListPods(t *testing.T) {
}, },
}, },
} }
receivedPodList, err := c.Setup().ListPods(ctx, labels.Everything()) receivedPodList, err := c.Setup().Pods(ns).List(labels.Everything())
c.Validate(t, receivedPodList, err) c.Validate(t, receivedPodList, err)
} }
@ -188,7 +188,7 @@ func validateLabels(a, b string) bool {
} }
func TestListPodsLabels(t *testing.T) { func TestListPodsLabels(t *testing.T) {
ctx := api.NewDefaultContext() ns := api.NamespaceDefault
c := &testClient{ c := &testClient{
Request: testRequest{Method: "GET", Path: "/pods", Query: url.Values{"labels": []string{"foo=bar,name=baz"}}}, Request: testRequest{Method: "GET", Path: "/pods", Query: url.Values{"labels": []string{"foo=bar,name=baz"}}},
Response: Response{ Response: Response{
@ -213,12 +213,12 @@ func TestListPodsLabels(t *testing.T) {
c.Setup() c.Setup()
c.QueryValidator["labels"] = validateLabels c.QueryValidator["labels"] = validateLabels
selector := labels.Set{"foo": "bar", "name": "baz"}.AsSelector() selector := labels.Set{"foo": "bar", "name": "baz"}.AsSelector()
receivedPodList, err := c.ListPods(ctx, selector) receivedPodList, err := c.Pods(ns).List(selector)
c.Validate(t, receivedPodList, err) c.Validate(t, receivedPodList, err)
} }
func TestGetPod(t *testing.T) { func TestGetPod(t *testing.T) {
ctx := api.NewDefaultContext() ns := api.NamespaceDefault
c := &testClient{ c := &testClient{
Request: testRequest{Method: "GET", Path: "/pods/foo"}, Request: testRequest{Method: "GET", Path: "/pods/foo"},
Response: Response{ Response: Response{
@ -236,7 +236,7 @@ func TestGetPod(t *testing.T) {
}, },
}, },
} }
receivedPod, err := c.Setup().GetPod(ctx, "foo") receivedPod, err := c.Setup().Pods(ns).Get("foo")
c.Validate(t, receivedPod, err) c.Validate(t, receivedPod, err)
} }
@ -245,7 +245,7 @@ func TestDeletePod(t *testing.T) {
Request: testRequest{Method: "DELETE", Path: "/pods/foo"}, Request: testRequest{Method: "DELETE", Path: "/pods/foo"},
Response: Response{StatusCode: 200}, Response: Response{StatusCode: 200},
} }
err := c.Setup().DeletePod(api.NewDefaultContext(), "foo") err := c.Setup().Pods(api.NamespaceDefault).Delete("foo")
c.Validate(t, nil, err) c.Validate(t, nil, err)
} }
@ -268,7 +268,7 @@ func TestCreatePod(t *testing.T) {
Body: requestPod, Body: requestPod,
}, },
} }
receivedPod, err := c.Setup().CreatePod(api.NewDefaultContext(), requestPod) receivedPod, err := c.Setup().Pods(api.NamespaceDefault).Create(requestPod)
c.Validate(t, receivedPod, err) c.Validate(t, receivedPod, err)
} }
@ -290,7 +290,7 @@ func TestUpdatePod(t *testing.T) {
Request: testRequest{Method: "PUT", Path: "/pods/foo"}, Request: testRequest{Method: "PUT", Path: "/pods/foo"},
Response: Response{StatusCode: 200, Body: requestPod}, Response: Response{StatusCode: 200, Body: requestPod},
} }
receivedPod, err := c.Setup().UpdatePod(api.NewDefaultContext(), requestPod) receivedPod, err := c.Setup().Pods(api.NamespaceDefault).Update(requestPod)
c.Validate(t, receivedPod, err) c.Validate(t, receivedPod, err)
} }
@ -316,7 +316,7 @@ func TestListControllers(t *testing.T) {
}, },
}, },
} }
receivedControllerList, err := c.Setup().ListReplicationControllers(api.NewContext(), labels.Everything()) receivedControllerList, err := c.Setup().ReplicationControllers(api.NamespaceAll).List(labels.Everything())
c.Validate(t, receivedControllerList, err) c.Validate(t, receivedControllerList, err)
} }
@ -340,7 +340,7 @@ func TestGetController(t *testing.T) {
}, },
}, },
} }
receivedController, err := c.Setup().GetReplicationController(api.NewDefaultContext(), "foo") receivedController, err := c.Setup().ReplicationControllers(api.NamespaceDefault).Get("foo")
c.Validate(t, receivedController, err) c.Validate(t, receivedController, err)
} }
@ -366,7 +366,7 @@ func TestUpdateController(t *testing.T) {
}, },
}, },
} }
receivedController, err := c.Setup().UpdateReplicationController(api.NewDefaultContext(), requestController) receivedController, err := c.Setup().ReplicationControllers(api.NamespaceDefault).Update(requestController)
c.Validate(t, receivedController, err) c.Validate(t, receivedController, err)
} }
@ -375,7 +375,7 @@ func TestDeleteController(t *testing.T) {
Request: testRequest{Method: "DELETE", Path: "/replicationControllers/foo"}, Request: testRequest{Method: "DELETE", Path: "/replicationControllers/foo"},
Response: Response{StatusCode: 200}, Response: Response{StatusCode: 200},
} }
err := c.Setup().DeleteReplicationController(api.NewDefaultContext(), "foo") err := c.Setup().ReplicationControllers(api.NamespaceDefault).Delete("foo")
c.Validate(t, nil, err) c.Validate(t, nil, err)
} }
@ -401,7 +401,7 @@ func TestCreateController(t *testing.T) {
}, },
}, },
} }
receivedController, err := c.Setup().CreateReplicationController(api.NewDefaultContext(), requestController) receivedController, err := c.Setup().ReplicationControllers(api.NamespaceDefault).Create(requestController)
c.Validate(t, receivedController, err) c.Validate(t, receivedController, err)
} }
@ -436,7 +436,7 @@ func TestListServices(t *testing.T) {
}, },
}, },
} }
receivedServiceList, err := c.Setup().ListServices(api.NewDefaultContext(), labels.Everything()) receivedServiceList, err := c.Setup().Services(api.NamespaceDefault).List(labels.Everything())
t.Logf("received services: %v %#v", err, receivedServiceList) t.Logf("received services: %v %#v", err, receivedServiceList)
c.Validate(t, receivedServiceList, err) c.Validate(t, receivedServiceList, err)
} }
@ -466,7 +466,7 @@ func TestListServicesLabels(t *testing.T) {
c.Setup() c.Setup()
c.QueryValidator["labels"] = validateLabels c.QueryValidator["labels"] = validateLabels
selector := labels.Set{"foo": "bar", "name": "baz"}.AsSelector() selector := labels.Set{"foo": "bar", "name": "baz"}.AsSelector()
receivedServiceList, err := c.ListServices(api.NewDefaultContext(), selector) receivedServiceList, err := c.Services(api.NamespaceDefault).List(selector)
c.Validate(t, receivedServiceList, err) c.Validate(t, receivedServiceList, err)
} }
@ -475,7 +475,7 @@ func TestGetService(t *testing.T) {
Request: testRequest{Method: "GET", Path: "/services/1"}, Request: testRequest{Method: "GET", Path: "/services/1"},
Response: Response{StatusCode: 200, Body: &api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}}}, Response: Response{StatusCode: 200, Body: &api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}}},
} }
response, err := c.Setup().GetService(api.NewDefaultContext(), "1") response, err := c.Setup().Services(api.NamespaceDefault).Get("1")
c.Validate(t, response, err) c.Validate(t, response, err)
} }
@ -484,7 +484,7 @@ func TestCreateService(t *testing.T) {
Request: testRequest{Method: "POST", Path: "/services", Body: &api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}}}, Request: testRequest{Method: "POST", Path: "/services", Body: &api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}}},
Response: Response{StatusCode: 200, Body: &api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}}}, Response: Response{StatusCode: 200, Body: &api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}}},
} }
response, err := c.Setup().CreateService(api.NewDefaultContext(), &api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}}) response, err := c.Setup().Services(api.NamespaceDefault).Create(&api.Service{ObjectMeta: api.ObjectMeta{Name: "service-1"}})
c.Validate(t, response, err) c.Validate(t, response, err)
} }
@ -494,7 +494,7 @@ func TestUpdateService(t *testing.T) {
Request: testRequest{Method: "PUT", Path: "/services/service-1", Body: svc}, Request: testRequest{Method: "PUT", Path: "/services/service-1", Body: svc},
Response: Response{StatusCode: 200, Body: svc}, Response: Response{StatusCode: 200, Body: svc},
} }
response, err := c.Setup().UpdateService(api.NewDefaultContext(), svc) response, err := c.Setup().Services(api.NamespaceDefault).Update(svc)
c.Validate(t, response, err) c.Validate(t, response, err)
} }
@ -503,7 +503,7 @@ func TestDeleteService(t *testing.T) {
Request: testRequest{Method: "DELETE", Path: "/services/1"}, Request: testRequest{Method: "DELETE", Path: "/services/1"},
Response: Response{StatusCode: 200}, Response: Response{StatusCode: 200},
} }
err := c.Setup().DeleteService(api.NewDefaultContext(), "1") err := c.Setup().Services(api.NamespaceDefault).Delete("1")
c.Validate(t, nil, err) c.Validate(t, nil, err)
} }
@ -521,7 +521,7 @@ func TestListEndpooints(t *testing.T) {
}, },
}, },
} }
receivedEndpointsList, err := c.Setup().ListEndpoints(api.NewDefaultContext(), labels.Everything()) receivedEndpointsList, err := c.Setup().Endpoints(api.NamespaceDefault).List(labels.Everything())
c.Validate(t, receivedEndpointsList, err) c.Validate(t, receivedEndpointsList, err)
} }
@ -530,7 +530,7 @@ func TestGetEndpoints(t *testing.T) {
Request: testRequest{Method: "GET", Path: "/endpoints/endpoint-1"}, Request: testRequest{Method: "GET", Path: "/endpoints/endpoint-1"},
Response: Response{StatusCode: 200, Body: &api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "endpoint-1"}}}, Response: Response{StatusCode: 200, Body: &api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "endpoint-1"}}},
} }
response, err := c.Setup().GetEndpoints(api.NewDefaultContext(), "endpoint-1") response, err := c.Setup().Endpoints(api.NamespaceDefault).Get("endpoint-1")
c.Validate(t, response, err) c.Validate(t, response, err)
} }
@ -566,7 +566,7 @@ func TestListMinions(t *testing.T) {
Request: testRequest{Method: "GET", Path: "/minions"}, Request: testRequest{Method: "GET", Path: "/minions"},
Response: Response{StatusCode: 200, Body: &api.MinionList{ListMeta: api.ListMeta{ResourceVersion: "1"}}}, Response: Response{StatusCode: 200, Body: &api.MinionList{ListMeta: api.ListMeta{ResourceVersion: "1"}}},
} }
response, err := c.Setup().ListMinions() response, err := c.Setup().Minions().List()
c.Validate(t, response, err) c.Validate(t, response, err)
} }
@ -590,7 +590,7 @@ func TestCreateMinion(t *testing.T) {
Body: requestMinion, Body: requestMinion,
}, },
} }
receivedMinion, err := c.Setup().CreateMinion(requestMinion) receivedMinion, err := c.Setup().Minions().Create(requestMinion)
c.Validate(t, receivedMinion, err) c.Validate(t, receivedMinion, err)
} }
@ -599,6 +599,6 @@ 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().DeleteMinion("foo") err := c.Setup().Minions().Delete("foo")
c.Validate(t, nil, err) c.Validate(t, nil, err)
} }

View File

@ -26,8 +26,7 @@ import (
// for a controller's ReplicaSelector equals the Replicas count. // for a controller's ReplicaSelector equals the Replicas count.
func (c *Client) ControllerHasDesiredReplicas(controller api.ReplicationController) wait.ConditionFunc { func (c *Client) ControllerHasDesiredReplicas(controller api.ReplicationController) wait.ConditionFunc {
return func() (bool, error) { return func() (bool, error) {
ctx := api.WithNamespace(api.NewContext(), controller.Namespace) pods, err := c.Pods(controller.Namespace).List(labels.Set(controller.DesiredState.ReplicaSelector).AsSelector())
pods, err := c.ListPods(ctx, labels.Set(controller.DesiredState.ReplicaSelector).AsSelector())
if err != nil { if err != nil {
return false, err return false, err
} }

98
pkg/client/endpoints.go Normal file
View File

@ -0,0 +1,98 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// EndpointsNamespacer has methods to work with Endpoint resources in a namespace
type EndpointsNamespacer interface {
Endpoint(namespace string) EndpointsInterface
}
// EndpointsInterface has methods to work with Endpoints resources
type EndpointsInterface interface {
Create(endpoints *api.Endpoints) (*api.Endpoints, error)
List(selector labels.Selector) (*api.EndpointsList, error)
Get(id string) (*api.Endpoints, error)
Update(endpoints *api.Endpoints) (*api.Endpoints, error)
Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error)
}
// endpoints implements EndpointsNamespacer interface
type endpoints struct {
r *Client
ns string
}
// newEndpoints returns a endpoints
func newEndpoints(c *Client, namespace string) *endpoints {
return &endpoints{c, namespace}
}
// Create creates a new endpoint.
func (c *endpoints) Create(endpoints *api.Endpoints) (*api.Endpoints, error) {
result := &api.Endpoints{}
err := c.r.Post().Namespace(c.ns).Path("endpoints").Body(endpoints).Do().Into(result)
return result, err
}
// List takes a selector, and returns the list of endpoints that match that selector
func (c *endpoints) List(selector labels.Selector) (result *api.EndpointsList, err error) {
result = &api.EndpointsList{}
err = c.r.Get().Namespace(c.ns).Path("endpoints").SelectorParam("labels", selector).Do().Into(result)
return
}
// Get returns information about the endpoints for a particular service.
func (c *endpoints) Get(id string) (result *api.Endpoints, err error) {
result = &api.Endpoints{}
err = c.r.Get().Namespace(c.ns).Path("endpoints").Path(id).Do().Into(result)
return
}
// Watch returns a watch.Interface that watches the requested endpoints for a service.
func (c *endpoints) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.r.Get().
Namespace(c.ns).
Path("watch").
Path("endpoints").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}
func (c *endpoints) Update(endpoints *api.Endpoints) (*api.Endpoints, error) {
result := &api.Endpoints{}
if len(endpoints.ResourceVersion) == 0 {
return nil, fmt.Errorf("invalid update object, missing resource version: %v", endpoints)
}
err := c.r.Put().
Namespace(c.ns).
Path("endpoints").
Path(endpoints.Name).
Body(endpoints).
Do().
Into(result)
return result, err
}

85
pkg/client/events.go Normal file
View File

@ -0,0 +1,85 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// Events has methods to work with Event resources
type EventsInterface interface {
Events() EventInterface
}
// EventInterface has methods to work with Event resources
type EventInterface interface {
Create(event *api.Event) (*api.Event, error)
List(label, field labels.Selector) (*api.EventList, error)
Get(id string) (*api.Event, error)
Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error)
}
// events implements Events interface
type events struct {
r *Client
}
// newEvents returns a events
func newEvents(c *Client) *events {
return &events{
r: c,
}
}
// Create makes a new event. Returns the copy of the event the server returns, or an error.
func (c *events) Create(event *api.Event) (*api.Event, error) {
result := &api.Event{}
err := c.r.Post().Path("events").Body(event).Do().Into(result)
return result, err
}
// List returns a list of events matching the selectors.
func (c *events) List(label, field labels.Selector) (*api.EventList, error) {
result := &api.EventList{}
err := c.r.Get().
Path("events").
SelectorParam("labels", label).
SelectorParam("fields", field).
Do().
Into(result)
return result, err
}
// Get returns the given event, or an error.
func (c *events) Get(id string) (*api.Event, error) {
result := &api.Event{}
err := c.r.Get().Path("events").Path(id).Do().Into(result)
return result, err
}
// Watch starts watching for events matching the given selectors.
func (c *events) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.r.Get().
Path("watch").
Path("events").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}

View File

@ -18,7 +18,6 @@ package client
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/version" "github.com/GoogleCloudPlatform/kubernetes/pkg/version"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -31,116 +30,39 @@ type FakeAction struct {
// Fake implements Interface. Meant to be embedded into a struct to get a default // Fake implements Interface. 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 Fake struct { type Fake struct {
// Fake by default keeps a simple list of the methods that have been called.
Actions []FakeAction Actions []FakeAction
Pods api.PodList PodsList api.PodList
Ctrl api.ReplicationController Ctrl api.ReplicationController
ServiceList api.ServiceList ServiceList api.ServiceList
EndpointsList api.EndpointsList EndpointsList api.EndpointsList
Minions api.MinionList MinionsList api.MinionList
Events api.EventList EventsList api.EventList
Err error Err error
Watch watch.Interface Watch watch.Interface
} }
func (c *Fake) ListPods(ctx api.Context, selector labels.Selector) (*api.PodList, error) { func (c *Fake) ReplicationControllers(namespace string) ReplicationControllerInterface {
c.Actions = append(c.Actions, FakeAction{Action: "list-pods"}) return &FakeReplicationControllers{Fake: c, Namespace: namespace}
return api.Scheme.CopyOrDie(&c.Pods).(*api.PodList), nil
} }
func (c *Fake) GetPod(ctx api.Context, name string) (*api.Pod, error) { func (c *Fake) Minions() MinionInterface {
c.Actions = append(c.Actions, FakeAction{Action: "get-pod", Value: name}) return &FakeMinions{Fake: c}
return &api.Pod{}, nil
} }
func (c *Fake) DeletePod(ctx api.Context, name string) error { func (c *Fake) Events() EventInterface {
c.Actions = append(c.Actions, FakeAction{Action: "delete-pod", Value: name}) return &FakeEvents{Fake: c}
return nil
} }
func (c *Fake) CreatePod(ctx api.Context, pod *api.Pod) (*api.Pod, error) { func (c *Fake) Endpoints(namespace string) EndpointsInterface {
c.Actions = append(c.Actions, FakeAction{Action: "create-pod"}) return &FakeEndpoints{Fake: c, Namespace: namespace}
return &api.Pod{}, nil
} }
func (c *Fake) UpdatePod(ctx api.Context, pod *api.Pod) (*api.Pod, error) { func (c *Fake) Pods(namespace string) PodInterface {
c.Actions = append(c.Actions, FakeAction{Action: "update-pod", Value: pod.Name}) return &FakePods{Fake: c, Namespace: namespace}
return &api.Pod{}, nil
} }
func (c *Fake) ListReplicationControllers(ctx api.Context, selector labels.Selector) (*api.ReplicationControllerList, error) { func (c *Fake) Services(namespace string) ServiceInterface {
c.Actions = append(c.Actions, FakeAction{Action: "list-controllers"}) return &FakeServices{Fake: c, Namespace: namespace}
return &api.ReplicationControllerList{}, nil
}
func (c *Fake) GetReplicationController(ctx api.Context, name string) (*api.ReplicationController, error) {
c.Actions = append(c.Actions, FakeAction{Action: "get-controller", Value: name})
return api.Scheme.CopyOrDie(&c.Ctrl).(*api.ReplicationController), nil
}
func (c *Fake) CreateReplicationController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error) {
c.Actions = append(c.Actions, FakeAction{Action: "create-controller", Value: controller})
return &api.ReplicationController{}, nil
}
func (c *Fake) UpdateReplicationController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error) {
c.Actions = append(c.Actions, FakeAction{Action: "update-controller", Value: controller})
return &api.ReplicationController{}, nil
}
func (c *Fake) DeleteReplicationController(ctx api.Context, controller string) error {
c.Actions = append(c.Actions, FakeAction{Action: "delete-controller", Value: controller})
return nil
}
func (c *Fake) WatchReplicationControllers(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Actions = append(c.Actions, FakeAction{Action: "watch-controllers", Value: resourceVersion})
return c.Watch, nil
}
func (c *Fake) ListServices(ctx api.Context, selector labels.Selector) (*api.ServiceList, error) {
c.Actions = append(c.Actions, FakeAction{Action: "list-services"})
return &c.ServiceList, c.Err
}
func (c *Fake) GetService(ctx api.Context, name string) (*api.Service, error) {
c.Actions = append(c.Actions, FakeAction{Action: "get-service", Value: name})
return &api.Service{}, nil
}
func (c *Fake) CreateService(ctx api.Context, service *api.Service) (*api.Service, error) {
c.Actions = append(c.Actions, FakeAction{Action: "create-service", Value: service})
return &api.Service{}, nil
}
func (c *Fake) UpdateService(ctx api.Context, service *api.Service) (*api.Service, error) {
c.Actions = append(c.Actions, FakeAction{Action: "update-service", Value: service})
return &api.Service{}, nil
}
func (c *Fake) DeleteService(ctx api.Context, service string) error {
c.Actions = append(c.Actions, FakeAction{Action: "delete-service", Value: service})
return nil
}
func (c *Fake) WatchServices(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Actions = append(c.Actions, FakeAction{Action: "watch-services", Value: resourceVersion})
return c.Watch, c.Err
}
func (c *Fake) ListEndpoints(ctx api.Context, selector labels.Selector) (*api.EndpointsList, error) {
c.Actions = append(c.Actions, FakeAction{Action: "list-endpoints"})
return api.Scheme.CopyOrDie(&c.EndpointsList).(*api.EndpointsList), c.Err
}
func (c *Fake) GetEndpoints(ctx api.Context, name string) (*api.Endpoints, error) {
c.Actions = append(c.Actions, FakeAction{Action: "get-endpoints"})
return &api.Endpoints{}, nil
}
func (c *Fake) WatchEndpoints(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Actions = append(c.Actions, FakeAction{Action: "watch-endpoints", Value: resourceVersion})
return c.Watch, c.Err
} }
func (c *Fake) ServerVersion() (*version.Info, error) { func (c *Fake) ServerVersion() (*version.Info, error) {
@ -148,42 +70,3 @@ func (c *Fake) ServerVersion() (*version.Info, error) {
versionInfo := version.Get() versionInfo := version.Get()
return &versionInfo, nil return &versionInfo, nil
} }
func (c *Fake) ListMinions() (*api.MinionList, error) {
c.Actions = append(c.Actions, FakeAction{Action: "list-minions", Value: nil})
return &c.Minions, nil
}
func (c *Fake) CreateMinion(minion *api.Minion) (*api.Minion, error) {
c.Actions = append(c.Actions, FakeAction{Action: "create-minion", Value: minion})
return &api.Minion{}, nil
}
func (c *Fake) DeleteMinion(id string) error {
c.Actions = append(c.Actions, FakeAction{Action: "delete-minion", Value: id})
return nil
}
// CreateEvent makes a new event. Returns the copy of the event the server returns, or an error.
func (c *Fake) CreateEvent(event *api.Event) (*api.Event, error) {
c.Actions = append(c.Actions, FakeAction{Action: "get-event", Value: event.Name})
return &api.Event{}, nil
}
// ListEvents returns a list of events matching the selectors.
func (c *Fake) ListEvents(label, field labels.Selector) (*api.EventList, error) {
c.Actions = append(c.Actions, FakeAction{Action: "list-events"})
return &c.Events, nil
}
// GetEvent returns the given event, or an error.
func (c *Fake) GetEvent(id string) (*api.Event, error) {
c.Actions = append(c.Actions, FakeAction{Action: "get-event", Value: id})
return &api.Event{}, nil
}
// WatchEvents starts watching for events matching the given selectors.
func (c *Fake) WatchEvents(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Actions = append(c.Actions, FakeAction{Action: "watch-events", Value: resourceVersion})
return c.Watch, c.Err
}

View File

@ -0,0 +1,55 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// FakeEndpoints implements EndpointInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakeEndpoints struct {
Fake *Fake
Namespace string
}
func (c *FakeEndpoints) Create(endpoints *api.Endpoints) (*api.Endpoints, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-endpoints"})
return &api.Endpoints{}, nil
}
func (c *FakeEndpoints) List(selector labels.Selector) (*api.EndpointsList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-endpoints"})
return api.Scheme.CopyOrDie(&c.Fake.EndpointsList).(*api.EndpointsList), c.Fake.Err
}
func (c *FakeEndpoints) Get(name string) (*api.Endpoints, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-endpoints"})
return &api.Endpoints{}, nil
}
func (c *FakeEndpoints) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-endpoints", Value: resourceVersion})
return c.Fake.Watch, c.Fake.Err
}
func (c *FakeEndpoints) Update(endpoints *api.Endpoints) (*api.Endpoints, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "update-endpoints", Value: endpoints.Name})
return &api.Endpoints{}, nil
}

53
pkg/client/fake_events.go Normal file
View File

@ -0,0 +1,53 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// FakeEvents implements EventInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakeEvents struct {
Fake *Fake
}
// Create makes a new event. Returns the copy of the event the server returns, or an error.
func (c *FakeEvents) Create(event *api.Event) (*api.Event, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-event", Value: event.Name})
return &api.Event{}, nil
}
// List returns a list of events matching the selectors.
func (c *FakeEvents) List(label, field labels.Selector) (*api.EventList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-events"})
return &c.Fake.EventsList, nil
}
// Get returns the given event, or an error.
func (c *FakeEvents) Get(id string) (*api.Event, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-event", Value: id})
return &api.Event{}, nil
}
// Watch starts watching for events matching the given selectors.
func (c *FakeEvents) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-events", Value: resourceVersion})
return c.Fake.Watch, c.Fake.Err
}

View File

@ -0,0 +1,47 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)
// FakeMinions 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.
type FakeMinions struct {
Fake *Fake
}
func (c *FakeMinions) Get(name string) (*api.Minion, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-minion", Value: name})
return &api.Minion{}, nil
}
func (c *FakeMinions) List() (*api.MinionList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-minions", Value: nil})
return &c.Fake.MinionsList, nil
}
func (c *FakeMinions) Create(minion *api.Minion) (*api.Minion, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-minion", Value: minion})
return &api.Minion{}, nil
}
func (c *FakeMinions) Delete(id string) error {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-minion", Value: id})
return nil
}

54
pkg/client/fake_pods.go Normal file
View File

@ -0,0 +1,54 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
)
// FakePods implements PodsInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the methods you want to test easier.
type FakePods struct {
Fake *Fake
Namespace string
}
func (c *FakePods) List(selector labels.Selector) (*api.PodList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-pods"})
return api.Scheme.CopyOrDie(&c.Fake.PodsList).(*api.PodList), nil
}
func (c *FakePods) Get(name string) (*api.Pod, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-pod", Value: name})
return &api.Pod{}, nil
}
func (c *FakePods) Delete(name string) error {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-pod", Value: name})
return nil
}
func (c *FakePods) Create(pod *api.Pod) (*api.Pod, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-pod"})
return &api.Pod{}, nil
}
func (c *FakePods) Update(pod *api.Pod) (*api.Pod, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "update-pod", Value: pod.Name})
return &api.Pod{}, nil
}

View File

@ -0,0 +1,60 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// FakeReplicationControllers implements ReplicationControllerInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakeReplicationControllers struct {
Fake *Fake
Namespace string
}
func (c *FakeReplicationControllers) List(selector labels.Selector) (*api.ReplicationControllerList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-controllers"})
return &api.ReplicationControllerList{}, nil
}
func (c *FakeReplicationControllers) Get(name string) (*api.ReplicationController, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-controller", Value: name})
return api.Scheme.CopyOrDie(&c.Fake.Ctrl).(*api.ReplicationController), nil
}
func (c *FakeReplicationControllers) Create(controller *api.ReplicationController) (*api.ReplicationController, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-controller", Value: controller})
return &api.ReplicationController{}, nil
}
func (c *FakeReplicationControllers) Update(controller *api.ReplicationController) (*api.ReplicationController, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "update-controller", Value: controller})
return &api.ReplicationController{}, nil
}
func (c *FakeReplicationControllers) Delete(controller string) error {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-controller", Value: controller})
return nil
}
func (c *FakeReplicationControllers) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-controllers", Value: resourceVersion})
return c.Fake.Watch, nil
}

View File

@ -0,0 +1,60 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// Fake implements ServiceInterface. Meant to be embedded into a struct to get a default
// implementation. This makes faking out just the method you want to test easier.
type FakeServices struct {
Fake *Fake
Namespace string
}
func (c *FakeServices) List(selector labels.Selector) (*api.ServiceList, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "list-services"})
return &c.Fake.ServiceList, c.Fake.Err
}
func (c *FakeServices) Get(name string) (*api.Service, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "get-service", Value: name})
return &api.Service{}, nil
}
func (c *FakeServices) Create(service *api.Service) (*api.Service, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "create-service", Value: service})
return &api.Service{}, nil
}
func (c *FakeServices) Update(service *api.Service) (*api.Service, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "update-service", Value: service})
return &api.Service{}, nil
}
func (c *FakeServices) Delete(service string) error {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "delete-service", Value: service})
return nil
}
func (c *FakeServices) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-services", Value: resourceVersion})
return c.Fake.Watch, c.Fake.Err
}

68
pkg/client/minions.go Normal file
View File

@ -0,0 +1,68 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
)
type MinionsInterface interface {
Minions() MinionInterface
}
type MinionInterface interface {
Get(id string) (result *api.Minion, err error)
Create(minion *api.Minion) (*api.Minion, error)
List() (*api.MinionList, error)
Delete(id string) error
}
// minions implements Minions interface
type minions struct {
r *Client
}
// newMinions returns a minions
func newMinions(c *Client) *minions {
return &minions{c}
}
// Create creates a new minion.
func (c *minions) Create(minion *api.Minion) (*api.Minion, error) {
result := &api.Minion{}
err := c.r.Post().Path("minions").Body(minion).Do().Into(result)
return result, err
}
// List lists all the minions in the cluster.
func (c *minions) List() (result *api.MinionList, err error) {
result = &api.MinionList{}
err = c.r.Get().Path("minions").Do().Into(result)
return
}
// Get gets an existing minion
func (c *minions) Get(id string) (result *api.Minion, err error) {
result = &api.Minion{}
err = c.r.Get().Path("minions").Path(id).Do().Into(result)
return
}
// Delete deletes an existing minion.
func (c *minions) Delete(id string) error {
return c.r.Delete().Path("minions").Path(id).Do().Error()
}

89
pkg/client/pods.go Normal file
View File

@ -0,0 +1,89 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
)
// PodsNamespacer has methods to work with Pod resources in a namespace
type PodsNamespacer interface {
Pods(namespace string) PodInterface
}
// PodInterface has methods to work with Pod resources.
type PodInterface interface {
List(selector labels.Selector) (*api.PodList, error)
Get(name string) (*api.Pod, error)
Delete(name string) error
Create(pod *api.Pod) (*api.Pod, error)
Update(pod *api.Pod) (*api.Pod, error)
}
// pods implements PodsNamespacer interface
type pods struct {
r *Client
ns string
}
// newPods returns a pods
func newPods(c *Client, namespace string) *pods {
return &pods{
r: c,
ns: namespace,
}
}
// ListPods takes a selector, and returns the list of pods that match that selector.
func (c *pods) List(selector labels.Selector) (result *api.PodList, err error) {
result = &api.PodList{}
err = c.r.Get().Namespace(c.ns).Path("pods").SelectorParam("labels", selector).Do().Into(result)
return
}
// GetPod takes the name of the pod, and returns the corresponding Pod object, and an error if it occurs
func (c *pods) Get(name string) (result *api.Pod, err error) {
result = &api.Pod{}
err = c.r.Get().Namespace(c.ns).Path("pods").Path(name).Do().Into(result)
return
}
// DeletePod takes the name of the pod, and returns an error if one occurs
func (c *pods) Delete(name string) error {
return c.r.Delete().Namespace(c.ns).Path("pods").Path(name).Do().Error()
}
// CreatePod takes the representation of a pod. Returns the server's representation of the pod, and an error, if it occurs.
func (c *pods) Create(pod *api.Pod) (result *api.Pod, err error) {
result = &api.Pod{}
err = c.r.Post().Namespace(c.ns).Path("pods").Body(pod).Do().Into(result)
return
}
// UpdatePod takes the representation of a pod to update. Returns the server's representation of the pod, and an error, if it occurs.
func (c *pods) Update(pod *api.Pod) (result *api.Pod, err error) {
result = &api.Pod{}
if len(pod.ResourceVersion) == 0 {
err = fmt.Errorf("invalid update object, missing resource version: %v", pod)
return
}
err = c.r.Put().Namespace(c.ns).Path("pods").Path(pod.Name).Body(pod).Do().Into(result)
return
}

View File

@ -30,7 +30,7 @@ import (
// EventRecorder knows how to store events (client.Client implements it.) // EventRecorder knows how to store events (client.Client implements it.)
type EventRecorder interface { type EventRecorder interface {
CreateEvent(event *api.Event) (*api.Event, error) Create(event *api.Event) (*api.Event, error)
} }
// StartRecording starts sending events to recorder. Call once while initializing // StartRecording starts sending events to recorder. Call once while initializing
@ -44,7 +44,7 @@ func StartRecording(recorder EventRecorder, sourceName string) watch.Interface {
event = &eventCopy event = &eventCopy
event.Source = sourceName event.Source = sourceName
for { for {
_, err := recorder.CreateEvent(event) _, err := recorder.Create(event)
if err == nil { if err == nil {
break break
} }

View File

@ -32,7 +32,7 @@ type testEventRecorder struct {
} }
// CreateEvent records the event for testing. // CreateEvent records the event for testing.
func (t *testEventRecorder) CreateEvent(e *api.Event) (*api.Event, error) { func (t *testEventRecorder) Create(e *api.Event) (*api.Event, error) {
if t.OnEvent != nil { if t.OnEvent != nil {
return t.OnEvent(e) return t.OnEvent(e)
} }

View File

@ -0,0 +1,100 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// ReplicationControllersNamespacer has methods to work with ReplicationController resources in a namespace
type ReplicationControllersNamespacer interface {
ReplicationControllers(namespace string) ReplicationControllerInterface
}
// ReplicationControllerInterface has methods to work with ReplicationController resources.
type ReplicationControllerInterface interface {
List(selector labels.Selector) (*api.ReplicationControllerList, error)
Get(name string) (*api.ReplicationController, error)
Create(ctrl *api.ReplicationController) (*api.ReplicationController, error)
Update(ctrl *api.ReplicationController) (*api.ReplicationController, error)
Delete(name string) error
Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error)
}
// replicationControllers implements ReplicationControllersNamespacer interface
type replicationControllers struct {
r *Client
ns string
}
// newReplicationControllers returns a PodsClient
func newReplicationControllers(c *Client, namespace string) *replicationControllers {
return &replicationControllers{c, namespace}
}
// List takes a selector, and returns the list of replication controllers that match that selector.
func (c *replicationControllers) List(selector labels.Selector) (result *api.ReplicationControllerList, err error) {
result = &api.ReplicationControllerList{}
err = c.r.Get().Namespace(c.ns).Path("replicationControllers").SelectorParam("labels", selector).Do().Into(result)
return
}
// Get returns information about a particular replication controller.
func (c *replicationControllers) Get(name string) (result *api.ReplicationController, err error) {
result = &api.ReplicationController{}
err = c.r.Get().Namespace(c.ns).Path("replicationControllers").Path(name).Do().Into(result)
return
}
// Create creates a new replication controller.
func (c *replicationControllers) Create(controller *api.ReplicationController) (result *api.ReplicationController, err error) {
result = &api.ReplicationController{}
err = c.r.Post().Namespace(c.ns).Path("replicationControllers").Body(controller).Do().Into(result)
return
}
// Update updates an existing replication controller.
func (c *replicationControllers) Update(controller *api.ReplicationController) (result *api.ReplicationController, err error) {
result = &api.ReplicationController{}
if len(controller.ResourceVersion) == 0 {
err = fmt.Errorf("invalid update object, missing resource version: %v", controller)
return
}
err = c.r.Put().Namespace(c.ns).Path("replicationControllers").Path(controller.Name).Body(controller).Do().Into(result)
return
}
// Delete deletes an existing replication controller.
func (c *replicationControllers) Delete(name string) error {
return c.r.Delete().Namespace(c.ns).Path("replicationControllers").Path(name).Do().Error()
}
// Watch returns a watch.Interface that watches the requested controllers.
func (c *replicationControllers) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.r.Get().
Namespace(c.ns).
Path("watch").
Path("replicationControllers").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}

100
pkg/client/services.go Normal file
View File

@ -0,0 +1,100 @@
/*
Copyright 2014 Google Inc. All rights reserved.
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 client
import (
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
)
// ServicesNamespacer has methods to work with Service resources in a namespace
type ServicesNamespacer interface {
Services(namespace string) ServiceInterface
}
// ServiceInterface has methods to work with Service resources.
type ServiceInterface interface {
List(selector labels.Selector) (*api.ServiceList, error)
Get(name string) (*api.Service, error)
Create(srv *api.Service) (*api.Service, error)
Update(srv *api.Service) (*api.Service, error)
Delete(name string) error
Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error)
}
// services implements PodsNamespacer interface
type services struct {
r *Client
ns string
}
// newServices returns a PodsClient
func newServices(c *Client, namespace string) *services {
return &services{c, namespace}
}
// List takes a selector, and returns the list of services that match that selector
func (c *services) List(selector labels.Selector) (result *api.ServiceList, err error) {
result = &api.ServiceList{}
err = c.r.Get().Namespace(c.ns).Path("services").SelectorParam("labels", selector).Do().Into(result)
return
}
// Get returns information about a particular service.
func (c *services) Get(name string) (result *api.Service, err error) {
result = &api.Service{}
err = c.r.Get().Namespace(c.ns).Path("services").Path(name).Do().Into(result)
return
}
// Create creates a new service.
func (c *services) Create(svc *api.Service) (result *api.Service, err error) {
result = &api.Service{}
err = c.r.Post().Namespace(c.ns).Path("services").Body(svc).Do().Into(result)
return
}
// Update updates an existing service.
func (c *services) Update(svc *api.Service) (result *api.Service, err error) {
result = &api.Service{}
if len(svc.ResourceVersion) == 0 {
err = fmt.Errorf("invalid update object, missing resource version: %v", svc)
return
}
err = c.r.Put().Namespace(c.ns).Path("services").Path(svc.Name).Body(svc).Do().Into(result)
return
}
// Delete deletes an existing service.
func (c *services) Delete(name string) error {
return c.r.Delete().Namespace(c.ns).Path("services").Path(name).Do().Error()
}
// Watch returns a watch.Interface that watches the requested services.
func (c *services) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error) {
return c.r.Get().
Namespace(c.ns).
Path("watch").
Path("services").
Param("resourceVersion", resourceVersion).
SelectorParam("labels", label).
SelectorParam("fields", field).
Watch()
}

View File

@ -42,9 +42,9 @@ type ReplicationManager struct {
// created as an interface to allow testing. // created as an interface to allow testing.
type PodControlInterface interface { type PodControlInterface interface {
// createReplica creates new replicated pods according to the spec. // createReplica creates new replicated pods according to the spec.
createReplica(ctx api.Context, controllerSpec api.ReplicationController) createReplica(namespace string, controllerSpec api.ReplicationController)
// deletePod deletes the pod identified by podID. // deletePod deletes the pod identified by podID.
deletePod(ctx api.Context, podID string) error deletePod(namespace string, podID string) error
} }
// RealPodControl is the default implementation of PodControllerInterface. // RealPodControl is the default implementation of PodControllerInterface.
@ -52,7 +52,7 @@ type RealPodControl struct {
kubeClient client.Interface kubeClient client.Interface
} }
func (r RealPodControl) createReplica(ctx api.Context, controllerSpec api.ReplicationController) { func (r RealPodControl) createReplica(namespace string, controllerSpec api.ReplicationController) {
desiredLabels := make(labels.Set) desiredLabels := make(labels.Set)
for k, v := range controllerSpec.DesiredState.PodTemplate.Labels { for k, v := range controllerSpec.DesiredState.PodTemplate.Labels {
desiredLabels[k] = v desiredLabels[k] = v
@ -65,13 +65,13 @@ func (r RealPodControl) createReplica(ctx api.Context, controllerSpec api.Replic
}, },
DesiredState: controllerSpec.DesiredState.PodTemplate.DesiredState, DesiredState: controllerSpec.DesiredState.PodTemplate.DesiredState,
} }
if _, err := r.kubeClient.CreatePod(ctx, pod); err != nil { if _, err := r.kubeClient.Pods(namespace).Create(pod); err != nil {
glog.Errorf("Unable to create pod replica: %v", err) glog.Errorf("Unable to create pod replica: %v", err)
} }
} }
func (r RealPodControl) deletePod(ctx api.Context, podID string) error { func (r RealPodControl) deletePod(namespace, podID string) error {
return r.kubeClient.DeletePod(ctx, podID) return r.kubeClient.Pods(namespace).Delete(podID)
} }
// NewReplicationManager creates a new ReplicationManager. // NewReplicationManager creates a new ReplicationManager.
@ -95,9 +95,7 @@ func (rm *ReplicationManager) Run(period time.Duration) {
// resourceVersion is a pointer to the resource version to use/update. // resourceVersion is a pointer to the resource version to use/update.
func (rm *ReplicationManager) watchControllers(resourceVersion *string) { func (rm *ReplicationManager) watchControllers(resourceVersion *string) {
ctx := api.NewContext() watching, err := rm.kubeClient.ReplicationControllers(api.NamespaceAll).Watch(
watching, err := rm.kubeClient.WatchReplicationControllers(
ctx,
labels.Everything(), labels.Everything(),
labels.Everything(), labels.Everything(),
*resourceVersion, *resourceVersion,
@ -147,8 +145,7 @@ func (rm *ReplicationManager) filterActivePods(pods []api.Pod) []api.Pod {
func (rm *ReplicationManager) syncReplicationController(controllerSpec api.ReplicationController) error { func (rm *ReplicationManager) syncReplicationController(controllerSpec api.ReplicationController) error {
s := labels.Set(controllerSpec.DesiredState.ReplicaSelector).AsSelector() s := labels.Set(controllerSpec.DesiredState.ReplicaSelector).AsSelector()
ctx := api.WithNamespace(api.NewContext(), controllerSpec.Namespace) podList, err := rm.kubeClient.Pods(controllerSpec.Namespace).List(s)
podList, err := rm.kubeClient.ListPods(ctx, s)
if err != nil { if err != nil {
return err return err
} }
@ -162,7 +159,7 @@ func (rm *ReplicationManager) syncReplicationController(controllerSpec api.Repli
for i := 0; i < diff; i++ { for i := 0; i < diff; i++ {
go func() { go func() {
defer wait.Done() defer wait.Done()
rm.podControl.createReplica(ctx, controllerSpec) rm.podControl.createReplica(controllerSpec.Namespace, controllerSpec)
}() }()
} }
wait.Wait() wait.Wait()
@ -173,7 +170,7 @@ func (rm *ReplicationManager) syncReplicationController(controllerSpec api.Repli
for i := 0; i < diff; i++ { for i := 0; i < diff; i++ {
go func(ix int) { go func(ix int) {
defer wait.Done() defer wait.Done()
rm.podControl.deletePod(ctx, filteredList[ix].Name) rm.podControl.deletePod(controllerSpec.Namespace, filteredList[ix].Name)
}(i) }(i)
} }
wait.Wait() wait.Wait()
@ -185,8 +182,7 @@ func (rm *ReplicationManager) synchronize() {
// TODO: remove this method completely and rely on the watch. // TODO: remove this method completely and rely on the watch.
// Add resource version tracking to watch to make this work. // Add resource version tracking to watch to make this work.
var controllerSpecs []api.ReplicationController var controllerSpecs []api.ReplicationController
ctx := api.NewContext() list, err := rm.kubeClient.ReplicationControllers(api.NamespaceAll).List(labels.Everything())
list, err := rm.kubeClient.ListReplicationControllers(ctx, labels.Everything())
if err != nil { if err != nil {
glog.Errorf("Synchronization error: %v (%#v)", err, err) glog.Errorf("Synchronization error: %v (%#v)", err, err)
return return

View File

@ -30,7 +30,6 @@ import (
"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/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools" "github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -44,20 +43,20 @@ func makeURL(suffix string) string {
type FakePodControl struct { type FakePodControl struct {
controllerSpec []api.ReplicationController controllerSpec []api.ReplicationController
deletePodID []string deletePodName []string
lock sync.Mutex lock sync.Mutex
} }
func (f *FakePodControl) createReplica(ctx api.Context, spec api.ReplicationController) { func (f *FakePodControl) createReplica(namespace string, spec api.ReplicationController) {
f.lock.Lock() f.lock.Lock()
defer f.lock.Unlock() defer f.lock.Unlock()
f.controllerSpec = append(f.controllerSpec, spec) f.controllerSpec = append(f.controllerSpec, spec)
} }
func (f *FakePodControl) deletePod(ctx api.Context, podID string) error { func (f *FakePodControl) deletePod(namespace string, podName string) error {
f.lock.Lock() f.lock.Lock()
defer f.lock.Unlock() defer f.lock.Unlock()
f.deletePodID = append(f.deletePodID, podID) f.deletePodName = append(f.deletePodName, podName)
return nil return nil
} }
@ -102,8 +101,8 @@ func validateSyncReplication(t *testing.T, fakePodControl *FakePodControl, expec
if len(fakePodControl.controllerSpec) != expectedCreates { if len(fakePodControl.controllerSpec) != expectedCreates {
t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", expectedCreates, len(fakePodControl.controllerSpec)) t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", expectedCreates, len(fakePodControl.controllerSpec))
} }
if len(fakePodControl.deletePodID) != expectedDeletes { if len(fakePodControl.deletePodName) != expectedDeletes {
t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", expectedDeletes, len(fakePodControl.deletePodID)) t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", expectedDeletes, len(fakePodControl.deletePodName))
} }
} }
@ -168,7 +167,7 @@ func TestSyncReplicationControllerCreates(t *testing.T) {
} }
func TestCreateReplica(t *testing.T) { func TestCreateReplica(t *testing.T) {
ctx := api.NewDefaultContext() ns := api.NamespaceDefault
body := runtime.EncodeOrDie(testapi.Codec(), &api.Pod{}) body := runtime.EncodeOrDie(testapi.Codec(), &api.Pod{})
fakeHandler := util.FakeHandler{ fakeHandler := util.FakeHandler{
StatusCode: 200, StatusCode: 200,
@ -205,7 +204,7 @@ func TestCreateReplica(t *testing.T) {
}, },
} }
podControl.createReplica(ctx, controllerSpec) podControl.createReplica(ns, controllerSpec)
expectedPod := api.Pod{ expectedPod := api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
@ -322,12 +321,9 @@ type FakeWatcher struct {
*client.Fake *client.Fake
} }
func (fw FakeWatcher) WatchReplicationControllers(ctx api.Context, l, f labels.Selector, rv string) (watch.Interface, error) {
return fw.w, nil
}
func TestWatchControllers(t *testing.T) { func TestWatchControllers(t *testing.T) {
client := FakeWatcher{watch.NewFake(), &client.Fake{}} fakeWatch := watch.NewFake()
client := &client.Fake{Watch: fakeWatch}
manager := NewReplicationManager(client) manager := NewReplicationManager(client)
var testControllerSpec api.ReplicationController var testControllerSpec api.ReplicationController
received := make(chan struct{}) received := make(chan struct{})
@ -344,7 +340,8 @@ func TestWatchControllers(t *testing.T) {
// Test normal case // Test normal case
testControllerSpec.Name = "foo" testControllerSpec.Name = "foo"
client.w.Add(&testControllerSpec)
fakeWatch.Add(&testControllerSpec)
select { select {
case <-received: case <-received:

View File

@ -127,14 +127,15 @@ func SaveNamespaceInfo(path string, ns *NamespaceInfo) error {
// updating more complex replication controllers. If this is blank then no // updating more complex replication controllers. If this is blank then no
// update of the image is performed. // update of the image is performed.
func Update(ctx api.Context, name string, client client.Interface, updatePeriod time.Duration, imageName string) error { func Update(ctx api.Context, name string, client client.Interface, updatePeriod time.Duration, imageName string) error {
controller, err := client.GetReplicationController(ctx, name) // TODO ctx is not needed as input to this function, should just be 'namespace'
controller, err := client.ReplicationControllers(api.Namespace(ctx)).Get(name)
if err != nil { if err != nil {
return err return err
} }
if len(imageName) != 0 { if len(imageName) != 0 {
controller.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image = imageName controller.DesiredState.PodTemplate.DesiredState.Manifest.Containers[0].Image = imageName
controller, err = client.UpdateReplicationController(ctx, controller) controller, err = client.ReplicationControllers(controller.Namespace).Update(controller)
if err != nil { if err != nil {
return err return err
} }
@ -142,7 +143,7 @@ func Update(ctx api.Context, name string, client client.Interface, updatePeriod
s := labels.Set(controller.DesiredState.ReplicaSelector).AsSelector() s := labels.Set(controller.DesiredState.ReplicaSelector).AsSelector()
podList, err := client.ListPods(ctx, s) podList, err := client.Pods(api.Namespace(ctx)).List(s)
if err != nil { if err != nil {
return err return err
} }
@ -153,14 +154,14 @@ func Update(ctx api.Context, name string, client client.Interface, updatePeriod
for _, pod := range podList.Items { for _, pod := range podList.Items {
// We delete the pod here, the controller will recreate it. This will result in pulling // We delete the pod here, the controller will recreate it. This will result in pulling
// a new Docker image. This isn't a full "update" but it's what we support for now. // a new Docker image. This isn't a full "update" but it's what we support for now.
err = client.DeletePod(ctx, pod.Name) err = client.Pods(pod.Namespace).Delete(pod.Name)
if err != nil { if err != nil {
return err return err
} }
time.Sleep(updatePeriod) time.Sleep(updatePeriod)
} }
return wait.Poll(time.Second*5, time.Second*300, func() (bool, error) { return wait.Poll(time.Second*5, time.Second*300, func() (bool, error) {
podList, err := client.ListPods(ctx, s) podList, err := client.Pods(api.Namespace(ctx)).List(s)
if err != nil { if err != nil {
return false, err return false, err
} }
@ -175,12 +176,13 @@ func StopController(ctx api.Context, name string, client client.Interface) error
// ResizeController resizes a controller named 'name' by setting replicas to 'replicas'. // ResizeController resizes a controller named 'name' by setting replicas to 'replicas'.
func ResizeController(ctx api.Context, name string, replicas int, client client.Interface) error { func ResizeController(ctx api.Context, name string, replicas int, client client.Interface) error {
controller, err := client.GetReplicationController(ctx, name) // TODO ctx is not needed, and should just be a namespace
controller, err := client.ReplicationControllers(api.Namespace(ctx)).Get(name)
if err != nil { if err != nil {
return err return err
} }
controller.DesiredState.Replicas = replicas controller.DesiredState.Replicas = replicas
controllerOut, err := client.UpdateReplicationController(ctx, controller) controllerOut, err := client.ReplicationControllers(api.Namespace(ctx)).Update(controller)
if err != nil { if err != nil {
return err return err
} }
@ -237,6 +239,7 @@ func portsFromString(spec string) ([]api.Port, error) {
// RunController creates a new replication controller named 'name' which creates 'replicas' pods running 'image'. // RunController creates a new replication controller named 'name' which creates 'replicas' pods running 'image'.
func RunController(ctx api.Context, image, name string, replicas int, client client.Interface, portSpec string, servicePort int) error { func RunController(ctx api.Context, image, name string, replicas int, client client.Interface, portSpec string, servicePort int) error {
// TODO replace ctx with a namespace string
if servicePort > 0 && !util.IsDNSLabel(name) { if servicePort > 0 && !util.IsDNSLabel(name) {
return fmt.Errorf("Service creation requested, but an invalid name for a service was provided (%s). Service names must be valid DNS labels.", name) return fmt.Errorf("Service creation requested, but an invalid name for a service was provided (%s). Service names must be valid DNS labels.", name)
} }
@ -273,7 +276,7 @@ func RunController(ctx api.Context, image, name string, replicas int, client cli
}, },
} }
controllerOut, err := client.CreateReplicationController(ctx, controller) controllerOut, err := client.ReplicationControllers(api.Namespace(ctx)).Create(controller)
if err != nil { if err != nil {
return err return err
} }
@ -298,6 +301,7 @@ func RunController(ctx api.Context, image, name string, replicas int, client cli
} }
func createService(ctx api.Context, name string, port int, client client.Interface) (*api.Service, error) { func createService(ctx api.Context, name string, port int, client client.Interface) (*api.Service, error) {
// TODO remove context in favor of just namespace string
svc := &api.Service{ svc := &api.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: name, Name: name,
@ -310,19 +314,20 @@ func createService(ctx api.Context, name string, port int, client client.Interfa
"simpleService": name, "simpleService": name,
}, },
} }
svc, err := client.CreateService(ctx, svc) svc, err := client.Services(api.Namespace(ctx)).Create(svc)
return svc, err return svc, err
} }
// DeleteController deletes a replication controller named 'name', requires that the controller // DeleteController deletes a replication controller named 'name', requires that the controller
// already be stopped. // already be stopped.
func DeleteController(ctx api.Context, name string, client client.Interface) error { func DeleteController(ctx api.Context, name string, client client.Interface) error {
controller, err := client.GetReplicationController(ctx, name) // TODO remove ctx in favor of just namespace string
controller, err := client.ReplicationControllers(api.Namespace(ctx)).Get(name)
if err != nil { if err != nil {
return err return err
} }
if controller.DesiredState.Replicas != 0 { if controller.DesiredState.Replicas != 0 {
return fmt.Errorf("controller has non-zero replicas (%d), please stop it first", controller.DesiredState.Replicas) return fmt.Errorf("controller has non-zero replicas (%d), please stop it first", controller.DesiredState.Replicas)
} }
return client.DeleteReplicationController(ctx, name) return client.ReplicationControllers(api.Namespace(ctx)).Delete(name)
} }

View File

@ -36,7 +36,7 @@ func validateAction(expectedAction, actualAction client.FakeAction, t *testing.T
func TestUpdateWithPods(t *testing.T) { func TestUpdateWithPods(t *testing.T) {
fakeClient := client.Fake{ fakeClient := client.Fake{
Pods: api.PodList{ PodsList: api.PodList{
Items: []api.Pod{ Items: []api.Pod{
{ObjectMeta: api.ObjectMeta{Name: "pod-1"}}, {ObjectMeta: api.ObjectMeta{Name: "pod-1"}},
{ObjectMeta: api.ObjectMeta{Name: "pod-2"}}, {ObjectMeta: api.ObjectMeta{Name: "pod-2"}},
@ -67,7 +67,7 @@ func TestUpdateNoPods(t *testing.T) {
func TestUpdateWithNewImage(t *testing.T) { func TestUpdateWithNewImage(t *testing.T) {
fakeClient := client.Fake{ fakeClient := client.Fake{
Pods: api.PodList{ PodsList: api.PodList{
Items: []api.Pod{ Items: []api.Pod{
{ObjectMeta: api.ObjectMeta{Name: "pod-1"}}, {ObjectMeta: api.ObjectMeta{Name: "pod-1"}},
{ObjectMeta: api.ObjectMeta{Name: "pod-2"}}, {ObjectMeta: api.ObjectMeta{Name: "pod-2"}},

View File

@ -55,7 +55,8 @@ func Describe(w io.Writer, c client.Interface, resource, id string) error {
} }
func describePod(w io.Writer, c client.Interface, id string) (string, error) { func describePod(w io.Writer, c client.Interface, id string) (string, error) {
pod, err := c.GetPod(api.NewDefaultContext(), id) // TODO this needs proper namespace support
pod, err := c.Pods(api.NamespaceDefault).Get(id)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -72,7 +73,8 @@ func describePod(w io.Writer, c client.Interface, id string) (string, error) {
} }
func describeReplicationController(w io.Writer, c client.Interface, id string) (string, error) { func describeReplicationController(w io.Writer, c client.Interface, id string) (string, error) {
controller, err := c.GetReplicationController(api.NewDefaultContext(), id) // TODO this needs proper namespace support
controller, err := c.ReplicationControllers(api.NamespaceDefault).Get(id)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -94,7 +96,7 @@ func describeReplicationController(w io.Writer, c client.Interface, id string) (
} }
func describeService(w io.Writer, c client.Interface, id string) (string, error) { func describeService(w io.Writer, c client.Interface, id string) (string, error) {
service, err := c.GetService(api.NewDefaultContext(), id) service, err := c.Services(api.NamespaceDefault).Get(id)
if err != nil { if err != nil {
return "", err return "", err
} }
@ -122,7 +124,7 @@ func describeMinion(w io.Writer, c client.Interface, id string) (string, error)
// client.Interface doesn't have GetMinion(id) yet so we hack it up. // client.Interface doesn't have GetMinion(id) yet so we hack it up.
func getMinion(c client.Interface, id string) (*api.Minion, error) { func getMinion(c client.Interface, id string) (*api.Minion, error) {
minionList, err := c.ListMinions() minionList, err := c.Minions().List()
if err != nil { if err != nil {
glog.Fatalf("Error getting minion info: %v\n", err) glog.Fatalf("Error getting minion info: %v\n", err)
} }
@ -141,7 +143,8 @@ func getMinion(c client.Interface, id string) (*api.Minion, error) {
// of getting all RC's and searching through them manually). // of getting all RC's and searching through them manually).
func getReplicationControllersForLabels(c client.Interface, labelsToMatch labels.Labels) string { func getReplicationControllersForLabels(c client.Interface, labelsToMatch labels.Labels) string {
// Get all replication controllers. // Get all replication controllers.
rcs, err := c.ListReplicationControllers(api.NewDefaultContext(), labels.Everything()) // TODO this needs a namespace scope as argument
rcs, err := c.ReplicationControllers(api.NamespaceDefault).List(labels.Everything())
if err != nil { if err != nil {
glog.Fatalf("Error getting replication controllers: %v\n", err) glog.Fatalf("Error getting replication controllers: %v\n", err)
} }
@ -169,7 +172,7 @@ func getReplicationControllersForLabels(c client.Interface, labelsToMatch labels
} }
func getPodStatusForReplicationController(kubeClient client.Interface, controller *api.ReplicationController) (running, waiting, terminated int, err error) { func getPodStatusForReplicationController(kubeClient client.Interface, controller *api.ReplicationController) (running, waiting, terminated int, err error) {
rcPods, err := kubeClient.ListPods(api.NewDefaultContext(), labels.SelectorFromSet(controller.DesiredState.ReplicaSelector)) rcPods, err := kubeClient.Pods(controller.Namespace).List(labels.SelectorFromSet(controller.DesiredState.ReplicaSelector))
if err != nil { if err != nil {
return return
} }

View File

@ -137,7 +137,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: m.client.Minions(),
}), }),
"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

@ -27,18 +27,24 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
) )
// Watcher is the interface needed to receive changes to services and endpoints. // ServicesWatcher is capable of listing and watching for changes to services across ALL namespaces
type Watcher interface { type ServicesWatcher interface {
ListServices(ctx api.Context, label labels.Selector) (*api.ServiceList, error) List(label labels.Selector) (*api.ServiceList, error)
ListEndpoints(ctx api.Context, label labels.Selector) (*api.EndpointsList, error) Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error)
WatchServices(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) }
WatchEndpoints(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error)
// EndpointsWatcher is capable of listing and watching for changes to endpoints across ALL namespaces
type EndpointsWatcher interface {
List(label labels.Selector) (*api.EndpointsList, error)
Watch(label, field labels.Selector, resourceVersion string) (watch.Interface, error)
} }
// SourceAPI implements a configuration source for services and endpoints that // SourceAPI implements a configuration source for services and endpoints that
// uses the client watch API to efficiently detect changes. // uses the client watch API to efficiently detect changes.
type SourceAPI struct { type SourceAPI struct {
client Watcher servicesWatcher ServicesWatcher
endpointsWatcher EndpointsWatcher
services chan<- ServiceUpdate services chan<- ServiceUpdate
endpoints chan<- EndpointsUpdate endpoints chan<- EndpointsUpdate
@ -47,9 +53,10 @@ type SourceAPI struct {
} }
// NewSourceAPI creates a config source that watches for changes to the services and endpoints. // NewSourceAPI creates a config source that watches for changes to the services and endpoints.
func NewSourceAPI(client Watcher, period time.Duration, services chan<- ServiceUpdate, endpoints chan<- EndpointsUpdate) *SourceAPI { func NewSourceAPI(servicesWatcher ServicesWatcher, endpointsWatcher EndpointsWatcher, period time.Duration, services chan<- ServiceUpdate, endpoints chan<- EndpointsUpdate) *SourceAPI {
config := &SourceAPI{ config := &SourceAPI{
client: client, servicesWatcher: servicesWatcher,
endpointsWatcher: endpointsWatcher,
services: services, services: services,
endpoints: endpoints, endpoints: endpoints,
@ -72,9 +79,8 @@ func NewSourceAPI(client Watcher, period time.Duration, services chan<- ServiceU
// runServices loops forever looking for changes to services. // runServices loops forever looking for changes to services.
func (s *SourceAPI) runServices(resourceVersion *string) { func (s *SourceAPI) runServices(resourceVersion *string) {
ctx := api.NewContext()
if len(*resourceVersion) == 0 { if len(*resourceVersion) == 0 {
services, err := s.client.ListServices(ctx, labels.Everything()) services, err := s.servicesWatcher.List(labels.Everything())
if err != nil { if err != nil {
glog.Errorf("Unable to load services: %v", err) glog.Errorf("Unable to load services: %v", err)
time.Sleep(wait.Jitter(s.waitDuration, 0.0)) time.Sleep(wait.Jitter(s.waitDuration, 0.0))
@ -84,7 +90,7 @@ func (s *SourceAPI) runServices(resourceVersion *string) {
s.services <- ServiceUpdate{Op: SET, Services: services.Items} s.services <- ServiceUpdate{Op: SET, Services: services.Items}
} }
watcher, err := s.client.WatchServices(ctx, labels.Everything(), labels.Everything(), *resourceVersion) watcher, err := s.servicesWatcher.Watch(labels.Everything(), labels.Everything(), *resourceVersion)
if err != nil { if err != nil {
glog.Errorf("Unable to watch for services changes: %v", err) glog.Errorf("Unable to watch for services changes: %v", err)
time.Sleep(wait.Jitter(s.waitDuration, 0.0)) time.Sleep(wait.Jitter(s.waitDuration, 0.0))
@ -122,9 +128,8 @@ func handleServicesWatch(resourceVersion *string, ch <-chan watch.Event, updates
// runEndpoints loops forever looking for changes to endpoints. // runEndpoints loops forever looking for changes to endpoints.
func (s *SourceAPI) runEndpoints(resourceVersion *string) { func (s *SourceAPI) runEndpoints(resourceVersion *string) {
ctx := api.NewContext()
if len(*resourceVersion) == 0 { if len(*resourceVersion) == 0 {
endpoints, err := s.client.ListEndpoints(ctx, labels.Everything()) endpoints, err := s.endpointsWatcher.List(labels.Everything())
if err != nil { if err != nil {
glog.Errorf("Unable to load endpoints: %v", err) glog.Errorf("Unable to load endpoints: %v", err)
time.Sleep(wait.Jitter(s.waitDuration, 0.0)) time.Sleep(wait.Jitter(s.waitDuration, 0.0))
@ -134,7 +139,7 @@ func (s *SourceAPI) runEndpoints(resourceVersion *string) {
s.endpoints <- EndpointsUpdate{Op: SET, Endpoints: endpoints.Items} s.endpoints <- EndpointsUpdate{Op: SET, Endpoints: endpoints.Items}
} }
watcher, err := s.client.WatchEndpoints(ctx, labels.Everything(), labels.Everything(), *resourceVersion) watcher, err := s.endpointsWatcher.Watch(labels.Everything(), labels.Everything(), *resourceVersion)
if err != nil { if err != nil {
glog.Errorf("Unable to watch for endpoints changes: %v", err) glog.Errorf("Unable to watch for endpoints changes: %v", err)
time.Sleep(wait.Jitter(s.waitDuration, 0.0)) time.Sleep(wait.Jitter(s.waitDuration, 0.0))

View File

@ -32,7 +32,7 @@ func TestServices(t *testing.T) {
fakeWatch := watch.NewFake() fakeWatch := watch.NewFake()
fakeClient := &client.Fake{Watch: fakeWatch} fakeClient := &client.Fake{Watch: fakeWatch}
services := make(chan ServiceUpdate) services := make(chan ServiceUpdate)
source := SourceAPI{client: fakeClient, services: services} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), services: services}
resourceVersion := "1" resourceVersion := "1"
go func() { go func() {
// called twice // called twice
@ -84,7 +84,7 @@ func TestServicesFromZero(t *testing.T) {
}, },
} }
services := make(chan ServiceUpdate) services := make(chan ServiceUpdate)
source := SourceAPI{client: fakeClient, services: services} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), services: services}
resourceVersion := "" resourceVersion := ""
ch := make(chan struct{}) ch := make(chan struct{})
go func() { go func() {
@ -112,7 +112,7 @@ func TestServicesFromZero(t *testing.T) {
func TestServicesError(t *testing.T) { func TestServicesError(t *testing.T) {
fakeClient := &client.Fake{Err: errors.New("test")} fakeClient := &client.Fake{Err: errors.New("test")}
services := make(chan ServiceUpdate) services := make(chan ServiceUpdate)
source := SourceAPI{client: fakeClient, services: services} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), services: services}
resourceVersion := "1" resourceVersion := "1"
ch := make(chan struct{}) ch := make(chan struct{})
go func() { go func() {
@ -133,7 +133,7 @@ func TestServicesError(t *testing.T) {
func TestServicesFromZeroError(t *testing.T) { func TestServicesFromZeroError(t *testing.T) {
fakeClient := &client.Fake{Err: errors.New("test")} fakeClient := &client.Fake{Err: errors.New("test")}
services := make(chan ServiceUpdate) services := make(chan ServiceUpdate)
source := SourceAPI{client: fakeClient, services: services} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), services: services}
resourceVersion := "" resourceVersion := ""
ch := make(chan struct{}) ch := make(chan struct{})
go func() { go func() {
@ -157,7 +157,7 @@ func TestEndpoints(t *testing.T) {
fakeWatch := watch.NewFake() fakeWatch := watch.NewFake()
fakeClient := &client.Fake{Watch: fakeWatch} fakeClient := &client.Fake{Watch: fakeWatch}
endpoints := make(chan EndpointsUpdate) endpoints := make(chan EndpointsUpdate)
source := SourceAPI{client: fakeClient, endpoints: endpoints} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), endpoints: endpoints}
resourceVersion := "1" resourceVersion := "1"
go func() { go func() {
// called twice // called twice
@ -209,7 +209,7 @@ func TestEndpointsFromZero(t *testing.T) {
}, },
} }
endpoints := make(chan EndpointsUpdate) endpoints := make(chan EndpointsUpdate)
source := SourceAPI{client: fakeClient, endpoints: endpoints} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), endpoints: endpoints}
resourceVersion := "" resourceVersion := ""
ch := make(chan struct{}) ch := make(chan struct{})
go func() { go func() {
@ -237,7 +237,7 @@ func TestEndpointsFromZero(t *testing.T) {
func TestEndpointsError(t *testing.T) { func TestEndpointsError(t *testing.T) {
fakeClient := &client.Fake{Err: errors.New("test")} fakeClient := &client.Fake{Err: errors.New("test")}
endpoints := make(chan EndpointsUpdate) endpoints := make(chan EndpointsUpdate)
source := SourceAPI{client: fakeClient, endpoints: endpoints} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), endpoints: endpoints}
resourceVersion := "1" resourceVersion := "1"
ch := make(chan struct{}) ch := make(chan struct{})
go func() { go func() {
@ -258,7 +258,7 @@ func TestEndpointsError(t *testing.T) {
func TestEndpointsFromZeroError(t *testing.T) { func TestEndpointsFromZeroError(t *testing.T) {
fakeClient := &client.Fake{Err: errors.New("test")} fakeClient := &client.Fake{Err: errors.New("test")}
endpoints := make(chan EndpointsUpdate) endpoints := make(chan EndpointsUpdate)
source := SourceAPI{client: fakeClient, endpoints: endpoints} source := SourceAPI{servicesWatcher: fakeClient.Services(api.NamespaceAll), endpointsWatcher: fakeClient.Endpoints(api.NamespaceAll), endpoints: endpoints}
resourceVersion := "" resourceVersion := ""
ch := make(chan struct{}) ch := make(chan struct{})
go func() { go func() {

View File

@ -273,7 +273,7 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodStatus,
return api.PodWaiting, nil return api.PodWaiting, nil
} }
if minions != nil { if minions != nil {
res, err := minions.ListMinions() res, err := minions.List()
if err != nil { if err != nil {
glog.Errorf("Error listing minions: %v", err) glog.Errorf("Error listing minions: %v", err)
return "", err return "", err

View File

@ -385,7 +385,7 @@ func TestGetPodCloud(t *testing.T) {
func TestMakePodStatus(t *testing.T) { func TestMakePodStatus(t *testing.T) {
fakeClient := client.Fake{ fakeClient := client.Fake{
Minions: api.MinionList{ MinionsList: api.MinionList{
Items: []api.Minion{ Items: []api.Minion{
{ {
ObjectMeta: api.ObjectMeta{Name: "machine"}, ObjectMeta: api.ObjectMeta{Name: "machine"},
@ -517,7 +517,7 @@ func TestMakePodStatus(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
if status, err := getPodStatus(test.pod, &fakeClient); status != test.status { if status, err := getPodStatus(test.pod, fakeClient.Minions()); 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.Minion, error) { func (nodes ClientNodeInfo) GetNodeInfo(nodeID string) (*api.Minion, error) {
return nodes.GetMinion(nodeID) return nodes.Minions().Get(nodeID)
} }
func isVolumeConflict(volume api.Volume, pod *api.Pod) bool { func isVolumeConflict(volume api.Volume, pod *api.Pod) bool {

View File

@ -44,16 +44,14 @@ func NewEndpointController(client *client.Client) *EndpointController {
// SyncServiceEndpoints syncs service endpoints. // SyncServiceEndpoints syncs service endpoints.
func (e *EndpointController) SyncServiceEndpoints() error { func (e *EndpointController) SyncServiceEndpoints() error {
ctx := api.NewContext() services, err := e.client.Services(api.NamespaceAll).List(labels.Everything())
services, err := e.client.ListServices(ctx, labels.Everything())
if err != nil { if err != nil {
glog.Errorf("Failed to list services: %v", err) glog.Errorf("Failed to list services: %v", err)
return err return err
} }
var resultErr error var resultErr error
for _, service := range services.Items { for _, service := range services.Items {
nsCtx := api.WithNamespace(ctx, service.Namespace) pods, err := e.client.Pods(service.Namespace).List(labels.Set(service.Selector).AsSelector())
pods, err := e.client.ListPods(nsCtx, labels.Set(service.Selector).AsSelector())
if err != nil { if err != nil {
glog.Errorf("Error syncing service: %#v, skipping.", service) glog.Errorf("Error syncing service: %#v, skipping.", service)
resultErr = err resultErr = err
@ -72,7 +70,7 @@ func (e *EndpointController) SyncServiceEndpoints() error {
} }
endpoints = append(endpoints, net.JoinHostPort(pod.CurrentState.PodIP, strconv.Itoa(port))) endpoints = append(endpoints, net.JoinHostPort(pod.CurrentState.PodIP, strconv.Itoa(port)))
} }
currentEndpoints, err := e.client.GetEndpoints(nsCtx, service.Name) currentEndpoints, err := e.client.Endpoints(service.Namespace).Get(service.Name)
if err != nil { if err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
currentEndpoints = &api.Endpoints{ currentEndpoints = &api.Endpoints{
@ -91,14 +89,14 @@ func (e *EndpointController) SyncServiceEndpoints() error {
if len(currentEndpoints.ResourceVersion) == 0 { if len(currentEndpoints.ResourceVersion) == 0 {
// No previous endpoints, create them // No previous endpoints, create them
_, err = e.client.CreateEndpoints(nsCtx, newEndpoints) _, err = e.client.Endpoints(service.Namespace).Create(newEndpoints)
} else { } else {
// Pre-existing // Pre-existing
if endpointsEqual(currentEndpoints, endpoints) { if endpointsEqual(currentEndpoints, endpoints) {
glog.V(2).Infof("endpoints are equal for %s, skipping update", service.Name) glog.V(2).Infof("endpoints are equal for %s, skipping update", service.Name)
continue continue
} }
_, err = e.client.UpdateEndpoints(nsCtx, newEndpoints) _, err = e.client.Endpoints(service.Namespace).Update(newEndpoints)
} }
if err != nil { if err != nil {
glog.Errorf("Error updating endpoints: %#v", err) glog.Errorf("Error updating endpoints: %#v", err)

View File

@ -56,7 +56,7 @@ func main() {
glog.Fatalf("Invalid API configuration: %v", err) glog.Fatalf("Invalid API configuration: %v", err)
} }
record.StartRecording(kubeClient, "scheduler") record.StartRecording(kubeClient.Events(), "scheduler")
go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil) go http.ListenAndServe(net.JoinHostPort(address.String(), strconv.Itoa(*port)), nil)

View File

@ -59,7 +59,7 @@ func TestClient(t *testing.T) {
} }
for apiVersion, values := range testCases { for apiVersion, values := range testCases {
ctx := api.NewDefaultContext() ns := api.NamespaceDefault
deleteAllEtcdKeys() deleteAllEtcdKeys()
s := httptest.NewServer(apiserver.Handle(values.Storage, values.Codec, fmt.Sprintf("/api/%s/", apiVersion), values.selfLinker)) s := httptest.NewServer(apiserver.Handle(values.Storage, values.Codec, fmt.Sprintf("/api/%s/", apiVersion), values.selfLinker))
client := client.NewOrDie(&client.Config{Host: s.URL, Version: apiVersion}) client := client.NewOrDie(&client.Config{Host: s.URL, Version: apiVersion})
@ -72,7 +72,7 @@ func TestClient(t *testing.T) {
t.Errorf("expected %#v, got %#v", e, a) t.Errorf("expected %#v, got %#v", e, a)
} }
pods, err := client.ListPods(ctx, labels.Everything()) pods, err := client.Pods(ns).List(labels.Everything())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -93,14 +93,14 @@ func TestClient(t *testing.T) {
}, },
}, },
} }
got, err := client.CreatePod(ctx, pod) got, err := client.Pods(ns).Create(pod)
if err == nil { if err == nil {
t.Fatalf("unexpected non-error: %v", err) t.Fatalf("unexpected non-error: %v", err)
} }
// get a created pod // get a created pod
pod.DesiredState.Manifest.Containers[0].Image = "an-image" pod.DesiredState.Manifest.Containers[0].Image = "an-image"
got, err = client.CreatePod(ctx, pod) got, err = client.Pods(ns).Create(pod)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -109,7 +109,7 @@ func TestClient(t *testing.T) {
} }
// pod is shown, but not scheduled // pod is shown, but not scheduled
pods, err = client.ListPods(ctx, labels.Everything()) pods, err = client.Pods(ns).List(labels.Everything())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }