Merge pull request #17227 from deads2k/gv-apigv

Auto commit by PR queue bot
pull/6/head
k8s-merge-robot 2015-11-17 01:53:17 -08:00
commit 5e20dcfd6f
8 changed files with 402 additions and 228 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)
}
}

File diff suppressed because it is too large Load Diff

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
@ -896,7 +896,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
}
@ -1009,7 +1009,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
}
@ -1022,20 +1022,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,
@ -1110,6 +1112,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,
@ -1119,12 +1122,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

@ -176,7 +176,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)
@ -323,12 +323,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