From cee738871e1532bf759d9834aa60e15a64c6d6b3 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Mon, 7 Dec 2015 14:15:44 -0800 Subject: [PATCH] Add a client implementation for third party resources --- pkg/client/unversioned/extensions.go | 5 + .../testclient/fake_thirdpartyresources.go | 83 ++++++++ .../unversioned/testclient/testclient.go | 4 + pkg/client/unversioned/thirdpartyresources.go | 101 ++++++++++ .../unversioned/thirdpartyresources_test.go | 182 ++++++++++++++++++ 5 files changed, 375 insertions(+) create mode 100644 pkg/client/unversioned/testclient/fake_thirdpartyresources.go create mode 100644 pkg/client/unversioned/thirdpartyresources.go create mode 100644 pkg/client/unversioned/thirdpartyresources_test.go diff --git a/pkg/client/unversioned/extensions.go b/pkg/client/unversioned/extensions.go index 0648014f07b..f35f53b93bf 100644 --- a/pkg/client/unversioned/extensions.go +++ b/pkg/client/unversioned/extensions.go @@ -37,6 +37,7 @@ type ExtensionsInterface interface { DeploymentsNamespacer JobsNamespacer IngressNamespacer + ThirdPartyResourceNamespacer } // ExtensionsClient is used to interact with experimental Kubernetes features. @@ -99,6 +100,10 @@ func (c *ExtensionsClient) Ingress(namespace string) IngressInterface { return newIngress(c, namespace) } +func (c *ExtensionsClient) ThirdPartyResources(namespace string) ThirdPartyResourceInterface { + return newThirdPartyResources(c, namespace) +} + // NewExtensions creates a new ExtensionsClient for the given config. This client // provides access to experimental Kubernetes features. // Features of Extensions group are not supported and may be changed or removed in diff --git a/pkg/client/unversioned/testclient/fake_thirdpartyresources.go b/pkg/client/unversioned/testclient/fake_thirdpartyresources.go new file mode 100644 index 00000000000..516724ff0ef --- /dev/null +++ b/pkg/client/unversioned/testclient/fake_thirdpartyresources.go @@ -0,0 +1,83 @@ +/* +Copyright 2015 The Kubernetes Authors 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 testclient + +import ( + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" + kclientlib "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/watch" +) + +// FakeThirdPartyResources implements ThirdPartyResourceInterface. 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 FakeThirdPartyResources struct { + Fake *FakeExperimental + Namespace string +} + +// Ensure statically that FakeThirdPartyResources implements DaemonInterface. +var _ kclientlib.ThirdPartyResourceInterface = &FakeThirdPartyResources{} + +func (c *FakeThirdPartyResources) Get(name string) (*extensions.ThirdPartyResource, error) { + obj, err := c.Fake.Invokes(NewGetAction("thirdpartyresources", c.Namespace, name), &extensions.ThirdPartyResource{}) + if obj == nil { + return nil, err + } + return obj.(*extensions.ThirdPartyResource), err +} + +func (c *FakeThirdPartyResources) List(opts unversioned.ListOptions) (*extensions.ThirdPartyResourceList, error) { + obj, err := c.Fake.Invokes(NewListAction("thirdpartyresources", c.Namespace, opts), &extensions.ThirdPartyResourceList{}) + if obj == nil { + return nil, err + } + return obj.(*extensions.ThirdPartyResourceList), err +} + +func (c *FakeThirdPartyResources) Create(daemon *extensions.ThirdPartyResource) (*extensions.ThirdPartyResource, error) { + obj, err := c.Fake.Invokes(NewCreateAction("thirdpartyresources", c.Namespace, daemon), &extensions.ThirdPartyResource{}) + if obj == nil { + return nil, err + } + return obj.(*extensions.ThirdPartyResource), err +} + +func (c *FakeThirdPartyResources) Update(daemon *extensions.ThirdPartyResource) (*extensions.ThirdPartyResource, error) { + obj, err := c.Fake.Invokes(NewUpdateAction("thirdpartyresources", c.Namespace, daemon), &extensions.ThirdPartyResource{}) + if obj == nil { + return nil, err + } + return obj.(*extensions.ThirdPartyResource), err +} + +func (c *FakeThirdPartyResources) UpdateStatus(daemon *extensions.ThirdPartyResource) (*extensions.ThirdPartyResource, error) { + obj, err := c.Fake.Invokes(NewUpdateSubresourceAction("thirdpartyresources", "status", c.Namespace, daemon), &extensions.ThirdPartyResource{}) + if obj == nil { + return nil, err + } + return obj.(*extensions.ThirdPartyResource), err +} + +func (c *FakeThirdPartyResources) Delete(name string) error { + _, err := c.Fake.Invokes(NewDeleteAction("thirdpartyresources", c.Namespace, name), &extensions.ThirdPartyResource{}) + return err +} + +func (c *FakeThirdPartyResources) Watch(opts unversioned.ListOptions) (watch.Interface, error) { + return c.Fake.InvokesWatch(NewWatchAction("thirdpartyresources", c.Namespace, opts)) +} diff --git a/pkg/client/unversioned/testclient/testclient.go b/pkg/client/unversioned/testclient/testclient.go index b6bd6e2150e..ebbc6008efd 100644 --- a/pkg/client/unversioned/testclient/testclient.go +++ b/pkg/client/unversioned/testclient/testclient.go @@ -353,6 +353,10 @@ func (c *FakeExperimental) Ingress(namespace string) client.IngressInterface { return &FakeIngress{Fake: c, Namespace: namespace} } +func (c *FakeExperimental) ThirdPartyResources(namespace string) client.ThirdPartyResourceInterface { + return &FakeThirdPartyResources{Fake: c, Namespace: namespace} +} + type FakeDiscovery struct { *Fake } diff --git a/pkg/client/unversioned/thirdpartyresources.go b/pkg/client/unversioned/thirdpartyresources.go new file mode 100644 index 00000000000..b7fbf8dcfed --- /dev/null +++ b/pkg/client/unversioned/thirdpartyresources.go @@ -0,0 +1,101 @@ +/* +Copyright 2015 The Kubernetes Authors 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 unversioned + +import ( + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/watch" +) + +// ThirdPartyResourceNamespacer has methods to work with ThirdPartyResource resources in a namespace +type ThirdPartyResourceNamespacer interface { + ThirdPartyResources(namespace string) ThirdPartyResourceInterface +} + +type ThirdPartyResourceInterface interface { + List(opts unversioned.ListOptions) (*extensions.ThirdPartyResourceList, error) + Get(name string) (*extensions.ThirdPartyResource, error) + Create(ctrl *extensions.ThirdPartyResource) (*extensions.ThirdPartyResource, error) + Update(ctrl *extensions.ThirdPartyResource) (*extensions.ThirdPartyResource, error) + UpdateStatus(ctrl *extensions.ThirdPartyResource) (*extensions.ThirdPartyResource, error) + Delete(name string) error + Watch(opts unversioned.ListOptions) (watch.Interface, error) +} + +// thirdPartyResources implements DaemonsSetsNamespacer interface +type thirdPartyResources struct { + r *ExtensionsClient + ns string +} + +func newThirdPartyResources(c *ExtensionsClient, namespace string) *thirdPartyResources { + return &thirdPartyResources{c, namespace} +} + +// Ensure statically that thirdPartyResources implements ThirdPartyResourcesInterface. +var _ ThirdPartyResourceInterface = &thirdPartyResources{} + +func (c *thirdPartyResources) List(opts unversioned.ListOptions) (result *extensions.ThirdPartyResourceList, err error) { + result = &extensions.ThirdPartyResourceList{} + err = c.r.Get().Namespace(c.ns).Resource("thirdpartyresources").VersionedParams(&opts, api.Scheme).Do().Into(result) + return +} + +// Get returns information about a particular daemon set. +func (c *thirdPartyResources) Get(name string) (result *extensions.ThirdPartyResource, err error) { + result = &extensions.ThirdPartyResource{} + err = c.r.Get().Namespace(c.ns).Resource("thirdpartyresources").Name(name).Do().Into(result) + return +} + +// Create creates a new daemon set. +func (c *thirdPartyResources) Create(daemon *extensions.ThirdPartyResource) (result *extensions.ThirdPartyResource, err error) { + result = &extensions.ThirdPartyResource{} + err = c.r.Post().Namespace(c.ns).Resource("thirdpartyresources").Body(daemon).Do().Into(result) + return +} + +// Update updates an existing daemon set. +func (c *thirdPartyResources) Update(daemon *extensions.ThirdPartyResource) (result *extensions.ThirdPartyResource, err error) { + result = &extensions.ThirdPartyResource{} + err = c.r.Put().Namespace(c.ns).Resource("thirdpartyresources").Name(daemon.Name).Body(daemon).Do().Into(result) + return +} + +// UpdateStatus updates an existing daemon set status +func (c *thirdPartyResources) UpdateStatus(daemon *extensions.ThirdPartyResource) (result *extensions.ThirdPartyResource, err error) { + result = &extensions.ThirdPartyResource{} + err = c.r.Put().Namespace(c.ns).Resource("thirdpartyresources").Name(daemon.Name).SubResource("status").Body(daemon).Do().Into(result) + return +} + +// Delete deletes an existing daemon set. +func (c *thirdPartyResources) Delete(name string) error { + return c.r.Delete().Namespace(c.ns).Resource("thirdpartyresources").Name(name).Do().Error() +} + +// Watch returns a watch.Interface that watches the requested daemon sets. +func (c *thirdPartyResources) Watch(opts unversioned.ListOptions) (watch.Interface, error) { + return c.r.Get(). + Prefix("watch"). + Namespace(c.ns). + Resource("thirdpartyresources"). + VersionedParams(&opts, api.Scheme). + Watch() +} diff --git a/pkg/client/unversioned/thirdpartyresources_test.go b/pkg/client/unversioned/thirdpartyresources_test.go new file mode 100644 index 00000000000..cccd58a8448 --- /dev/null +++ b/pkg/client/unversioned/thirdpartyresources_test.go @@ -0,0 +1,182 @@ +/* +Copyright 2015 The Kubernetes Authors 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 unversioned_test + +import ( + . "k8s.io/kubernetes/pkg/client/unversioned" + "k8s.io/kubernetes/pkg/client/unversioned/testclient/simple" +) + +import ( + "testing" + + "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/testapi" + "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/apis/extensions" +) + +func getThirdPartyResourceName() string { + return "thirdpartyresources" +} + +func TestListThirdPartyResources(t *testing.T) { + ns := api.NamespaceAll + c := &simple.Client{ + Request: simple.Request{ + Method: "GET", + Path: testapi.Extensions.ResourcePath(getThirdPartyResourceName(), ns, ""), + }, + Response: simple.Response{StatusCode: 200, + Body: &extensions.ThirdPartyResourceList{ + Items: []extensions.ThirdPartyResource{ + { + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Description: "test third party resource", + }, + }, + }, + }, + } + receivedDSs, err := c.Setup(t).Extensions().ThirdPartyResources(ns).List(unversioned.ListOptions{}) + c.Validate(t, receivedDSs, err) + +} + +func TestGetThirdPartyResource(t *testing.T) { + ns := api.NamespaceDefault + c := &simple.Client{ + Request: simple.Request{Method: "GET", Path: testapi.Extensions.ResourcePath(getThirdPartyResourceName(), ns, "foo"), Query: simple.BuildQueryValues(nil)}, + Response: simple.Response{ + StatusCode: 200, + Body: &extensions.ThirdPartyResource{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Description: "test third party resource", + }, + }, + } + receivedThirdPartyResource, err := c.Setup(t).Extensions().ThirdPartyResources(ns).Get("foo") + c.Validate(t, receivedThirdPartyResource, err) +} + +func TestGetThirdPartyResourceWithNoName(t *testing.T) { + ns := api.NamespaceDefault + c := &simple.Client{Error: true} + receivedPod, err := c.Setup(t).Extensions().ThirdPartyResources(ns).Get("") + if (err != nil) && (err.Error() != simple.NameRequiredError) { + t.Errorf("Expected error: %v, but got %v", simple.NameRequiredError, err) + } + + c.Validate(t, receivedPod, err) +} + +func TestUpdateThirdPartyResource(t *testing.T) { + ns := api.NamespaceDefault + requestThirdPartyResource := &extensions.ThirdPartyResource{ + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + } + c := &simple.Client{ + Request: simple.Request{Method: "PUT", Path: testapi.Extensions.ResourcePath(getThirdPartyResourceName(), ns, "foo"), Query: simple.BuildQueryValues(nil)}, + Response: simple.Response{ + StatusCode: 200, + Body: &extensions.ThirdPartyResource{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Description: "test third party resource", + }, + }, + } + receivedThirdPartyResource, err := c.Setup(t).Extensions().ThirdPartyResources(ns).Update(requestThirdPartyResource) + c.Validate(t, receivedThirdPartyResource, err) +} + +func TestUpdateThirdPartyResourceUpdateStatus(t *testing.T) { + ns := api.NamespaceDefault + requestThirdPartyResource := &extensions.ThirdPartyResource{ + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + } + c := &simple.Client{ + Request: simple.Request{Method: "PUT", Path: testapi.Extensions.ResourcePath(getThirdPartyResourceName(), ns, "foo") + "/status", Query: simple.BuildQueryValues(nil)}, + Response: simple.Response{ + StatusCode: 200, + Body: &extensions.ThirdPartyResource{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Description: "test third party resource", + }, + }, + } + receivedThirdPartyResource, err := c.Setup(t).Extensions().ThirdPartyResources(ns).UpdateStatus(requestThirdPartyResource) + c.Validate(t, receivedThirdPartyResource, err) +} + +func TestDeleteThirdPartyResource(t *testing.T) { + ns := api.NamespaceDefault + c := &simple.Client{ + Request: simple.Request{Method: "DELETE", Path: testapi.Extensions.ResourcePath(getThirdPartyResourceName(), ns, "foo"), Query: simple.BuildQueryValues(nil)}, + Response: simple.Response{StatusCode: 200}, + } + err := c.Setup(t).Extensions().ThirdPartyResources(ns).Delete("foo") + c.Validate(t, nil, err) +} + +func TestCreateThirdPartyResource(t *testing.T) { + ns := api.NamespaceDefault + requestThirdPartyResource := &extensions.ThirdPartyResource{ + ObjectMeta: api.ObjectMeta{Name: "foo"}, + } + c := &simple.Client{ + Request: simple.Request{Method: "POST", Path: testapi.Extensions.ResourcePath(getThirdPartyResourceName(), ns, ""), Body: requestThirdPartyResource, Query: simple.BuildQueryValues(nil)}, + Response: simple.Response{ + StatusCode: 200, + Body: &extensions.ThirdPartyResource{ + ObjectMeta: api.ObjectMeta{ + Name: "foo", + Labels: map[string]string{ + "foo": "bar", + "name": "baz", + }, + }, + Description: "test third party resource", + }, + }, + } + receivedThirdPartyResource, err := c.Setup(t).Extensions().ThirdPartyResources(ns).Create(requestThirdPartyResource) + c.Validate(t, receivedThirdPartyResource, err) +}