Merge pull request #10060 from nikhiljindal/scopeParamPath

Updating the path param name to "namespace" instead of "namespaces"
This commit is contained in:
Maxwell Forbes 2015-06-25 09:56:15 -07:00
commit fc349fdd47
5 changed files with 445 additions and 459 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -115,10 +115,8 @@ type RESTScope interface {
// ParamName is the optional name of the parameter that should be inserted in the resource url // ParamName is the optional name of the parameter that should be inserted in the resource url
// If empty, no param will be inserted // If empty, no param will be inserted
ParamName() string ParamName() string
// ParamPath is a boolean that controls how the parameter is manifested in resource paths // ArgumentName is the optional name that should be used for the variable holding the value.
// If true, this parameter is encoded in path (i.e. /{paramName}/{paramValue}) ArgumentName() string
// If false, this parameter is encoded in query (i.e. ?{paramName}={paramValue})
ParamPath() bool
// ParamDescription is the optional description to use to document the parameter in api documentation // ParamDescription is the optional description to use to document the parameter in api documentation
ParamDescription() string ParamDescription() string
} }

View File

@ -26,7 +26,7 @@ import (
type restScope struct { type restScope struct {
name RESTScopeName name RESTScopeName
paramName string paramName string
paramPath bool argumentName string
paramDescription string paramDescription string
} }
@ -36,24 +36,17 @@ func (r *restScope) Name() RESTScopeName {
func (r *restScope) ParamName() string { func (r *restScope) ParamName() string {
return r.paramName return r.paramName
} }
func (r *restScope) ParamPath() bool { func (r *restScope) ArgumentName() string {
return r.paramPath return r.argumentName
} }
func (r *restScope) ParamDescription() string { func (r *restScope) ParamDescription() string {
return r.paramDescription return r.paramDescription
} }
var RESTScopeNamespaceLegacy = &restScope{
name: RESTScopeNameNamespace,
paramName: "namespace",
paramPath: false,
paramDescription: "object name and auth scope, such as for teams and projects",
}
var RESTScopeNamespace = &restScope{ var RESTScopeNamespace = &restScope{
name: RESTScopeNameNamespace, name: RESTScopeNameNamespace,
paramName: "namespaces", paramName: "namespaces",
paramPath: true, argumentName: "namespace",
paramDescription: "object name and auth scope, such as for teams and projects", paramDescription: "object name and auth scope, such as for teams and projects",
} }

View File

@ -250,7 +250,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
actions := []action{} actions := []action{}
// Get the list of actions for the given scope. // Get the list of actions for the given scope.
if scope.Name() != meta.RESTScopeNameNamespace { switch scope.Name() {
case meta.RESTScopeNameRoot:
// Handle non-namespace scoped resources like nodes. // Handle non-namespace scoped resources like nodes.
resourcePath := resource resourcePath := resource
resourceParams := params resourceParams := params
@ -283,61 +284,55 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
actions = appendIf(actions, action{"PROXY", "proxy/" + itemPath, nameParams, namer}, isRedirector) actions = appendIf(actions, action{"PROXY", "proxy/" + itemPath, nameParams, namer}, isRedirector)
actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer}, isConnecter) actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer}, isConnecter)
actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer}, isConnecter && connectSubpath) actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer}, isConnecter && connectSubpath)
break
case meta.RESTScopeNameNamespace:
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
namespaceParam := ws.PathParameter(scope.ArgumentName(), scope.ParamDescription()).DataType("string")
namespacedPath := scope.ParamName() + "/{" + scope.ArgumentName() + "}/" + resource
namespaceParams := []*restful.Parameter{namespaceParam}
} else { resourcePath := namespacedPath
// Handle namespace scoped resources like pods. resourceParams := namespaceParams
if scope.ParamPath() { itemPath := namespacedPath + "/{name}"
// Handle the case when namespace is part of the path. nameParams := append(namespaceParams, nameParam)
// Handler for standard REST verbs (GET, PUT, POST and DELETE). proxyParams := append(nameParams, pathParam)
namespaceParam := ws.PathParameter(scope.ParamName(), scope.ParamDescription()).DataType("string") if hasSubresource {
namespacedPath := scope.ParamName() + "/{" + scope.ParamName() + "}/" + resource itemPath = itemPath + "/" + subresource
namespaceParams := []*restful.Parameter{namespaceParam} resourcePath = itemPath
resourceParams = nameParams
resourcePath := namespacedPath
resourceParams := namespaceParams
itemPath := namespacedPath + "/{name}"
nameParams := append(namespaceParams, nameParam)
proxyParams := append(nameParams, pathParam)
if hasSubresource {
itemPath = itemPath + "/" + subresource
resourcePath = itemPath
resourceParams = nameParams
}
namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false}
// Add actions at the resource path: /api/apiVersion/namespaces/{namespaces}/resource
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister)
actions = appendIf(actions, action{"POST", resourcePath, resourceParams, namer}, isCreater)
// DEPRECATED
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resourcePath, resourceParams, namer}, allowWatchList)
// Add actions at the item path: /api/apiVersion/namespaces/{namespaces}/resource/{name}
actions = appendIf(actions, action{"GET", itemPath, nameParams, namer}, isGetter)
if getSubpath {
actions = appendIf(actions, action{"GET", itemPath + "/{path:*}", proxyParams, namer}, isGetter)
}
actions = appendIf(actions, action{"PUT", itemPath, nameParams, namer}, isUpdater)
actions = appendIf(actions, action{"PATCH", itemPath, nameParams, namer}, isPatcher)
actions = appendIf(actions, action{"DELETE", itemPath, nameParams, namer}, isDeleter)
actions = appendIf(actions, action{"WATCH", "watch/" + itemPath, nameParams, namer}, isWatcher)
actions = appendIf(actions, action{"PROXY", "proxy/" + itemPath + "/{path:*}", proxyParams, namer}, isRedirector)
actions = appendIf(actions, action{"PROXY", "proxy/" + itemPath, nameParams, namer}, isRedirector)
actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer}, isConnecter)
actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer}, isConnecter && connectSubpath)
// list or post across namespace.
// For ex: LIST all pods in all namespaces by sending a LIST request at /api/apiVersion/pods.
// TODO: more strongly type whether a resource allows these actions on "all namespaces" (bulk delete)
if !hasSubresource {
namer = scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), true}
actions = appendIf(actions, action{"LIST", resource, params, namer}, isLister)
actions = appendIf(actions, action{"POST", resource, params, namer}, isCreater)
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer}, allowWatchList)
}
} else {
// Legacy behavior: Namespace as param is no longer supported
return fmt.Errorf("namespace as a parameter is no longer supported")
} }
namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false}
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister)
actions = appendIf(actions, action{"POST", resourcePath, resourceParams, namer}, isCreater)
// DEPRECATED
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resourcePath, resourceParams, namer}, allowWatchList)
actions = appendIf(actions, action{"GET", itemPath, nameParams, namer}, isGetter)
if getSubpath {
actions = appendIf(actions, action{"GET", itemPath + "/{path:*}", proxyParams, namer}, isGetter)
}
actions = appendIf(actions, action{"PUT", itemPath, nameParams, namer}, isUpdater)
actions = appendIf(actions, action{"PATCH", itemPath, nameParams, namer}, isPatcher)
actions = appendIf(actions, action{"DELETE", itemPath, nameParams, namer}, isDeleter)
actions = appendIf(actions, action{"WATCH", "watch/" + itemPath, nameParams, namer}, isWatcher)
actions = appendIf(actions, action{"PROXY", "proxy/" + itemPath + "/{path:*}", proxyParams, namer}, isRedirector)
actions = appendIf(actions, action{"PROXY", "proxy/" + itemPath, nameParams, namer}, isRedirector)
actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer}, isConnecter)
actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer}, isConnecter && connectSubpath)
// list or post across namespace.
// For ex: LIST all pods in all namespaces by sending a LIST request at /api/apiVersion/pods.
// TODO: more strongly type whether a resource allows these actions on "all namespaces" (bulk delete)
if !hasSubresource {
namer = scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), true}
actions = appendIf(actions, action{"LIST", resource, params, namer}, isLister)
actions = appendIf(actions, action{"POST", resource, params, namer}, isCreater)
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer}, allowWatchList)
}
break
default:
return fmt.Errorf("unsupported restscope: %s", scope.Name())
} }
// Create Routes for the actions. // Create Routes for the actions.
@ -658,7 +653,7 @@ func (n scopeNaming) Namespace(req *restful.Request) (namespace string, err erro
if n.allNamespaces { if n.allNamespaces {
return "", nil return "", nil
} }
namespace = req.PathParameter(n.scope.ParamName()) namespace = req.PathParameter(n.scope.ArgumentName())
if len(namespace) == 0 { if len(namespace) == 0 {
// a URL was constructed without the namespace, or this method was invoked // a URL was constructed without the namespace, or this method was invoked
// on an object without a namespace path parameter. // on an object without a namespace path parameter.
@ -694,7 +689,7 @@ func (n scopeNaming) GenerateLink(req *restful.Request, obj runtime.Object) (pat
return "", "", errEmptyName return "", "", errEmptyName
} }
path = strings.Replace(n.itemPath, "{name}", name, 1) path = strings.Replace(n.itemPath, "{name}", name, 1)
path = strings.Replace(path, "{"+n.scope.ParamName()+"}", namespace, 1) path = strings.Replace(path, "{"+n.scope.ArgumentName()+"}", namespace, 1)
return path, "", nil return path, "", nil
} }