Remove rest.ConnectRequest.
Make apiserver pass connectRequest.Options directly to the admission layer. All the information in rest.ConnectRequest is present in admission attributes.
This commit is contained in:
		| @@ -20,10 +20,8 @@ import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | ||||
| 	"k8s.io/apimachinery/pkg/api/errors" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apiserver/pkg/admission" | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" | ||||
| 	kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" | ||||
| @@ -94,15 +92,15 @@ func NewDenyExecOnPrivileged() *DenyExec { | ||||
|  | ||||
| // Validate makes an admission decision based on the request attributes | ||||
| func (d *DenyExec) Validate(a admission.Attributes) (err error) { | ||||
| 	connectRequest, ok := a.GetObject().(*rest.ConnectRequest) | ||||
| 	if !ok { | ||||
| 		return errors.NewBadRequest("a connect request was received, but could not convert the request object.") | ||||
| 	path := a.GetResource().Resource | ||||
| 	if subresource := a.GetSubresource(); subresource != "" { | ||||
| 		path = path + "/" + subresource | ||||
| 	} | ||||
| 	// Only handle exec or attach requests on pods | ||||
| 	if connectRequest.ResourcePath != "pods/exec" && connectRequest.ResourcePath != "pods/attach" { | ||||
| 	if path != "pods/exec" && path != "pods/attach" { | ||||
| 		return nil | ||||
| 	} | ||||
| 	pod, err := d.client.Core().Pods(a.GetNamespace()).Get(connectRequest.Name, metav1.GetOptions{}) | ||||
| 	pod, err := d.client.Core().Pods(a.GetNamespace()).Get(a.GetName(), metav1.GetOptions{}) | ||||
| 	if err != nil { | ||||
| 		return admission.NewForbidden(a, err) | ||||
| 	} | ||||
|   | ||||
| @@ -22,7 +22,6 @@ import ( | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	"k8s.io/apiserver/pkg/admission" | ||||
| 	"k8s.io/apiserver/pkg/registry/rest" | ||||
| 	core "k8s.io/client-go/testing" | ||||
| 	api "k8s.io/kubernetes/pkg/apis/core" | ||||
| 	"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" | ||||
| @@ -122,8 +121,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b | ||||
|  | ||||
| 	// pods/exec | ||||
| 	{ | ||||
| 		req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"} | ||||
| 		err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil)) | ||||
| 		err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil)) | ||||
| 		if shouldAccept && err != nil { | ||||
| 			t.Errorf("Unexpected error returned from admission handler: %v", err) | ||||
| 		} | ||||
| @@ -134,8 +132,7 @@ func testAdmission(t *testing.T, pod *api.Pod, handler *DenyExec, shouldAccept b | ||||
|  | ||||
| 	// pods/attach | ||||
| 	{ | ||||
| 		req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"} | ||||
| 		err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil)) | ||||
| 		err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil)) | ||||
| 		if shouldAccept && err != nil { | ||||
| 			t.Errorf("Unexpected error returned from admission handler: %v", err) | ||||
| 		} | ||||
|   | ||||
| @@ -115,22 +115,17 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi | ||||
| 			return | ||||
| 		} | ||||
| 		if admit != nil && admit.Handles(admission.Connect) { | ||||
| 			connectRequest := &rest.ConnectRequest{ | ||||
| 				Name:         name, | ||||
| 				Options:      opts, | ||||
| 				ResourcePath: restPath, | ||||
| 			} | ||||
| 			userInfo, _ := request.UserFrom(ctx) | ||||
| 			// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT | ||||
| 			if mutatingAdmission, ok := admit.(admission.MutationInterface); ok { | ||||
| 				err = mutatingAdmission.Admit(admission.NewAttributesRecord(connectRequest, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo)) | ||||
| 				err = mutatingAdmission.Admit(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo)) | ||||
| 				if err != nil { | ||||
| 					scope.err(err, w, req) | ||||
| 					return | ||||
| 				} | ||||
| 			} | ||||
| 			if validatingAdmission, ok := admit.(admission.ValidationInterface); ok { | ||||
| 				err = validatingAdmission.Validate(admission.NewAttributesRecord(connectRequest, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo)) | ||||
| 				err = validatingAdmission.Validate(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo)) | ||||
| 				if err != nil { | ||||
| 					scope.err(err, w, req) | ||||
| 					return | ||||
|   | ||||
| @@ -334,19 +334,3 @@ type StorageMetadata interface { | ||||
| 	// it is not nil. Only the type of the return object matters, the value will be ignored. | ||||
| 	ProducesObject(verb string) interface{} | ||||
| } | ||||
|  | ||||
| // +k8s:deepcopy-gen=true | ||||
| // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object | ||||
| // 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 | ||||
| } | ||||
|  | ||||
| func (obj *ConnectRequest) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind } | ||||
|   | ||||
| @@ -1,52 +0,0 @@ | ||||
| // +build !ignore_autogenerated | ||||
|  | ||||
| /* | ||||
| Copyright The Kubernetes Authors. | ||||
|  | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
|  | ||||
|     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
|  | ||||
| // Code generated by deepcopy-gen. DO NOT EDIT. | ||||
|  | ||||
| package rest | ||||
|  | ||||
| import ( | ||||
| 	runtime "k8s.io/apimachinery/pkg/runtime" | ||||
| ) | ||||
|  | ||||
| // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. | ||||
| func (in *ConnectRequest) DeepCopyInto(out *ConnectRequest) { | ||||
| 	*out = *in | ||||
| 	if in.Options != nil { | ||||
| 		out.Options = in.Options.DeepCopyObject() | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectRequest. | ||||
| func (in *ConnectRequest) DeepCopy() *ConnectRequest { | ||||
| 	if in == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	out := new(ConnectRequest) | ||||
| 	in.DeepCopyInto(out) | ||||
| 	return out | ||||
| } | ||||
|  | ||||
| // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. | ||||
| func (in *ConnectRequest) DeepCopyObject() runtime.Object { | ||||
| 	if c := in.DeepCopy(); c != nil { | ||||
| 		return c | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Chao Xu
					Chao Xu