Skip to content

Commit bca9d5d

Browse files
committed
Add olm operator plug-in framework
Signed-off-by: perdasilva <[email protected]>
1 parent 665c25b commit bca9d5d

File tree

4 files changed

+106
-10
lines changed

4 files changed

+106
-10
lines changed

pkg/controller/operators/olm/config.go

+20
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ type operatorConfig struct {
3737
configClient configv1client.Interface
3838
}
3939

40+
func (o *operatorConfig) OperatorClient() operatorclient.ClientInterface {
41+
return o.operatorClient
42+
}
43+
44+
func (o *operatorConfig) ExternalClient() versioned.Interface {
45+
return o.externalClient
46+
}
47+
48+
func (o *operatorConfig) ResyncPeriod() func() time.Duration {
49+
return o.resyncPeriod
50+
}
51+
52+
func (o *operatorConfig) WatchedNamespaces() []string {
53+
return o.watchedNamespaces
54+
}
55+
56+
func (o *operatorConfig) Logger() *logrus.Logger {
57+
return o.logger
58+
}
59+
4060
func (o *operatorConfig) apply(options []OperatorOption) {
4161
for _, option := range options {
4262
option(o)

pkg/controller/operators/olm/operator.go

+31
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88
"time"
99

10+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/plugins"
1011
"github.com/sirupsen/logrus"
1112
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
1213
corev1 "k8s.io/api/core/v1"
@@ -61,6 +62,10 @@ var (
6162
ErrAPIServiceOwnerConflict = errors.New("unable to adopt APIService")
6263
)
6364

65+
// this unexported operator plugin slice provides an entrypoint for
66+
// downstream to inject its own plugins to augment the controller behavior
67+
var operatorPlugInFactoryFuncs []plugins.OperatorPlugInFactoryFunc
68+
6469
type Operator struct {
6570
queueinformer.Operator
6671

@@ -91,6 +96,7 @@ type Operator struct {
9196
clientAttenuator *scoped.ClientAttenuator
9297
serviceAccountQuerier *scoped.UserDefinedServiceAccountQuerier
9398
clientFactory clients.Factory
99+
plugins []plugins.OperatorPlugin
94100
}
95101

96102
func NewOperator(ctx context.Context, options ...OperatorOption) (*Operator, error) {
@@ -588,6 +594,31 @@ func newOperatorWithConfig(ctx context.Context, config *operatorConfig) (*Operat
588594
OverridesBuilderFunc: overridesBuilderFunc.GetDeploymentInitializer,
589595
}
590596

597+
// initialize plugins
598+
for _, makePlugIn := range operatorPlugInFactoryFuncs {
599+
plugin, err := makePlugIn(ctx, config, op)
600+
if err != nil {
601+
return nil, fmt.Errorf("error creating plugin: %s", err)
602+
}
603+
op.plugins = append(op.plugins, plugin)
604+
}
605+
606+
if len(operatorPlugInFactoryFuncs) > 0 {
607+
go func() {
608+
// block until operator is done
609+
<-op.Done()
610+
611+
// shutdown plug-ins
612+
for _, plugin := range op.plugins {
613+
if err := plugin.Shutdown(); err != nil {
614+
if op.logger != nil {
615+
op.logger.Warnf("error shutting down plug-in: %s", err)
616+
}
617+
}
618+
}
619+
}()
620+
}
621+
591622
return op, nil
592623
}
593624

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package plugins
2+
3+
import (
4+
"context"
5+
"time"
6+
7+
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
8+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
9+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
10+
"github.com/sirupsen/logrus"
11+
)
12+
13+
// HostOperator is an extensible and observable operator that hosts the plug-in, i.e. which the plug-in is extending
14+
type HostOperator interface {
15+
queueinformer.ObservableOperator
16+
queueinformer.ExtensibleOperator
17+
}
18+
19+
// OperatorConfig gives access to required configuration from the host operator
20+
type OperatorConfig interface {
21+
OperatorClient() operatorclient.ClientInterface
22+
ExternalClient() versioned.Interface
23+
ResyncPeriod() func() time.Duration
24+
WatchedNamespaces() []string
25+
Logger() *logrus.Logger
26+
}
27+
28+
// OperatorPlugin provides a simple interface
29+
// that can be used to extend the olm operator's functionality
30+
type OperatorPlugin interface {
31+
// Shutdown is called once the host operator is done
32+
// to give the plug-in a change to clean up resources if necessary
33+
Shutdown() error
34+
}
35+
36+
// OperatorPlugInFactoryFunc factory function that returns a new instance of a plug-in
37+
type OperatorPlugInFactoryFunc func(ctx context.Context, config OperatorConfig, hostOperator HostOperator) (OperatorPlugin, error)

pkg/lib/queueinformer/queueinformer_operator.go

+18-10
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,19 @@ import (
1313
"k8s.io/client-go/tools/cache"
1414
)
1515

16-
// Operator describes a Reconciler that manages a set of QueueInformers.
17-
type Operator interface {
16+
// ExtensibleOperator describes a Reconciler that can be extended with additional informers and queue informers
17+
type ExtensibleOperator interface {
18+
// RegisterQueueInformer registers the given QueueInformer with the Operator.
19+
// This method returns an error if the Operator has already been started.
20+
RegisterQueueInformer(queueInformer *QueueInformer) error
21+
22+
// RegisterInformer registers an informer with the Operator.
23+
// This method returns an error if the Operator has already been started.
24+
RegisterInformer(cache.SharedIndexInformer) error
25+
}
26+
27+
// ObservableOperator describes a Reconciler whose state can be queried
28+
type ObservableOperator interface {
1829
// Ready returns a channel that is closed when the Operator is ready to run.
1930
Ready() <-chan struct{}
2031

@@ -29,15 +40,12 @@ type Operator interface {
2940

3041
// HasSynced returns true if the Operator's Informers have synced, false otherwise.
3142
HasSynced() bool
43+
}
3244

33-
// RegisterQueueInformer registers the given QueueInformer with the Operator.
34-
// This method returns an error if the Operator has already been started.
35-
RegisterQueueInformer(queueInformer *QueueInformer) error
36-
37-
// RegisterInformer registers an informer with the Operator.
38-
// This method returns an error if the Operator has already been started.
39-
RegisterInformer(cache.SharedIndexInformer) error
40-
45+
// Operator describes a Reconciler that manages a set of QueueInformers.
46+
type Operator interface {
47+
ObservableOperator
48+
ExtensibleOperator
4149
// RunInformers starts the Operator's underlying Informers.
4250
RunInformers(ctx context.Context)
4351

0 commit comments

Comments
 (0)