Skip to content

Commit 97b7042

Browse files
Merge pull request #861 from stlaz/further_split_oauth
OCPBUGS-29532: ouathclients: further split oidc and integrated oauth handling
2 parents c29bbd5 + 68e37a8 commit 97b7042

File tree

6 files changed

+548
-215
lines changed

6 files changed

+548
-215
lines changed

pkg/console/controllers/oauthclients/oauthclients.go

Lines changed: 30 additions & 207 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,15 @@ import (
66
"time"
77

88
corev1 "k8s.io/api/core/v1"
9-
apiexensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
10-
apiexensionsv1informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
11-
apiexensionsv1listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
12-
apierrors "k8s.io/apimachinery/pkg/api/errors"
139
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1410
"k8s.io/apimachinery/pkg/util/wait"
1511
corev1informers "k8s.io/client-go/informers/core/v1"
16-
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
1712
corev1listers "k8s.io/client-go/listers/core/v1"
1813
"k8s.io/client-go/tools/cache"
1914
"k8s.io/klog/v2"
2015

2116
configv1 "github.com/openshift/api/config/v1"
2217
operatorv1 "github.com/openshift/api/operator/v1"
23-
configv1client "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
2418
configv1informers "github.com/openshift/client-go/config/informers/externalversions/config/v1"
2519
configv1lister "github.com/openshift/client-go/config/listers/config/v1"
2620
oauthclient "github.com/openshift/client-go/oauth/clientset/versioned"
@@ -32,80 +26,59 @@ import (
3226
routev1listers "github.com/openshift/client-go/route/listers/route/v1"
3327
"github.com/openshift/library-go/pkg/controller/factory"
3428
"github.com/openshift/library-go/pkg/operator/events"
35-
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
3629
"github.com/openshift/library-go/pkg/operator/v1helpers"
37-
appsv1informers "k8s.io/client-go/informers/apps/v1"
38-
appsv1listers "k8s.io/client-go/listers/apps/v1"
3930

4031
"github.com/openshift/console-operator/pkg/api"
4132
"github.com/openshift/console-operator/pkg/console/controllers/util"
4233
"github.com/openshift/console-operator/pkg/console/status"
43-
deploymentsub "github.com/openshift/console-operator/pkg/console/subresource/deployment"
4434
oauthsub "github.com/openshift/console-operator/pkg/console/subresource/oauthclient"
4535
routesub "github.com/openshift/console-operator/pkg/console/subresource/route"
4636
secretsub "github.com/openshift/console-operator/pkg/console/subresource/secret"
47-
utilsub "github.com/openshift/console-operator/pkg/console/subresource/util"
48-
"github.com/openshift/console-operator/pkg/crypto"
4937
)
5038

39+
// oauthClientsController:
40+
//
41+
// updates:
42+
// - oauthclient.oauth.openshift.io/console (created by CVO)
43+
// writes:
44+
// - consoles.operator.openshift.io/cluster .status.conditions:
45+
// - type=OAuthClientSyncProgressing
46+
// - type=OAuthClientSyncDegraded
5147
type oauthClientsController struct {
5248
oauthClient oauthv1client.OAuthClientsGetter
5349
operatorClient v1helpers.OperatorClient
54-
secretsClient corev1client.SecretsGetter
5550

5651
oauthClientLister oauthv1lister.OAuthClientLister
5752
oauthClientSwitchedInformer *util.InformerWithSwitch
58-
authentication configv1client.AuthenticationInterface
5953
authnLister configv1lister.AuthenticationLister
6054
consoleOperatorLister operatorv1listers.ConsoleLister
61-
crdLister apiexensionsv1listers.CustomResourceDefinitionLister
6255
routesLister routev1listers.RouteLister
6356
ingressConfigLister configv1lister.IngressLister
6457
targetNSSecretsLister corev1listers.SecretLister
65-
configNSSecretsLister corev1listers.SecretLister
66-
targetNSDeploymentsLister appsv1listers.DeploymentLister
67-
targetNSConfigLister corev1listers.ConfigMapLister
68-
69-
authStatusHandler status.AuthStatusHandler
7058
}
7159

7260
func NewOAuthClientsController(
73-
ctx context.Context,
7461
operatorClient v1helpers.OperatorClient,
7562
oauthClient oauthclient.Interface,
76-
secretsClient corev1client.SecretsGetter,
77-
crdInformer apiexensionsv1informers.CustomResourceDefinitionInformer,
78-
authentication configv1client.AuthenticationInterface,
7963
authnInformer configv1informers.AuthenticationInformer,
8064
consoleOperatorInformer operatorv1informers.ConsoleInformer,
8165
routeInformer routev1informers.RouteInformer,
8266
ingressConfigInformer configv1informers.IngressInformer,
8367
targetNSsecretsInformer corev1informers.SecretInformer,
84-
configNSSecretsInformer corev1informers.SecretInformer,
85-
targetNSConfigInformer corev1informers.ConfigMapInformer,
86-
targetNSDeploymentsInformer appsv1informers.DeploymentInformer,
8768
oauthClientSwitchedInformer *util.InformerWithSwitch,
8869
recorder events.Recorder,
8970
) factory.Controller {
9071
c := oauthClientsController{
9172
oauthClient: oauthClient.OauthV1(),
9273
operatorClient: operatorClient,
93-
secretsClient: secretsClient,
9474

9575
oauthClientLister: oauthClientSwitchedInformer.Lister(),
9676
oauthClientSwitchedInformer: oauthClientSwitchedInformer,
97-
authentication: authentication,
9877
authnLister: authnInformer.Lister(),
9978
consoleOperatorLister: consoleOperatorInformer.Lister(),
10079
routesLister: routeInformer.Lister(),
10180
ingressConfigLister: ingressConfigInformer.Lister(),
10281
targetNSSecretsLister: targetNSsecretsInformer.Lister(),
103-
configNSSecretsLister: configNSSecretsInformer.Lister(),
104-
targetNSConfigLister: targetNSConfigInformer.Lister(),
105-
targetNSDeploymentsLister: targetNSDeploymentsInformer.Lister(),
106-
crdLister: crdInformer.Lister(),
107-
108-
authStatusHandler: status.NewAuthStatusHandler(authentication, api.OpenShiftConsoleName, api.TargetNamespace, api.OpenShiftConsoleOperator),
10982
}
11083

11184
return factory.New().
@@ -116,42 +89,44 @@ func NewOAuthClientsController(
11689
routeInformer.Informer(),
11790
ingressConfigInformer.Informer(),
11891
targetNSsecretsInformer.Informer(),
119-
configNSSecretsInformer.Informer(),
120-
targetNSDeploymentsInformer.Informer(),
12192
).
12293
WithFilteredEventsInformers(
12394
factory.NamesFilter(api.OAuthClientName),
12495
oauthClientSwitchedInformer.Informer(),
12596
).
126-
WithFilteredEventsInformers(
127-
factory.NamesFilter("authentications.config.openshift.io"),
128-
crdInformer.Informer(),
129-
).
13097
WithSyncDegradedOnError(operatorClient).
13198
ResyncEvery(wait.Jitter(time.Minute, 1.0)).
13299
ToController("OAuthClientsController", recorder.WithComponentSuffix("oauth-clients-controller"))
133100
}
134101

135102
func (c *oauthClientsController) sync(ctx context.Context, controllerContext factory.SyncContext) error {
136-
statusHandler := status.NewStatusHandler(c.operatorClient)
137-
138103
if shouldSync, err := c.handleManaged(ctx); err != nil {
139104
return err
140105
} else if !shouldSync {
141106
return nil
142107
}
143108

144-
operatorConfig, err := c.consoleOperatorLister.Get(api.ConfigResourceName)
109+
statusHandler := status.NewStatusHandler(c.operatorClient)
110+
111+
authnConfig, err := c.authnLister.Get(api.ConfigResourceName)
145112
if err != nil {
146113
return err
147114
}
148115

149-
ingressConfig, err := c.ingressConfigLister.Get(api.ConfigResourceName)
116+
switch authnConfig.Spec.Type {
117+
case "", configv1.AuthenticationTypeIntegratedOAuth:
118+
default:
119+
// if we're not using integrated oauth, reset all degraded conditions
120+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OAuthClientSync", "", nil))
121+
return statusHandler.FlushAndReturn(nil)
122+
}
123+
124+
operatorConfig, err := c.consoleOperatorLister.Get(api.ConfigResourceName)
150125
if err != nil {
151126
return err
152127
}
153128

154-
authnConfig, err := c.authnLister.Get(api.ConfigResourceName)
129+
ingressConfig, err := c.ingressConfigLister.Get(api.ConfigResourceName)
155130
if err != nil {
156131
return err
157132
}
@@ -167,142 +142,24 @@ func (c *oauthClientsController) sync(ctx context.Context, controllerContext fac
167142
return routeErr
168143
}
169144

170-
var syncErr error
171-
switch authnConfig.Spec.Type {
172-
case "", configv1.AuthenticationTypeIntegratedOAuth:
173-
waitCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
174-
defer cancel()
175-
if !cache.WaitForCacheSync(waitCtx.Done(), c.oauthClientSwitchedInformer.Informer().HasSynced) {
176-
return statusHandler.FlushAndReturn(fmt.Errorf("timed out waiting for OAuthClients cache sync"))
177-
}
178-
179-
clientSecret, secErr := c.syncSecret(ctx, operatorConfig, controllerContext.Recorder())
180-
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OAuthClientSecretSync", "FailedApply", secErr))
181-
if secErr != nil {
182-
return statusHandler.FlushAndReturn(secErr)
183-
}
184-
185-
oauthErrReason, oauthErr := c.syncOAuthClient(ctx, clientSecret, consoleURL.String())
186-
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OAuthClientSync", oauthErrReason, oauthErr))
187-
if oauthErr != nil {
188-
return statusHandler.FlushAndReturn(oauthErr)
189-
}
190-
191-
case configv1.AuthenticationTypeOIDC:
192-
syncErr = c.syncAuthTypeOIDC(ctx, controllerContext, statusHandler, operatorConfig, authnConfig)
193-
if syncErr != nil {
194-
return statusHandler.FlushAndReturn(syncErr)
195-
}
196-
}
197-
198-
oidcClientsSchema, err := authnConfigHasOIDCFields(c.crdLister)
199-
if err != nil {
200-
return statusHandler.FlushAndReturn(err)
201-
}
202-
203-
if oidcClientsSchema {
204-
applyErr := c.authStatusHandler.Apply(ctx, authnConfig)
205-
statusHandler.AddConditions(status.HandleProgressingOrDegraded("AuthStatusHandler", "FailedApply", applyErr))
206-
if applyErr != nil {
207-
return statusHandler.FlushAndReturn(applyErr)
208-
}
209-
}
210-
211-
return statusHandler.FlushAndReturn(nil)
212-
}
213-
214-
func (c *oauthClientsController) syncAuthTypeOIDC(
215-
ctx context.Context,
216-
controllerContext factory.SyncContext,
217-
statusHandler status.StatusHandler,
218-
operatorConfig *operatorv1.Console,
219-
authnConfig *configv1.Authentication,
220-
) error {
221-
222-
clientConfig := utilsub.GetOIDCClientConfig(authnConfig)
223-
if clientConfig == nil {
224-
c.authStatusHandler.WithCurrentOIDCClient("")
225-
c.authStatusHandler.Unavailable("OIDCClientConfig", "no OIDC client found")
226-
return nil
227-
}
228-
229-
if len(clientConfig.ClientID) == 0 {
230-
err := fmt.Errorf("no ID set on OIDC client")
231-
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OIDCClientConfig", "MissingID", err))
232-
return statusHandler.FlushAndReturn(err)
233-
}
234-
c.authStatusHandler.WithCurrentOIDCClient(clientConfig.ClientID)
235-
236-
if len(clientConfig.ClientSecret.Name) == 0 {
237-
c.authStatusHandler.Degraded("OIDCClientMissingSecret", "no client secret in the OIDC client config")
238-
return nil
145+
waitCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
146+
defer cancel()
147+
if !cache.WaitForCacheSync(waitCtx.Done(), c.oauthClientSwitchedInformer.Informer().HasSynced) {
148+
return statusHandler.FlushAndReturn(fmt.Errorf("timed out waiting for OAuthClients cache sync"))
239149
}
240150

241-
clientSecret, err := c.configNSSecretsLister.Secrets(api.OpenShiftConfigNamespace).Get(clientConfig.ClientSecret.Name)
151+
clientSecret, err := c.targetNSSecretsLister.Secrets(api.TargetNamespace).Get("console-oauth-config")
242152
if err != nil {
243-
c.authStatusHandler.Degraded("OIDCClientSecretGet", err.Error())
244-
return err
245-
}
246-
247-
secret, err := c.targetNSSecretsLister.Secrets(api.TargetNamespace).Get(secretsub.Stub().Name)
248-
expectedClientSecret := secretsub.GetSecretString(clientSecret)
249-
if apierrors.IsNotFound(err) || secretsub.GetSecretString(secret) != expectedClientSecret {
250-
secret, _, err = resourceapply.ApplySecret(ctx, c.secretsClient, controllerContext.Recorder(), secretsub.DefaultSecret(operatorConfig, expectedClientSecret))
251-
if err != nil {
252-
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OIDCClientSecretSync", "FailedApply", err))
253-
return err
254-
}
255-
}
256-
257-
if valid, msg, err := c.checkClientConfigStatus(authnConfig, secret); err != nil {
258-
c.authStatusHandler.Degraded("DeploymentOIDCConfig", err.Error())
259153
return err
260-
261-
} else if !valid {
262-
c.authStatusHandler.Progressing("DeploymentOIDCConfig", msg)
263-
return nil
264154
}
265155

266-
c.authStatusHandler.Available("OIDCConfigAvailable", "")
267-
return nil
268-
}
269-
270-
// checkClientConfigStatus checks whether the current client configuration is being currently in use,
271-
// by looking at the deployment status. It checks whether the deployment is available and updated,
272-
// and also whether the resource versions for the oauth secret and server CA trust configmap match
273-
// the deployment.
274-
func (c *oauthClientsController) checkClientConfigStatus(authnConfig *configv1.Authentication, clientSecret *corev1.Secret) (bool, string, error) {
275-
depl, err := c.targetNSDeploymentsLister.Deployments(api.OpenShiftConsoleNamespace).Get(api.OpenShiftConsoleDeploymentName)
156+
oauthErrReason, err := c.syncOAuthClient(ctx, clientSecret, consoleURL.String())
157+
statusHandler.AddConditions(status.HandleProgressingOrDegraded("OAuthClientSync", oauthErrReason, err))
276158
if err != nil {
277-
return false, "", err
278-
}
279-
280-
deplAvailableUpdated := deploymentsub.IsAvailableAndUpdated(depl)
281-
if !deplAvailableUpdated {
282-
return false, "deployment unavailable or outdated", nil
283-
}
284-
285-
if clientSecret.GetResourceVersion() != depl.ObjectMeta.Annotations["console.openshift.io/oauth-secret-version"] {
286-
return false, "client secret version not up to date in current deployment", nil
287-
}
288-
289-
if len(authnConfig.Spec.OIDCProviders) > 0 {
290-
serverCAConfigName := authnConfig.Spec.OIDCProviders[0].Issuer.CertificateAuthority.Name
291-
if len(serverCAConfigName) == 0 {
292-
return deplAvailableUpdated, "", nil
293-
}
294-
295-
serverCAConfig, err := c.targetNSConfigLister.ConfigMaps(api.OpenShiftConsoleNamespace).Get(serverCAConfigName)
296-
if err != nil {
297-
return false, "", err
298-
}
299-
300-
if serverCAConfig.GetResourceVersion() != depl.ObjectMeta.Annotations["console.openshift.io/authn-ca-trust-config-version"] {
301-
return false, "OIDC provider CA version not up to date in current deployment", nil
302-
}
159+
return statusHandler.FlushAndReturn(err)
303160
}
304161

305-
return deplAvailableUpdated, "", nil
162+
return statusHandler.FlushAndReturn(nil)
306163
}
307164

308165
// handleStatus returns whether sync should happen and any error encountering
@@ -329,15 +186,6 @@ func (c *oauthClientsController) handleManaged(ctx context.Context) (bool, error
329186
}
330187
}
331188

332-
func (c *oauthClientsController) syncSecret(ctx context.Context, operatorConfig *operatorv1.Console, recorder events.Recorder) (*corev1.Secret, error) {
333-
secret, err := c.targetNSSecretsLister.Secrets(api.TargetNamespace).Get(secretsub.Stub().Name)
334-
if apierrors.IsNotFound(err) || secretsub.GetSecretString(secret) == "" {
335-
secret, _, err = resourceapply.ApplySecret(ctx, c.secretsClient, recorder, secretsub.DefaultSecret(operatorConfig, crypto.Random256BitsString()))
336-
}
337-
// any error should be returned & kill the sync loop
338-
return secret, err
339-
}
340-
341189
// applies changes to the oauthclient
342190
// should not be called until route & secret dependencies are verified
343191
func (c *oauthClientsController) syncOAuthClient(
@@ -375,28 +223,3 @@ func (c *oauthClientsController) deregisterClient(ctx context.Context) error {
375223
return err
376224

377225
}
378-
379-
func authnConfigHasOIDCFields(crdLister apiexensionsv1listers.CustomResourceDefinitionLister) (bool, error) {
380-
authnCRD, err := crdLister.Get("authentications.config.openshift.io")
381-
if err != nil {
382-
return false, err
383-
}
384-
385-
var authnV1Config *apiexensionsv1.CustomResourceDefinitionVersion
386-
for _, version := range authnCRD.Spec.Versions {
387-
if version.Name == "v1" && version.Served && version.Storage {
388-
authnV1Config = &version
389-
break
390-
}
391-
}
392-
393-
if authnV1Config == nil {
394-
return false, fmt.Errorf("authentications.config.openshift.io is not served or stored as v1")
395-
}
396-
397-
schema := authnV1Config.Schema.OpenAPIV3Schema
398-
_, clientsExist := schema.Properties["status"].Properties["oidcClients"]
399-
400-
return clientsExist, nil
401-
402-
}

0 commit comments

Comments
 (0)