From ef25520baa736ae7ec2afbd19bb7dfb17a1be164 Mon Sep 17 00:00:00 2001 From: derekwaynecarr Date: Mon, 24 Nov 2014 13:35:24 -0500 Subject: [PATCH] make selfLink namespace aware --- pkg/apiserver/apiserver_test.go | 21 +++++++++++++++------ pkg/apiserver/resthandler.go | 22 +++++++++++++++++++++- pkg/runtime/interfaces.go | 2 ++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/pkg/apiserver/apiserver_test.go b/pkg/apiserver/apiserver_test.go index fc17d7c54d9..612bd0b8455 100644 --- a/pkg/apiserver/apiserver_test.go +++ b/pkg/apiserver/apiserver_test.go @@ -316,7 +316,8 @@ func TestSimpleList(t *testing.T) { storage["simple"] = &simpleStorage selfLinker := &setTestSelfLinker{ t: t, - expectedSet: "/prefix/version/simple", + namespace: "other", + expectedSet: "/prefix/version/simple?namespace=other", } handler := Handle(storage, codec, "/prefix", testVersion, selfLinker) server := httptest.NewServer(handler) @@ -360,8 +361,9 @@ func TestNonEmptyList(t *testing.T) { simpleStorage := SimpleRESTStorage{ list: []Simple{ { - TypeMeta: api.TypeMeta{Kind: "Simple"}, - Other: "foo", + TypeMeta: api.TypeMeta{Kind: "Simple"}, + ObjectMeta: api.ObjectMeta{Namespace: "other"}, + Other: "foo", }, }, } @@ -394,6 +396,10 @@ func TestNonEmptyList(t *testing.T) { if listOut.Items[0].Other != simpleStorage.list[0].Other { t.Errorf("Unexpected data: %#v, %s", listOut.Items[0], string(body)) } + expectedSelfLink := "/prefix/version/simple?namespace=other" + if listOut.Items[0].ObjectMeta.SelfLink != expectedSelfLink { + t.Errorf("Unexpected data: %#v, %s", listOut.Items[0].ObjectMeta.SelfLink, expectedSelfLink) + } } func TestGet(t *testing.T) { @@ -651,11 +657,13 @@ type setTestSelfLinker struct { t *testing.T expectedSet string name string + namespace string called bool } -func (s *setTestSelfLinker) Name(runtime.Object) (string, error) { return s.name, nil } -func (*setTestSelfLinker) SelfLink(runtime.Object) (string, error) { return "", nil } +func (s *setTestSelfLinker) Namespace(runtime.Object) (string, error) { return s.namespace, nil } +func (s *setTestSelfLinker) Name(runtime.Object) (string, error) { return s.name, nil } +func (*setTestSelfLinker) SelfLink(runtime.Object) (string, error) { return "", nil } func (s *setTestSelfLinker) SetSelfLink(obj runtime.Object, selfLink string) error { if e, a := s.expectedSet, selfLink; e != a { s.t.Errorf("expected '%v', got '%v'", e, a) @@ -674,7 +682,8 @@ func TestSyncCreate(t *testing.T) { selfLinker := &setTestSelfLinker{ t: t, name: "bar", - expectedSet: "/prefix/version/foo/bar", + namespace: "other", + expectedSet: "/prefix/version/foo/bar?namespace=other", } handler := Handle(map[string]RESTStorage{ "foo": &storage, diff --git a/pkg/apiserver/resthandler.go b/pkg/apiserver/resthandler.go index 673dc3bba7c..9b31701844c 100644 --- a/pkg/apiserver/resthandler.go +++ b/pkg/apiserver/resthandler.go @@ -62,7 +62,17 @@ func (h *RESTHandler) setSelfLink(obj runtime.Object, req *http.Request) error { newURL.Path = path.Join(h.canonicalPrefix, req.URL.Path) newURL.RawQuery = "" newURL.Fragment = "" - err := h.selfLinker.SetSelfLink(obj, newURL.String()) + namespace, err := h.selfLinker.Namespace(obj) + if err != nil { + return err + } + // TODO Remove this when namespace is in path + if len(namespace) > 0 { + query := newURL.Query() + query.Set("namespace", namespace) + newURL.RawQuery = query.Encode() + } + err = h.selfLinker.SetSelfLink(obj, newURL.String()) if err != nil { return err } @@ -89,10 +99,20 @@ func (h *RESTHandler) setSelfLinkAddName(obj runtime.Object, req *http.Request) if err != nil { return err } + namespace, err := h.selfLinker.Namespace(obj) + if err != nil { + return err + } newURL := *req.URL newURL.Path = path.Join(h.canonicalPrefix, req.URL.Path, name) newURL.RawQuery = "" newURL.Fragment = "" + // TODO Remove this when namespace is in path + if len(namespace) > 0 { + query := newURL.Query() + query.Set("namespace", namespace) + newURL.RawQuery = query.Encode() + } return h.selfLinker.SetSelfLink(obj, newURL.String()) } diff --git a/pkg/runtime/interfaces.go b/pkg/runtime/interfaces.go index 01d0741c48e..4bfbf087e8c 100644 --- a/pkg/runtime/interfaces.go +++ b/pkg/runtime/interfaces.go @@ -59,6 +59,8 @@ type SelfLinker interface { // Knowing Name is sometimes necessary to use a SelfLinker. Name(obj Object) (string, error) + // Knowing Namespace is sometimes necessary to use a SelfLinker + Namespace(obj Object) (string, error) } // All api types must support the Object interface. It's deliberately tiny so that this is not an onerous