diff --git a/pkg/operator2/auth.go b/pkg/operator2/auth.go index a358207fd7..9bb6f537cd 100644 --- a/pkg/operator2/auth.go +++ b/pkg/operator2/auth.go @@ -1,6 +1,7 @@ package operator2 import ( + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" configv1 "github.com/openshift/api/config/v1" @@ -18,8 +19,15 @@ import ( // used to fill the data in the /.well-known/oauth-authorization-server // endpoint, but since that endpoint belongs to the apiserver, its syncing is // handled in cluster-kube-apiserver-operator -func (c *authOperator) handleAuthConfig() (*configv1.Authentication, error) { - auth, err := c.authentication.Get(globalConfigName, metav1.GetOptions{}) +func (c *authOperator) handleAuthConfigInner() (*configv1.Authentication, error) { + // always make sure this function does not rely on defaulting from defaultAuthConfig + + authConfigNoDefaults, err := c.authentication.Get(globalConfigName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + authConfigNoDefaults, err = c.authentication.Create(&configv1.Authentication{ + ObjectMeta: defaultGlobalConfigMeta(), + }) + } if err != nil { return nil, err } @@ -28,10 +36,28 @@ func (c *authOperator) handleAuthConfig() (*configv1.Authentication, error) { Name: targetName, } - if auth.Status.IntegratedOAuthMetadata == expectedReference { - return auth, nil + if authConfigNoDefaults.Status.IntegratedOAuthMetadata == expectedReference { + return authConfigNoDefaults, nil + } + + authConfigNoDefaults.Status.IntegratedOAuthMetadata = expectedReference + return c.authentication.UpdateStatus(authConfigNoDefaults) +} + +func (c *authOperator) handleAuthConfig() (*configv1.Authentication, error) { + auth, err := c.handleAuthConfigInner() + if err != nil { + return nil, err + } + return defaultAuthConfig(auth), nil +} + +func defaultAuthConfig(authConfig *configv1.Authentication) *configv1.Authentication { + out := authConfig.DeepCopy() // do not mutate informer cache + + if len(out.Spec.Type) == 0 { + out.Spec.Type = configv1.AuthenticationTypeIntegratedOAuth } - auth.Status.IntegratedOAuthMetadata = expectedReference - return c.authentication.UpdateStatus(auth) + return out } diff --git a/pkg/operator2/oauth.go b/pkg/operator2/oauth.go index f415331038..d945930ccb 100644 --- a/pkg/operator2/oauth.go +++ b/pkg/operator2/oauth.go @@ -4,6 +4,7 @@ import ( "fmt" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -30,10 +31,16 @@ func (c *authOperator) handleOAuthConfig( *configSyncData, error, ) { - oauthConfig, err := c.oauth.Get(globalConfigName, metav1.GetOptions{}) + oauthConfigNoDefaults, err := c.oauth.Get(globalConfigName, metav1.GetOptions{}) + if errors.IsNotFound(err) { + oauthConfigNoDefaults, err = c.oauth.Create(&configv1.OAuth{ + ObjectMeta: defaultGlobalConfigMeta(), + }) + } if err != nil { return nil, nil, nil, err } + oauthConfig := defaultOAuthConfig(oauthConfigNoDefaults) var accessTokenInactivityTimeoutSeconds *int32 timeout := oauthConfig.Spec.TokenConfig.AccessTokenInactivityTimeoutSeconds @@ -163,3 +170,13 @@ func getMasterCA() *string { ca := serviceCAPath // need local var to be able to take address of it return &ca } + +func defaultOAuthConfig(oauthConfig *configv1.OAuth) *configv1.OAuth { + out := oauthConfig.DeepCopy() // do not mutate informer cache + + if out.Spec.TokenConfig.AccessTokenMaxAgeSeconds == 0 { + out.Spec.TokenConfig.AccessTokenMaxAgeSeconds = 24 * 60 * 60 // 1 day + } + + return out +} diff --git a/pkg/operator2/operator.go b/pkg/operator2/operator.go index 96706262f6..9c195102e3 100644 --- a/pkg/operator2/operator.go +++ b/pkg/operator2/operator.go @@ -596,6 +596,16 @@ func defaultMeta() metav1.ObjectMeta { } } +func defaultGlobalConfigMeta() metav1.ObjectMeta { + return metav1.ObjectMeta{ + Name: globalConfigName, + Labels: map[string]string{}, + Annotations: map[string]string{ + "release.openshift.io/create-only": "true", + }, + } +} + func getPrefixFilter() controller.Filter { names := operator.FilterByNames(targetName) prefix := func(obj metav1.Object) bool { // TODO add helper to combine filters diff --git a/pkg/operator2/starter.go b/pkg/operator2/starter.go index e2f13d26a2..56bf65c45b 100644 --- a/pkg/operator2/starter.go +++ b/pkg/operator2/starter.go @@ -29,6 +29,7 @@ import ( const ( resync = 20 * time.Minute + // TODO handle defaulting for this one once lib-go tolerated empty managementState defaultOperatorConfig = ` apiVersion: operator.openshift.io/v1 kind: Authentication @@ -37,31 +38,10 @@ metadata: spec: managementState: Managed ` - - // TODO figure out the permanent home for top level CRDs and default CRs - defaultAuthentication = ` -apiVersion: config.openshift.io/v1 -kind: Authentication -metadata: - name: ` + globalConfigName + ` -spec: - type: IntegratedOAuth -` - defaultOAuth = ` -apiVersion: config.openshift.io/v1 -kind: OAuth -metadata: - name: ` + globalConfigName + ` -spec: - tokenConfig: - accessTokenMaxAgeSeconds: 86400 -` ) var customResources = map[schema.GroupVersionResource]string{ operatorv1.GroupVersion.WithResource("authentications"): defaultOperatorConfig, - configv1.GroupVersion.WithResource("authentications"): defaultAuthentication, - configv1.GroupVersion.WithResource("oauths"): defaultOAuth, } func RunOperator(ctx *controllercmd.ControllerContext) error {