diff --git a/pkg/api/unversioned/group_version.go b/pkg/api/unversioned/group_version.go index 8d294582ff2..2cd68baa3f5 100644 --- a/pkg/api/unversioned/group_version.go +++ b/pkg/api/unversioned/group_version.go @@ -56,15 +56,6 @@ func ParseGroupVersion(gv string) (GroupVersion, error) { } } -func ParseGroupVersionOrDie(gv string) GroupVersion { - ret, err := ParseGroupVersion(gv) - if err != nil { - panic(err) - } - - return ret -} - // MarshalJSON implements the json.Marshaller interface. func (gv GroupVersion) MarshalJSON() ([]byte, error) { s := gv.String() diff --git a/pkg/apiserver/api_installer.go b/pkg/apiserver/api_installer.go index 208c687799e..ffcf6968302 100644 --- a/pkg/apiserver/api_installer.go +++ b/pkg/apiserver/api_installer.go @@ -95,7 +95,7 @@ func (a *APIInstaller) NewWebService() *restful.WebService { // TODO: change to restful.MIME_JSON when we set content type in client ws.Consumes("*/*") ws.Produces(restful.MIME_JSON) - ws.ApiVersion(a.group.GroupVersion.String()) + ws.ApiVersion(a.group.Version) return ws } @@ -104,9 +104,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag admit := a.group.Admit context := a.group.Context - serverGroupVersion := a.group.GroupVersion - if a.group.ServerGroupVersion != nil { - serverGroupVersion = *a.group.ServerGroupVersion + serverVersion := a.group.ServerVersion + if len(serverVersion) == 0 { + serverVersion = a.group.Version } var resource, subresource string @@ -126,13 +126,13 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if err != nil { return nil, err } - versionedPtr, err := a.group.Creater.New(a.group.GroupVersion.String(), kind) + versionedPtr, err := a.group.Creater.New(a.group.Version, kind) if err != nil { return nil, err } versionedObject := indirectArbitraryPointer(versionedPtr) - mapping, err := a.group.Mapper.RESTMapping(kind, a.group.GroupVersion.String()) + mapping, err := a.group.Mapper.RESTMapping(kind, a.group.Version) if err != nil { return nil, err } @@ -148,7 +148,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if err != nil { return nil, err } - parentMapping, err := a.group.Mapper.RESTMapping(parentKind, a.group.GroupVersion.String()) + parentMapping, err := a.group.Mapper.RESTMapping(parentKind, a.group.Version) if err != nil { return nil, err } @@ -181,14 +181,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if isLister { list := lister.NewList() _, listKind, err := a.group.Typer.ObjectVersionAndKind(list) - versionedListPtr, err := a.group.Creater.New(a.group.GroupVersion.String(), listKind) + versionedListPtr, err := a.group.Creater.New(a.group.Version, listKind) if err != nil { return nil, err } versionedList = indirectArbitraryPointer(versionedListPtr) } - versionedListOptions, err := a.group.Creater.New(serverGroupVersion.String(), "ListOptions") + versionedListOptions, err := a.group.Creater.New(serverVersion, "ListOptions") if err != nil { return nil, err } @@ -196,7 +196,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag var versionedDeleterObject interface{} switch { case isGracefulDeleter: - objectPtr, err := a.group.Creater.New(serverGroupVersion.String(), "DeleteOptions") + objectPtr, err := a.group.Creater.New(serverVersion, "DeleteOptions") if err != nil { return nil, err } @@ -206,7 +206,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag gracefulDeleter = rest.GracefulDeleteAdapter{Deleter: deleter} } - versionedStatusPtr, err := a.group.Creater.New(serverGroupVersion.String(), "Status") + versionedStatusPtr, err := a.group.Creater.New(serverVersion, "Status") if err != nil { return nil, err } @@ -224,7 +224,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if err != nil { return nil, err } - versionedGetOptions, err = a.group.Creater.New(serverGroupVersion.String(), getOptionsKind) + versionedGetOptions, err = a.group.Creater.New(serverVersion, getOptionsKind) if err != nil { return nil, err } @@ -245,7 +245,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if err != nil { return nil, err } - versionedConnectOptions, err = a.group.Creater.New(serverGroupVersion.String(), connectOptionsKind) + versionedConnectOptions, err = a.group.Creater.New(serverVersion, connectOptionsKind) } } @@ -379,8 +379,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag Creater: a.group.Creater, Convertor: a.group.Convertor, Codec: mapping.Codec, - APIVersion: a.group.GroupVersion.String(), - ServerAPIVersion: serverGroupVersion.String(), + APIVersion: a.group.Version, + ServerAPIVersion: serverVersion, Resource: resource, Subresource: subresource, Kind: kind, diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 7254a004f0e..4ccc5738787 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -79,8 +79,9 @@ type Mux interface { type APIGroupVersion struct { Storage map[string]rest.Storage - Root string - GroupVersion unversioned.GroupVersion + Root string + // TODO: caesarxuchao: Version actually contains "group/version", refactor it to avoid confusion. + Version string // RequestInfoResolver is used to parse URLs for the legacy proxy handler. Don't use this for anything else // TODO: refactor proxy handler to use sub resources @@ -90,8 +91,9 @@ type APIGroupVersion struct { // schema like api.Status, api.DeleteOptions, and api.ListOptions. Other implementors may // define a version "v1beta1" but want to use the Kubernetes "v1" internal objects. If // empty, defaults to Version. - // TODO this seems suspicious. Is this actually just "unversioned" now? - ServerGroupVersion *unversioned.GroupVersion + // TODO: caesarxuchao: ServerVersion actually contains "group/version", + // refactor it to avoid confusion. + ServerVersion string Mapper meta.RESTMapper @@ -124,7 +126,8 @@ func (g *APIGroupVersion) InstallREST(container *restful.Container) error { installer := g.newInstaller() ws := installer.NewWebService() apiResources, registrationErrors := installer.Install(ws) - AddSupportedResourcesWebService(ws, g.GroupVersion, apiResources) + // TODO: g.Version only contains "version" now, it will contain "group/version" in the near future. + AddSupportedResourcesWebService(ws, g.Version, apiResources) container.Add(ws) return utilerrors.NewAggregate(registrationErrors) } @@ -148,13 +151,14 @@ func (g *APIGroupVersion) UpdateREST(container *restful.Container) error { return apierrors.NewInternalError(fmt.Errorf("unable to find an existing webservice for prefix %s", installer.prefix)) } apiResources, registrationErrors := installer.Install(ws) - AddSupportedResourcesWebService(ws, g.GroupVersion, apiResources) + // TODO: g.Version only contains "version" now, it will contain "group/version" in the near future. + AddSupportedResourcesWebService(ws, g.Version, apiResources) return utilerrors.NewAggregate(registrationErrors) } // newInstaller is a helper to create the installer. Used by InstallREST and UpdateREST. func (g *APIGroupVersion) newInstaller() *APIInstaller { - prefix := path.Join(g.Root, g.GroupVersion.Group, g.GroupVersion.Version) + prefix := path.Join(g.Root, g.Version) installer := &APIInstaller{ group: g, info: g.RequestInfoResolver, @@ -283,7 +287,7 @@ func AddGroupWebService(container *restful.Container, path string, group unversi // Adds a service to return the supported resources, E.g., a such web service // will be registered at /apis/extensions/v1. -func AddSupportedResourcesWebService(ws *restful.WebService, groupVersion unversioned.GroupVersion, apiResources []unversioned.APIResource) { +func AddSupportedResourcesWebService(ws *restful.WebService, groupVersion string, apiResources []unversioned.APIResource) { resourceHandler := SupportedResourcesHandler(groupVersion, apiResources) ws.Route(ws.GET("/").To(resourceHandler). Doc("get available resources"). @@ -324,10 +328,10 @@ func GroupHandler(group unversioned.APIGroup) restful.RouteFunction { } // SupportedResourcesHandler returns a handler which will list the provided resources as available. -func SupportedResourcesHandler(groupVersion unversioned.GroupVersion, apiResources []unversioned.APIResource) restful.RouteFunction { +func SupportedResourcesHandler(groupVersion string, apiResources []unversioned.APIResource) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { // TODO: use restful's Response methods - writeJSON(http.StatusOK, api.Codec, &unversioned.APIResourceList{GroupVersion: groupVersion.String(), APIResources: apiResources}, resp.ResponseWriter, true) + writeJSON(http.StatusOK, api.Codec, &unversioned.APIResourceList{GroupVersion: groupVersion, APIResources: apiResources}, resp.ResponseWriter, true) } } diff --git a/pkg/apiserver/apiserver_test.go b/pkg/apiserver/apiserver_test.go index 7aef5f8577c..a0a990a5ef0 100644 --- a/pkg/apiserver/apiserver_test.go +++ b/pkg/apiserver/apiserver_test.go @@ -57,12 +57,8 @@ func convert(obj runtime.Object) (runtime.Object, error) { } // This creates fake API versions, similar to api/latest.go. -var testAPIGroup = "test.group" -var testGroupVersion = unversioned.GroupVersion{Group: testAPIGroup, Version: "version"} -var testVersion = testGroupVersion.String() -var newGroupVersion = unversioned.GroupVersion{Group: testAPIGroup, Version: "version2"} -var newVersion = newGroupVersion.String() -var prefix = "apis" +const testVersion = "version" +const newVersion = "version2" var versions = []string{testVersion, newVersion} var codec = runtime.CodecFor(api.Scheme, testVersion) @@ -212,7 +208,7 @@ func handleInternal(legacy bool, storage map[string]rest.Storage, admissionContr group := &APIGroupVersion{ Storage: storage, - Root: "/" + prefix, + Root: "/api", RequestInfoResolver: newTestRequestInfoResolver(), Creater: api.Scheme, @@ -224,13 +220,13 @@ func handleInternal(legacy bool, storage map[string]rest.Storage, admissionContr Context: requestContextMapper, } if legacy { - group.GroupVersion = testGroupVersion - group.ServerGroupVersion = &testGroupVersion + group.Version = testVersion + group.ServerVersion = testVersion group.Codec = codec group.Mapper = namespaceMapper } else { - group.GroupVersion = newGroupVersion - group.ServerGroupVersion = &newGroupVersion + group.Version = newVersion + group.ServerVersion = newVersion group.Codec = newCodec group.Mapper = namespaceMapper } @@ -239,7 +235,7 @@ func handleInternal(legacy bool, storage map[string]rest.Storage, admissionContr container.Router(restful.CurlyRouter{}) mux := container.ServeMux if err := group.InstallREST(container); err != nil { - panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err)) + panic(fmt.Sprintf("unable to install container %s: %v", group.Version, err)) } ws := new(restful.WebService) InstallSupport(mux, ws, false) @@ -603,35 +599,35 @@ func TestNotFound(t *testing.T) { } cases := map[string]T{ // Positive checks to make sure everything is wired correctly - "GET root": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusOK}, - // TODO: JTL: "GET root item": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar", http.StatusOK}, - "GET namespaced": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusOK}, - // TODO: JTL: "GET namespaced item": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusOK}, + "GET root": {"GET", "/api/version/simpleroots", http.StatusOK}, + // TODO: JTL: "GET root item": {"GET", "/api/version/simpleroots/bar", http.StatusOK}, + "GET namespaced": {"GET", "/api/version/namespaces/ns/simples", http.StatusOK}, + // TODO: JTL: "GET namespaced item": {"GET", "/api/version/namespaces/ns/simples/bar", http.StatusOK}, - "GET long prefix": {"GET", "/" + prefix + "/", http.StatusNotFound}, + "GET long prefix": {"GET", "/api/", http.StatusNotFound}, - "root PATCH method": {"PATCH", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed}, - "root GET missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/blah", http.StatusNotFound}, - "root GET with extra segment": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound}, - // TODO: JTL: "root POST with extra segment": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar", http.StatusMethodNotAllowed}, - "root DELETE without extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed}, - "root DELETE with extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound}, - "root PUT without extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots", http.StatusMethodNotAllowed}, - "root PUT with extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simpleroots/bar/baz", http.StatusNotFound}, - "root watch missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/", http.StatusNotFound}, - // TODO: JTL: "root watch with bad method": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simpleroot/bar", http.StatusMethodNotAllowed}, + "root PATCH method": {"PATCH", "/api/version/simpleroots", http.StatusMethodNotAllowed}, + "root GET missing storage": {"GET", "/api/version/blah", http.StatusNotFound}, + "root GET with extra segment": {"GET", "/api/version/simpleroots/bar/baz", http.StatusNotFound}, + // TODO: JTL: "root POST with extra segment": {"POST", "/api/version/simpleroots/bar", http.StatusMethodNotAllowed}, + "root DELETE without extra segment": {"DELETE", "/api/version/simpleroots", http.StatusMethodNotAllowed}, + "root DELETE with extra segment": {"DELETE", "/api/version/simpleroots/bar/baz", http.StatusNotFound}, + "root PUT without extra segment": {"PUT", "/api/version/simpleroots", http.StatusMethodNotAllowed}, + "root PUT with extra segment": {"PUT", "/api/version/simpleroots/bar/baz", http.StatusNotFound}, + "root watch missing storage": {"GET", "/api/version/watch/", http.StatusNotFound}, + // TODO: JTL: "root watch with bad method": {"POST", "/api/version/watch/simpleroot/bar", http.StatusMethodNotAllowed}, - "namespaced PATCH method": {"PATCH", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed}, - "namespaced GET long prefix": {"GET", "/" + prefix + "/", http.StatusNotFound}, - "namespaced GET missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/blah", http.StatusNotFound}, - "namespaced GET with extra segment": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound}, - "namespaced POST with extra segment": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar", http.StatusMethodNotAllowed}, - "namespaced DELETE without extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed}, - "namespaced DELETE with extra segment": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound}, - "namespaced PUT without extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples", http.StatusMethodNotAllowed}, - "namespaced PUT with extra segment": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/ns/simples/bar/baz", http.StatusNotFound}, - "namespaced watch missing storage": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/", http.StatusNotFound}, - "namespaced watch with bad method": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/namespaces/ns/simples/bar", http.StatusMethodNotAllowed}, + "namespaced PATCH method": {"PATCH", "/api/version/namespaces/ns/simples", http.StatusMethodNotAllowed}, + "namespaced GET long prefix": {"GET", "/api/", http.StatusNotFound}, + "namespaced GET missing storage": {"GET", "/api/version/blah", http.StatusNotFound}, + "namespaced GET with extra segment": {"GET", "/api/version/namespaces/ns/simples/bar/baz", http.StatusNotFound}, + "namespaced POST with extra segment": {"POST", "/api/version/namespaces/ns/simples/bar", http.StatusMethodNotAllowed}, + "namespaced DELETE without extra segment": {"DELETE", "/api/version/namespaces/ns/simples", http.StatusMethodNotAllowed}, + "namespaced DELETE with extra segment": {"DELETE", "/api/version/namespaces/ns/simples/bar/baz", http.StatusNotFound}, + "namespaced PUT without extra segment": {"PUT", "/api/version/namespaces/ns/simples", http.StatusMethodNotAllowed}, + "namespaced PUT with extra segment": {"PUT", "/api/version/namespaces/ns/simples/bar/baz", http.StatusNotFound}, + "namespaced watch missing storage": {"GET", "/api/version/watch/", http.StatusNotFound}, + "namespaced watch with bad method": {"POST", "/api/version/watch/namespaces/ns/simples/bar", http.StatusMethodNotAllowed}, } handler := handle(map[string]rest.Storage{ "simples": &SimpleRESTStorage{}, @@ -676,15 +672,15 @@ func TestUnimplementedRESTStorage(t *testing.T) { ErrCode int } cases := map[string]T{ - "GET object": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound}, - "GET list": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo", http.StatusNotFound}, - "POST list": {"POST", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo", http.StatusNotFound}, - "PUT object": {"PUT", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound}, - "DELETE object": {"DELETE", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/foo/bar", http.StatusNotFound}, - "watch list": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/foo", http.StatusNotFound}, - "watch object": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/foo/bar", http.StatusNotFound}, - "proxy object": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/proxy/foo/bar", http.StatusNotFound}, - "redirect object": {"GET", "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/redirect/foo/bar", http.StatusNotFound}, + "GET object": {"GET", "/api/version/foo/bar", http.StatusNotFound}, + "GET list": {"GET", "/api/version/foo", http.StatusNotFound}, + "POST list": {"POST", "/api/version/foo", http.StatusNotFound}, + "PUT object": {"PUT", "/api/version/foo/bar", http.StatusNotFound}, + "DELETE object": {"DELETE", "/api/version/foo/bar", http.StatusNotFound}, + "watch list": {"GET", "/api/version/watch/foo", http.StatusNotFound}, + "watch object": {"GET", "/api/version/watch/foo/bar", http.StatusNotFound}, + "proxy object": {"GET", "/api/version/proxy/foo/bar", http.StatusNotFound}, + "redirect object": {"GET", "/api/version/redirect/foo/bar", http.StatusNotFound}, } handler := handle(map[string]rest.Storage{ "foo": UnimplementedRESTStorage{}, @@ -752,76 +748,76 @@ func TestList(t *testing.T) { }{ // legacy namespace param is ignored { - url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=", + url: "/api/version/simple?namespace=", namespace: "", - selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", + selfLink: "/api/version/simple", legacy: true, }, { - url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other", + url: "/api/version/simple?namespace=other", namespace: "", - selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", + selfLink: "/api/version/simple", legacy: true, }, { - url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other&labels=a%3Db&fields=c%3Dd", + url: "/api/version/simple?namespace=other&labels=a%3Db&fields=c%3Dd", namespace: "", - selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", + selfLink: "/api/version/simple", legacy: true, label: "a=b", field: "c=d", }, // legacy api version is honored { - url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", + url: "/api/version/simple", namespace: "", - selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", + selfLink: "/api/version/simple", legacy: true, }, { - url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple", + url: "/api/version/namespaces/other/simple", namespace: "other", - selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple", + selfLink: "/api/version/namespaces/other/simple", legacy: true, }, { - url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple?labels=a%3Db&fields=c%3Dd", + url: "/api/version/namespaces/other/simple?labels=a%3Db&fields=c%3Dd", namespace: "other", - selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple", + selfLink: "/api/version/namespaces/other/simple", legacy: true, label: "a=b", field: "c=d", }, // list items across all namespaces { - url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", + url: "/api/version/simple", namespace: "", - selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple", + selfLink: "/api/version/simple", legacy: true, }, // list items in a namespace in the path { - url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/default/simple", + url: "/api/version2/namespaces/default/simple", namespace: "default", - selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/default/simple", + selfLink: "/api/version2/namespaces/default/simple", }, { - url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple", + url: "/api/version2/namespaces/other/simple", namespace: "other", - selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple", + selfLink: "/api/version2/namespaces/other/simple", }, { - url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd", + url: "/api/version2/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd", namespace: "other", - selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple", + selfLink: "/api/version2/namespaces/other/simple", label: "a=b", field: "c=d", }, // list items across all namespaces { - url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple", + url: "/api/version2/simple", namespace: "", - selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple", + selfLink: "/api/version2/simple", }, } for i, testCase := range testCases { @@ -885,7 +881,7 @@ func TestErrorList(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple") + resp, err := http.Get(server.URL + "/api/version/simple") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -910,7 +906,7 @@ func TestNonEmptyList(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple") + resp, err := http.Get(server.URL + "/api/version/simple") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -937,10 +933,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)) } - if listOut.SelfLink != "/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/simple" { + if listOut.SelfLink != "/api/version/simple" { t.Errorf("unexpected list self link: %#v", listOut) } - expectedSelfLink := "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple/something" + expectedSelfLink := "/api/version/namespaces/other/simple/something" if listOut.Items[0].ObjectMeta.SelfLink != expectedSelfLink { t.Errorf("Unexpected data: %#v, %s", listOut.Items[0].ObjectMeta.SelfLink, expectedSelfLink) } @@ -961,7 +957,7 @@ func TestSelfLinkSkipsEmptyName(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple") + resp, err := http.Get(server.URL + "/api/version/simple") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -987,7 +983,7 @@ func TestSelfLinkSkipsEmptyName(t *testing.T) { if listOut.Items[0].Other != simpleStorage.list[0].Other { t.Errorf("Unexpected data: %#v, %s", listOut.Items[0], string(body)) } - if listOut.SelfLink != "/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/simple" { + if listOut.SelfLink != "/api/version/simple" { t.Errorf("unexpected list self link: %#v", listOut) } expectedSelfLink := "" @@ -1025,7 +1021,7 @@ func TestGet(t *testing.T) { } selfLinker := &setTestSelfLinker{ t: t, - expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id", + expectedSet: "/api/version/namespaces/default/simple/id", name: "id", namespace: "default", } @@ -1034,7 +1030,7 @@ func TestGet(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/id") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -1066,7 +1062,7 @@ func TestGetBinary(t *testing.T) { server := httptest.NewServer(handle(map[string]rest.Storage{"simple": &simpleStorage})) defer server.Close() - req, err := http.NewRequest("GET", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/binary", nil) + req, err := http.NewRequest("GET", server.URL+"/api/version/namespaces/default/simple/binary", nil) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -1082,7 +1078,7 @@ func TestGetBinary(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - if !stream.closed || stream.version != testGroupVersion.String() || stream.accept != "text/other, */*" || + if !stream.closed || stream.version != "version" || stream.accept != "text/other, */*" || resp.Header.Get("Content-Type") != stream.contentType || string(body) != "response data" { t.Errorf("unexpected stream: %#v", stream) } @@ -1143,7 +1139,7 @@ func TestGetWithOptions(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id?param1=test1¶m2=test2") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/id?param1=test1¶m2=test2") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -1185,7 +1181,7 @@ func TestGetWithOptionsAndPath(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id/a/different/path?param1=test1¶m2=test2&atAPath=not") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/id/a/different/path?param1=test1¶m2=test2&atAPath=not") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -1220,7 +1216,7 @@ func TestGetAlternateSelfLink(t *testing.T) { } selfLinker := &setTestSelfLinker{ t: t, - expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/test/simple/id", + expectedSet: "/api/version/namespaces/test/simple/id", name: "id", namespace: "test", } @@ -1229,7 +1225,7 @@ func TestGetAlternateSelfLink(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/test/simple/id") + resp, err := http.Get(server.URL + "/api/version/namespaces/test/simple/id") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -1258,7 +1254,7 @@ func TestGetNamespaceSelfLink(t *testing.T) { } selfLinker := &setTestSelfLinker{ t: t, - expectedSet: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/foo/simple/id", + expectedSet: "/api/version2/namespaces/foo/simple/id", name: "id", namespace: "foo", } @@ -1267,7 +1263,7 @@ func TestGetNamespaceSelfLink(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/foo/simple/id") + resp, err := http.Get(server.URL + "/api/version2/namespaces/foo/simple/id") if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -1296,7 +1292,7 @@ func TestGetMissing(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple/id") + resp, err := http.Get(server.URL + "/api/version/simple/id") if err != nil { t.Errorf("unexpected error: %v", err) } @@ -1322,7 +1318,7 @@ func TestConnect(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect") if err != nil { t.Errorf("unexpected error: %v", err) @@ -1360,7 +1356,7 @@ func TestConnectResponderObject(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect") if err != nil { t.Errorf("unexpected error: %v", err) @@ -1401,7 +1397,7 @@ func TestConnectResponderError(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect") if err != nil { t.Errorf("unexpected error: %v", err) @@ -1470,7 +1466,7 @@ func TestConnectWithOptions(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect?param1=value1¶m2=value2") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect?param1=value1¶m2=value2") if err != nil { t.Errorf("unexpected error: %v", err) @@ -1520,7 +1516,7 @@ func TestConnectWithOptionsAndPath(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect/" + testPath + "?param1=value1¶m2=value2") + resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect/" + testPath + "?param1=value1¶m2=value2") if err != nil { t.Errorf("unexpected error: %v", err) @@ -1561,7 +1557,7 @@ func TestDelete(t *testing.T) { defer server.Close() client := http.Client{} - request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil) + request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil) res, err := client.Do(request) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1593,7 +1589,7 @@ func TestDeleteWithOptions(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) res, err := client.Do(request) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1625,7 +1621,7 @@ func TestLegacyDelete(t *testing.T) { defer server.Close() client := http.Client{} - request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil) + request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil) res, err := client.Do(request) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1657,7 +1653,7 @@ func TestLegacyDeleteIgnoresOptions(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) res, err := client.Do(request) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1683,7 +1679,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) { defer server.Close() client := http.Client{} - request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil) + request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil) response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1705,7 +1701,7 @@ func TestDeleteMissing(t *testing.T) { defer server.Close() client := http.Client{} - request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil) + request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil) response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1730,7 +1726,7 @@ func TestPatch(t *testing.T) { storage["simple"] = &simpleStorage selfLinker := &setTestSelfLinker{ t: t, - expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + ID, + expectedSet: "/api/version/namespaces/default/simple/" + ID, name: ID, namespace: api.NamespaceDefault, } @@ -1739,7 +1735,7 @@ func TestPatch(t *testing.T) { defer server.Close() client := http.Client{} - request, err := http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`))) + request, err := http.NewRequest("PATCH", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`))) request.Header.Set("Content-Type", "application/merge-patch+json; charset=UTF-8") _, err = client.Do(request) if err != nil { @@ -1771,7 +1767,7 @@ func TestPatchRequiresMatchingName(t *testing.T) { defer server.Close() client := http.Client{} - request, err := http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"metadata":{"name":"idbar"}}`))) + request, err := http.NewRequest("PATCH", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"metadata":{"name":"idbar"}}`))) request.Header.Set("Content-Type", "application/merge-patch+json") response, err := client.Do(request) if err != nil { @@ -1789,7 +1785,7 @@ func TestUpdate(t *testing.T) { storage["simple"] = &simpleStorage selfLinker := &setTestSelfLinker{ t: t, - expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + ID, + expectedSet: "/api/version/namespaces/default/simple/" + ID, name: ID, namespace: api.NamespaceDefault, } @@ -1811,7 +1807,7 @@ func TestUpdate(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) _, err = client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1848,7 +1844,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1877,7 +1873,7 @@ func TestUpdateRequiresMatchingName(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1909,7 +1905,7 @@ func TestUpdateAllowsMissingNamespace(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1947,7 +1943,7 @@ func TestUpdateAllowsMismatchedNamespaceOnError(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) _, err = client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -1984,7 +1980,7 @@ func TestUpdatePreventsMismatchedNamespace(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -2018,7 +2014,7 @@ func TestUpdateMissing(t *testing.T) { } client := http.Client{} - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body)) response, err := client.Do(request) if err != nil { t.Errorf("unexpected error: %v", err) @@ -2045,7 +2041,7 @@ func TestCreateNotFound(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/simple", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2071,7 +2067,7 @@ func TestCreateChecksDecode(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/simple", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2096,7 +2092,7 @@ func TestUpdateREST(t *testing.T) { makeGroup := func(storage map[string]rest.Storage) *APIGroupVersion { return &APIGroupVersion{ Storage: storage, - Root: "/" + prefix, + Root: "/api", RequestInfoResolver: newTestRequestInfoResolver(), Creater: api.Scheme, Convertor: api.Scheme, @@ -2107,9 +2103,9 @@ func TestUpdateREST(t *testing.T) { Context: requestContextMapper, Mapper: namespaceMapper, - GroupVersion: newGroupVersion, - ServerGroupVersion: &newGroupVersion, - Codec: newCodec, + Version: newVersion, + ServerVersion: newVersion, + Codec: newCodec, } } @@ -2123,13 +2119,13 @@ func TestUpdateREST(t *testing.T) { testREST := func(t *testing.T, container *restful.Container, barCode int) { w := httptest.NewRecorder() - container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/test/foo/test"}}) + container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/api/version2/namespaces/test/foo/test"}}) if w.Code != http.StatusOK { t.Fatalf("expected OK: %#v", w) } w = httptest.NewRecorder() - container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/test/bar/test"}}) + container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/api/version2/namespaces/test/bar/test"}}) if w.Code != barCode { t.Errorf("expected response code %d for GET to bar but received %d", barCode, w.Code) } @@ -2178,7 +2174,7 @@ func TestParentResourceIsRequired(t *testing.T) { Storage: map[string]rest.Storage{ "simple/sub": storage, }, - Root: "/" + prefix, + Root: "/api", RequestInfoResolver: newTestRequestInfoResolver(), Creater: api.Scheme, Convertor: api.Scheme, @@ -2189,9 +2185,9 @@ func TestParentResourceIsRequired(t *testing.T) { Context: requestContextMapper, Mapper: namespaceMapper, - GroupVersion: newGroupVersion, - ServerGroupVersion: &newGroupVersion, - Codec: newCodec, + Version: newVersion, + ServerVersion: newVersion, + Codec: newCodec, } container := restful.NewContainer() if err := group.InstallREST(container); err == nil { @@ -2207,7 +2203,7 @@ func TestParentResourceIsRequired(t *testing.T) { "simple": &SimpleRESTStorage{}, "simple/sub": storage, }, - Root: "/" + prefix, + Root: "/api", RequestInfoResolver: newTestRequestInfoResolver(), Creater: api.Scheme, Convertor: api.Scheme, @@ -2218,9 +2214,9 @@ func TestParentResourceIsRequired(t *testing.T) { Context: requestContextMapper, Mapper: namespaceMapper, - GroupVersion: newGroupVersion, - ServerGroupVersion: &newGroupVersion, - Codec: newCodec, + Version: newVersion, + ServerVersion: newVersion, + Codec: newCodec, } container = restful.NewContainer() if err := group.InstallREST(container); err != nil { @@ -2229,14 +2225,14 @@ func TestParentResourceIsRequired(t *testing.T) { // resource is NOT registered in the root scope w := httptest.NewRecorder() - container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/simple/test/sub"}}) + container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/api/simple/test/sub"}}) if w.Code != http.StatusNotFound { t.Errorf("expected not found: %#v", w) } // resource is registered in the namespace scope w = httptest.NewRecorder() - container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/test/simple/test/sub"}}) + container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/api/version2/namespaces/test/simple/test/sub"}}) if w.Code != http.StatusOK { t.Fatalf("expected OK: %#v", w) } @@ -2261,7 +2257,7 @@ func TestCreateWithName(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+pathName+"/sub", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/simple/"+pathName+"/sub", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2288,7 +2284,7 @@ func TestUpdateChecksDecode(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/bar", bytes.NewBuffer(data)) + request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/bar", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2350,7 +2346,7 @@ func TestCreate(t *testing.T) { t: t, name: "bar", namespace: "default", - expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar", + expectedSet: "/api/version/namespaces/default/foo/bar", } handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker) server := httptest.NewServer(handler) @@ -2364,7 +2360,7 @@ func TestCreate(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/foo", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2409,7 +2405,7 @@ func TestCreateInNamespace(t *testing.T) { t: t, name: "bar", namespace: "other", - expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/foo/bar", + expectedSet: "/api/version/namespaces/other/foo/bar", } handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker) server := httptest.NewServer(handler) @@ -2423,7 +2419,7 @@ func TestCreateInNamespace(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/other/foo", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2468,7 +2464,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) { t: t, name: "bar", namespace: "other", - expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/foo/bar", + expectedSet: "/api/version/namespaces/other/foo/bar", } handler := handleInternal(true, map[string]rest.Storage{"foo": &storage}, deny.NewAlwaysDeny(), selfLinker) server := httptest.NewServer(handler) @@ -2482,7 +2478,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/other/foo", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2536,7 +2532,7 @@ func TestDelayReturnsError(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - status := expectApiStatus(t, "DELETE", fmt.Sprintf("%s/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo/bar", server.URL), nil, http.StatusConflict) + status := expectApiStatus(t, "DELETE", fmt.Sprintf("%s/api/version/namespaces/default/foo/bar", server.URL), nil, http.StatusConflict) if status.Status != unversioned.StatusFailure || status.Message == "" || status.Details == nil || status.Reason != unversioned.StatusReasonAlreadyExists { t.Errorf("Unexpected status %#v", status) } @@ -2610,7 +2606,7 @@ func TestCreateTimeout(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - itemOut := expectApiStatus(t, "POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo?timeout=4ms", data, apierrs.StatusServerTimeout) + itemOut := expectApiStatus(t, "POST", server.URL+"/api/version/namespaces/default/foo?timeout=4ms", data, apierrs.StatusServerTimeout) if itemOut.Status != unversioned.StatusFailure || itemOut.Reason != unversioned.StatusReasonTimeout { t.Errorf("Unexpected status %#v", itemOut) } @@ -2702,7 +2698,7 @@ func TestCreateChecksAPIVersion(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2743,7 +2739,7 @@ func TestCreateDefaultsAPIVersion(t *testing.T) { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data)) + request, err := http.NewRequest("POST", server.URL+"/api/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -2767,7 +2763,7 @@ func TestUpdateChecksAPIVersion(t *testing.T) { if err != nil { t.Errorf("unexpected error: %v", err) } - request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testVersion+"/namespaces/default/simple/bar", bytes.NewBuffer(data)) + request, err := http.NewRequest("PUT", server.URL+"/api/"+testVersion+"/namespaces/default/simple/bar", bytes.NewBuffer(data)) if err != nil { t.Errorf("unexpected error: %v", err) } diff --git a/pkg/apiserver/proxy_test.go b/pkg/apiserver/proxy_test.go index 75f7a9f3969..3980181e2b4 100644 --- a/pkg/apiserver/proxy_test.go +++ b/pkg/apiserver/proxy_test.go @@ -95,7 +95,7 @@ func TestProxy(t *testing.T) { server *httptest.Server proxyTestPattern string }{ - {namespaceServer, "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/proxy/namespaces/" + item.reqNamespace + "/foo/id" + item.path}, + {namespaceServer, "/api/version2/proxy/namespaces/" + item.reqNamespace + "/foo/id" + item.path}, } for _, serverPattern := range serverPatterns { @@ -212,7 +212,7 @@ func TestProxyUpgrade(t *testing.T) { server := httptest.NewServer(namespaceHandler) defer server.Close() - ws, err := websocket.Dial("ws://"+server.Listener.Addr().String()+"/"+prefix+"/"+newGroupVersion.Group+"/"+newGroupVersion.Version+"/proxy/namespaces/myns/foo/123", "", "http://127.0.0.1/") + ws, err := websocket.Dial("ws://"+server.Listener.Addr().String()+"/api/version2/proxy/namespaces/myns/foo/123", "", "http://127.0.0.1/") if err != nil { t.Errorf("%s: websocket dial err: %s", k, err) continue @@ -276,7 +276,7 @@ func TestRedirectOnMissingTrailingSlash(t *testing.T) { server := httptest.NewServer(handler) defer server.Close() - proxyTestPattern := "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/proxy/namespaces/ns/foo/id" + item.path + proxyTestPattern := "/api/version2/proxy/namespaces/ns/foo/id" + item.path req, err := http.NewRequest( "GET", server.URL+proxyTestPattern+"?"+item.query, diff --git a/pkg/apiserver/watch_test.go b/pkg/apiserver/watch_test.go index b82c031c397..6553424bf4a 100644 --- a/pkg/apiserver/watch_test.go +++ b/pkg/apiserver/watch_test.go @@ -62,7 +62,7 @@ func TestWatchWebsocket(t *testing.T) { dest, _ := url.Parse(server.URL) dest.Scheme = "ws" // Required by websocket, though the server never sees it. - dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples" + dest.Path = "/api/version/watch/simples" dest.RawQuery = "" ws, err := websocket.Dial(dest.String(), "", "http://localhost") @@ -114,7 +114,7 @@ func TestWatchHTTP(t *testing.T) { client := http.Client{} dest, _ := url.Parse(server.URL) - dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples" + dest.Path = "/api/version/watch/simples" dest.RawQuery = "" request, err := http.NewRequest("GET", dest.String(), nil) @@ -178,8 +178,8 @@ func TestWatchParamParsing(t *testing.T) { dest, _ := url.Parse(server.URL) - rootPath := "/" + prefix + "/" + testVersion + "/watch/simples" - namespacedPath := "/" + prefix + "/" + testVersion + "/watch/namespaces/other/simpleroots" + rootPath := "/api/" + testVersion + "/watch/simples" + namespacedPath := "/api/" + testVersion + "/watch/namespaces/other/simpleroots" table := []struct { path string @@ -286,7 +286,7 @@ func TestWatchProtocolSelection(t *testing.T) { client := http.Client{} dest, _ := url.Parse(server.URL) - dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/watch/simples" + dest.Path = "/api/version/watch/simples" dest.RawQuery = "" table := []struct { @@ -358,7 +358,7 @@ func TestWatchHTTPTimeout(t *testing.T) { // Setup a client dest, _ := url.Parse(s.URL) - dest.Path = "/" + prefix + "/" + newVersion + "/simple" + dest.Path = "/api/" + newVersion + "/simple" dest.RawQuery = "watch=true" req, _ := http.NewRequest("GET", dest.String(), nil) diff --git a/pkg/master/master.go b/pkg/master/master.go index 715cf567d6b..d64f0e7e166 100644 --- a/pkg/master/master.go +++ b/pkg/master/master.go @@ -670,8 +670,8 @@ func (m *Master) init(c *Config) { } expAPIVersions := []unversioned.GroupVersionForDiscovery{ { - GroupVersion: expVersion.GroupVersion.String(), - Version: expVersion.GroupVersion.Version, + GroupVersion: expVersion.Version, + Version: apiutil.GetVersion(expVersion.Version), }, } storageVersion, found := c.StorageVersions[g.Group] @@ -685,7 +685,7 @@ func (m *Master) init(c *Config) { } apiserver.AddGroupWebService(m.handlerContainer, c.APIGroupPrefix+"/"+latest.GroupOrDie("extensions").Group, group) allGroups = append(allGroups, group) - apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newRequestInfoResolver(), []string{expVersion.GroupVersion.String()}) + apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newRequestInfoResolver(), []string{expVersion.Version}) } // This should be done after all groups are registered @@ -892,7 +892,7 @@ func (m *Master) api_v1() *apiserver.APIGroupVersion { } version := m.defaultAPIGroupVersion() version.Storage = storage - version.GroupVersion = unversioned.GroupVersion{Version: "v1"} + version.Version = "v1" version.Codec = v1.Codec return version } @@ -1005,7 +1005,7 @@ func (m *Master) InstallThirdPartyResource(rsrc *expapi.ThirdPartyResource) erro } apiserver.AddGroupWebService(m.handlerContainer, path, apiGroup) m.addThirdPartyResourceStorage(path, thirdparty.Storage[strings.ToLower(kind)+"s"].(*thirdpartyresourcedataetcd.REST)) - apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newRequestInfoResolver(), []string{thirdparty.GroupVersion.String()}) + apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newRequestInfoResolver(), []string{thirdparty.Version}) return nil } @@ -1018,22 +1018,20 @@ func (m *Master) thirdpartyapi(group, kind, version string) *apiserver.APIGroupV strings.ToLower(kind) + "s": resourceStorage, } - serverGroupVersion := unversioned.ParseGroupVersionOrDie(latest.GroupOrDie("").GroupVersion) - return &apiserver.APIGroupVersion{ Root: apiRoot, - GroupVersion: unversioned.GroupVersion{Group: group, Version: version}, + Version: apiutil.GetGroupVersion(group, version), RequestInfoResolver: m.newRequestInfoResolver(), Creater: thirdpartyresourcedata.NewObjectCreator(group, version, api.Scheme), Convertor: api.Scheme, Typer: api.Scheme, - Mapper: thirdpartyresourcedata.NewMapper(latest.GroupOrDie("extensions").RESTMapper, kind, version, group), - Codec: thirdpartyresourcedata.NewCodec(latest.GroupOrDie("extensions").Codec, kind), - Linker: latest.GroupOrDie("extensions").SelfLinker, - Storage: storage, - ServerGroupVersion: &serverGroupVersion, + Mapper: thirdpartyresourcedata.NewMapper(latest.GroupOrDie("extensions").RESTMapper, kind, version, group), + Codec: thirdpartyresourcedata.NewCodec(latest.GroupOrDie("extensions").Codec, kind), + Linker: latest.GroupOrDie("extensions").SelfLinker, + Storage: storage, + ServerVersion: latest.GroupOrDie("").GroupVersion, Context: m.requestContextMapper, @@ -1108,7 +1106,6 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion { } extensionsGroup := latest.GroupOrDie("extensions") - serverGroupVersion := unversioned.ParseGroupVersionOrDie(latest.GroupOrDie("").GroupVersion) return &apiserver.APIGroupVersion{ Root: m.apiGroupPrefix, @@ -1118,12 +1115,12 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion { Convertor: api.Scheme, Typer: api.Scheme, - Mapper: extensionsGroup.RESTMapper, - Codec: extensionsGroup.Codec, - Linker: extensionsGroup.SelfLinker, - Storage: storage, - GroupVersion: unversioned.ParseGroupVersionOrDie(extensionsGroup.GroupVersion), - ServerGroupVersion: &serverGroupVersion, + Mapper: extensionsGroup.RESTMapper, + Codec: extensionsGroup.Codec, + Linker: extensionsGroup.SelfLinker, + Storage: storage, + Version: extensionsGroup.GroupVersion, + ServerVersion: latest.GroupOrDie("").GroupVersion, Admit: m.admissionControl, Context: m.requestContextMapper, diff --git a/pkg/master/master_test.go b/pkg/master/master_test.go index 65fb2feedcc..f5819b616e9 100644 --- a/pkg/master/master_test.go +++ b/pkg/master/master_test.go @@ -175,7 +175,7 @@ func TestFindExternalAddress(t *testing.T) { func TestApi_v1(t *testing.T) { master, _, assert := setUp(t) version := master.api_v1() - assert.Equal(unversioned.GroupVersion{Version: "v1"}, version.GroupVersion, "Version was not v1: %s", version.GroupVersion) + assert.Equal("v1", version.Version, "Version was not v1: %s", version.Version) assert.Equal(v1.Codec, version.Codec, "version.Codec was not for v1: %s", version.Codec) for k, v := range master.storage { assert.Contains(version.Storage, v, "Value %s not found (key: %s)", k, v) @@ -322,14 +322,12 @@ func TestDefaultAPIGroupVersion(t *testing.T) { func TestExpapi(t *testing.T) { master, config, assert := setUp(t) - extensionsGroupMeta := latest.GroupOrDie("extensions") - expAPIGroup := master.experimental(&config) assert.Equal(expAPIGroup.Root, master.apiGroupPrefix) - assert.Equal(expAPIGroup.Mapper, extensionsGroupMeta.RESTMapper) - assert.Equal(expAPIGroup.Codec, extensionsGroupMeta.Codec) - assert.Equal(expAPIGroup.Linker, extensionsGroupMeta.SelfLinker) - assert.Equal(expAPIGroup.GroupVersion, unversioned.GroupVersion{Group: extensionsGroupMeta.Group, Version: extensionsGroupMeta.Version}) + assert.Equal(expAPIGroup.Mapper, latest.GroupOrDie("extensions").RESTMapper) + assert.Equal(expAPIGroup.Codec, latest.GroupOrDie("extensions").Codec) + assert.Equal(expAPIGroup.Linker, latest.GroupOrDie("extensions").SelfLinker) + assert.Equal(expAPIGroup.Version, latest.GroupOrDie("extensions").GroupVersion) } // TestGetNodeAddresses verifies that proper results are returned