Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 4 additions & 19 deletions pkg/controllers/common/external_oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,6 @@ func AuthConfigCheckerInformers[T factory.Informer](c *AuthConfigChecker) []T {
// that includes the structured auth-config ConfigMap, and the KAS args include the respective
// arg that enables usage of the structured auth-config. It returns false otherwise.
func (c *AuthConfigChecker) OIDCAvailable() (bool, error) {
if !c.authenticationsInformer.HasSynced() {
return false, fmt.Errorf("AuthConfigChecker authentications informer has not synced yet")
}

if !c.kubeAPIServersInformer.HasSynced() {
return false, fmt.Errorf("AuthConfigChecker kubeapiservers informer has not synced yet")
}

if !c.kasNamespaceConfigMapsInformer.HasSynced() {
return false, fmt.Errorf("AuthConfigChecker configmaps informer has not synced yet")
}

if auth, err := c.authLister.Get("cluster"); err != nil {
return false, fmt.Errorf("getting authentications.config.openshift.io/cluster: %v", err)
} else if auth.Spec.Type != configv1.AuthenticationTypeOIDC {
Expand All @@ -79,18 +67,15 @@ func (c *AuthConfigChecker) OIDCAvailable() (bool, error) {
return false, fmt.Errorf("getting kubeapiservers.operator.openshift.io/cluster: %v", err)
}

if len(kas.Status.NodeStatuses) == 0 {
return false, fmt.Errorf("determining observed revisions in kubeapiservers.operator.openshift.io/cluster; no node statuses found")
}

observedRevisions := sets.New[int32]()
for _, nodeStatus := range kas.Status.NodeStatuses {
if nodeStatus.CurrentRevision <= 0 {
return false, fmt.Errorf("determining observed revisions in kubeapiservers.operator.openshift.io/cluster; some nodes do not have a valid CurrentRevision")
}
observedRevisions.Insert(nodeStatus.CurrentRevision)
}

if observedRevisions.Len() == 0 {
return false, nil
}

for _, revision := range observedRevisions.UnsortedList() {
// ensure every observed revision includes an auth-config revisioned configmap
_, err := c.kasConfigMapLister.ConfigMaps("openshift-kube-apiserver").Get(fmt.Sprintf("auth-config-%d", revision))
Expand Down
183 changes: 42 additions & 141 deletions pkg/controllers/common/external_oidc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
operatorv1 "github.com/openshift/api/operator/v1"
configv1listers "github.com/openshift/client-go/config/listers/config/v1"
operatorv1listers "github.com/openshift/client-go/operator/listers/operator/v1"
test "github.com/openshift/cluster-authentication-operator/test/library"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -22,60 +21,23 @@ const (

func TestExternalOIDCConfigAvailable(t *testing.T) {
for _, tt := range []struct {
name string
authInformerSynced bool
kasInformerSynced bool
cmInformerSynced bool
configMaps []*corev1.ConfigMap
authType configv1.AuthenticationType
nodeStatuses []operatorv1.NodeStatus
expectAvailable bool
expectError bool
name string
configMaps []*corev1.ConfigMap
authType configv1.AuthenticationType
nodeStatuses []operatorv1.NodeStatus
expectAvailable bool
expectError bool
}{
{
name: "no node statuses observed",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
authType: configv1.AuthenticationTypeOIDC,
expectAvailable: false,
expectError: true,
},
{
name: "some node revisions are zero",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
authType: configv1.AuthenticationTypeOIDC,
nodeStatuses: []operatorv1.NodeStatus{
{CurrentRevision: 10},
{CurrentRevision: 10},
{CurrentRevision: 0},
},
name: "no node statuses observed",
authType: configv1.AuthenticationTypeOIDC,
expectAvailable: false,
expectError: true,
},
{
name: "node revisions are zero",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
authType: configv1.AuthenticationTypeOIDC,
nodeStatuses: []operatorv1.NodeStatus{
{CurrentRevision: 0},
{CurrentRevision: 0},
{CurrentRevision: 0},
},
expectAvailable: false,
expectError: true,
expectError: false,
},
{
name: "oidc disabled, no rollout",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
configMaps: []*corev1.ConfigMap{cm("config-10", "config.yaml", kasConfigJSONWithoutOIDC)},
authType: configv1.AuthenticationTypeIntegratedOAuth,
name: "oidc disabled, no rollout",
configMaps: []*corev1.ConfigMap{cm("config-10", "config.yaml", kasConfigJSONWithoutOIDC)},
authType: configv1.AuthenticationTypeIntegratedOAuth,
nodeStatuses: []operatorv1.NodeStatus{
{CurrentRevision: 10},
{CurrentRevision: 10},
Expand All @@ -85,10 +47,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc getting enabled, rollout in progress",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc getting enabled, rollout in progress",
configMaps: []*corev1.ConfigMap{
cm("config-10", "config.yaml", kasConfigJSONWithoutOIDC),
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -104,10 +63,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc getting enabled, rollout in progress, one node ready",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc getting enabled, rollout in progress, one node ready",
configMaps: []*corev1.ConfigMap{
cm("config-10", "config.yaml", kasConfigJSONWithoutOIDC),
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -123,10 +79,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc getting enabled, rollout in progress, two nodes ready",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc getting enabled, rollout in progress, two nodes ready",
configMaps: []*corev1.ConfigMap{
cm("config-10", "config.yaml", kasConfigJSONWithoutOIDC),
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -142,10 +95,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc got enabled",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc got enabled",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("auth-config-11", "", ""),
Expand All @@ -160,10 +110,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc enabled, rollout in progress",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc enabled, rollout in progress",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-12", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -180,10 +127,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc enabled, rollout in progress, one node ready",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc enabled, rollout in progress, one node ready",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-12", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -200,10 +144,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc enabled, rollout in progress, two nodes ready",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc enabled, rollout in progress, two nodes ready",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-12", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -220,10 +161,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc still enabled",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc still enabled",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-12", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -240,10 +178,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc getting disabled, rollout in progress",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc getting disabled, rollout in progress",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-12", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -261,10 +196,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc getting disabled, rollout in progress, one node ready",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc getting disabled, rollout in progress, one node ready",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-12", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -282,11 +214,8 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc getting disabled, rollout in progress, two nodes ready",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
authType: configv1.AuthenticationTypeIntegratedOAuth,
name: "oidc getting disabled, rollout in progress, two nodes ready",
authType: configv1.AuthenticationTypeIntegratedOAuth,
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -303,10 +232,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectError: false,
},
{
name: "oidc got disabled",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: true,
name: "oidc got disabled",
configMaps: []*corev1.ConfigMap{
cm("config-11", "config.yaml", kasConfigJSONWithOIDC),
cm("config-12", "config.yaml", kasConfigJSONWithOIDC),
Expand All @@ -323,43 +249,6 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
expectAvailable: false,
expectError: false,
},
{
name: "auth informer not synced",
authInformerSynced: false,
kasInformerSynced: true,
cmInformerSynced: true,
authType: configv1.AuthenticationTypeOIDC,
expectAvailable: false,
expectError: true,
},
{
name: "kas informer not synced",
authInformerSynced: true,
kasInformerSynced: false,
cmInformerSynced: true,
authType: configv1.AuthenticationTypeOIDC,
nodeStatuses: []operatorv1.NodeStatus{
{CurrentRevision: 10},
{CurrentRevision: 10},
{CurrentRevision: 10},
},
expectAvailable: false,
expectError: true,
},
{
name: "configmap informer not synced",
authInformerSynced: true,
kasInformerSynced: true,
cmInformerSynced: false,
authType: configv1.AuthenticationTypeOIDC,
nodeStatuses: []operatorv1.NodeStatus{
{CurrentRevision: 10},
{CurrentRevision: 10},
{CurrentRevision: 10},
},
expectAvailable: false,
expectError: true,
},
} {
t.Run(tt.name, func(t *testing.T) {

Expand All @@ -368,7 +257,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
cmIndexer.Add(cm)
}

kasIndexer := cache.NewIndexer(func(obj any) (string, error) {
kasIndexer := cache.NewIndexer(func(obj interface{}) (string, error) {
return "cluster", nil
}, cache.Indexers{})

Expand All @@ -383,7 +272,7 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
},
})

authIndexer := cache.NewIndexer(func(obj any) (string, error) {
authIndexer := cache.NewIndexer(func(obj interface{}) (string, error) {
return "cluster", nil
}, cache.Indexers{})

Expand All @@ -394,9 +283,9 @@ func TestExternalOIDCConfigAvailable(t *testing.T) {
})

authConfigChecker := NewAuthConfigChecker(
test.NewFakeSharedIndexInformerWithSync(configv1listers.NewAuthenticationLister(authIndexer), tt.authInformerSynced),
test.NewFakeSharedIndexInformerWithSync(operatorv1listers.NewKubeAPIServerLister(kasIndexer), tt.kasInformerSynced),
test.NewFakeSharedIndexInformerWithSync(corelistersv1.NewConfigMapLister(cmIndexer), tt.cmInformerSynced),
&fakeInformer[configv1listers.AuthenticationLister]{configv1listers.NewAuthenticationLister(authIndexer)},
&fakeInformer[operatorv1listers.KubeAPIServerLister]{operatorv1listers.NewKubeAPIServerLister(kasIndexer)},
&fakeInformer[corelistersv1.ConfigMapLister]{corelistersv1.NewConfigMapLister(cmIndexer)},
)

available, err := authConfigChecker.OIDCAvailable()
Expand Down Expand Up @@ -428,3 +317,15 @@ func cm(name, dataKey, dataValue string) *corev1.ConfigMap {

return cm
}

type fakeInformer[T any] struct {
lister T
}

func (f *fakeInformer[T]) Informer() cache.SharedIndexInformer {
return nil
}

func (f *fakeInformer[T]) Lister() T {
return f.lister
}
13 changes: 5 additions & 8 deletions pkg/controllers/deployment/deployment_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,6 @@ func NewOAuthServerWorkloadController(
oauthDeploymentSyncer.bootstrapUserChangeRollOut = userExists
}

clusterScopedInformers := []factory.Informer{
configInformers.Config().V1().Ingresses().Informer(),
configInformers.Config().V1().Proxies().Informer(),
nodeInformer.Informer(),
}
clusterScopedInformers = append(clusterScopedInformers, common.AuthConfigCheckerInformers[factory.Informer](&authConfigChecker)...)

return workload.NewController(
"OAuthServer",
"cluster-authentication-operator",
Expand All @@ -130,7 +123,11 @@ func NewOAuthServerWorkloadController(
operatorClient,
kubeClient,
kubeInformersForTargetNamespace.Core().V1().Pods().Lister(),
clusterScopedInformers,
[]factory.Informer{
configInformers.Config().V1().Ingresses().Informer(),
configInformers.Config().V1().Proxies().Informer(),
nodeInformer.Informer(),
},
[]factory.Informer{
kubeInformersForTargetNamespace.Apps().V1().Deployments().Informer(),
kubeInformersForTargetNamespace.Core().V1().ConfigMaps().Informer(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ func NewIngressNodesAvailableController(
ingressControllerInformer.Informer(),
nodeInformer.Informer(),
).
WithInformers(common.AuthConfigCheckerInformers[factory.Informer](&authConfigChecker)...).
WithSync(controller.sync).
ResyncEvery(wait.Jitter(time.Minute, 1.0)).
ToController(controller.controllerInstanceName, eventRecorder)
Expand Down
Loading