-
Notifications
You must be signed in to change notification settings - Fork 108
WIP: CNTRLPLANE-84: auth-operator manages the RoleBindingRestrictions CRD based on auth type #796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ import ( | |
|
|
||
| configv1 "github.com/openshift/api/config/v1" | ||
| "github.com/openshift/api/features" | ||
| authzclient "github.com/openshift/client-go/authorization/clientset/versioned" | ||
| configinformers "github.com/openshift/client-go/config/informers/externalversions" | ||
| configv1listers "github.com/openshift/client-go/config/listers/config/v1" | ||
| "github.com/openshift/library-go/pkg/controller/factory" | ||
|
|
@@ -24,6 +25,7 @@ import ( | |
| "github.com/openshift/library-go/pkg/operator/v1helpers" | ||
| "golang.org/x/net/http/httpproxy" | ||
|
|
||
| apiextensionsv1lister "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1" | ||
| "k8s.io/apimachinery/pkg/api/equality" | ||
| apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
|
|
@@ -50,6 +52,8 @@ type externalOIDCController struct { | |
| eventName string | ||
| authLister configv1listers.AuthenticationLister | ||
| configMapLister corev1listers.ConfigMapLister | ||
| crdLister apiextensionsv1lister.CustomResourceDefinitionLister | ||
| authzClient authzclient.Interface | ||
| configMaps corev1client.ConfigMapsGetter | ||
| featureGates featuregates.FeatureGate | ||
| } | ||
|
|
@@ -59,6 +63,8 @@ func NewExternalOIDCController( | |
| configInformer configinformers.SharedInformerFactory, | ||
| operatorClient v1helpers.OperatorClient, | ||
| configMaps corev1client.ConfigMapsGetter, | ||
| crdLister apiextensionsv1lister.CustomResourceDefinitionLister, | ||
| rbrClient authzclient.Interface, | ||
| recorder events.Recorder, | ||
| featureGates featuregates.FeatureGate, | ||
| ) factory.Controller { | ||
|
|
@@ -69,6 +75,8 @@ func NewExternalOIDCController( | |
| authLister: configInformer.Config().V1().Authentications().Lister(), | ||
| configMapLister: kubeInformersForNamespaces.ConfigMapLister(), | ||
| configMaps: configMaps, | ||
| crdLister: crdLister, | ||
| authzClient: rbrClient, | ||
| featureGates: featureGates, | ||
| } | ||
|
|
||
|
|
@@ -97,6 +105,11 @@ func (c *externalOIDCController) sync(ctx context.Context, syncCtx factory.SyncC | |
| return c.deleteAuthConfig(ctx, syncCtx) | ||
| } | ||
|
|
||
| // check if we can proceed with the OIDC configuration based on current cluster state | ||
| if err := c.checkOIDCPreconditions(ctx); err != nil { | ||
| return fmt.Errorf("OIDC preconditions failed: %v", err) | ||
| } | ||
|
|
||
| authConfig, err := c.generateAuthConfig(*auth) | ||
| if err != nil { | ||
| return err | ||
|
|
@@ -129,6 +142,34 @@ func (c *externalOIDCController) sync(ctx context.Context, syncCtx factory.SyncC | |
| return nil | ||
| } | ||
|
|
||
| func (c *externalOIDCController) checkOIDCPreconditions(ctx context.Context) error { | ||
| if _, err := c.crdLister.Get("rolebindingrestrictions.authorization.openshift.io"); err != nil { | ||
| if !apierrors.IsNotFound(err) { | ||
| return fmt.Errorf("could not get RoleBindingRestrictions CRD: %v", err) | ||
| } | ||
| // CRD doesn't exist - continue with OIDC config | ||
| return nil | ||
| } | ||
|
|
||
| // CRD exists - check if any RoleBindingRestriction objects exist | ||
| rbrs, err := c.authzClient.AuthorizationV1().RoleBindingRestrictions("").List(ctx, metav1.ListOptions{}) | ||
| if err != nil { | ||
| return fmt.Errorf("could not list existing RoleBindingRestrictions: %v", err) | ||
| } | ||
|
|
||
| if len(rbrs.Items) > 0 { | ||
| // RoleBindingRestriction objects exist - precondition failed | ||
| var rbrNames []string | ||
| for _, rbr := range rbrs.Items { | ||
| rbrNames = append(rbrNames, fmt.Sprintf("%s/%s", rbr.Namespace, rbr.Name)) | ||
| } | ||
| return fmt.Errorf("no RoleBindingRestriction objects must exist; found: %s", strings.Join(rbrNames, " ")) | ||
| } | ||
|
|
||
| // no RoleBindingRestriction objects exist - continue with OIDC config | ||
| return nil | ||
| } | ||
|
Comment on lines
+145
to
+171
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard against unsynced CRD cache. Without waiting for the CRD informer's cache to sync, Get() may temporarily return NotFound and let OIDC proceed even if the CRD exists. The constructor change above addresses this by adding the CRD informer to WithInformers. |
||
|
|
||
| // deleteAuthConfig checks if the auth config ConfigMap exists in the managed namespace, and deletes it | ||
| // if it does; it returns an error if it encounters one. | ||
| func (c *externalOIDCController) deleteAuthConfig(ctx context.Context, syncCtx factory.SyncContext) error { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Constructor wiring LGTM, but add CRD informer to WithInformers to avoid cache-sync race.
Currently only configmaps/authentications informers are waited on. The CRD lister can return stale/empty before sync. Prefer passing a typed CRD informer into the constructor, use its Lister for c.crdLister, and add its Informer to WithInformers so factory waits for sync.
Apply this diff (constructor signature + body + WithInformers):
Add the needed import at top:
+ apiextensionsv1informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"And update the call sites (see starter files) to pass the typed informer.
Also applies to: 78-81
🤖 Prompt for AI Agents