use GroupVersion in APIGroupVersion for api installer

pull/6/head
deads2k 2015-11-12 15:20:20 -05:00
parent 3d123ba390
commit 3c725f17ea
8 changed files with 209 additions and 195 deletions

View File

@ -56,6 +56,15 @@ 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()

View File

@ -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.Version)
ws.ApiVersion(a.group.GroupVersion.String())
return ws
}
@ -104,9 +104,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
admit := a.group.Admit
context := a.group.Context
serverVersion := a.group.ServerVersion
if len(serverVersion) == 0 {
serverVersion = a.group.Version
serverGroupVersion := a.group.GroupVersion
if a.group.ServerGroupVersion != nil {
serverGroupVersion = *a.group.ServerGroupVersion
}
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.Version, kind)
versionedPtr, err := a.group.Creater.New(a.group.GroupVersion.String(), kind)
if err != nil {
return nil, err
}
versionedObject := indirectArbitraryPointer(versionedPtr)
mapping, err := a.group.Mapper.RESTMapping(kind, a.group.Version)
mapping, err := a.group.Mapper.RESTMapping(kind, a.group.GroupVersion.String())
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.Version)
parentMapping, err := a.group.Mapper.RESTMapping(parentKind, a.group.GroupVersion.String())
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.Version, listKind)
versionedListPtr, err := a.group.Creater.New(a.group.GroupVersion.String(), listKind)
if err != nil {
return nil, err
}
versionedList = indirectArbitraryPointer(versionedListPtr)
}
versionedListOptions, err := a.group.Creater.New(serverVersion, "ListOptions")
versionedListOptions, err := a.group.Creater.New(serverGroupVersion.String(), "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(serverVersion, "DeleteOptions")
objectPtr, err := a.group.Creater.New(serverGroupVersion.String(), "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(serverVersion, "Status")
versionedStatusPtr, err := a.group.Creater.New(serverGroupVersion.String(), "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(serverVersion, getOptionsKind)
versionedGetOptions, err = a.group.Creater.New(serverGroupVersion.String(), 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(serverVersion, connectOptionsKind)
versionedConnectOptions, err = a.group.Creater.New(serverGroupVersion.String(), 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.Version,
ServerAPIVersion: serverVersion,
APIVersion: a.group.GroupVersion.String(),
ServerAPIVersion: serverGroupVersion.String(),
Resource: resource,
Subresource: subresource,
Kind: kind,

View File

@ -79,9 +79,8 @@ type Mux interface {
type APIGroupVersion struct {
Storage map[string]rest.Storage
Root string
// TODO: caesarxuchao: Version actually contains "group/version", refactor it to avoid confusion.
Version string
Root string
GroupVersion unversioned.GroupVersion
// 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
@ -91,9 +90,8 @@ 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: caesarxuchao: ServerVersion actually contains "group/version",
// refactor it to avoid confusion.
ServerVersion string
// TODO this seems suspicious. Is this actually just "unversioned" now?
ServerGroupVersion *unversioned.GroupVersion
Mapper meta.RESTMapper
@ -126,8 +124,7 @@ func (g *APIGroupVersion) InstallREST(container *restful.Container) error {
installer := g.newInstaller()
ws := installer.NewWebService()
apiResources, registrationErrors := installer.Install(ws)
// TODO: g.Version only contains "version" now, it will contain "group/version" in the near future.
AddSupportedResourcesWebService(ws, g.Version, apiResources)
AddSupportedResourcesWebService(ws, g.GroupVersion, apiResources)
container.Add(ws)
return utilerrors.NewAggregate(registrationErrors)
}
@ -151,14 +148,13 @@ 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)
// TODO: g.Version only contains "version" now, it will contain "group/version" in the near future.
AddSupportedResourcesWebService(ws, g.Version, apiResources)
AddSupportedResourcesWebService(ws, g.GroupVersion, 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.Version)
prefix := path.Join(g.Root, g.GroupVersion.Group, g.GroupVersion.Version)
installer := &APIInstaller{
group: g,
info: g.RequestInfoResolver,
@ -287,7 +283,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 string, apiResources []unversioned.APIResource) {
func AddSupportedResourcesWebService(ws *restful.WebService, groupVersion unversioned.GroupVersion, apiResources []unversioned.APIResource) {
resourceHandler := SupportedResourcesHandler(groupVersion, apiResources)
ws.Route(ws.GET("/").To(resourceHandler).
Doc("get available resources").
@ -328,10 +324,10 @@ func GroupHandler(group unversioned.APIGroup) restful.RouteFunction {
}
// SupportedResourcesHandler returns a handler which will list the provided resources as available.
func SupportedResourcesHandler(groupVersion string, apiResources []unversioned.APIResource) restful.RouteFunction {
func SupportedResourcesHandler(groupVersion unversioned.GroupVersion, 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, APIResources: apiResources}, resp.ResponseWriter, true)
writeJSON(http.StatusOK, api.Codec, &unversioned.APIResourceList{GroupVersion: groupVersion.String(), APIResources: apiResources}, resp.ResponseWriter, true)
}
}

View File

@ -57,8 +57,12 @@ func convert(obj runtime.Object) (runtime.Object, error) {
}
// This creates fake API versions, similar to api/latest.go.
const testVersion = "version"
const newVersion = "version2"
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"
var versions = []string{testVersion, newVersion}
var codec = runtime.CodecFor(api.Scheme, testVersion)
@ -208,7 +212,7 @@ func handleInternal(legacy bool, storage map[string]rest.Storage, admissionContr
group := &APIGroupVersion{
Storage: storage,
Root: "/api",
Root: "/" + prefix,
RequestInfoResolver: newTestRequestInfoResolver(),
Creater: api.Scheme,
@ -220,13 +224,13 @@ func handleInternal(legacy bool, storage map[string]rest.Storage, admissionContr
Context: requestContextMapper,
}
if legacy {
group.Version = testVersion
group.ServerVersion = testVersion
group.GroupVersion = testGroupVersion
group.ServerGroupVersion = &testGroupVersion
group.Codec = codec
group.Mapper = namespaceMapper
} else {
group.Version = newVersion
group.ServerVersion = newVersion
group.GroupVersion = newGroupVersion
group.ServerGroupVersion = &newGroupVersion
group.Codec = newCodec
group.Mapper = namespaceMapper
}
@ -235,7 +239,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.Version, err))
panic(fmt.Sprintf("unable to install container %s: %v", group.GroupVersion, err))
}
ws := new(restful.WebService)
InstallSupport(mux, ws, false)
@ -599,35 +603,35 @@ func TestNotFound(t *testing.T) {
}
cases := map[string]T{
// Positive checks to make sure everything is wired correctly
"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 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 long prefix": {"GET", "/api/", http.StatusNotFound},
"GET long prefix": {"GET", "/" + prefix + "/", http.StatusNotFound},
"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},
"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},
"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},
"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},
}
handler := handle(map[string]rest.Storage{
"simples": &SimpleRESTStorage{},
@ -672,15 +676,15 @@ func TestUnimplementedRESTStorage(t *testing.T) {
ErrCode int
}
cases := map[string]T{
"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},
"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},
}
handler := handle(map[string]rest.Storage{
"foo": UnimplementedRESTStorage{},
@ -748,76 +752,76 @@ func TestList(t *testing.T) {
}{
// legacy namespace param is ignored
{
url: "/api/version/simple?namespace=",
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=",
namespace: "",
selfLink: "/api/version/simple",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true,
},
{
url: "/api/version/simple?namespace=other",
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other",
namespace: "",
selfLink: "/api/version/simple",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true,
},
{
url: "/api/version/simple?namespace=other&labels=a%3Db&fields=c%3Dd",
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple?namespace=other&labels=a%3Db&fields=c%3Dd",
namespace: "",
selfLink: "/api/version/simple",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true,
label: "a=b",
field: "c=d",
},
// legacy api version is honored
{
url: "/api/version/simple",
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
namespace: "",
selfLink: "/api/version/simple",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true,
},
{
url: "/api/version/namespaces/other/simple",
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
namespace: "other",
selfLink: "/api/version/namespaces/other/simple",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
legacy: true,
},
{
url: "/api/version/namespaces/other/simple?labels=a%3Db&fields=c%3Dd",
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple?labels=a%3Db&fields=c%3Dd",
namespace: "other",
selfLink: "/api/version/namespaces/other/simple",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple",
legacy: true,
label: "a=b",
field: "c=d",
},
// list items across all namespaces
{
url: "/api/version/simple",
url: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
namespace: "",
selfLink: "/api/version/simple",
selfLink: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple",
legacy: true,
},
// list items in a namespace in the path
{
url: "/api/version2/namespaces/default/simple",
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/default/simple",
namespace: "default",
selfLink: "/api/version2/namespaces/default/simple",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/default/simple",
},
{
url: "/api/version2/namespaces/other/simple",
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple",
namespace: "other",
selfLink: "/api/version2/namespaces/other/simple",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple",
},
{
url: "/api/version2/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd",
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple?labelSelector=a%3Db&fieldSelector=c%3Dd",
namespace: "other",
selfLink: "/api/version2/namespaces/other/simple",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/other/simple",
label: "a=b",
field: "c=d",
},
// list items across all namespaces
{
url: "/api/version2/simple",
url: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple",
namespace: "",
selfLink: "/api/version2/simple",
selfLink: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/simple",
},
}
for i, testCase := range testCases {
@ -881,7 +885,7 @@ func TestErrorList(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/simple")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -906,7 +910,7 @@ func TestNonEmptyList(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/simple")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -933,10 +937,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 != "/api/version/simple" {
if listOut.SelfLink != "/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/simple" {
t.Errorf("unexpected list self link: %#v", listOut)
}
expectedSelfLink := "/api/version/namespaces/other/simple/something"
expectedSelfLink := "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/simple/something"
if listOut.Items[0].ObjectMeta.SelfLink != expectedSelfLink {
t.Errorf("Unexpected data: %#v, %s", listOut.Items[0].ObjectMeta.SelfLink, expectedSelfLink)
}
@ -957,7 +961,7 @@ func TestSelfLinkSkipsEmptyName(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/simple")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -983,7 +987,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 != "/api/version/simple" {
if listOut.SelfLink != "/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/simple" {
t.Errorf("unexpected list self link: %#v", listOut)
}
expectedSelfLink := ""
@ -1021,7 +1025,7 @@ func TestGet(t *testing.T) {
}
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/api/version/namespaces/default/simple/id",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id",
name: "id",
namespace: "default",
}
@ -1030,7 +1034,7 @@ func TestGet(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/id")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -1062,7 +1066,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+"/api/version/namespaces/default/simple/binary", nil)
req, err := http.NewRequest("GET", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/binary", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -1078,7 +1082,7 @@ func TestGetBinary(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if !stream.closed || stream.version != "version" || stream.accept != "text/other, */*" ||
if !stream.closed || stream.version != testGroupVersion.String() || stream.accept != "text/other, */*" ||
resp.Header.Get("Content-Type") != stream.contentType || string(body) != "response data" {
t.Errorf("unexpected stream: %#v", stream)
}
@ -1139,7 +1143,7 @@ func TestGetWithOptions(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/id?param1=test1&param2=test2")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id?param1=test1&param2=test2")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -1181,7 +1185,7 @@ func TestGetWithOptionsAndPath(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/id/a/different/path?param1=test1&param2=test2&atAPath=not")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id/a/different/path?param1=test1&param2=test2&atAPath=not")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -1216,7 +1220,7 @@ func TestGetAlternateSelfLink(t *testing.T) {
}
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/api/version/namespaces/test/simple/id",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/test/simple/id",
name: "id",
namespace: "test",
}
@ -1225,7 +1229,7 @@ func TestGetAlternateSelfLink(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/test/simple/id")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/test/simple/id")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -1254,7 +1258,7 @@ func TestGetNamespaceSelfLink(t *testing.T) {
}
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/api/version2/namespaces/foo/simple/id",
expectedSet: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/foo/simple/id",
name: "id",
namespace: "foo",
}
@ -1263,7 +1267,7 @@ func TestGetNamespaceSelfLink(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version2/namespaces/foo/simple/id")
resp, err := http.Get(server.URL + "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/foo/simple/id")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -1292,7 +1296,7 @@ func TestGetMissing(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/simple/id")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/simple/id")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -1318,7 +1322,7 @@ func TestConnect(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1356,7 +1360,7 @@ func TestConnectResponderObject(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1397,7 +1401,7 @@ func TestConnectResponderError(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1466,7 +1470,7 @@ func TestConnectWithOptions(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect?param1=value1&param2=value2")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect?param1=value1&param2=value2")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1516,7 +1520,7 @@ func TestConnectWithOptionsAndPath(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/api/version/namespaces/default/simple/" + itemID + "/connect/" + testPath + "?param1=value1&param2=value2")
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + itemID + "/connect/" + testPath + "?param1=value1&param2=value2")
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1557,7 +1561,7 @@ func TestDelete(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil)
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
res, err := client.Do(request)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -1589,7 +1593,7 @@ func TestDeleteWithOptions(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
res, err := client.Do(request)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -1621,7 +1625,7 @@ func TestLegacyDelete(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil)
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
res, err := client.Do(request)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -1653,7 +1657,7 @@ func TestLegacyDeleteIgnoresOptions(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
res, err := client.Do(request)
if err != nil {
t.Fatalf("unexpected error: %v", err)
@ -1679,7 +1683,7 @@ func TestDeleteInvokesAdmissionControl(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil)
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1701,7 +1705,7 @@ func TestDeleteMissing(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("DELETE", server.URL+"/api/version/namespaces/default/simple/"+ID, nil)
request, err := http.NewRequest("DELETE", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, nil)
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1726,7 +1730,7 @@ func TestPatch(t *testing.T) {
storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/api/version/namespaces/default/simple/" + ID,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + ID,
name: ID,
namespace: api.NamespaceDefault,
}
@ -1735,7 +1739,7 @@ func TestPatch(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("PATCH", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"labels":{"foo":"bar"}}`)))
request, err := http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.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 {
@ -1767,7 +1771,7 @@ func TestPatchRequiresMatchingName(t *testing.T) {
defer server.Close()
client := http.Client{}
request, err := http.NewRequest("PATCH", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader([]byte(`{"metadata":{"name":"idbar"}}`)))
request, err := http.NewRequest("PATCH", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.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 {
@ -1785,7 +1789,7 @@ func TestUpdate(t *testing.T) {
storage["simple"] = &simpleStorage
selfLinker := &setTestSelfLinker{
t: t,
expectedSet: "/api/version/namespaces/default/simple/" + ID,
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/" + ID,
name: ID,
namespace: api.NamespaceDefault,
}
@ -1807,7 +1811,7 @@ func TestUpdate(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
_, err = client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1844,7 +1848,7 @@ func TestUpdateInvokesAdmissionControl(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1873,7 +1877,7 @@ func TestUpdateRequiresMatchingName(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1905,7 +1909,7 @@ func TestUpdateAllowsMissingNamespace(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1943,7 +1947,7 @@ func TestUpdateAllowsMismatchedNamespaceOnError(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
_, err = client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -1980,7 +1984,7 @@ func TestUpdatePreventsMismatchedNamespace(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -2014,7 +2018,7 @@ func TestUpdateMissing(t *testing.T) {
}
client := http.Client{}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/"+ID, bytes.NewReader(body))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+ID, bytes.NewReader(body))
response, err := client.Do(request)
if err != nil {
t.Errorf("unexpected error: %v", err)
@ -2041,7 +2045,7 @@ func TestCreateNotFound(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2067,7 +2071,7 @@ func TestCreateChecksDecode(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2092,7 +2096,7 @@ func TestUpdateREST(t *testing.T) {
makeGroup := func(storage map[string]rest.Storage) *APIGroupVersion {
return &APIGroupVersion{
Storage: storage,
Root: "/api",
Root: "/" + prefix,
RequestInfoResolver: newTestRequestInfoResolver(),
Creater: api.Scheme,
Convertor: api.Scheme,
@ -2103,9 +2107,9 @@ func TestUpdateREST(t *testing.T) {
Context: requestContextMapper,
Mapper: namespaceMapper,
Version: newVersion,
ServerVersion: newVersion,
Codec: newCodec,
GroupVersion: newGroupVersion,
ServerGroupVersion: &newGroupVersion,
Codec: newCodec,
}
}
@ -2119,13 +2123,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: "/api/version2/namespaces/test/foo/test"}})
container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/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: "/api/version2/namespaces/test/bar/test"}})
container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/test/bar/test"}})
if w.Code != barCode {
t.Errorf("expected response code %d for GET to bar but received %d", barCode, w.Code)
}
@ -2174,7 +2178,7 @@ func TestParentResourceIsRequired(t *testing.T) {
Storage: map[string]rest.Storage{
"simple/sub": storage,
},
Root: "/api",
Root: "/" + prefix,
RequestInfoResolver: newTestRequestInfoResolver(),
Creater: api.Scheme,
Convertor: api.Scheme,
@ -2185,9 +2189,9 @@ func TestParentResourceIsRequired(t *testing.T) {
Context: requestContextMapper,
Mapper: namespaceMapper,
Version: newVersion,
ServerVersion: newVersion,
Codec: newCodec,
GroupVersion: newGroupVersion,
ServerGroupVersion: &newGroupVersion,
Codec: newCodec,
}
container := restful.NewContainer()
if err := group.InstallREST(container); err == nil {
@ -2203,7 +2207,7 @@ func TestParentResourceIsRequired(t *testing.T) {
"simple": &SimpleRESTStorage{},
"simple/sub": storage,
},
Root: "/api",
Root: "/" + prefix,
RequestInfoResolver: newTestRequestInfoResolver(),
Creater: api.Scheme,
Convertor: api.Scheme,
@ -2214,9 +2218,9 @@ func TestParentResourceIsRequired(t *testing.T) {
Context: requestContextMapper,
Mapper: namespaceMapper,
Version: newVersion,
ServerVersion: newVersion,
Codec: newCodec,
GroupVersion: newGroupVersion,
ServerGroupVersion: &newGroupVersion,
Codec: newCodec,
}
container = restful.NewContainer()
if err := group.InstallREST(container); err != nil {
@ -2225,14 +2229,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: "/api/simple/test/sub"}})
container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/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: "/api/version2/namespaces/test/simple/test/sub"}})
container.ServeHTTP(w, &http.Request{Method: "GET", URL: &url.URL{Path: "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/namespaces/test/simple/test/sub"}})
if w.Code != http.StatusOK {
t.Fatalf("expected OK: %#v", w)
}
@ -2257,7 +2261,7 @@ func TestCreateWithName(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/simple/"+pathName+"/sub", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/"+pathName+"/sub", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2284,7 +2288,7 @@ func TestUpdateChecksDecode(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("PUT", server.URL+"/api/version/namespaces/default/simple/bar", bytes.NewBuffer(data))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/simple/bar", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2346,7 +2350,7 @@ func TestCreate(t *testing.T) {
t: t,
name: "bar",
namespace: "default",
expectedSet: "/api/version/namespaces/default/foo/bar",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/foo/bar",
}
handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker)
server := httptest.NewServer(handler)
@ -2360,7 +2364,7 @@ func TestCreate(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/default/foo", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2405,7 +2409,7 @@ func TestCreateInNamespace(t *testing.T) {
t: t,
name: "bar",
namespace: "other",
expectedSet: "/api/version/namespaces/other/foo/bar",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/foo/bar",
}
handler := handleLinker(map[string]rest.Storage{"foo": &storage}, selfLinker)
server := httptest.NewServer(handler)
@ -2419,7 +2423,7 @@ func TestCreateInNamespace(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/other/foo", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2464,7 +2468,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) {
t: t,
name: "bar",
namespace: "other",
expectedSet: "/api/version/namespaces/other/foo/bar",
expectedSet: "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/other/foo/bar",
}
handler := handleInternal(true, map[string]rest.Storage{"foo": &storage}, deny.NewAlwaysDeny(), selfLinker)
server := httptest.NewServer(handler)
@ -2478,7 +2482,7 @@ func TestCreateInvokesAdmissionControl(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/version/namespaces/other/foo", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/other/foo", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2532,7 +2536,7 @@ func TestDelayReturnsError(t *testing.T) {
server := httptest.NewServer(handler)
defer server.Close()
status := expectApiStatus(t, "DELETE", fmt.Sprintf("%s/api/version/namespaces/default/foo/bar", server.URL), nil, http.StatusConflict)
status := expectApiStatus(t, "DELETE", fmt.Sprintf("%s/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.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)
}
@ -2606,7 +2610,7 @@ func TestCreateTimeout(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
itemOut := expectApiStatus(t, "POST", server.URL+"/api/version/namespaces/default/foo?timeout=4ms", data, apierrs.StatusServerTimeout)
itemOut := expectApiStatus(t, "POST", server.URL+"/"+prefix+"/"+testGroupVersion.Group+"/"+testGroupVersion.Version+"/namespaces/default/foo?timeout=4ms", data, apierrs.StatusServerTimeout)
if itemOut.Status != unversioned.StatusFailure || itemOut.Reason != unversioned.StatusReasonTimeout {
t.Errorf("Unexpected status %#v", itemOut)
}
@ -2698,7 +2702,7 @@ func TestCreateChecksAPIVersion(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2739,7 +2743,7 @@ func TestCreateDefaultsAPIVersion(t *testing.T) {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("POST", server.URL+"/api/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data))
request, err := http.NewRequest("POST", server.URL+"/"+prefix+"/"+testVersion+"/namespaces/default/simple", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -2763,7 +2767,7 @@ func TestUpdateChecksAPIVersion(t *testing.T) {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
request, err := http.NewRequest("PUT", server.URL+"/api/"+testVersion+"/namespaces/default/simple/bar", bytes.NewBuffer(data))
request, err := http.NewRequest("PUT", server.URL+"/"+prefix+"/"+testVersion+"/namespaces/default/simple/bar", bytes.NewBuffer(data))
if err != nil {
t.Errorf("unexpected error: %v", err)
}

View File

@ -95,7 +95,7 @@ func TestProxy(t *testing.T) {
server *httptest.Server
proxyTestPattern string
}{
{namespaceServer, "/api/version2/proxy/namespaces/" + item.reqNamespace + "/foo/id" + item.path},
{namespaceServer, "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/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()+"/api/version2/proxy/namespaces/myns/foo/123", "", "http://127.0.0.1/")
ws, err := websocket.Dial("ws://"+server.Listener.Addr().String()+"/"+prefix+"/"+newGroupVersion.Group+"/"+newGroupVersion.Version+"/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 := "/api/version2/proxy/namespaces/ns/foo/id" + item.path
proxyTestPattern := "/" + prefix + "/" + newGroupVersion.Group + "/" + newGroupVersion.Version + "/proxy/namespaces/ns/foo/id" + item.path
req, err := http.NewRequest(
"GET",
server.URL+proxyTestPattern+"?"+item.query,

View File

@ -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 = "/api/version/watch/simples"
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.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 = "/api/version/watch/simples"
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.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 := "/api/" + testVersion + "/watch/simples"
namespacedPath := "/api/" + testVersion + "/watch/namespaces/other/simpleroots"
rootPath := "/" + prefix + "/" + testVersion + "/watch/simples"
namespacedPath := "/" + prefix + "/" + 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 = "/api/version/watch/simples"
dest.Path = "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.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 = "/api/" + newVersion + "/simple"
dest.Path = "/" + prefix + "/" + newVersion + "/simple"
dest.RawQuery = "watch=true"
req, _ := http.NewRequest("GET", dest.String(), nil)

View File

@ -670,8 +670,8 @@ func (m *Master) init(c *Config) {
}
expAPIVersions := []unversioned.GroupVersionForDiscovery{
{
GroupVersion: expVersion.Version,
Version: apiutil.GetVersion(expVersion.Version),
GroupVersion: expVersion.GroupVersion.String(),
Version: expVersion.GroupVersion.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.Version})
apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newRequestInfoResolver(), []string{expVersion.GroupVersion.String()})
}
// 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.Version = "v1"
version.GroupVersion = unversioned.GroupVersion{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.Version})
apiserver.InstallServiceErrorHandler(m.handlerContainer, m.newRequestInfoResolver(), []string{thirdparty.GroupVersion.String()})
return nil
}
@ -1018,20 +1018,22 @@ 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,
Version: apiutil.GetGroupVersion(group, version),
GroupVersion: unversioned.GroupVersion{Group: group, Version: 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,
ServerVersion: latest.GroupOrDie("").GroupVersion,
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,
Context: m.requestContextMapper,
@ -1106,6 +1108,7 @@ func (m *Master) experimental(c *Config) *apiserver.APIGroupVersion {
}
extensionsGroup := latest.GroupOrDie("extensions")
serverGroupVersion := unversioned.ParseGroupVersionOrDie(latest.GroupOrDie("").GroupVersion)
return &apiserver.APIGroupVersion{
Root: m.apiGroupPrefix,
@ -1115,12 +1118,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,
Version: extensionsGroup.GroupVersion,
ServerVersion: latest.GroupOrDie("").GroupVersion,
Mapper: extensionsGroup.RESTMapper,
Codec: extensionsGroup.Codec,
Linker: extensionsGroup.SelfLinker,
Storage: storage,
GroupVersion: unversioned.ParseGroupVersionOrDie(extensionsGroup.GroupVersion),
ServerGroupVersion: &serverGroupVersion,
Admit: m.admissionControl,
Context: m.requestContextMapper,

View File

@ -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("v1", version.Version, "Version was not v1: %s", version.Version)
assert.Equal(unversioned.GroupVersion{Version: "v1"}, version.GroupVersion, "Version was not v1: %s", version.GroupVersion)
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,12 +322,14 @@ 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, 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)
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})
}
// TestGetNodeAddresses verifies that proper results are returned