Commit d437703d authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

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 ```
parents fab3d23b b8096604
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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) {
......
......@@ -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
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment