Commit c5e2f7c2 authored by deads2k's avatar deads2k

remove dependency on gorestful for rest handling

parent f5052024
...@@ -679,6 +679,29 @@ func (r *GetWithOptionsRESTStorage) NewGetOptions() (runtime.Object, bool, strin ...@@ -679,6 +679,29 @@ func (r *GetWithOptionsRESTStorage) NewGetOptions() (runtime.Object, bool, strin
var _ rest.GetterWithOptions = &GetWithOptionsRESTStorage{} var _ rest.GetterWithOptions = &GetWithOptionsRESTStorage{}
type GetWithOptionsRootRESTStorage struct {
*SimpleTypedStorage
optionsReceived runtime.Object
takesPath string
}
func (r *GetWithOptionsRootRESTStorage) Get(ctx request.Context, name string, options runtime.Object) (runtime.Object, error) {
if _, ok := options.(*genericapitesting.SimpleGetOptions); !ok {
return nil, fmt.Errorf("Unexpected options object: %#v", options)
}
r.optionsReceived = options
return r.SimpleTypedStorage.Get(ctx, name, &metav1.GetOptions{})
}
func (r *GetWithOptionsRootRESTStorage) NewGetOptions() (runtime.Object, bool, string) {
if len(r.takesPath) > 0 {
return &genericapitesting.SimpleGetOptions{}, true, r.takesPath
}
return &genericapitesting.SimpleGetOptions{}, false, ""
}
var _ rest.GetterWithOptions = &GetWithOptionsRootRESTStorage{}
type NamedCreaterRESTStorage struct { type NamedCreaterRESTStorage struct {
*SimpleRESTStorage *SimpleRESTStorage
createdName string createdName string
...@@ -1519,87 +1542,123 @@ func TestGetWithOptionsRouteParams(t *testing.T) { ...@@ -1519,87 +1542,123 @@ func TestGetWithOptionsRouteParams(t *testing.T) {
} }
func TestGetWithOptions(t *testing.T) { func TestGetWithOptions(t *testing.T) {
storage := map[string]rest.Storage{}
simpleStorage := GetWithOptionsRESTStorage{
SimpleRESTStorage: &SimpleRESTStorage{
item: genericapitesting.Simple{
Other: "foo",
},
},
}
storage["simple"] = &simpleStorage
handler := handle(storage)
server := httptest.NewServer(handler)
defer server.Close()
resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + "/namespaces/default/simple/id?param1=test1&param2=test2") tests := []struct {
if err != nil { name string
t.Fatalf("unexpected error: %v", err) rootScoped bool
} requestURL string
if resp.StatusCode != http.StatusOK { expectedPath string
t.Fatalf("unexpected response: %#v", resp) }{
} {
var itemOut genericapitesting.Simple name: "basic",
body, err := extractBody(resp, &itemOut) requestURL: "/namespaces/default/simple/id?param1=test1&param2=test2",
if err != nil { expectedPath: "",
t.Errorf("unexpected error: %v", err) },
{
name: "with path",
requestURL: "/namespaces/default/simple/id/a/different/path?param1=test1&param2=test2",
expectedPath: "a/different/path",
},
{
name: "as subresource",
requestURL: "/namespaces/default/simple/id/subresource/another/different/path?param1=test1&param2=test2",
expectedPath: "another/different/path",
},
{
name: "cluster-scoped basic",
rootScoped: true,
requestURL: "/simple/id?param1=test1&param2=test2",
expectedPath: "",
},
{
name: "cluster-scoped basic with path",
rootScoped: true,
requestURL: "/simple/id/a/cluster/path?param1=test1&param2=test2",
expectedPath: "a/cluster/path",
},
{
name: "cluster-scoped basic as subresource",
rootScoped: true,
requestURL: "/simple/id/subresource/another/cluster/path?param1=test1&param2=test2",
expectedPath: "another/cluster/path",
},
} }
if itemOut.Name != simpleStorage.item.Name { for _, test := range tests {
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body)) simpleStorage := GetWithOptionsRESTStorage{
} SimpleRESTStorage: &SimpleRESTStorage{
item: genericapitesting.Simple{
Other: "foo",
},
},
takesPath: "atAPath",
}
simpleRootStorage := GetWithOptionsRootRESTStorage{
SimpleTypedStorage: &SimpleTypedStorage{
baseType: &genericapitesting.SimpleRoot{}, // a root scoped type
item: &genericapitesting.SimpleRoot{
Other: "foo",
},
},
takesPath: "atAPath",
}
opts, ok := simpleStorage.optionsReceived.(*genericapitesting.SimpleGetOptions) storage := map[string]rest.Storage{}
if !ok { if test.rootScoped {
t.Errorf("Unexpected options object received: %#v", simpleStorage.optionsReceived) storage["simple"] = &simpleRootStorage
return storage["simple/subresource"] = &simpleRootStorage
} } else {
if opts.Param1 != "test1" || opts.Param2 != "test2" { storage["simple"] = &simpleStorage
t.Errorf("Did not receive expected options: %#v", opts) storage["simple/subresource"] = &simpleStorage
} }
} handler := handle(storage)
server := httptest.NewServer(handler)
defer server.Close()
func TestGetWithOptionsAndPath(t *testing.T) { resp, err := http.Get(server.URL + "/" + prefix + "/" + testGroupVersion.Group + "/" + testGroupVersion.Version + test.requestURL)
storage := map[string]rest.Storage{} if err != nil {
simpleStorage := GetWithOptionsRESTStorage{ t.Errorf("%s: %v", test.name, err)
SimpleRESTStorage: &SimpleRESTStorage{ continue
item: genericapitesting.Simple{ }
Other: "foo", if resp.StatusCode != http.StatusOK {
}, t.Errorf("%s: unexpected response: %#v", test.name, resp)
}, continue
takesPath: "atAPath", }
} var itemOut genericapitesting.Simple
storage["simple"] = &simpleStorage body, err := extractBody(resp, &itemOut)
handler := handle(storage) if err != nil {
server := httptest.NewServer(handler) t.Errorf("%s: %v", test.name, err)
defer server.Close() continue
}
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 itemOut.Name != simpleStorage.item.Name {
if err != nil { t.Errorf("%s: Unexpected data: %#v, expected %#v (%s)", test.name, itemOut, simpleStorage.item, string(body))
t.Fatalf("unexpected error: %v", err) continue
} }
if resp.StatusCode != http.StatusOK {
t.Fatalf("unexpected response: %#v", resp)
}
var itemOut genericapitesting.Simple
body, err := extractBody(resp, &itemOut)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if itemOut.Name != simpleStorage.item.Name { var opts *genericapitesting.SimpleGetOptions
t.Errorf("Unexpected data: %#v, expected %#v (%s)", itemOut, simpleStorage.item, string(body)) var ok bool
} if test.rootScoped {
opts, ok = simpleRootStorage.optionsReceived.(*genericapitesting.SimpleGetOptions)
} else {
opts, ok = simpleStorage.optionsReceived.(*genericapitesting.SimpleGetOptions)
opts, ok := simpleStorage.optionsReceived.(*genericapitesting.SimpleGetOptions) }
if !ok { if !ok {
t.Errorf("Unexpected options object received: %#v", simpleStorage.optionsReceived) t.Errorf("%s: Unexpected options object received: %#v", test.name, simpleStorage.optionsReceived)
return continue
} }
if opts.Param1 != "test1" || opts.Param2 != "test2" || opts.Path != "a/different/path" { if opts.Param1 != "test1" || opts.Param2 != "test2" {
t.Errorf("Did not receive expected options: %#v", opts) t.Errorf("%s: Did not receive expected options: %#v", test.name, opts)
continue
}
if opts.Path != test.expectedPath {
t.Errorf("%s: Unexpected path value. Expected: %s. Actual: %s.", test.name, test.expectedPath, opts.Path)
continue
}
} }
} }
func TestGetAlternateSelfLink(t *testing.T) { func TestGetAlternateSelfLink(t *testing.T) {
storage := map[string]rest.Storage{} storage := map[string]rest.Storage{}
simpleStorage := SimpleRESTStorage{ simpleStorage := SimpleRESTStorage{
......
...@@ -33,7 +33,6 @@ import ( ...@@ -33,7 +33,6 @@ import (
"k8s.io/apiserver/pkg/server/httplog" "k8s.io/apiserver/pkg/server/httplog"
"k8s.io/apiserver/pkg/util/wsstream" "k8s.io/apiserver/pkg/util/wsstream"
"github.com/emicklei/go-restful"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
) )
...@@ -62,18 +61,18 @@ func (w *realTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) { ...@@ -62,18 +61,18 @@ func (w *realTimeoutFactory) TimeoutCh() (<-chan time.Time, func() bool) {
// serveWatch handles serving requests to the server // serveWatch handles serving requests to the server
// TODO: the functionality in this method and in WatchServer.Serve is not cleanly decoupled. // TODO: the functionality in this method and in WatchServer.Serve is not cleanly decoupled.
func serveWatch(watcher watch.Interface, scope RequestScope, req *restful.Request, res *restful.Response, timeout time.Duration) { func serveWatch(watcher watch.Interface, scope RequestScope, req *http.Request, w http.ResponseWriter, timeout time.Duration) {
// negotiate for the stream serializer // negotiate for the stream serializer
serializer, err := negotiation.NegotiateOutputStreamSerializer(req.Request, scope.Serializer) serializer, err := negotiation.NegotiateOutputStreamSerializer(req, scope.Serializer)
if err != nil { if err != nil {
scope.err(err, res.ResponseWriter, req.Request) scope.err(err, w, req)
return return
} }
framer := serializer.StreamSerializer.Framer framer := serializer.StreamSerializer.Framer
streamSerializer := serializer.StreamSerializer.Serializer streamSerializer := serializer.StreamSerializer.Serializer
embedded := serializer.Serializer embedded := serializer.Serializer
if framer == nil { if framer == nil {
scope.err(fmt.Errorf("no framer defined for %q available for embedded encoding", serializer.MediaType), res.ResponseWriter, req.Request) scope.err(fmt.Errorf("no framer defined for %q available for embedded encoding", serializer.MediaType), w, req)
return return
} }
encoder := scope.Serializer.EncoderForVersion(streamSerializer, scope.Kind.GroupVersion()) encoder := scope.Serializer.EncoderForVersion(streamSerializer, scope.Kind.GroupVersion())
...@@ -107,7 +106,7 @@ func serveWatch(watcher watch.Interface, scope RequestScope, req *restful.Reques ...@@ -107,7 +106,7 @@ func serveWatch(watcher watch.Interface, scope RequestScope, req *restful.Reques
TimeoutFactory: &realTimeoutFactory{timeout}, TimeoutFactory: &realTimeoutFactory{timeout},
} }
server.ServeHTTP(res.ResponseWriter, req.Request) server.ServeHTTP(w, req)
} }
// WatchServer serves a watch.Interface over a websocket or vanilla HTTP. // WatchServer serves a watch.Interface over a websocket or vanilla HTTP.
......
...@@ -32,6 +32,7 @@ import ( ...@@ -32,6 +32,7 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/endpoints/handlers" "k8s.io/apiserver/pkg/endpoints/handlers"
"k8s.io/apiserver/pkg/endpoints/handlers/negotiation" "k8s.io/apiserver/pkg/endpoints/handlers/negotiation"
"k8s.io/apiserver/pkg/endpoints/metrics" "k8s.io/apiserver/pkg/endpoints/metrics"
...@@ -560,9 +561,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -560,9 +561,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
case "GET": // Get a resource. case "GET": // Get a resource.
var handler restful.RouteFunction var handler restful.RouteFunction
if isGetterWithOptions { if isGetterWithOptions {
handler = handlers.GetResourceWithOptions(getterWithOptions, reqScope) handler = restfulGetResourceWithOptions(getterWithOptions, reqScope, hasSubresource)
} else { } else {
handler = handlers.GetResource(getter, exporter, reqScope) handler = restfulGetResource(getter, exporter, reqScope)
} }
handler = metrics.InstrumentRouteFunc(action.Verb, resource, handler) handler = metrics.InstrumentRouteFunc(action.Verb, resource, handler)
doc := "read the specified " + kind doc := "read the specified " + kind
...@@ -593,7 +594,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -593,7 +594,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "list " + subresource + " of objects of kind " + kind doc = "list " + subresource + " of objects of kind " + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.ListResource(lister, watcher, reqScope, false, a.minRequestTimeout)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulListResource(lister, watcher, reqScope, false, a.minRequestTimeout))
route := ws.GET(action.Path).To(handler). route := ws.GET(action.Path).To(handler).
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
...@@ -625,7 +626,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -625,7 +626,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "replace " + subresource + " of the specified " + kind doc = "replace " + subresource + " of the specified " + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.UpdateResource(updater, reqScope, a.group.Typer, admit)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulUpdateResource(updater, reqScope, a.group.Typer, admit))
route := ws.PUT(action.Path).To(handler). route := ws.PUT(action.Path).To(handler).
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
...@@ -641,7 +642,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -641,7 +642,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "partially update " + subresource + " of the specified " + kind doc = "partially update " + subresource + " of the specified " + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.PatchResource(patcher, reqScope, admit, mapping.ObjectConvertor)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulPatchResource(patcher, reqScope, admit, mapping.ObjectConvertor))
route := ws.PATCH(action.Path).To(handler). route := ws.PATCH(action.Path).To(handler).
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
...@@ -656,9 +657,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -656,9 +657,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
case "POST": // Create a resource. case "POST": // Create a resource.
var handler restful.RouteFunction var handler restful.RouteFunction
if isNamedCreater { if isNamedCreater {
handler = handlers.CreateNamedResource(namedCreater, reqScope, a.group.Typer, admit) handler = restfulCreateNamedResource(namedCreater, reqScope, a.group.Typer, admit)
} else { } else {
handler = handlers.CreateResource(creater, reqScope, a.group.Typer, admit) handler = restfulCreateResource(creater, reqScope, a.group.Typer, admit)
} }
handler = metrics.InstrumentRouteFunc(action.Verb, resource, handler) handler = metrics.InstrumentRouteFunc(action.Verb, resource, handler)
article := getArticleForNoun(kind, " ") article := getArticleForNoun(kind, " ")
...@@ -682,7 +683,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -682,7 +683,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "delete " + subresource + " of" + article + kind doc = "delete " + subresource + " of" + article + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.DeleteResource(gracefulDeleter, isGracefulDeleter, reqScope, admit)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulDeleteResource(gracefulDeleter, isGracefulDeleter, reqScope, admit))
route := ws.DELETE(action.Path).To(handler). route := ws.DELETE(action.Path).To(handler).
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
...@@ -703,7 +704,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -703,7 +704,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "delete collection of " + subresource + " of a " + kind doc = "delete collection of " + subresource + " of a " + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.DeleteCollection(collectionDeleter, isCollectionDeleter, reqScope, admit)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulDeleteCollection(collectionDeleter, isCollectionDeleter, reqScope, admit))
route := ws.DELETE(action.Path).To(handler). route := ws.DELETE(action.Path).To(handler).
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
...@@ -722,7 +723,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -722,7 +723,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "watch changes to " + subresource + " of an object of kind " + kind doc = "watch changes to " + subresource + " of an object of kind " + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.ListResource(lister, watcher, reqScope, true, a.minRequestTimeout)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulListResource(lister, watcher, reqScope, true, a.minRequestTimeout))
route := ws.GET(action.Path).To(handler). route := ws.GET(action.Path).To(handler).
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
...@@ -741,7 +742,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -741,7 +742,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "watch individual changes to a list of " + subresource + " of " + kind doc = "watch individual changes to a list of " + subresource + " of " + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.ListResource(lister, watcher, reqScope, true, a.minRequestTimeout)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulListResource(lister, watcher, reqScope, true, a.minRequestTimeout))
route := ws.GET(action.Path).To(handler). route := ws.GET(action.Path).To(handler).
Doc(doc). Doc(doc).
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")). Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
...@@ -772,7 +773,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag ...@@ -772,7 +773,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
if hasSubresource { if hasSubresource {
doc = "connect " + method + " requests to " + subresource + " of " + kind doc = "connect " + method + " requests to " + subresource + " of " + kind
} }
handler := metrics.InstrumentRouteFunc(action.Verb, resource, handlers.ConnectResource(connecter, reqScope, admit, path)) handler := metrics.InstrumentRouteFunc(action.Verb, resource, restfulConnectResource(connecter, reqScope, admit, path, hasSubresource))
route := ws.Method(method).Path(action.Path). route := ws.Method(method).Path(action.Path).
To(handler). To(handler).
Doc(doc). Doc(doc).
...@@ -979,3 +980,63 @@ func isVowel(c rune) bool { ...@@ -979,3 +980,63 @@ func isVowel(c rune) bool {
} }
return false return false
} }
func restfulListResource(r rest.Lister, rw rest.Watcher, scope handlers.RequestScope, forceWatch bool, minRequestTimeout time.Duration) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.ListResource(r, rw, scope, forceWatch, minRequestTimeout)(res.ResponseWriter, req.Request)
}
}
func restfulCreateNamedResource(r rest.NamedCreater, scope handlers.RequestScope, typer runtime.ObjectTyper, admit admission.Interface) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.CreateNamedResource(r, scope, typer, admit)(res.ResponseWriter, req.Request)
}
}
func restfulCreateResource(r rest.Creater, scope handlers.RequestScope, typer runtime.ObjectTyper, admit admission.Interface) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.CreateResource(r, scope, typer, admit)(res.ResponseWriter, req.Request)
}
}
func restfulDeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.DeleteResource(r, allowsOptions, scope, admit)(res.ResponseWriter, req.Request)
}
}
func restfulDeleteCollection(r rest.CollectionDeleter, checkBody bool, scope handlers.RequestScope, admit admission.Interface) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.DeleteCollection(r, checkBody, scope, admit)(res.ResponseWriter, req.Request)
}
}
func restfulUpdateResource(r rest.Updater, scope handlers.RequestScope, typer runtime.ObjectTyper, admit admission.Interface) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.UpdateResource(r, scope, typer, admit)(res.ResponseWriter, req.Request)
}
}
func restfulPatchResource(r rest.Patcher, scope handlers.RequestScope, admit admission.Interface, converter runtime.ObjectConvertor) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.PatchResource(r, scope, admit, converter)(res.ResponseWriter, req.Request)
}
}
func restfulGetResource(r rest.Getter, e rest.Exporter, scope handlers.RequestScope) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.GetResource(r, e, scope)(res.ResponseWriter, req.Request)
}
}
func restfulGetResourceWithOptions(r rest.GetterWithOptions, scope handlers.RequestScope, isSubresource bool) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.GetResourceWithOptions(r, scope, isSubresource)(res.ResponseWriter, req.Request)
}
}
func restfulConnectResource(connecter rest.Connecter, scope handlers.RequestScope, admit admission.Interface, restPath string, isSubresource bool) restful.RouteFunction {
return func(req *restful.Request, res *restful.Response) {
handlers.ConnectResource(connecter, scope, admit, restPath, isSubresource)(res.ResponseWriter, req.Request)
}
}
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