Skip to content

Commit 1ee9a0a

Browse files
simplify controller logic + lock down cr
1 parent 2f12153 commit 1ee9a0a

5 files changed

Lines changed: 79 additions & 84 deletions

File tree

manifests/03-rbac-role-cluster.yaml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,20 @@ rules:
153153
resources:
154154
- serviceaccounts
155155
verbs:
156-
- get
157-
- list
158-
- delete
159156
- create
160-
- update
157+
- list
161158
- watch
159+
- get
160+
- apiGroups:
161+
- ""
162+
resources:
163+
- serviceaccounts
164+
verbs:
165+
- update
166+
- delete
167+
resourceNames:
168+
- console
169+
- downloads
162170
---
163171
kind: ClusterRole
164172
apiVersion: rbac.authorization.k8s.io/v1

pkg/api/api.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,16 @@ const (
5656
DefaultIngressController = "default"
5757
IngressControllerNamespace = "openshift-ingress-operator"
5858

59-
OAuthClientName = OpenShiftConsoleName
60-
OpenShiftConsoleDeploymentName = OpenShiftConsoleName
61-
OpenShiftConsoleDownloadsDeploymentName = DownloadsResourceName
62-
OpenShiftConsoleDownloadsPDBName = DownloadsResourceName
63-
OpenShiftConsoleDownloadsRouteName = DownloadsResourceName
64-
OpenShiftConsoleNamespace = TargetNamespace
65-
OpenShiftConsolePDBName = OpenShiftConsoleName
66-
OpenShiftConsoleRouteName = OpenShiftConsoleName
67-
OpenShiftConsoleServiceName = OpenShiftConsoleName
68-
OpenShiftConsoleDownloadsServiceAccountName = OpenShiftConsoleDownloadsDeploymentName
69-
OpenshiftConsoleServiceAccountName = OpenShiftConsoleDeploymentName
70-
RedirectContainerTargetPort = RedirectContainerPort
71-
OpenShiftConsoleSASyncControllerSuffix = "ConsoleServiceAccountSyncController"
72-
OpenshiftConsoleDownloadsSASyncControllerPrefix = "DownloadsServiceAccountSyncController"
59+
OAuthClientName = OpenShiftConsoleName
60+
OpenShiftConsoleDeploymentName = OpenShiftConsoleName
61+
OpenShiftConsoleDownloadsDeploymentName = DownloadsResourceName
62+
OpenShiftConsoleDownloadsPDBName = DownloadsResourceName
63+
OpenShiftConsoleDownloadsRouteName = DownloadsResourceName
64+
OpenShiftConsoleNamespace = TargetNamespace
65+
OpenShiftConsolePDBName = OpenShiftConsoleName
66+
OpenShiftConsoleRouteName = OpenShiftConsoleName
67+
OpenShiftConsoleServiceName = OpenShiftConsoleName
68+
OpenShiftConsoleDownloadsServiceAccountName = OpenShiftConsoleDownloadsDeploymentName
69+
OpenShiftConsoleServiceAccountName = OpenShiftConsoleDeploymentName
70+
RedirectContainerTargetPort = RedirectContainerPort
7371
)

pkg/console/controllers/serviceaccounts/controller.go

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package serviceaccounts
33
import (
44
"context"
55
"fmt"
6+
"reflect"
7+
"strings"
68
"time"
79

810
operatorv1 "github.com/openshift/api/operator/v1"
@@ -11,13 +13,15 @@ import (
1113
operatorinformerv1 "github.com/openshift/client-go/operator/informers/externalversions/operator/v1"
1214
operatorlistersv1 "github.com/openshift/client-go/operator/listers/operator/v1"
1315

16+
"github.com/openshift/console-operator/bindata"
1417
"github.com/openshift/console-operator/pkg/api"
1518
"github.com/openshift/console-operator/pkg/console/controllers/util"
1619
"github.com/openshift/console-operator/pkg/console/status"
17-
serviceaccountssub "github.com/openshift/console-operator/pkg/console/subresource/serviceaccount"
20+
subresourceutil "github.com/openshift/console-operator/pkg/console/subresource/util"
1821
"github.com/openshift/library-go/pkg/controller/factory"
1922
"github.com/openshift/library-go/pkg/operator/events"
2023
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
24+
"github.com/openshift/library-go/pkg/operator/resource/resourceread"
2125
"github.com/openshift/library-go/pkg/operator/v1helpers"
2226

2327
corev1 "k8s.io/api/core/v1"
@@ -31,6 +35,7 @@ import (
3135

3236
type ServiceAccountSyncController struct {
3337
serviceAccountName string
38+
conditionType string
3439
operatorClient v1helpers.OperatorClient
3540
// configs
3641
consoleOperatorLister operatorlistersv1.ConsoleLister
@@ -54,13 +59,12 @@ func NewServiceAccountSyncController(
5459
serviceAccountName string,
5560
// controllerName,
5661
controllerName string,
57-
// controllerSuffix
58-
controllerSuffix string,
5962
) factory.Controller {
6063
configV1Informers := configInformer.Config().V1()
6164

6265
ctrl := &ServiceAccountSyncController{
6366
serviceAccountName: serviceAccountName,
67+
conditionType: fmt.Sprintf("%sServiceAccountSync", controllerName),
6468
// configs
6569
operatorClient: operatorClient,
6670
consoleOperatorLister: operatorConfigInformer.Lister(),
@@ -81,32 +85,32 @@ func NewServiceAccountSyncController(
8185
serviceAccountNameFilter,
8286
serviceAccountInformer.Informer(),
8387
).ResyncEvery(time.Minute).WithSync(ctrl.Sync).
84-
ToController(controllerName, recorder.WithComponentSuffix(controllerSuffix))
88+
ToController(fmt.Sprintf("%sServiceAccountController", strings.Title(controllerName)), recorder.WithComponentSuffix(fmt.Sprintf("%s-service-account-controller", controllerName)))
8589
}
8690

8791
func (c *ServiceAccountSyncController) Sync(ctx context.Context, controllerContext factory.SyncContext) error {
8892
operatorConfig, err := c.consoleOperatorLister.Get(api.ConfigResourceName)
8993
if err != nil {
90-
return err
94+
return fmt.Errorf("failed to get console operator config %s: %w", api.ConfigResourceName, err)
9195
}
9296
operatorConfigCopy := operatorConfig.DeepCopy()
9397

9498
switch operatorConfigCopy.Spec.ManagementState {
9599
case operatorv1.Managed:
96-
klog.V(4).Infoln("console is in a managed state: syncing service account")
100+
klog.V(4).Infoln("console is in a managed state: syncing serviceaccount")
97101
case operatorv1.Unmanaged:
98-
klog.V(4).Infoln("console is in an unmanaged state: skipping service account sync")
102+
klog.V(4).Infoln("console is in an unmanaged state: skipping serviceaccount sync")
99103
return nil
100104
case operatorv1.Removed:
101-
klog.V(4).Infoln("console is in a removed state: removing synced service account")
105+
klog.V(4).Infoln("console is in a removed state: removing synced serviceaccount")
102106
return c.removeServiceAccount(ctx)
103107
default:
104108
return fmt.Errorf("unknown state: %v", operatorConfigCopy.Spec.ManagementState)
105109
}
106110
statusHandler := status.NewStatusHandler(c.operatorClient)
107111

108-
_, _, serviceAccountErr := c.SyncServiceAccount(ctx, operatorConfigCopy, controllerContext)
109-
statusHandler.AddConditions(status.HandleProgressingOrDegraded("ServiceAccountSync", "FailedApply", serviceAccountErr))
112+
serviceAccountErr := c.SyncServiceAccount(ctx, operatorConfigCopy, controllerContext)
113+
statusHandler.AddConditions(status.HandleProgressingOrDegraded(c.conditionType, "FailedApply", serviceAccountErr))
110114
if serviceAccountErr != nil {
111115
return statusHandler.FlushAndReturn(serviceAccountErr)
112116
}
@@ -122,25 +126,52 @@ func (c *ServiceAccountSyncController) removeServiceAccount(ctx context.Context)
122126
return err
123127
}
124128

125-
func (c *ServiceAccountSyncController) SyncServiceAccount(ctx context.Context, operatorConfigCopy *operatorv1.Console, controllerContext factory.SyncContext) (*corev1.ServiceAccount, bool, error) {
126-
requiredServiceAccount, err := serviceaccountssub.DefaultServiceAccountFactory(c.serviceAccountName, operatorConfigCopy)
129+
func (c *ServiceAccountSyncController) SyncServiceAccount(ctx context.Context, operatorConfigCopy *operatorv1.Console, controllerContext factory.SyncContext) error {
130+
serviceAccount, err := c.DefaultServiceAccount(operatorConfigCopy)
131+
127132
if err != nil {
128-
return nil, false, err
133+
return err
129134
}
130135

131-
// if the object has one or more ownerRef objects, then we must
132-
// ensure that their controller attribute is set to false.
133-
// Only one ownerRef.controller == true .
134-
// https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/#owner-references-in-object-specifications
135-
136-
for oR := range requiredServiceAccount.OwnerReferences {
137-
falseBool := false
138-
requiredServiceAccount.OwnerReferences[oR].Controller = &falseBool
136+
// check for service account existence
137+
138+
existingServiceAccount, err := c.serviceAccountClient.ServiceAccounts(serviceAccount.Namespace).Get(ctx, serviceAccount.Name, metav1.GetOptions{})
139+
140+
if err == nil {
141+
for _, oR := range existingServiceAccount.OwnerReferences {
142+
// mark ownerref for deletion. we cannot have multiple owner refs
143+
// https://github.com/openshift/library-go/blob/master/pkg/operator/resource/resourcemerge/object_merger.go#L214-L219
144+
if reflect.DeepEqual(oR, *subresourceutil.OwnerRefFrom(operatorConfigCopy)) {
145+
continue // we want to keep this controller=true
146+
}
147+
removalRef := oR.DeepCopy()
148+
removalRef.UID = removalRef.UID + "-"
149+
serviceAccount.OwnerReferences = append(serviceAccount.OwnerReferences, *removalRef)
150+
}
151+
} else if !apierrors.IsNotFound(err) {
152+
return fmt.Errorf("failed to get existing service account %s: %w", c.serviceAccountName, err)
139153
}
140154

141-
return resourceapply.ApplyServiceAccount(ctx,
155+
_, _, err = resourceapply.ApplyServiceAccount(ctx,
142156
c.serviceAccountClient,
143157
controllerContext.Recorder(),
144-
requiredServiceAccount,
158+
serviceAccount,
159+
)
160+
161+
if err != nil {
162+
return fmt.Errorf("failed to apply service account %s: %w", c.serviceAccountName, err)
163+
}
164+
165+
return nil
166+
}
167+
168+
func (c *ServiceAccountSyncController) DefaultServiceAccount(cr *operatorv1.Console) (*corev1.ServiceAccount, error) {
169+
serviceAccount := resourceread.ReadServiceAccountV1OrDie(
170+
bindata.MustAsset(fmt.Sprintf("assets/serviceaccounts/%s-sa.yaml", c.serviceAccountName)),
145171
)
172+
if serviceAccount.Name == "" {
173+
return nil, fmt.Errorf("No service account found for name %v .", c.serviceAccountName)
174+
}
175+
serviceAccount.SetOwnerReferences([]metav1.OwnerReference{*subresourceutil.OwnerRefFrom(cr)})
176+
return serviceAccount, nil
146177
}

pkg/console/starter/starter.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,9 +338,8 @@ func RunOperator(ctx context.Context, controllerContext *controllercmd.Controlle
338338
kubeInformersNamespaced.Core().V1().ServiceAccounts(), // ServiceAccount
339339

340340
recorder,
341-
api.OpenshiftConsoleServiceAccountName,
341+
api.OpenShiftConsoleServiceAccountName,
342342
api.OpenShiftConsoleName, // controller name
343-
api.OpenShiftConsoleSASyncControllerSuffix,
344343
)
345344

346345
downloadsServiceAccountController := serviceaccounts.NewServiceAccountSyncController(
@@ -357,7 +356,6 @@ func RunOperator(ctx context.Context, controllerContext *controllercmd.Controlle
357356

358357
api.OpenShiftConsoleDownloadsServiceAccountName,
359358
api.DownloadsResourceName,
360-
api.OpenshiftConsoleDownloadsSASyncControllerPrefix,
361359
)
362360

363361
downloadsDeploymentController := downloadsdeployment.NewDownloadsDeploymentSyncController(

pkg/console/subresource/serviceaccount/serviceaccount.go

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)