diff --git a/pkg/api/rest/rest.go b/pkg/api/rest/rest.go index fbb80b47f5a..fbb8a131576 100644 --- a/pkg/api/rest/rest.go +++ b/pkg/api/rest/rest.go @@ -246,3 +246,18 @@ type StorageMetadata interface { // PATCH) can respond with. ProducesMIMETypes(verb string) []string } + +// ConnectRequest is an object passed to admission control for Connect operations +type ConnectRequest struct { + // Name is the name of the object on which the connect request was made + Name string + + // Options is the options object passed to the connect request. See the NewConnectOptions method on Connecter + Options runtime.Object + + // ResourcePath is the path for the resource in the REST server (ie. "pods/proxy") + ResourcePath string +} + +// IsAnAPIObject makes ConnectRequest a runtime.Object +func (*ConnectRequest) IsAnAPIObject() {} diff --git a/pkg/apiserver/api_installer.go b/pkg/apiserver/api_installer.go index 7aa68b871c0..2099d5458d6 100644 --- a/pkg/apiserver/api_installer.go +++ b/pkg/apiserver/api_installer.go @@ -539,7 +539,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag case "CONNECT": for _, method := range connecter.ConnectMethods() { route := ws.Method(method).Path(action.Path). - To(ConnectResource(connecter, reqScope, connectOptionsKind, connectSubpath, connectSubpathKey)). + To(ConnectResource(connecter, reqScope, admit, connectOptionsKind, path, connectSubpath, connectSubpathKey)). Filter(m). Doc("connect " + method + " requests to " + kind). Operation("connect" + method + kind). diff --git a/pkg/apiserver/resthandler.go b/pkg/apiserver/resthandler.go index 45d95e8989e..66733822730 100644 --- a/pkg/apiserver/resthandler.go +++ b/pkg/apiserver/resthandler.go @@ -142,7 +142,7 @@ func getRequestOptions(req *restful.Request, scope RequestScope, kind string, su } // ConnectResource returns a function that handles a connect request on a rest.Storage object. -func ConnectResource(connecter rest.Connecter, scope RequestScope, connectOptionsKind string, subpath bool, subpathKey string) restful.RouteFunction { +func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admission.Interface, connectOptionsKind, restPath string, subpath bool, subpathKey string) restful.RouteFunction { return func(req *restful.Request, res *restful.Response) { w := res.ResponseWriter namespace, name, err := scope.Namer.Name(req) @@ -157,6 +157,19 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, connectOption errorJSON(err, scope.Codec, w) return } + if admit.Handles(admission.Connect) { + connectRequest := &rest.ConnectRequest{ + Name: name, + Options: opts, + ResourcePath: restPath, + } + userInfo, _ := api.UserFrom(ctx) + err = admit.Admit(admission.NewAttributesRecord(connectRequest, scope.Kind, namespace, scope.Resource, admission.Connect, userInfo)) + if err != nil { + errorJSON(err, scope.Codec, w) + return + } + } handler, err := connecter.Connect(ctx, name, opts) if err != nil { errorJSON(err, scope.Codec, w)