mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Merge pull request #53156 from p0lyn0mial/move_admission_initializer_interfaces_to_apiserver
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. moved admission interfaces WantsClientCert, WantsAuthorizer and Wants… **What this PR does / why we need it**: moves some admission interfaces to apiserver, hopefully moving the webhook admission in the future will be much easier. **Release note**: ``` NONE ```
This commit is contained in:
commit
dd99659dc1
@ -467,9 +467,28 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp
|
|||||||
return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err)
|
return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is the wrong cert/key pair.
|
||||||
|
// Given the generic case of webhook admission from a generic apiserver,
|
||||||
|
// this key pair should be signed by the the API server's client CA.
|
||||||
|
// Read client cert/key for plugins that need to make calls out
|
||||||
|
certBytes, keyBytes := []byte{}, []byte{}
|
||||||
|
if len(s.ProxyClientCertFile) > 0 && len(s.ProxyClientKeyFile) > 0 {
|
||||||
|
var err error
|
||||||
|
certBytes, err = ioutil.ReadFile(s.ProxyClientCertFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, nil, nil, fmt.Errorf("failed to read proxy client cert file from: %s, err: %v", s.ProxyClientCertFile, err)
|
||||||
|
}
|
||||||
|
keyBytes, err = ioutil.ReadFile(s.ProxyClientKeyFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, nil, nil, fmt.Errorf("failed to read proxy client key file from: %s, err: %v", s.ProxyClientKeyFile, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = s.Admission.ApplyTo(
|
err = s.Admission.ApplyTo(
|
||||||
genericConfig,
|
genericConfig,
|
||||||
versionedInformers,
|
versionedInformers,
|
||||||
|
certBytes,
|
||||||
|
keyBytes,
|
||||||
pluginInitializer)
|
pluginInitializer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)
|
return nil, nil, nil, nil, nil, fmt.Errorf("failed to initialize admission: %v", err)
|
||||||
@ -498,19 +517,6 @@ func BuildAdmissionPluginInitializer(s *options.ServerRunOptions, client interna
|
|||||||
|
|
||||||
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, externalClient, sharedInformers, apiAuthorizer, cloudConfig, restMapper, quotaRegistry)
|
pluginInitializer := kubeapiserveradmission.NewPluginInitializer(client, externalClient, sharedInformers, apiAuthorizer, cloudConfig, restMapper, quotaRegistry)
|
||||||
|
|
||||||
// Read client cert/key for plugins that need to make calls out
|
|
||||||
if len(s.ProxyClientCertFile) > 0 && len(s.ProxyClientKeyFile) > 0 {
|
|
||||||
certBytes, err := ioutil.ReadFile(s.ProxyClientCertFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keyBytes, err := ioutil.ReadFile(s.ProxyClientKeyFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pluginInitializer = pluginInitializer.SetClientCert(certBytes, keyBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
pluginInitializer = pluginInitializer.SetServiceResolver(serviceResolver)
|
pluginInitializer = pluginInitializer.SetServiceResolver(serviceResolver)
|
||||||
pluginInitializer = pluginInitializer.SetProxyTransport(proxyTransport)
|
pluginInitializer = pluginInitializer.SetProxyTransport(proxyTransport)
|
||||||
|
|
||||||
|
@ -219,6 +219,8 @@ func NonBlockingRun(s *options.ServerRunOptions, stopCh <-chan struct{}) error {
|
|||||||
err = s.Admission.ApplyTo(
|
err = s.Admission.ApplyTo(
|
||||||
genericConfig,
|
genericConfig,
|
||||||
versionedInformers,
|
versionedInformers,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
pluginInitializer,
|
pluginInitializer,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -12,6 +12,7 @@ go_test(
|
|||||||
library = ":go_default_library",
|
library = ":go_default_library",
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -25,6 +26,7 @@ go_library(
|
|||||||
"//pkg/quota:go_default_library",
|
"//pkg/quota:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
|
genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ admission.Interface = &WantAuthorizerAdmission{}
|
var _ admission.Interface = &WantAuthorizerAdmission{}
|
||||||
var _ WantsAuthorizer = &WantAuthorizerAdmission{}
|
var _ genericadmissioninit.WantsAuthorizer = &WantAuthorizerAdmission{}
|
||||||
|
|
||||||
// TestWantsAuthorizer ensures that the authorizer is injected when the WantsAuthorizer
|
// TestWantsAuthorizer ensures that the authorizer is injected when the WantsAuthorizer
|
||||||
// interface is implemented.
|
// interface is implemented.
|
||||||
@ -106,19 +107,3 @@ func TestWantsServiceResolver(t *testing.T) {
|
|||||||
t.Errorf("plumbing fail - %v %v#", ok, got)
|
t.Errorf("plumbing fail - %v %v#", ok, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type clientCertWanter struct {
|
|
||||||
doNothingAdmission
|
|
||||||
gotCert, gotKey []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *clientCertWanter) SetClientCert(cert, key []byte) { s.gotCert, s.gotKey = cert, key }
|
|
||||||
|
|
||||||
func TestWantsClientCert(t *testing.T) {
|
|
||||||
i := &PluginInitializer{}
|
|
||||||
ccw := &clientCertWanter{}
|
|
||||||
i.SetClientCert([]byte("cert"), []byte("key")).Initialize(ccw)
|
|
||||||
if string(ccw.gotCert) != "cert" || string(ccw.gotKey) != "key" {
|
|
||||||
t.Errorf("plumbing fail - %v %v", ccw.gotCert, ccw.gotKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
|
admissioninit "k8s.io/apiserver/pkg/admission/initializer"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
@ -37,24 +38,12 @@ type WantsInternalKubeClientSet interface {
|
|||||||
admission.Validator
|
admission.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
// WantsExternalKubeClientSet defines a function which sets ClientSet for admission plugins that need it
|
|
||||||
type WantsExternalKubeClientSet interface {
|
|
||||||
SetExternalKubeClientSet(clientset.Interface)
|
|
||||||
admission.Validator
|
|
||||||
}
|
|
||||||
|
|
||||||
// WantsInternalKubeInformerFactory defines a function which sets InformerFactory for admission plugins that need it
|
// WantsInternalKubeInformerFactory defines a function which sets InformerFactory for admission plugins that need it
|
||||||
type WantsInternalKubeInformerFactory interface {
|
type WantsInternalKubeInformerFactory interface {
|
||||||
SetInternalKubeInformerFactory(informers.SharedInformerFactory)
|
SetInternalKubeInformerFactory(informers.SharedInformerFactory)
|
||||||
admission.Validator
|
admission.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
// WantsAuthorizer defines a function which sets Authorizer for admission plugins that need it.
|
|
||||||
type WantsAuthorizer interface {
|
|
||||||
SetAuthorizer(authorizer.Authorizer)
|
|
||||||
admission.Validator
|
|
||||||
}
|
|
||||||
|
|
||||||
// WantsCloudConfig defines a function which sets CloudConfig for admission plugins that need it.
|
// WantsCloudConfig defines a function which sets CloudConfig for admission plugins that need it.
|
||||||
type WantsCloudConfig interface {
|
type WantsCloudConfig interface {
|
||||||
SetCloudConfig([]byte)
|
SetCloudConfig([]byte)
|
||||||
@ -77,12 +66,6 @@ type WantsServiceResolver interface {
|
|||||||
SetServiceResolver(ServiceResolver)
|
SetServiceResolver(ServiceResolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WantsClientCert defines a fuction that accepts a cert & key for admission
|
|
||||||
// plugins that need to make calls and prove their identity.
|
|
||||||
type WantsClientCert interface {
|
|
||||||
SetClientCert(cert, key []byte)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceResolver knows how to convert a service reference into an actual
|
// ServiceResolver knows how to convert a service reference into an actual
|
||||||
// location.
|
// location.
|
||||||
type ServiceResolver interface {
|
type ServiceResolver interface {
|
||||||
@ -106,8 +89,6 @@ type PluginInitializer struct {
|
|||||||
serviceResolver ServiceResolver
|
serviceResolver ServiceResolver
|
||||||
|
|
||||||
// for proving we are apiserver in call-outs
|
// for proving we are apiserver in call-outs
|
||||||
clientCert []byte
|
|
||||||
clientKey []byte
|
|
||||||
proxyTransport *http.Transport
|
proxyTransport *http.Transport
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,14 +123,6 @@ func (i *PluginInitializer) SetServiceResolver(s ServiceResolver) *PluginInitial
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetClientCert sets the client cert & key (identity used for calling out to
|
|
||||||
// web hooks) which is needed by some plugins.
|
|
||||||
func (i *PluginInitializer) SetClientCert(cert, key []byte) *PluginInitializer {
|
|
||||||
i.clientCert = cert
|
|
||||||
i.clientKey = key
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetProxyTransport sets the proxyTransport which is needed by some plugins.
|
// SetProxyTransport sets the proxyTransport which is needed by some plugins.
|
||||||
func (i *PluginInitializer) SetProxyTransport(proxyTransport *http.Transport) *PluginInitializer {
|
func (i *PluginInitializer) SetProxyTransport(proxyTransport *http.Transport) *PluginInitializer {
|
||||||
i.proxyTransport = proxyTransport
|
i.proxyTransport = proxyTransport
|
||||||
@ -163,7 +136,7 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) {
|
|||||||
wants.SetInternalKubeClientSet(i.internalClient)
|
wants.SetInternalKubeClientSet(i.internalClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
if wants, ok := plugin.(WantsExternalKubeClientSet); ok {
|
if wants, ok := plugin.(admissioninit.WantsExternalKubeClientSet); ok {
|
||||||
wants.SetExternalKubeClientSet(i.externalClient)
|
wants.SetExternalKubeClientSet(i.externalClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +144,7 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) {
|
|||||||
wants.SetInternalKubeInformerFactory(i.informers)
|
wants.SetInternalKubeInformerFactory(i.informers)
|
||||||
}
|
}
|
||||||
|
|
||||||
if wants, ok := plugin.(WantsAuthorizer); ok {
|
if wants, ok := plugin.(admissioninit.WantsAuthorizer); ok {
|
||||||
wants.SetAuthorizer(i.authorizer)
|
wants.SetAuthorizer(i.authorizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,13 +164,6 @@ func (i *PluginInitializer) Initialize(plugin admission.Interface) {
|
|||||||
wants.SetServiceResolver(i.serviceResolver)
|
wants.SetServiceResolver(i.serviceResolver)
|
||||||
}
|
}
|
||||||
|
|
||||||
if wants, ok := plugin.(WantsClientCert); ok {
|
|
||||||
if i.clientCert == nil || i.clientKey == nil {
|
|
||||||
panic("An admission plugin wants a client cert/key, but they were not provided.")
|
|
||||||
}
|
|
||||||
wants.SetClientCert(i.clientCert, i.clientKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
if wants, ok := plugin.(WantsProxyTransport); ok {
|
if wants, ok := plugin.(WantsProxyTransport); ok {
|
||||||
wants.SetProxyTransport(i.proxyTransport)
|
wants.SetProxyTransport(i.proxyTransport)
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
|
genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -82,7 +83,7 @@ func (plugin *podSecurityPolicyPlugin) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ admission.Interface = &podSecurityPolicyPlugin{}
|
var _ admission.Interface = &podSecurityPolicyPlugin{}
|
||||||
var _ kubeapiserveradmission.WantsAuthorizer = &podSecurityPolicyPlugin{}
|
var _ genericadmissioninit.WantsAuthorizer = &podSecurityPolicyPlugin{}
|
||||||
var _ kubeapiserveradmission.WantsInternalKubeInformerFactory = &podSecurityPolicyPlugin{}
|
var _ kubeapiserveradmission.WantsInternalKubeInformerFactory = &podSecurityPolicyPlugin{}
|
||||||
|
|
||||||
// NewPlugin creates a new PSP admission plugin.
|
// NewPlugin creates a new PSP admission plugin.
|
||||||
|
@ -52,6 +52,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
|
"//vendor/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
|
genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@ -114,8 +115,8 @@ type GenericAdmissionWebhook struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
_ = admissioninit.WantsServiceResolver(&GenericAdmissionWebhook{})
|
_ = admissioninit.WantsServiceResolver(&GenericAdmissionWebhook{})
|
||||||
_ = admissioninit.WantsClientCert(&GenericAdmissionWebhook{})
|
_ = genericadmissioninit.WantsClientCert(&GenericAdmissionWebhook{})
|
||||||
_ = admissioninit.WantsExternalKubeClientSet(&GenericAdmissionWebhook{})
|
_ = genericadmissioninit.WantsExternalKubeClientSet(&GenericAdmissionWebhook{})
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *GenericAdmissionWebhook) SetProxyTransport(pt *http.Transport) {
|
func (a *GenericAdmissionWebhook) SetProxyTransport(pt *http.Transport) {
|
||||||
@ -140,6 +141,9 @@ func (a *GenericAdmissionWebhook) SetExternalKubeClientSet(client clientset.Inte
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *GenericAdmissionWebhook) Validate() error {
|
func (a *GenericAdmissionWebhook) Validate() error {
|
||||||
|
if a.clientCert == nil || a.clientKey == nil {
|
||||||
|
return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a client certificate and the private key to be provided")
|
||||||
|
}
|
||||||
if a.hookSource == nil {
|
if a.hookSource == nil {
|
||||||
return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a Kubernetes client to be provided")
|
return fmt.Errorf("the GenericAdmissionWebhook admission plugin requires a Kubernetes client to be provided")
|
||||||
}
|
}
|
||||||
|
@ -27,14 +27,21 @@ type pluginInitializer struct {
|
|||||||
externalClient kubernetes.Interface
|
externalClient kubernetes.Interface
|
||||||
externalInformers informers.SharedInformerFactory
|
externalInformers informers.SharedInformerFactory
|
||||||
authorizer authorizer.Authorizer
|
authorizer authorizer.Authorizer
|
||||||
|
// serverIdentifyingClientCert used to provide identity when calling out to admission plugins
|
||||||
|
serverIdentifyingClientCert []byte
|
||||||
|
// serverIdentifyingClientKey private key for the client certificate used when calling out to admission plugins
|
||||||
|
serverIdentifyingClientKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates an instance of admission plugins initializer.
|
// New creates an instance of admission plugins initializer.
|
||||||
func New(extClientset kubernetes.Interface, extInformers informers.SharedInformerFactory, authz authorizer.Authorizer) (pluginInitializer, error) {
|
// TODO(p0lyn0mial): make the parameters public, this construction seems to be redundant.
|
||||||
|
func New(extClientset kubernetes.Interface, extInformers informers.SharedInformerFactory, authz authorizer.Authorizer, serverIdentifyingClientCert, serverIdentifyingClientKey []byte) (pluginInitializer, error) {
|
||||||
return pluginInitializer{
|
return pluginInitializer{
|
||||||
externalClient: extClientset,
|
externalClient: extClientset,
|
||||||
externalInformers: extInformers,
|
externalInformers: extInformers,
|
||||||
authorizer: authz,
|
authorizer: authz,
|
||||||
|
serverIdentifyingClientCert: serverIdentifyingClientCert,
|
||||||
|
serverIdentifyingClientKey: serverIdentifyingClientKey,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +59,10 @@ func (i pluginInitializer) Initialize(plugin admission.Interface) {
|
|||||||
if wants, ok := plugin.(WantsAuthorizer); ok {
|
if wants, ok := plugin.(WantsAuthorizer); ok {
|
||||||
wants.SetAuthorizer(i.authorizer)
|
wants.SetAuthorizer(i.authorizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if wants, ok := plugin.(WantsClientCert); ok {
|
||||||
|
wants.SetClientCert(i.serverIdentifyingClientCert, i.serverIdentifyingClientKey)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ admission.PluginInitializer = pluginInitializer{}
|
var _ admission.PluginInitializer = pluginInitializer{}
|
||||||
|
@ -31,7 +31,7 @@ import (
|
|||||||
// TestWantsAuthorizer ensures that the authorizer is injected
|
// TestWantsAuthorizer ensures that the authorizer is injected
|
||||||
// when the WantsAuthorizer interface is implemented by a plugin.
|
// when the WantsAuthorizer interface is implemented by a plugin.
|
||||||
func TestWantsAuthorizer(t *testing.T) {
|
func TestWantsAuthorizer(t *testing.T) {
|
||||||
target, err := initializer.New(nil, nil, &TestAuthorizer{})
|
target, err := initializer.New(nil, nil, &TestAuthorizer{}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error())
|
t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error())
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ func TestWantsAuthorizer(t *testing.T) {
|
|||||||
// when the WantsExternalKubeClientSet interface is implemented by a plugin.
|
// when the WantsExternalKubeClientSet interface is implemented by a plugin.
|
||||||
func TestWantsExternalKubeClientSet(t *testing.T) {
|
func TestWantsExternalKubeClientSet(t *testing.T) {
|
||||||
cs := &fake.Clientset{}
|
cs := &fake.Clientset{}
|
||||||
target, err := initializer.New(cs, nil, &TestAuthorizer{})
|
target, err := initializer.New(cs, nil, &TestAuthorizer{}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error())
|
t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error())
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ func TestWantsExternalKubeClientSet(t *testing.T) {
|
|||||||
func TestWantsExternalKubeInformerFactory(t *testing.T) {
|
func TestWantsExternalKubeInformerFactory(t *testing.T) {
|
||||||
cs := &fake.Clientset{}
|
cs := &fake.Clientset{}
|
||||||
sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
|
sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
|
||||||
target, err := initializer.New(cs, sf, &TestAuthorizer{})
|
target, err := initializer.New(cs, sf, &TestAuthorizer{}, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error())
|
t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error())
|
||||||
}
|
}
|
||||||
@ -73,6 +73,20 @@ func TestWantsExternalKubeInformerFactory(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestWantsClientCert ensures that the client certificate and key are injected
|
||||||
|
// when the WantsClientCert interface is implemented by a plugin.
|
||||||
|
func TestWantsClientCert(t *testing.T) {
|
||||||
|
target, err := initializer.New(nil, nil, nil, []byte("cert"), []byte("key"))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected to create an instance of initializer but got an error = %s", err.Error())
|
||||||
|
}
|
||||||
|
wantClientCert := &clientCertWanter{}
|
||||||
|
target.Initialize(wantClientCert)
|
||||||
|
if string(wantClientCert.gotCert) != "cert" || string(wantClientCert.gotKey) != "key" {
|
||||||
|
t.Errorf("expected client cert to be initialized, clientCert = %v, clientKey = %v", wantClientCert.gotCert, wantClientCert.gotKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface
|
// WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface
|
||||||
type WantExternalKubeInformerFactory struct {
|
type WantExternalKubeInformerFactory struct {
|
||||||
sf informers.SharedInformerFactory
|
sf informers.SharedInformerFactory
|
||||||
@ -114,9 +128,19 @@ func (self *WantAuthorizerAdmission) Validate() error { re
|
|||||||
var _ admission.Interface = &WantAuthorizerAdmission{}
|
var _ admission.Interface = &WantAuthorizerAdmission{}
|
||||||
var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{}
|
var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{}
|
||||||
|
|
||||||
// TestAuthorizer is a test stub for testing that fulfills the authorizer interface.
|
// TestAuthorizer is a test stub that fulfills the WantsAuthorizer interface.
|
||||||
type TestAuthorizer struct{}
|
type TestAuthorizer struct{}
|
||||||
|
|
||||||
func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) {
|
func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) {
|
||||||
return false, "", nil
|
return false, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wantClientCert is a test stub for testing that fulfulls the WantsClientCert interface.
|
||||||
|
type clientCertWanter struct {
|
||||||
|
gotCert, gotKey []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *clientCertWanter) SetClientCert(cert, key []byte) { s.gotCert, s.gotKey = cert, key }
|
||||||
|
func (s *clientCertWanter) Admit(a admission.Attributes) error { return nil }
|
||||||
|
func (s *clientCertWanter) Handles(o admission.Operation) bool { return false }
|
||||||
|
func (s *clientCertWanter) Validate() error { return nil }
|
||||||
|
@ -40,3 +40,10 @@ type WantsAuthorizer interface {
|
|||||||
SetAuthorizer(authorizer.Authorizer)
|
SetAuthorizer(authorizer.Authorizer)
|
||||||
admission.Validator
|
admission.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WantsClientCert defines a fuction that accepts a cert & key for admission
|
||||||
|
// plugins that need to make calls and prove their identity.
|
||||||
|
type WantsClientCert interface {
|
||||||
|
SetClientCert(cert, key []byte)
|
||||||
|
admission.Validator
|
||||||
|
}
|
||||||
|
@ -48,7 +48,7 @@ func newHandlerForTestWithClock(c clientset.Interface, cacheClock clock.Clock) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, f, err
|
return nil, f, err
|
||||||
}
|
}
|
||||||
pluginInitializer, err := kubeadmission.New(c, f, nil)
|
pluginInitializer, err := kubeadmission.New(c, f, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handler, f, err
|
return handler, f, err
|
||||||
}
|
}
|
||||||
|
@ -73,9 +73,14 @@ func (a *AdmissionOptions) AddFlags(fs *pflag.FlagSet) {
|
|||||||
// In addition the method lazily initializes a generic plugin that is appended to the list of pluginInitializers
|
// In addition the method lazily initializes a generic plugin that is appended to the list of pluginInitializers
|
||||||
// note this method uses:
|
// note this method uses:
|
||||||
// genericconfig.LoopbackClientConfig
|
// genericconfig.LoopbackClientConfig
|
||||||
// genericconfig.SharedInformerFactory
|
|
||||||
// genericconfig.Authorizer
|
// genericconfig.Authorizer
|
||||||
func (a *AdmissionOptions) ApplyTo(c *server.Config, informers informers.SharedInformerFactory, pluginInitializers ...admission.PluginInitializer) error {
|
func (a *AdmissionOptions) ApplyTo(
|
||||||
|
c *server.Config,
|
||||||
|
informers informers.SharedInformerFactory,
|
||||||
|
serverIdentifyingClientCert []byte,
|
||||||
|
serverIdentifyingClientKey []byte,
|
||||||
|
pluginInitializers ...admission.PluginInitializer,
|
||||||
|
) error {
|
||||||
pluginNames := a.PluginNames
|
pluginNames := a.PluginNames
|
||||||
if len(a.PluginNames) == 0 {
|
if len(a.PluginNames) == 0 {
|
||||||
pluginNames = a.enabledPluginNames()
|
pluginNames = a.enabledPluginNames()
|
||||||
@ -90,7 +95,7 @@ func (a *AdmissionOptions) ApplyTo(c *server.Config, informers informers.SharedI
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
genericInitializer, err := initializer.New(clientset, informers, c.Authorizer)
|
genericInitializer, err := initializer.New(clientset, informers, c.Authorizer, serverIdentifyingClientCert, serverIdentifyingClientKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ func (o WardleServerOptions) Config() (*apiserver.Config, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, admissionInitializer); err != nil {
|
if err := o.Admission.ApplyTo(&serverConfig.Config, serverConfig.SharedInformerFactory, nil, nil, admissionInitializer); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user