github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/controller/operators/olm/config.go (about)

     1  package olm
     2  
     3  import (
     4  	"strings"
     5  	"time"
     6  
     7  	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
     8  	"k8s.io/client-go/metadata"
     9  
    10  	"github.com/pkg/errors"
    11  	"github.com/sirupsen/logrus"
    12  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  	"k8s.io/client-go/rest"
    14  	utilclock "k8s.io/utils/clock"
    15  
    16  	configv1client "github.com/openshift/client-go/config/clientset/versioned"
    17  	"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
    18  	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
    19  	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/labeler"
    20  	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
    21  )
    22  
    23  type OperatorOption func(*operatorConfig)
    24  
    25  type operatorConfig struct {
    26  	protectedCopiedCSVNamespaces map[string]struct{}
    27  	resyncPeriod                 func() time.Duration
    28  	operatorNamespace            string
    29  	watchedNamespaces            []string
    30  	clock                        utilclock.Clock
    31  	logger                       *logrus.Logger
    32  	operatorClient               operatorclient.ClientInterface
    33  	metadataClient               metadata.Interface
    34  	externalClient               versioned.Interface
    35  	strategyResolver             install.StrategyResolverInterface
    36  	apiReconciler                APIIntersectionReconciler
    37  	apiLabeler                   labeler.Labeler
    38  	restConfig                   *rest.Config
    39  	configClient                 configv1client.Interface
    40  }
    41  
    42  func (o *operatorConfig) OperatorClient() operatorclient.ClientInterface {
    43  	return o.operatorClient
    44  }
    45  
    46  func (o *operatorConfig) ExternalClient() versioned.Interface {
    47  	return o.externalClient
    48  }
    49  
    50  func (o *operatorConfig) ResyncPeriod() func() time.Duration {
    51  	return o.resyncPeriod
    52  }
    53  
    54  func (o *operatorConfig) WatchedNamespaces() []string {
    55  	return o.watchedNamespaces
    56  }
    57  
    58  func (o *operatorConfig) Logger() *logrus.Logger {
    59  	return o.logger
    60  }
    61  
    62  func (o *operatorConfig) apply(options []OperatorOption) {
    63  	for _, option := range options {
    64  		option(o)
    65  	}
    66  }
    67  
    68  func newInvalidConfigError(name, msg string) error {
    69  	return errors.Errorf("%s config invalid: %s", name, msg)
    70  }
    71  
    72  func (o *operatorConfig) validate() (err error) {
    73  	// TODO: Add better config validation
    74  	switch {
    75  	case o.resyncPeriod == nil:
    76  		err = newInvalidConfigError("resync period", "must not be nil")
    77  	case o.operatorNamespace == metav1.NamespaceAll:
    78  		err = newInvalidConfigError("operator namespace", "must be a single namespace")
    79  	case len(o.watchedNamespaces) == 0:
    80  		err = newInvalidConfigError("watched namespaces", "must watch at least one namespace")
    81  	case o.clock == nil:
    82  		err = newInvalidConfigError("clock", "must not be nil")
    83  	case o.logger == nil:
    84  		err = newInvalidConfigError("logger", "must not be nil")
    85  	case o.operatorClient == nil:
    86  		err = newInvalidConfigError("operator client", "must not be nil")
    87  	case o.externalClient == nil:
    88  		err = newInvalidConfigError("external client", "must not be nil")
    89  	case o.strategyResolver == nil:
    90  		err = newInvalidConfigError("strategy resolver", "must not be nil")
    91  	case o.apiReconciler == nil:
    92  		err = newInvalidConfigError("api reconciler", "must not be nil")
    93  	case o.apiLabeler == nil:
    94  		err = newInvalidConfigError("api labeler", "must not be nil")
    95  	case o.restConfig == nil:
    96  		err = newInvalidConfigError("rest config", "must not be nil")
    97  	}
    98  
    99  	return
   100  }
   101  
   102  func defaultOperatorConfig() *operatorConfig {
   103  	return &operatorConfig{
   104  		resyncPeriod:                 queueinformer.ResyncWithJitter(30*time.Second, 0.2),
   105  		operatorNamespace:            "default",
   106  		watchedNamespaces:            []string{metav1.NamespaceAll},
   107  		clock:                        utilclock.RealClock{},
   108  		logger:                       logrus.New(),
   109  		strategyResolver:             &install.StrategyResolver{},
   110  		apiReconciler:                APIIntersectionReconcileFunc(ReconcileAPIIntersection),
   111  		apiLabeler:                   labeler.Func(LabelSetsFor),
   112  		protectedCopiedCSVNamespaces: map[string]struct{}{},
   113  	}
   114  }
   115  
   116  func WithResyncPeriod(resyncPeriod func() time.Duration) OperatorOption {
   117  	return func(config *operatorConfig) {
   118  		config.resyncPeriod = resyncPeriod
   119  	}
   120  }
   121  
   122  func WithOperatorNamespace(namespace string) OperatorOption {
   123  	return func(config *operatorConfig) {
   124  		config.operatorNamespace = namespace
   125  	}
   126  }
   127  
   128  func WithWatchedNamespaces(namespaces ...string) OperatorOption {
   129  	return func(config *operatorConfig) {
   130  		config.watchedNamespaces = namespaces
   131  	}
   132  }
   133  
   134  func WithLogger(logger *logrus.Logger) OperatorOption {
   135  	return func(config *operatorConfig) {
   136  		config.logger = logger
   137  	}
   138  }
   139  
   140  func WithProtectedCopiedCSVNamespaces(namespaces string) OperatorOption {
   141  	return func(config *operatorConfig) {
   142  		if namespaces == "" {
   143  			return
   144  		}
   145  
   146  		for _, ns := range strings.Split(namespaces, ",") {
   147  			config.protectedCopiedCSVNamespaces[ns] = struct{}{}
   148  		}
   149  	}
   150  }
   151  
   152  func WithClock(clock utilclock.Clock) OperatorOption {
   153  	return func(config *operatorConfig) {
   154  		config.clock = clock
   155  	}
   156  }
   157  
   158  func WithOperatorClient(operatorClient operatorclient.ClientInterface) OperatorOption {
   159  	return func(config *operatorConfig) {
   160  		config.operatorClient = operatorClient
   161  	}
   162  }
   163  
   164  func WithMetadataClient(metadataClient metadata.Interface) OperatorOption {
   165  	return func(config *operatorConfig) {
   166  		config.metadataClient = metadataClient
   167  	}
   168  }
   169  
   170  func WithExternalClient(externalClient versioned.Interface) OperatorOption {
   171  	return func(config *operatorConfig) {
   172  		config.externalClient = externalClient
   173  	}
   174  }
   175  
   176  func WithStrategyResolver(strategyResolver install.StrategyResolverInterface) OperatorOption {
   177  	return func(config *operatorConfig) {
   178  		config.strategyResolver = strategyResolver
   179  	}
   180  }
   181  
   182  func WithAPIReconciler(apiReconciler APIIntersectionReconciler) OperatorOption {
   183  	return func(config *operatorConfig) {
   184  		config.apiReconciler = apiReconciler
   185  	}
   186  }
   187  
   188  func WithAPILabeler(apiLabeler labeler.Labeler) OperatorOption {
   189  	return func(config *operatorConfig) {
   190  		config.apiLabeler = apiLabeler
   191  	}
   192  }
   193  
   194  func WithRestConfig(restConfig *rest.Config) OperatorOption {
   195  	return func(config *operatorConfig) {
   196  		config.restConfig = restConfig
   197  	}
   198  }
   199  
   200  func WithConfigClient(configClient configv1client.Interface) OperatorOption {
   201  	return func(config *operatorConfig) {
   202  		config.configClient = configClient
   203  	}
   204  }