From 8f65442c2fd9d62c6ae9e65165e12e624190294d Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Fri, 12 Dec 2014 16:33:18 -0500 Subject: [PATCH] Client should not include ns/ for non-namespaced calls in v1beta3 --- pkg/client/client.go | 2 +- pkg/client/request.go | 8 +++++--- pkg/client/request_test.go | 5 +++++ pkg/conversion/converter.go | 4 ++++ pkg/kubectl/cmd/get_test.go | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 8a92fc6ce3f..84adb91592b 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -40,7 +40,7 @@ type Interface interface { } func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface { - return newReplicationControllers(c, namespace) + return newReplicationControllers(c, namespace, c.preV1Beta3) } func (c *Client) Nodes() NodeInterface { diff --git a/pkg/client/request.go b/pkg/client/request.go index cb440ed02dc..ca0fb9aadc9 100644 --- a/pkg/client/request.go +++ b/pkg/client/request.go @@ -103,6 +103,7 @@ type Request struct { // structural elements of the request that are part of the Kubernetes API conventions namespace string + namespaceSet bool resource string resourceName string selector labels.Selector @@ -190,10 +191,11 @@ func (r *Request) Namespace(namespace string) *Request { if r.err != nil { return r } - if len(r.namespace) != 0 { + if r.namespaceSet { r.err = fmt.Errorf("namespace already set to %q, cannot change to %q", r.namespace, namespace) return r } + r.namespaceSet = true r.namespace = namespace return r } @@ -330,7 +332,7 @@ func (r *Request) Poller(poller PollFunc) *Request { func (r *Request) finalURL() string { p := r.path - if !r.namespaceInQuery { + if r.namespaceSet && !r.namespaceInQuery && len(r.namespace) > 0 { p = path.Join(p, "ns", r.namespace) } if len(r.resource) != 0 { @@ -353,7 +355,7 @@ func (r *Request) finalURL() string { query.Add(key, value) } - if r.namespaceInQuery && len(r.namespace) > 0 { + if r.namespaceSet && r.namespaceInQuery && len(r.namespace) > 0 { query.Add("namespace", r.namespace) } diff --git a/pkg/client/request_test.go b/pkg/client/request_test.go index 2891615187a..3f96e02d4a1 100644 --- a/pkg/client/request_test.go +++ b/pkg/client/request_test.go @@ -86,6 +86,11 @@ func TestRequestAbsPathPreservesTrailingSlash(t *testing.T) { if s := r.finalURL(); s != "/foo/" { t.Errorf("trailing slash should be preserved: %s", s) } + + r = (&Request{baseURL: &url.URL{}}).AbsPath("/foo/") + if s := r.finalURL(); s != "/foo/" { + t.Errorf("trailing slash should be preserved: %s", s) + } } func TestRequestAbsPathJoins(t *testing.T) { diff --git a/pkg/conversion/converter.go b/pkg/conversion/converter.go index 4ae2755b382..753d95c74f2 100644 --- a/pkg/conversion/converter.go +++ b/pkg/conversion/converter.go @@ -457,6 +457,10 @@ func (c *Converter) defaultConvert(sv, dv reflect.Value, scope *scope) error { } dkv := reflect.New(dt.Elem()).Elem() scope.setKeys(sk.Interface(), dk.Interface()) + // TODO: sv.MapIndex(sk) may return a value with CanAddr() == false, + // because a map[string]struct{} does not allow a pointer reference. + // Calling a custom conversion function defined for the map value + // will panic. Example is PodInfo map[string]ContainerStatus. if err := c.convert(sv.MapIndex(sk), dkv, scope); err != nil { return err } diff --git a/pkg/kubectl/cmd/get_test.go b/pkg/kubectl/cmd/get_test.go index 0f5b58200f7..f108e711414 100644 --- a/pkg/kubectl/cmd/get_test.go +++ b/pkg/kubectl/cmd/get_test.go @@ -21,9 +21,13 @@ import ( "fmt" "net/http" "reflect" + "strings" "testing" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) // Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get. @@ -50,3 +54,31 @@ func TestGetUnknownSchemaObject(t *testing.T) { t.Errorf("unexpected output: %s", buf.String()) } } + +// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get. +func TestGetSchemaObject(t *testing.T) { + f, tf, _ := NewTestFactory() + f.Mapper = latest.RESTMapper + f.Typer = api.Scheme + codec := latest.Codec + tf.Printer = &testPrinter{} + tf.Client = &client.FakeRESTClient{ + Codec: codec, + Resp: &http.Response{StatusCode: 200, Body: objBody(codec, &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}})}, + } + buf := bytes.NewBuffer([]byte{}) + + cmd := f.NewCmdGet(buf) + cmd.Flags().String("api-version", "v1beta3", "") + cmd.Flags().String("namespace", "test", "") + cmd.Run(cmd, []string{"replicationcontrollers", "foo"}) + + expected := &api.ReplicationController{ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ReplicationControllerSpec{Template: &api.PodTemplateSpec{}}} + actual := tf.Printer.(*testPrinter).Obj + if !reflect.DeepEqual(expected, actual) { + t.Errorf("unexpected object: %s", util.ObjectGoPrintDiff(expected, actual)) + } + if !strings.Contains(buf.String(), "\"foo\"") { + t.Errorf("unexpected output: %s", buf.String()) + } +}