k8s.io/apiserver@v0.31.1/pkg/admission/initializer/initializer_test.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package initializer_test
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  	"time"
    23  
    24  	"k8s.io/apimachinery/pkg/api/meta"
    25  	"k8s.io/apimachinery/pkg/runtime/schema"
    26  	"k8s.io/apiserver/pkg/admission"
    27  	"k8s.io/apiserver/pkg/admission/initializer"
    28  	"k8s.io/apiserver/pkg/authorization/authorizer"
    29  	"k8s.io/client-go/informers"
    30  	"k8s.io/client-go/kubernetes"
    31  	"k8s.io/client-go/kubernetes/fake"
    32  )
    33  
    34  // TestWantsAuthorizer ensures that the authorizer is injected
    35  // when the WantsAuthorizer interface is implemented by a plugin.
    36  func TestWantsAuthorizer(t *testing.T) {
    37  	target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, nil, nil)
    38  	wantAuthorizerAdmission := &WantAuthorizerAdmission{}
    39  	target.Initialize(wantAuthorizerAdmission)
    40  	if wantAuthorizerAdmission.auth == nil {
    41  		t.Errorf("expected authorizer to be initialized but found nil")
    42  	}
    43  }
    44  
    45  // TestWantsExternalKubeClientSet ensures that the clientset is injected
    46  // when the WantsExternalKubeClientSet interface is implemented by a plugin.
    47  func TestWantsExternalKubeClientSet(t *testing.T) {
    48  	cs := &fake.Clientset{}
    49  	target := initializer.New(cs, nil, nil, &TestAuthorizer{}, nil, nil, nil)
    50  	wantExternalKubeClientSet := &WantExternalKubeClientSet{}
    51  	target.Initialize(wantExternalKubeClientSet)
    52  	if wantExternalKubeClientSet.cs != cs {
    53  		t.Errorf("expected clientset to be initialized")
    54  	}
    55  }
    56  
    57  // TestWantsExternalKubeInformerFactory ensures that the informer factory is injected
    58  // when the WantsExternalKubeInformerFactory interface is implemented by a plugin.
    59  func TestWantsExternalKubeInformerFactory(t *testing.T) {
    60  	cs := &fake.Clientset{}
    61  	sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
    62  	target := initializer.New(cs, nil, sf, &TestAuthorizer{}, nil, nil, nil)
    63  	wantExternalKubeInformerFactory := &WantExternalKubeInformerFactory{}
    64  	target.Initialize(wantExternalKubeInformerFactory)
    65  	if wantExternalKubeInformerFactory.sf != sf {
    66  		t.Errorf("expected informer factory to be initialized")
    67  	}
    68  }
    69  
    70  // TestWantsShutdownSignal ensures that the shutdown signal is injected
    71  // when the WantsShutdownSignal interface is implemented by a plugin.
    72  func TestWantsShutdownNotification(t *testing.T) {
    73  	stopCh := make(chan struct{})
    74  	target := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, stopCh, nil)
    75  	wantDrainedNotification := &WantDrainedNotification{}
    76  	target.Initialize(wantDrainedNotification)
    77  	if wantDrainedNotification.stopCh == nil {
    78  		t.Errorf("expected stopCh to be initialized but found nil")
    79  	}
    80  }
    81  
    82  // WantExternalKubeInformerFactory is a test stub that fulfills the WantsExternalKubeInformerFactory interface
    83  type WantExternalKubeInformerFactory struct {
    84  	sf informers.SharedInformerFactory
    85  }
    86  
    87  func (self *WantExternalKubeInformerFactory) SetExternalKubeInformerFactory(sf informers.SharedInformerFactory) {
    88  	self.sf = sf
    89  }
    90  func (self *WantExternalKubeInformerFactory) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
    91  	return nil
    92  }
    93  func (self *WantExternalKubeInformerFactory) Handles(o admission.Operation) bool { return false }
    94  func (self *WantExternalKubeInformerFactory) ValidateInitialization() error      { return nil }
    95  
    96  var _ admission.Interface = &WantExternalKubeInformerFactory{}
    97  var _ initializer.WantsExternalKubeInformerFactory = &WantExternalKubeInformerFactory{}
    98  
    99  // WantExternalKubeClientSet is a test stub that fulfills the WantsExternalKubeClientSet interface
   100  type WantExternalKubeClientSet struct {
   101  	cs kubernetes.Interface
   102  }
   103  
   104  func (self *WantExternalKubeClientSet) SetExternalKubeClientSet(cs kubernetes.Interface) {
   105  	self.cs = cs
   106  }
   107  func (self *WantExternalKubeClientSet) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
   108  	return nil
   109  }
   110  func (self *WantExternalKubeClientSet) Handles(o admission.Operation) bool { return false }
   111  func (self *WantExternalKubeClientSet) ValidateInitialization() error      { return nil }
   112  
   113  var _ admission.Interface = &WantExternalKubeClientSet{}
   114  var _ initializer.WantsExternalKubeClientSet = &WantExternalKubeClientSet{}
   115  
   116  // WantAuthorizerAdmission is a test stub that fulfills the WantsAuthorizer interface.
   117  type WantAuthorizerAdmission struct {
   118  	auth authorizer.Authorizer
   119  }
   120  
   121  func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) { self.auth = a }
   122  func (self *WantAuthorizerAdmission) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
   123  	return nil
   124  }
   125  func (self *WantAuthorizerAdmission) Handles(o admission.Operation) bool { return false }
   126  func (self *WantAuthorizerAdmission) ValidateInitialization() error      { return nil }
   127  
   128  var _ admission.Interface = &WantAuthorizerAdmission{}
   129  var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{}
   130  
   131  // WantDrainedNotification is a test stub that filfills the WantsDrainedNotification interface.
   132  type WantDrainedNotification struct {
   133  	stopCh <-chan struct{}
   134  }
   135  
   136  func (self *WantDrainedNotification) SetDrainedNotification(stopCh <-chan struct{}) {
   137  	self.stopCh = stopCh
   138  }
   139  func (self *WantDrainedNotification) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
   140  	return nil
   141  }
   142  func (self *WantDrainedNotification) Handles(o admission.Operation) bool { return false }
   143  func (self *WantDrainedNotification) ValidateInitialization() error      { return nil }
   144  
   145  var _ admission.Interface = &WantDrainedNotification{}
   146  var _ initializer.WantsDrainedNotification = &WantDrainedNotification{}
   147  
   148  // TestAuthorizer is a test stub that fulfills the WantsAuthorizer interface.
   149  type TestAuthorizer struct{}
   150  
   151  func (t *TestAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
   152  	return authorizer.DecisionNoOpinion, "", nil
   153  }
   154  
   155  func TestRESTMapperAdmissionPlugin(t *testing.T) {
   156  	initializer := initializer.New(nil, nil, nil, &TestAuthorizer{}, nil, nil, &doNothingRESTMapper{})
   157  	wantsRESTMapperAdmission := &WantsRESTMapperAdmissionPlugin{}
   158  	initializer.Initialize(wantsRESTMapperAdmission)
   159  
   160  	if wantsRESTMapperAdmission.mapper == nil {
   161  		t.Errorf("Expected REST mapper to be initialized but found nil")
   162  	}
   163  }
   164  
   165  type WantsRESTMapperAdmissionPlugin struct {
   166  	doNothingAdmission
   167  	doNothingPluginInitialization
   168  	mapper meta.RESTMapper
   169  }
   170  
   171  func (p *WantsRESTMapperAdmissionPlugin) SetRESTMapper(mapper meta.RESTMapper) {
   172  	p.mapper = mapper
   173  }
   174  
   175  type doNothingRESTMapper struct{}
   176  
   177  func (doNothingRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
   178  	return schema.GroupVersionKind{}, nil
   179  }
   180  func (doNothingRESTMapper) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) {
   181  	return nil, nil
   182  }
   183  func (doNothingRESTMapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) {
   184  	return schema.GroupVersionResource{}, nil
   185  }
   186  func (doNothingRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
   187  	return nil, nil
   188  }
   189  func (doNothingRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) {
   190  	return nil, nil
   191  }
   192  func (doNothingRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*meta.RESTMapping, error) {
   193  	return nil, nil
   194  }
   195  func (doNothingRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
   196  	return "", nil
   197  }
   198  
   199  type doNothingAdmission struct{}
   200  
   201  func (doNothingAdmission) Admit(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
   202  	return nil
   203  }
   204  func (doNothingAdmission) Handles(o admission.Operation) bool { return false }
   205  func (doNothingAdmission) Validate() error                    { return nil }
   206  
   207  type doNothingPluginInitialization struct{}
   208  
   209  func (doNothingPluginInitialization) ValidateInitialization() error { return nil }