k8s.io/kubernetes@v1.29.3/test/e2e/framework/provider.go (about)

     1  /*
     2  Copyright 2018 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 framework
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"os"
    23  	"sync"
    24  
    25  	v1 "k8s.io/api/core/v1"
    26  	clientset "k8s.io/client-go/kubernetes"
    27  )
    28  
    29  // Factory is a func which operates provider specific behavior.
    30  type Factory func() (ProviderInterface, error)
    31  
    32  var (
    33  	providers = make(map[string]Factory)
    34  	mutex     sync.Mutex
    35  )
    36  
    37  // RegisterProvider is expected to be called during application init,
    38  // typically by an init function in a provider package.
    39  func RegisterProvider(name string, factory Factory) {
    40  	mutex.Lock()
    41  	defer mutex.Unlock()
    42  	if _, ok := providers[name]; ok {
    43  		panic(fmt.Sprintf("provider %s already registered", name))
    44  	}
    45  	providers[name] = factory
    46  }
    47  
    48  // GetProviders returns the names of all currently registered providers.
    49  func GetProviders() []string {
    50  	mutex.Lock()
    51  	defer mutex.Unlock()
    52  	var providerNames []string
    53  	for name := range providers {
    54  		providerNames = append(providerNames, name)
    55  	}
    56  	return providerNames
    57  }
    58  
    59  func init() {
    60  	// "local" or "skeleton" can always be used.
    61  	RegisterProvider("local", func() (ProviderInterface, error) {
    62  		return NullProvider{}, nil
    63  	})
    64  	RegisterProvider("skeleton", func() (ProviderInterface, error) {
    65  		return NullProvider{}, nil
    66  	})
    67  	// The empty string used to be accepted in the past, but is not
    68  	// a valid value anymore.
    69  }
    70  
    71  // SetupProviderConfig validates the chosen provider and creates
    72  // an interface instance for it.
    73  func SetupProviderConfig(providerName string) (ProviderInterface, error) {
    74  	var err error
    75  
    76  	mutex.Lock()
    77  	defer mutex.Unlock()
    78  	factory, ok := providers[providerName]
    79  	if !ok {
    80  		return nil, fmt.Errorf("The provider %s is unknown: %w", providerName, os.ErrNotExist)
    81  	}
    82  	provider, err := factory()
    83  
    84  	return provider, err
    85  }
    86  
    87  // ProviderInterface contains the implementation for certain
    88  // provider-specific functionality.
    89  type ProviderInterface interface {
    90  	FrameworkBeforeEach(f *Framework)
    91  	FrameworkAfterEach(f *Framework)
    92  
    93  	ResizeGroup(group string, size int32) error
    94  	GetGroupNodes(group string) ([]string, error)
    95  	GroupSize(group string) (int, error)
    96  
    97  	DeleteNode(node *v1.Node) error
    98  
    99  	CreatePD(zone string) (string, error)
   100  	DeletePD(pdName string) error
   101  	CreateShare() (string, string, string, error)
   102  	DeleteShare(accountName, shareName string) error
   103  
   104  	CreatePVSource(ctx context.Context, zone, diskName string) (*v1.PersistentVolumeSource, error)
   105  	DeletePVSource(ctx context.Context, pvSource *v1.PersistentVolumeSource) error
   106  
   107  	CleanupServiceResources(ctx context.Context, c clientset.Interface, loadBalancerName, region, zone string)
   108  
   109  	EnsureLoadBalancerResourcesDeleted(ctx context.Context, ip, portRange string) error
   110  	LoadBalancerSrcRanges() []string
   111  	EnableAndDisableInternalLB() (enable, disable func(svc *v1.Service))
   112  }
   113  
   114  // NullProvider is the default implementation of the ProviderInterface
   115  // which doesn't do anything.
   116  type NullProvider struct{}
   117  
   118  // FrameworkBeforeEach is a base implementation which does BeforeEach.
   119  func (n NullProvider) FrameworkBeforeEach(f *Framework) {}
   120  
   121  // FrameworkAfterEach is a base implementation which does AfterEach.
   122  func (n NullProvider) FrameworkAfterEach(f *Framework) {}
   123  
   124  // ResizeGroup is a base implementation which resizes group.
   125  func (n NullProvider) ResizeGroup(string, int32) error {
   126  	return fmt.Errorf("Provider does not support InstanceGroups")
   127  }
   128  
   129  // GetGroupNodes is a base implementation which returns group nodes.
   130  func (n NullProvider) GetGroupNodes(group string) ([]string, error) {
   131  	return nil, fmt.Errorf("provider does not support InstanceGroups")
   132  }
   133  
   134  // GroupSize returns the size of an instance group
   135  func (n NullProvider) GroupSize(group string) (int, error) {
   136  	return -1, fmt.Errorf("provider does not support InstanceGroups")
   137  }
   138  
   139  // DeleteNode is a base implementation which deletes a node.
   140  func (n NullProvider) DeleteNode(node *v1.Node) error {
   141  	return fmt.Errorf("provider does not support DeleteNode")
   142  }
   143  
   144  func (n NullProvider) CreateShare() (string, string, string, error) {
   145  	return "", "", "", fmt.Errorf("provider does not support volume creation")
   146  }
   147  
   148  func (n NullProvider) DeleteShare(accountName, shareName string) error {
   149  	return fmt.Errorf("provider does not support volume deletion")
   150  }
   151  
   152  // CreatePD is a base implementation which creates PD.
   153  func (n NullProvider) CreatePD(zone string) (string, error) {
   154  	return "", fmt.Errorf("provider does not support volume creation")
   155  }
   156  
   157  // DeletePD is a base implementation which deletes PD.
   158  func (n NullProvider) DeletePD(pdName string) error {
   159  	return fmt.Errorf("provider does not support volume deletion")
   160  }
   161  
   162  // CreatePVSource is a base implementation which creates PV source.
   163  func (n NullProvider) CreatePVSource(ctx context.Context, zone, diskName string) (*v1.PersistentVolumeSource, error) {
   164  	return nil, fmt.Errorf("Provider not supported")
   165  }
   166  
   167  // DeletePVSource is a base implementation which deletes PV source.
   168  func (n NullProvider) DeletePVSource(ctx context.Context, pvSource *v1.PersistentVolumeSource) error {
   169  	return fmt.Errorf("Provider not supported")
   170  }
   171  
   172  // CleanupServiceResources is a base implementation which cleans up service resources.
   173  func (n NullProvider) CleanupServiceResources(ctx context.Context, c clientset.Interface, loadBalancerName, region, zone string) {
   174  }
   175  
   176  // EnsureLoadBalancerResourcesDeleted is a base implementation which ensures load balancer is deleted.
   177  func (n NullProvider) EnsureLoadBalancerResourcesDeleted(ctx context.Context, ip, portRange string) error {
   178  	return nil
   179  }
   180  
   181  // LoadBalancerSrcRanges is a base implementation which returns the ranges of ips used by load balancers.
   182  func (n NullProvider) LoadBalancerSrcRanges() []string {
   183  	return nil
   184  }
   185  
   186  // EnableAndDisableInternalLB is a base implementation which returns functions for enabling/disabling an internal LB.
   187  func (n NullProvider) EnableAndDisableInternalLB() (enable, disable func(svc *v1.Service)) {
   188  	nop := func(svc *v1.Service) {}
   189  	return nop, nop
   190  }
   191  
   192  var _ ProviderInterface = NullProvider{}