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:
Chao Xu 2018-07-30 18:35:51 -07:00
parent 6fe7f9f4b7
commit 355691d310
5 changed files with 9 additions and 87 deletions

View File

@ -20,10 +20,8 @@ import (
"fmt" "fmt"
"io" "io"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/registry/rest"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission" kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
@ -94,15 +92,15 @@ func NewDenyExecOnPrivileged() *DenyExec {
// Validate makes an admission decision based on the request attributes // Validate makes an admission decision based on the request attributes
func (d *DenyExec) Validate(a admission.Attributes) (err error) { func (d *DenyExec) Validate(a admission.Attributes) (err error) {
connectRequest, ok := a.GetObject().(*rest.ConnectRequest) path := a.GetResource().Resource
if !ok { if subresource := a.GetSubresource(); subresource != "" {
return errors.NewBadRequest("a connect request was received, but could not convert the request object.") path = path + "/" + subresource
} }
// Only handle exec or attach requests on pods // 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 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 { if err != nil {
return admission.NewForbidden(a, err) return admission.NewForbidden(a, err)
} }

View File

@ -22,7 +22,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/registry/rest"
core "k8s.io/client-go/testing" core "k8s.io/client-go/testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "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 // pods/exec
{ {
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"} 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))
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil))
if shouldAccept && err != nil { if shouldAccept && err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err) 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 // pods/attach
{ {
req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/attach"} 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))
err := handler.Validate(admission.NewAttributesRecord(req, nil, api.Kind("Pod").WithVersion("version"), "test", "name", api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil))
if shouldAccept && err != nil { if shouldAccept && err != nil {
t.Errorf("Unexpected error returned from admission handler: %v", err) t.Errorf("Unexpected error returned from admission handler: %v", err)
} }

View File

@ -115,22 +115,17 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi
return return
} }
if admit != nil && admit.Handles(admission.Connect) { if admit != nil && admit.Handles(admission.Connect) {
connectRequest := &rest.ConnectRequest{
Name: name,
Options: opts,
ResourcePath: restPath,
}
userInfo, _ := request.UserFrom(ctx) userInfo, _ := request.UserFrom(ctx)
// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT // TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok { 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 { if err != nil {
scope.err(err, w, req) scope.err(err, w, req)
return return
} }
} }
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok { 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 { if err != nil {
scope.err(err, w, req) scope.err(err, w, req)
return return

View File

@ -334,19 +334,3 @@ type StorageMetadata interface {
// it is not nil. Only the type of the return object matters, the value will be ignored. // it is not nil. Only the type of the return object matters, the value will be ignored.
ProducesObject(verb string) interface{} 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 }

View File

@ -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
}