|
| 1 | +package downloadsserviceaccount |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + "time" |
| 7 | + |
| 8 | + corev1 "k8s.io/api/core/v1" |
| 9 | + apierrors "k8s.io/apimachinery/pkg/api/errors" |
| 10 | + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| 11 | + coreinformersv1 "k8s.io/client-go/informers/core/v1" |
| 12 | + coreclientv1 "k8s.io/client-go/kubernetes/typed/core/v1" |
| 13 | + "k8s.io/klog/v2" |
| 14 | + |
| 15 | + operatorv1 "github.com/openshift/api/operator/v1" |
| 16 | + operatorinformerv1 "github.com/openshift/client-go/operator/informers/externalversions/operator/v1" |
| 17 | + operatorlistersv1 "github.com/openshift/client-go/operator/listers/operator/v1" |
| 18 | + "github.com/openshift/console-operator/pkg/api" |
| 19 | + "github.com/openshift/console-operator/pkg/console/controllers/util" |
| 20 | + "github.com/openshift/console-operator/pkg/console/status" |
| 21 | + serviceaccountsub "github.com/openshift/console-operator/pkg/console/subresource/serviceaccount" |
| 22 | + "github.com/openshift/library-go/pkg/controller/factory" |
| 23 | + "github.com/openshift/library-go/pkg/operator/events" |
| 24 | + "github.com/openshift/library-go/pkg/operator/resource/resourceapply" |
| 25 | + "github.com/openshift/library-go/pkg/operator/v1helpers" |
| 26 | +) |
| 27 | + |
| 28 | +type DownloadsServiceAccountSyncController struct { |
| 29 | + operatorClient v1helpers.OperatorClient |
| 30 | + // configs |
| 31 | + consoleOperatorLister operatorlistersv1.ConsoleLister |
| 32 | + // core kube |
| 33 | + serviceAccountClient coreclientv1.ServiceAccountsGetter |
| 34 | +} |
| 35 | + |
| 36 | +func NewDownloadsServiceAccountSyncController( |
| 37 | + // clients |
| 38 | + operatorClient v1helpers.OperatorClient, |
| 39 | + // informer |
| 40 | + operatorConfigInformer operatorinformerv1.ConsoleInformer, |
| 41 | + // core kube |
| 42 | + serviceAccountClient coreclientv1.ServiceAccountsGetter, |
| 43 | + serviceAccountInformer coreinformersv1.ServiceAccountInformer, |
| 44 | + // events |
| 45 | + recorder events.Recorder, |
| 46 | +) factory.Controller { |
| 47 | + ctrl := &DownloadsServiceAccountSyncController{ |
| 48 | + // configs |
| 49 | + operatorClient: operatorClient, |
| 50 | + consoleOperatorLister: operatorConfigInformer.Lister(), |
| 51 | + // client |
| 52 | + serviceAccountClient: serviceAccountClient, |
| 53 | + } |
| 54 | + |
| 55 | + configNameFilter := util.IncludeNamesFilter(api.ConfigResourceName) |
| 56 | + downloadsNameFilter := util.IncludeNamesFilter(api.DownloadsResourceName) |
| 57 | + |
| 58 | + return factory.New(). |
| 59 | + WithFilteredEventsInformers( // configs |
| 60 | + configNameFilter, |
| 61 | + operatorConfigInformer.Informer(), |
| 62 | + ).WithFilteredEventsInformers( // downloads service account |
| 63 | + downloadsNameFilter, |
| 64 | + serviceAccountInformer.Informer(), |
| 65 | + ).ResyncEvery(time.Minute).WithSync(ctrl.Sync). |
| 66 | + ToController("ConsoleDownloadsServiceAccountSyncController", recorder.WithComponentSuffix("console-downloads-service-account-controller")) |
| 67 | +} |
| 68 | + |
| 69 | +func (c *DownloadsServiceAccountSyncController) Sync(ctx context.Context, controllerContext factory.SyncContext) error { |
| 70 | + operatorConfig, err := c.consoleOperatorLister.Get(api.ConfigResourceName) |
| 71 | + if err != nil { |
| 72 | + return err |
| 73 | + } |
| 74 | + operatorConfigCopy := operatorConfig.DeepCopy() |
| 75 | + |
| 76 | + switch operatorConfigCopy.Spec.ManagementState { |
| 77 | + case operatorv1.Managed: |
| 78 | + klog.V(4).Infoln("console is in a managed state: syncing downloads service account") |
| 79 | + case operatorv1.Unmanaged: |
| 80 | + klog.V(4).Infoln("console is in an unmanaged state: skipping downloads service account sync") |
| 81 | + return nil |
| 82 | + case operatorv1.Removed: |
| 83 | + klog.V(4).Infoln("console is in a removed state: removing downloads service account") |
| 84 | + return c.removeDownloadsServiceAccount(ctx) |
| 85 | + default: |
| 86 | + return fmt.Errorf("unknown state: %v", operatorConfigCopy.Spec.ManagementState) |
| 87 | + } |
| 88 | + statusHandler := status.NewStatusHandler(c.operatorClient) |
| 89 | + |
| 90 | + _, _, serviceAccountErr := c.SyncDownloadsServiceAccount(ctx, operatorConfigCopy, controllerContext) |
| 91 | + statusHandler.AddConditions(status.HandleProgressingOrDegraded("DownloadsServiceAccountSync", "FailedApply", serviceAccountErr)) |
| 92 | + if serviceAccountErr != nil { |
| 93 | + return statusHandler.FlushAndReturn(serviceAccountErr) |
| 94 | + } |
| 95 | + |
| 96 | + return statusHandler.FlushAndReturn(nil) |
| 97 | +} |
| 98 | + |
| 99 | +func (c *DownloadsServiceAccountSyncController) SyncDownloadsServiceAccount(ctx context.Context, operatorConfigCopy *operatorv1.Console, controllerContext factory.SyncContext) (*corev1.ServiceAccount, bool, error) { |
| 100 | + requiredDownloadsServiceAccount := serviceaccountsub.DefaultDownloadsServiceAccount(operatorConfigCopy) |
| 101 | + |
| 102 | + return resourceapply.ApplyServiceAccount(ctx, |
| 103 | + c.serviceAccountClient, |
| 104 | + controllerContext.Recorder(), |
| 105 | + requiredDownloadsServiceAccount, |
| 106 | + ) |
| 107 | +} |
| 108 | + |
| 109 | +func (c *DownloadsServiceAccountSyncController) removeDownloadsServiceAccount(ctx context.Context) error { |
| 110 | + err := c.serviceAccountClient.ServiceAccounts(api.OpenShiftConsoleNamespace).Delete(ctx, api.DownloadsResourceName, metav1.DeleteOptions{}) |
| 111 | + if apierrors.IsNotFound(err) { |
| 112 | + return nil |
| 113 | + } |
| 114 | + return err |
| 115 | +} |
0 commit comments