Merge pull request #44787 from mbohlool/c1

Automatic merge from submit-queue (batch tested with PRs 45684, 45266, 45669, 44787, 44984)

Add GroupVersionKind extension to OpenAPI operations

Fixes: #43249
ref: #34254

```release-note
Added Group/Version/Kind and Action extension to OpenAPI Operations 
```
This commit is contained in:
Kubernetes Submit Queue 2017-05-12 03:20:42 -07:00 committed by GitHub
commit d437703d27
4 changed files with 4565 additions and 20 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,11 @@ import (
"github.com/emicklei/go-restful"
)
const (
ROUTE_META_GVK = "x-kubernetes-group-version-kind"
ROUTE_META_ACTION = "x-kubernetes-action"
)
type APIInstaller struct {
group *APIGroupVersion
prefix string // Path prefix where API resources are to be registered.
@ -557,6 +562,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
return nil, fmt.Errorf("unknown action verb for discovery: %s", action.Verb)
}
routes := []*restful.RouteBuilder{}
switch action.Verb {
case "GET": // Get a resource.
var handler restful.RouteFunction
@ -588,7 +595,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
}
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
case "LIST": // List all resources of a kind.
doc := "list objects of kind " + kind
if hasSubresource {
@ -620,7 +627,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
route.Doc(doc)
}
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
case "PUT": // Update a resource.
doc := "replace the specified " + kind
if hasSubresource {
@ -636,7 +643,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Reads(versionedObject).
Writes(versionedObject)
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
case "PATCH": // Partially update a resource
doc := "partially update the specified " + kind
if hasSubresource {
@ -653,7 +660,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Reads(metav1.Patch{}).
Writes(versionedObject)
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
case "POST": // Create a resource.
var handler restful.RouteFunction
if isNamedCreater {
@ -676,7 +683,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
Reads(versionedObject).
Writes(versionedObject)
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
case "DELETE": // Delete a resource.
article := getArticleForNoun(kind, " ")
doc := "delete" + article + kind
@ -698,7 +705,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
}
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
case "DELETECOLLECTION":
doc := "delete collection of " + kind
if hasSubresource {
@ -716,7 +723,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
return nil, err
}
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
// TODO: deprecated
case "WATCH": // Watch a resource.
doc := "watch changes to an object of kind " + kind
@ -735,7 +742,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
return nil, err
}
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
// TODO: deprecated
case "WATCHLIST": // Watch all resources of a kind.
doc := "watch individual changes to a list of " + kind
@ -754,19 +761,19 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
return nil, err
}
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
// We add "proxy" subresource to remove the need for the generic top level prefix proxy.
// The generic top level prefix proxy is deprecated in v1.2, and will be removed in 1.3, or 1.4 at the latest.
// TODO: DEPRECATED in v1.2.
case "PROXY": // Proxy requests to a resource.
// Accept all methods as per http://issue.k8s.io/3996
addProxyRoute(ws, "GET", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix)
addProxyRoute(ws, "PUT", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix)
addProxyRoute(ws, "POST", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix)
addProxyRoute(ws, "PATCH", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix)
addProxyRoute(ws, "DELETE", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix)
addProxyRoute(ws, "HEAD", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix)
addProxyRoute(ws, "OPTIONS", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix)
routes = append(routes, buildProxyRoute(ws, "GET", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix))
routes = append(routes, buildProxyRoute(ws, "PUT", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix))
routes = append(routes, buildProxyRoute(ws, "POST", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix))
routes = append(routes, buildProxyRoute(ws, "PATCH", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix))
routes = append(routes, buildProxyRoute(ws, "DELETE", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix))
routes = append(routes, buildProxyRoute(ws, "HEAD", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix))
routes = append(routes, buildProxyRoute(ws, "OPTIONS", a.prefix, action.Path, proxyHandler, namespaced, kind, resource, subresource, hasSubresource, action.Params, operationSuffix))
case "CONNECT":
for _, method := range connecter.ConnectMethods() {
doc := "connect " + method + " requests to " + kind
@ -787,11 +794,16 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
}
addParams(route, action.Params)
ws.Route(route)
routes = append(routes, route)
}
default:
return nil, fmt.Errorf("unrecognized action verb: %s", action.Verb)
}
for _, route := range routes {
route.Metadata(ROUTE_META_GVK, reqScope.Kind)
route.Metadata(ROUTE_META_ACTION, action.Verb)
ws.Route(route)
}
// Note: update GetAuthorizerAttributes() when adding a custom handler.
}
@ -824,7 +836,7 @@ func routeFunction(handler http.Handler) restful.RouteFunction {
}
}
func addProxyRoute(ws *restful.WebService, method string, prefix string, path string, proxyHandler http.Handler, namespaced, kind, resource, subresource string, hasSubresource bool, params []*restful.Parameter, operationSuffix string) {
func buildProxyRoute(ws *restful.WebService, method string, prefix string, path string, proxyHandler http.Handler, namespaced, kind, resource, subresource string, hasSubresource bool, params []*restful.Parameter, operationSuffix string) *restful.RouteBuilder {
doc := "proxy " + method + " requests to " + kind
if hasSubresource {
doc = "proxy " + method + " requests to " + subresource + " of " + kind
@ -837,7 +849,7 @@ func addProxyRoute(ws *restful.WebService, method string, prefix string, path st
Consumes("*/*").
Writes("string")
addParams(proxyRoute, params)
ws.Route(proxyRoute)
return proxyRoute
}
func addParams(route *restful.RouteBuilder, params []*restful.Parameter) {

View File

@ -32,7 +32,8 @@ import (
)
const (
OpenAPIVersion = "2.0"
OpenAPIVersion = "2.0"
extensionPrefix = "x-kubernetes-"
)
type openAPI struct {
@ -259,6 +260,14 @@ func (o *openAPI) buildOperations(route restful.Route, inPathCommonParamsMap map
},
},
}
for k, v := range route.Metadata {
if strings.HasPrefix(k, extensionPrefix) {
if ret.Extensions == nil {
ret.Extensions = spec.Extensions{}
}
ret.Extensions.Add(k, v)
}
}
if ret.ID, ret.Tags, err = o.config.GetOperationIDAndTags(o.servePath, &route); err != nil {
return ret, err
}