Skip to content

Commit df36664

Browse files
committed
Adds OLM Operator Plugin interface and CSV Namespace labeller plug-in
Signed-off-by: perdasilva <[email protected]> Upstream-repository: perdasilva Upstream-commit: baaafa10f8d9f5c3251bfccb207c20bb84cdbc80 Signed-off-by: perdasilva <[email protected]>
1 parent 1ecfafd commit df36664

File tree

19 files changed

+1117
-90
lines changed

19 files changed

+1117
-90
lines changed

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
github.com/maxbrunsfeld/counterfeiter/v6 v6.4.1
1212
github.com/mikefarah/yq/v3 v3.0.0-20201202084205-8846255d1c37
1313
github.com/onsi/ginkgo/v2 v2.1.3
14-
github.com/openshift/api v0.0.0-20200331152225-585af27e34fd
14+
github.com/openshift/api v0.0.0-20220525145417-ee5b62754c68
1515
github.com/operator-framework/api v0.15.0
1616
github.com/operator-framework/operator-lifecycle-manager v0.0.0-00010101000000-000000000000
1717
github.com/operator-framework/operator-registry v1.17.5
@@ -176,7 +176,8 @@ require (
176176
github.com/onsi/gomega v1.18.1 // indirect
177177
github.com/opencontainers/go-digest v1.0.0 // indirect
178178
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
179-
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0 // indirect
179+
github.com/openshift/client-go v0.0.0-20220525160904-9e1acff93e4a // indirect
180+
github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f // indirect
180181
github.com/otiai10/copy v1.2.0 // indirect
181182
github.com/pbnjay/strptime v0.0.0-20140226051138-5c05b0d668c9 // indirect
182183
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
@@ -223,7 +224,7 @@ require (
223224
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
224225
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
225226
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 // indirect
226-
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
227+
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
227228
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
228229
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
229230
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect

go.sum

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,8 @@ github.com/openshift/api v0.0.0-20210517065120-b325f58df679/go.mod h1:dZ4kytOo3s
989989
github.com/openshift/build-machinery-go v0.0.0-20210209125900-0da259a2c359/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
990990
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0 h1:kMiuiZXH1GdfbiMwsuAQOqGaMxlo9NCUk0wT4XAdfNM=
991991
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0/go.mod h1:uUQ4LClRO+fg5MF/P6QxjMCb1C9f7Oh4RKepftDnEJE=
992+
github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f h1:ll0eE7rgGHsFlrI6ksr6nXL2ur8GYBe8Jj0GwNQ/1+o=
993+
github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f/go.mod h1:r9ZZT5wjwoS2heBfYR26uJhhkGYwgmFqomu9ww0y9Qw=
992994
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
993995
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
994996
github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k=
@@ -1435,8 +1437,9 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ
14351437
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
14361438
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
14371439
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
1438-
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
14391440
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
1441+
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
1442+
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
14401443
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
14411444
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
14421445
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

staging/operator-lifecycle-manager/go.mod

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ require (
2222
github.com/mitchellh/mapstructure v1.4.1
2323
github.com/onsi/ginkgo/v2 v2.1.3
2424
github.com/onsi/gomega v1.18.1
25-
github.com/openshift/api v0.0.0-20200331152225-585af27e34fd
26-
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0
25+
github.com/openshift/api v0.0.0-20220525145417-ee5b62754c68
26+
github.com/openshift/client-go v0.0.0-20220525160904-9e1acff93e4a
2727
github.com/operator-framework/api v0.15.0
2828
github.com/operator-framework/operator-registry v1.17.5
2929
github.com/otiai10/copy v1.2.0
@@ -221,7 +221,7 @@ require (
221221
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
222222
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
223223
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
224-
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
224+
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
225225
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
226226
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
227227
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
@@ -258,3 +258,6 @@ replace (
258258
go.opentelemetry.io/otel => go.opentelemetry.io/otel v0.20.0
259259
go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v0.20.0
260260
)
261+
262+
// downstream only
263+
require github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f

staging/operator-lifecycle-manager/go.sum

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,8 @@ github.com/openshift/api v0.0.0-20211014063134-be2a7fb8aa44/go.mod h1:RsQCVJu4qh
10751075
github.com/openshift/build-machinery-go v0.0.0-20210712174854-1bb7fd1518d3/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
10761076
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0 h1:kMiuiZXH1GdfbiMwsuAQOqGaMxlo9NCUk0wT4XAdfNM=
10771077
github.com/openshift/client-go v0.0.0-20200326155132-2a6cd50aedd0/go.mod h1:uUQ4LClRO+fg5MF/P6QxjMCb1C9f7Oh4RKepftDnEJE=
1078+
github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f h1:ll0eE7rgGHsFlrI6ksr6nXL2ur8GYBe8Jj0GwNQ/1+o=
1079+
github.com/openshift/cluster-policy-controller v0.0.0-20220825134653-523e4104074f/go.mod h1:r9ZZT5wjwoS2heBfYR26uJhhkGYwgmFqomu9ww0y9Qw=
10781080
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
10791081
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
10801082
github.com/operator-framework/api v0.7.1/go.mod h1:L7IvLd/ckxJEJg/t4oTTlnHKAJIP/p51AvEslW3wYdY=
@@ -1550,8 +1552,9 @@ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ
15501552
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
15511553
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
15521554
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
1553-
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
15541555
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
1556+
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
1557+
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
15551558
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
15561559
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
15571560
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package olm
2+
3+
import (
4+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/olm/plugins"
5+
)
6+
7+
func init() {
8+
operatorPlugInFactoryFuncs = []plugins.OperatorPlugInFactoryFunc{
9+
// labels unlabeled non-payload openshift-* csv namespaces with
10+
// security.openshift.io/scc.podSecurityLabelSync: true
11+
plugins.NewCsvNamespaceLabelerPlugInfunc,
12+
}
13+
}

staging/operator-lifecycle-manager/pkg/controller/operators/olm/operator_plugin.go

Lines changed: 0 additions & 24 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package plugins
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/openshift/cluster-policy-controller/pkg/psalabelsyncer/nsexemptions"
9+
"github.com/operator-framework/api/pkg/operators/v1alpha1"
10+
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
11+
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/internal/pruning"
12+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubestate"
13+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
14+
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
15+
"github.com/sirupsen/logrus"
16+
v1 "k8s.io/api/core/v1"
17+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18+
"k8s.io/client-go/informers"
19+
listerv1 "k8s.io/client-go/listers/core/v1"
20+
"k8s.io/client-go/tools/cache"
21+
"k8s.io/client-go/util/workqueue"
22+
)
23+
24+
const NamespaceLabelSyncerLabelKey = "security.openshift.io/scc.podSecurityLabelSync"
25+
26+
// csvNamespaceLabelerPlugin is responsible for labeling non-payload openshift-* namespaces
27+
// with the label "security.openshift.io/scc.podSecurityLabelSync=true" so that the PSA Label Syncer
28+
// see https://github.com/openshift/cluster-policy-controller/blob/master/pkg/psalabelsyncer/podsecurity_label_sync_controller.go
29+
// can help ensure that the operator payloads in the namespace continue to work even if they don't yet respect the
30+
// upstream Pod Security Admission controller, which will become active in k8s 1.15.
31+
// see https://kubernetes.io/docs/concepts/security/pod-security-admission/
32+
// If a CSV is created or modified, this controller will look at the csv's namespace. If it is a non-payload namespace,
33+
// if the namespace name is prefixed with 'openshift-', and if the namespace does not contain the label (whatever
34+
// value it may be set to), it will add the "security.openshift.io/scc.podSecurityLabelSync=true" to the namespace.
35+
type csvNamespaceLabelerPlugin struct {
36+
namespaceListerMap map[string]listerv1.NamespaceLister
37+
kubeClient operatorclient.ClientInterface
38+
externalClient versioned.Interface
39+
logger *logrus.Logger
40+
}
41+
42+
func NewCsvNamespaceLabelerPlugInfunc(ctx context.Context, config OperatorConfig, hostOperator HostOperator) (OperatorPlugin, error) {
43+
44+
if hostOperator == nil {
45+
return nil, fmt.Errorf("cannot initialize plugin: operator undefined")
46+
}
47+
48+
plugin := &csvNamespaceLabelerPlugin{
49+
kubeClient: config.OperatorClient(),
50+
externalClient: config.ExternalClient(),
51+
logger: config.Logger(),
52+
namespaceListerMap: map[string]listerv1.NamespaceLister{},
53+
}
54+
55+
for _, namespace := range config.WatchedNamespaces() {
56+
57+
// create a namespace informer for namespaces that do not include
58+
// the label syncer label
59+
namespaceInformer := informers.NewSharedInformerFactoryWithOptions(
60+
plugin.kubeClient.KubernetesInterface(),
61+
config.ResyncPeriod()(),
62+
informers.WithNamespace(namespace),
63+
).Core().V1().Namespaces()
64+
65+
if err := hostOperator.RegisterInformer(namespaceInformer.Informer()); err != nil {
66+
return nil, err
67+
}
68+
plugin.namespaceListerMap[namespace] = namespaceInformer.Lister()
69+
70+
// create a new csv informer and prune status to reduce memory footprint
71+
csvNamespaceLabelerInformer := cache.NewSharedIndexInformer(
72+
pruning.NewListerWatcher(
73+
plugin.externalClient,
74+
namespace,
75+
func(opts *metav1.ListOptions) {
76+
opts.LabelSelector = fmt.Sprintf("!%s", v1alpha1.CopiedLabelKey)
77+
},
78+
pruning.PrunerFunc(func(csv *v1alpha1.ClusterServiceVersion) {
79+
*csv = v1alpha1.ClusterServiceVersion{
80+
TypeMeta: csv.TypeMeta,
81+
ObjectMeta: csv.ObjectMeta,
82+
}
83+
}),
84+
),
85+
&v1alpha1.ClusterServiceVersion{},
86+
config.ResyncPeriod()(),
87+
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
88+
)
89+
90+
csvNamespaceLabelerPluginQueue := workqueue.NewNamedRateLimitingQueue(
91+
workqueue.DefaultControllerRateLimiter(),
92+
fmt.Sprintf("%s/csv-ns-labeler-plugin", namespace),
93+
)
94+
csvNamespaceLabelerPluginQueueInformer, err := queueinformer.NewQueueInformer(
95+
ctx,
96+
queueinformer.WithInformer(csvNamespaceLabelerInformer),
97+
queueinformer.WithLogger(config.Logger()),
98+
queueinformer.WithQueue(csvNamespaceLabelerPluginQueue),
99+
queueinformer.WithIndexer(csvNamespaceLabelerInformer.GetIndexer()),
100+
queueinformer.WithSyncer(plugin),
101+
)
102+
if err != nil {
103+
return nil, err
104+
}
105+
if err := hostOperator.RegisterQueueInformer(csvNamespaceLabelerPluginQueueInformer); err != nil {
106+
return nil, err
107+
}
108+
}
109+
110+
return plugin, nil
111+
}
112+
113+
func (p *csvNamespaceLabelerPlugin) Shutdown() error {
114+
return nil
115+
}
116+
117+
func (p *csvNamespaceLabelerPlugin) Sync(ctx context.Context, event kubestate.ResourceEvent) error {
118+
// only act on csv added and updated events
119+
if event.Type() != kubestate.ResourceAdded && event.Type() != kubestate.ResourceUpdated {
120+
return nil
121+
}
122+
123+
csv, ok := event.Resource().(*v1alpha1.ClusterServiceVersion)
124+
if !ok {
125+
return fmt.Errorf("event resource is not a ClusterServiceVersion")
126+
}
127+
128+
// ignore copied csvs
129+
// informer should already be filtering these out - but just in case
130+
if csv.IsCopied() {
131+
return nil
132+
}
133+
134+
// ignore non-openshift-* and payload openshift-* namespaces
135+
if !strings.HasPrefix(csv.GetNamespace(), "openshift-") || nsexemptions.IsNamespacePSALabelSyncExemptedInVendoredOCPVersion(csv.GetNamespace()) {
136+
return nil
137+
}
138+
139+
namespace, err := p.getNamespace(csv.GetNamespace())
140+
if err != nil {
141+
return fmt.Errorf("error getting csv namespace (%s) for label sync'er labeling", csv.GetNamespace())
142+
}
143+
144+
// add label sync'er label if it does not exist
145+
if _, ok := namespace.GetLabels()[NamespaceLabelSyncerLabelKey]; !ok {
146+
nsCopy := namespace.DeepCopy()
147+
if nsCopy.GetLabels() == nil {
148+
nsCopy.SetLabels(map[string]string{})
149+
}
150+
nsCopy.GetLabels()[NamespaceLabelSyncerLabelKey] = "true"
151+
if _, err := p.kubeClient.KubernetesInterface().CoreV1().Namespaces().Update(ctx, nsCopy, metav1.UpdateOptions{}); err != nil {
152+
return fmt.Errorf("error updating csv namespace (%s) with label sync'er label", nsCopy.GetNamespace())
153+
}
154+
155+
if p.logger != nil {
156+
p.logger.Infof("applied %s=true label to namespace %s", NamespaceLabelSyncerLabelKey, nsCopy.GetNamespace())
157+
}
158+
}
159+
160+
return nil
161+
}
162+
163+
func (p *csvNamespaceLabelerPlugin) getNamespace(namespace string) (*v1.Namespace, error) {
164+
lister, ok := p.namespaceListerMap[namespace]
165+
if !ok {
166+
lister, ok = p.namespaceListerMap[metav1.NamespaceAll]
167+
if !ok {
168+
return nil, fmt.Errorf("no namespace lister found for namespace: %s", namespace)
169+
}
170+
}
171+
return lister.Get(namespace)
172+
}

0 commit comments

Comments
 (0)