Skip to content

Commit 26246b6

Browse files
committed
Support serviceaccount pull secrets
Serviceaccounts reference pull secrets! * Determine our serviceaccount (via the new internal/shared/util/sa package). * Use a common pull_secret_controller * Update the pull_secret_controller to know about the service account * Update the pull_secret_controller to watch the namespace-local secrets * Update caching to include sa, and use filters for additional secrets * Add RBAC to access these secrets and sa * Update writing the auth.json file to handle dockercfg and dockerconfigjson * Update writing the auth.json file to include multiple secrets Signed-off-by: Todd Short <[email protected]>
1 parent 8f81c23 commit 26246b6

File tree

16 files changed

+491
-369
lines changed

16 files changed

+491
-369
lines changed

cmd/catalogd/main.go

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ import (
6161
"github.com/operator-framework/operator-controller/internal/catalogd/serverutil"
6262
"github.com/operator-framework/operator-controller/internal/catalogd/storage"
6363
"github.com/operator-framework/operator-controller/internal/catalogd/webhook"
64+
sharedcontrollers "github.com/operator-framework/operator-controller/internal/shared/controllers"
6465
fsutil "github.com/operator-framework/operator-controller/internal/shared/util/fs"
6566
imageutil "github.com/operator-framework/operator-controller/internal/shared/util/image"
67+
sautil "github.com/operator-framework/operator-controller/internal/shared/util/sa"
6668
"github.com/operator-framework/operator-controller/internal/shared/version"
6769
)
6870

@@ -246,18 +248,40 @@ func run(ctx context.Context) error {
246248
cacheOptions := crcache.Options{
247249
ByObject: map[client.Object]crcache.ByObject{},
248250
}
249-
if cfg.globalPullSecretKey != nil {
250-
cacheOptions.ByObject[&corev1.Secret{}] = crcache.ByObject{
251-
Namespaces: map[string]crcache.Config{
252-
cfg.globalPullSecretKey.Namespace: {
253-
LabelSelector: k8slabels.Everything(),
254-
FieldSelector: fields.SelectorFromSet(map[string]string{
255-
"metadata.name": cfg.globalPullSecretKey.Name,
256-
}),
257-
},
251+
252+
saKey, err := sautil.GetServiceAccount()
253+
if err != nil {
254+
setupLog.Error(err, "Unable to get pod namesapce and serviceaccount")
255+
return err
256+
}
257+
258+
setupLog.Info("Read token", "serviceaccount", saKey)
259+
cacheOptions.ByObject[&corev1.ServiceAccount{}] = crcache.ByObject{
260+
Namespaces: map[string]crcache.Config{
261+
saKey.Namespace: {
262+
LabelSelector: k8slabels.Everything(),
263+
FieldSelector: fields.SelectorFromSet(map[string]string{
264+
"metadata.name": saKey.Name,
265+
}),
258266
},
267+
},
268+
}
269+
270+
secretCache := crcache.ByObject{}
271+
secretCache.Namespaces = make(map[string]crcache.Config, 2)
272+
secretCache.Namespaces[saKey.Namespace] = crcache.Config{
273+
LabelSelector: k8slabels.Everything(),
274+
FieldSelector: fields.Everything(),
275+
}
276+
if cfg.globalPullSecretKey != nil {
277+
secretCache.Namespaces[cfg.globalPullSecretKey.Namespace] = crcache.Config{
278+
LabelSelector: k8slabels.Everything(),
279+
FieldSelector: fields.SelectorFromSet(map[string]string{
280+
"metadata.name": cfg.globalPullSecretKey.Name,
281+
}),
259282
}
260283
}
284+
cacheOptions.ByObject[&corev1.Secret{}] = secretCache
261285

262286
// Create manager
263287
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
@@ -312,7 +336,7 @@ func run(ctx context.Context) error {
312336
DockerCertPath: cfg.pullCasDir,
313337
OCICertPath: cfg.pullCasDir,
314338
}
315-
if _, err := os.Stat(authFilePath); err == nil && cfg.globalPullSecretKey != nil {
339+
if _, err := os.Stat(authFilePath); err == nil {
316340
logger.Info("using available authentication information for pulling image")
317341
srcContext.AuthFilePath = authFilePath
318342
} else if os.IsNotExist(err) {
@@ -370,17 +394,16 @@ func run(ctx context.Context) error {
370394
return err
371395
}
372396

373-
if cfg.globalPullSecretKey != nil {
374-
setupLog.Info("creating SecretSyncer controller for watching secret", "Secret", cfg.globalPullSecret)
375-
err := (&corecontrollers.PullSecretReconciler{
376-
Client: mgr.GetClient(),
377-
AuthFilePath: authFilePath,
378-
SecretKey: *cfg.globalPullSecretKey,
379-
}).SetupWithManager(mgr)
380-
if err != nil {
381-
setupLog.Error(err, "unable to create controller", "controller", "SecretSyncer")
382-
return err
383-
}
397+
setupLog.Info("creating SecretSyncer controller for watching secret", "Secret", cfg.globalPullSecret)
398+
err = (&sharedcontrollers.PullSecretReconciler{
399+
Client: mgr.GetClient(),
400+
AuthFilePath: authFilePath,
401+
SecretKey: cfg.globalPullSecretKey,
402+
ServiceAccountKey: saKey,
403+
}).SetupWithManager(mgr)
404+
if err != nil {
405+
setupLog.Error(err, "unable to create controller", "controller", "SecretSyncer")
406+
return err
384407
}
385408
//+kubebuilder:scaffold:builder
386409

cmd/operator-controller/main.go

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ import (
7171
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render/certproviders"
7272
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render/registryv1"
7373
"github.com/operator-framework/operator-controller/internal/operator-controller/scheme"
74+
sharedcontrollers "github.com/operator-framework/operator-controller/internal/shared/controllers"
7475
fsutil "github.com/operator-framework/operator-controller/internal/shared/util/fs"
7576
httputil "github.com/operator-framework/operator-controller/internal/shared/util/http"
7677
imageutil "github.com/operator-framework/operator-controller/internal/shared/util/image"
78+
sautil "github.com/operator-framework/operator-controller/internal/shared/util/sa"
7779
"github.com/operator-framework/operator-controller/internal/shared/version"
7880
)
7981

@@ -217,18 +219,40 @@ func run() error {
217219
},
218220
DefaultLabelSelector: k8slabels.Nothing(),
219221
}
220-
if globalPullSecretKey != nil {
221-
cacheOptions.ByObject[&corev1.Secret{}] = crcache.ByObject{
222-
Namespaces: map[string]crcache.Config{
223-
globalPullSecretKey.Namespace: {
224-
LabelSelector: k8slabels.Everything(),
225-
FieldSelector: fields.SelectorFromSet(map[string]string{
226-
"metadata.name": globalPullSecretKey.Name,
227-
}),
228-
},
222+
223+
saKey, err := sautil.GetServiceAccount()
224+
if err != nil {
225+
setupLog.Error(err, "Unable to get pod namesapce and serviceaccount")
226+
return err
227+
}
228+
229+
setupLog.Info("Read token", "serviceaccount", saKey)
230+
cacheOptions.ByObject[&corev1.ServiceAccount{}] = crcache.ByObject{
231+
Namespaces: map[string]crcache.Config{
232+
saKey.Namespace: {
233+
LabelSelector: k8slabels.Everything(),
234+
FieldSelector: fields.SelectorFromSet(map[string]string{
235+
"metadata.name": saKey.Name,
236+
}),
229237
},
238+
},
239+
}
240+
241+
secretCache := crcache.ByObject{}
242+
secretCache.Namespaces = make(map[string]crcache.Config, 2)
243+
secretCache.Namespaces[saKey.Namespace] = crcache.Config{
244+
LabelSelector: k8slabels.Everything(),
245+
FieldSelector: fields.Everything(),
246+
}
247+
if globalPullSecretKey != nil {
248+
secretCache.Namespaces[globalPullSecretKey.Namespace] = crcache.Config{
249+
LabelSelector: k8slabels.Everything(),
250+
FieldSelector: fields.SelectorFromSet(map[string]string{
251+
"metadata.name": globalPullSecretKey.Name,
252+
}),
230253
}
231254
}
255+
cacheOptions.ByObject[&corev1.Secret{}] = secretCache
232256

233257
metricsServerOptions := server.Options{}
234258
if len(cfg.certFile) > 0 && len(cfg.keyFile) > 0 {
@@ -360,7 +384,7 @@ func run() error {
360384
OCICertPath: cfg.pullCasDir,
361385
}
362386
logger := log.FromContext(ctx)
363-
if _, err := os.Stat(authFilePath); err == nil && globalPullSecretKey != nil {
387+
if _, err := os.Stat(authFilePath); err == nil {
364388
logger.Info("using available authentication information for pulling image")
365389
srcContext.AuthFilePath = authFilePath
366390
} else if os.IsNotExist(err) {
@@ -482,17 +506,16 @@ func run() error {
482506
return err
483507
}
484508

485-
if globalPullSecretKey != nil {
486-
setupLog.Info("creating SecretSyncer controller for watching secret", "Secret", cfg.globalPullSecret)
487-
err := (&controllers.PullSecretReconciler{
488-
Client: mgr.GetClient(),
489-
AuthFilePath: authFilePath,
490-
SecretKey: *globalPullSecretKey,
491-
}).SetupWithManager(mgr)
492-
if err != nil {
493-
setupLog.Error(err, "unable to create controller", "controller", "SecretSyncer")
494-
return err
495-
}
509+
setupLog.Info("creating SecretSyncer controller for watching secret", "Secret", cfg.globalPullSecret)
510+
err = (&sharedcontrollers.PullSecretReconciler{
511+
Client: mgr.GetClient(),
512+
AuthFilePath: authFilePath,
513+
SecretKey: globalPullSecretKey,
514+
ServiceAccountKey: saKey,
515+
}).SetupWithManager(mgr)
516+
if err != nil {
517+
setupLog.Error(err, "unable to create controller", "controller", "SecretSyncer")
518+
return err
496519
}
497520

498521
//+kubebuilder:scaffold:builder

config/base/catalogd/rbac/role.yaml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ kind: ClusterRole
44
metadata:
55
name: manager-role
66
rules:
7+
- apiGroups:
8+
- ""
9+
resources:
10+
- secrets
11+
verbs:
12+
- get
13+
- list
14+
- watch
715
- apiGroups:
816
- olm.operatorframework.io
917
resources:
@@ -30,3 +38,18 @@ rules:
3038
- get
3139
- patch
3240
- update
41+
---
42+
apiVersion: rbac.authorization.k8s.io/v1
43+
kind: Role
44+
metadata:
45+
name: manager-role
46+
namespace: system
47+
rules:
48+
- apiGroups:
49+
- ""
50+
resources:
51+
- serviceaccounts
52+
verbs:
53+
- get
54+
- list
55+
- watch

config/base/catalogd/rbac/role_binding.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,20 @@ subjects:
1313
- kind: ServiceAccount
1414
name: controller-manager
1515
namespace: system
16+
---
17+
apiVersion: rbac.authorization.k8s.io/v1
18+
kind: RoleBinding
19+
metadata:
20+
labels:
21+
app.kubernetes.io/part-of: olm
22+
app.kubernetes.io/name: catalogd
23+
name: manager-rolebinding
24+
namespace: system
25+
roleRef:
26+
apiGroup: rbac.authorization.k8s.io
27+
kind: Role
28+
name: manager-role
29+
subjects:
30+
- kind: ServiceAccount
31+
name: controller-manager
32+
namespace: system

config/base/operator-controller/rbac/role.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,11 @@ rules:
7777
- patch
7878
- update
7979
- watch
80+
- apiGroups:
81+
- ""
82+
resources:
83+
- serviceaccounts
84+
verbs:
85+
- get
86+
- list
87+
- watch

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/containers/image/v5 v5.35.0
1212
github.com/fsnotify/fsnotify v1.9.0
1313
github.com/go-logr/logr v1.4.3
14+
github.com/golang-jwt/jwt/v5 v5.2.2
1415
github.com/google/go-cmp v0.7.0
1516
github.com/google/go-containerregistry v0.20.3
1617
github.com/gorilla/handlers v1.5.2

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA
209209
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
210210
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
211211
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
212+
github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
213+
github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
212214
github.com/golang-migrate/migrate/v4 v4.18.3 h1:EYGkoOsvgHHfm5U/naS1RP/6PL/Xv3S4B/swMiAmDLs=
213215
github.com/golang-migrate/migrate/v4 v4.18.3/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY=
214216
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=

internal/catalogd/controllers/core/clustercatalog_controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ type storedCatalogData struct {
7979
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clustercatalogs,verbs=get;list;watch;create;update;patch;delete
8080
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clustercatalogs/status,verbs=get;update;patch
8181
//+kubebuilder:rbac:groups=olm.operatorframework.io,resources=clustercatalogs/finalizers,verbs=update
82+
//+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch
83+
//+kubebuilder:rbac:namespace=system,groups=core,resources=serviceaccounts,verbs=get;list;watch
8284

8385
// Reconcile is part of the main kubernetes reconciliation loop which aims to
8486
// move the current state of the cluster closer to the desired state.

0 commit comments

Comments
 (0)