Skip to content

Commit

Permalink
Merge pull request #705 from bertinatto/try-apply-wellknown-controller
Browse files Browse the repository at this point in the history
API-1835: Migrate WellKnownReadyController to SSA
  • Loading branch information
openshift-merge-bot[bot] authored Oct 11, 2024
2 parents 7ef902b + fd3b5d5 commit 2d71f16
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 50 deletions.
13 changes: 6 additions & 7 deletions pkg/controllers/common/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@ func (e *ControllerProgressingError) Unwrap() error {
return e.err
}

func (e *ControllerProgressingError) ToCondition(controllerName string) operatorv1.OperatorCondition {
return operatorv1.OperatorCondition{
Type: ControllerProgressingConditionName(controllerName),
Status: operatorv1.ConditionTrue,
Reason: e.reason,
Message: e.err.Error(),
}
func (e *ControllerProgressingError) ToCondition(controllerName string) *applyoperatorv1.OperatorConditionApplyConfiguration {
return applyoperatorv1.OperatorCondition().
WithType(ControllerProgressingConditionName(controllerName)).
WithStatus(operatorv1.ConditionTrue).
WithReason(e.reason).
WithMessage(e.err.Error())
}

// IsDegraded returns true if the condition matching this error (same type, reason and message)
Expand Down
101 changes: 58 additions & 43 deletions pkg/controllers/readiness/wellknown_ready_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
operatorv1 "github.com/openshift/api/operator/v1"
configinformer "github.com/openshift/client-go/config/informers/externalversions"
configv1lister "github.com/openshift/client-go/config/listers/config/v1"
applyoperatorv1 "github.com/openshift/client-go/operator/applyconfigurations/operator/v1"
routeinformer "github.com/openshift/client-go/route/informers/externalversions/route/v1"
routev1lister "github.com/openshift/client-go/route/listers/route/v1"
"github.com/openshift/cluster-authentication-operator/pkg/controllers/common"
Expand Down Expand Up @@ -49,31 +50,33 @@ func init() {
}

type wellKnownReadyController struct {
serviceLister corev1lister.ServiceLister
endpointLister corev1lister.EndpointsLister
operatorClient v1helpers.OperatorClient
authLister configv1lister.AuthenticationLister
configMapLister corev1lister.ConfigMapLister
routeLister routev1lister.RouteLister
infrastructureLister configv1lister.InfrastructureLister
controllerInstanceName string
serviceLister corev1lister.ServiceLister
endpointLister corev1lister.EndpointsLister
operatorClient v1helpers.OperatorClient
authLister configv1lister.AuthenticationLister
configMapLister corev1lister.ConfigMapLister
routeLister routev1lister.RouteLister
infrastructureLister configv1lister.InfrastructureLister
}

const controllerName = "WellKnownReadyController"

func NewWellKnownReadyController(kubeInformers v1helpers.KubeInformersForNamespaces, configInformers configinformer.SharedInformerFactory, routeInformer routeinformer.RouteInformer,
func NewWellKnownReadyController(instanceName string, kubeInformers v1helpers.KubeInformersForNamespaces, configInformers configinformer.SharedInformerFactory, routeInformer routeinformer.RouteInformer,
operatorClient v1helpers.OperatorClient, recorder events.Recorder) factory.Controller {

nsOpenshiftConfigManagedInformers := kubeInformers.InformersFor("openshift-config-managed")
nsDefaultInformers := kubeInformers.InformersFor("default")

c := &wellKnownReadyController{
serviceLister: nsDefaultInformers.Core().V1().Services().Lister(),
endpointLister: nsDefaultInformers.Core().V1().Endpoints().Lister(),
authLister: configInformers.Config().V1().Authentications().Lister(),
infrastructureLister: configInformers.Config().V1().Infrastructures().Lister(),
configMapLister: nsOpenshiftConfigManagedInformers.Core().V1().ConfigMaps().Lister(),
routeLister: routeInformer.Lister(),
operatorClient: operatorClient,
controllerInstanceName: factory.ControllerInstanceName(instanceName, "WellKnownReady"),
serviceLister: nsDefaultInformers.Core().V1().Services().Lister(),
endpointLister: nsDefaultInformers.Core().V1().Endpoints().Lister(),
authLister: configInformers.Config().V1().Authentications().Lister(),
infrastructureLister: configInformers.Config().V1().Infrastructures().Lister(),
configMapLister: nsOpenshiftConfigManagedInformers.Core().V1().ConfigMaps().Lister(),
routeLister: routeInformer.Lister(),
operatorClient: operatorClient,
}

return factory.New().WithInformers(
Expand All @@ -87,7 +90,9 @@ func NewWellKnownReadyController(kubeInformers v1helpers.KubeInformersForNamespa
WithSync(c.sync).
WithSyncDegradedOnError(operatorClient).
ResyncEvery(wait.Jitter(time.Minute, 1.0)).
ToController(controllerName, recorder.WithComponentSuffix("wellknown-ready-controller"))
ToController(
controllerName, // Don't change what is passed here unless you also remove the old FooDegraded condition
recorder.WithComponentSuffix("wellknown-ready-controller"))
}

func (c *wellKnownReadyController) sync(ctx context.Context, controllerContext factory.SyncContext) error {
Expand All @@ -106,9 +111,18 @@ func (c *wellKnownReadyController) sync(ctx context.Context, controllerContext f
}

// the code below this point triggers status updates, unify status update handling in defer
statusUpdates := []v1helpers.UpdateStatusFunc{}
status := applyoperatorv1.OperatorStatus()

// create conditions to be applied during defer. These conditions are intentionally left without a status,
// ensuring the API server will reject the Apply operation if the status is not set down below
available := applyoperatorv1.OperatorCondition().
WithType("WellKnownAvailable")
progressing := applyoperatorv1.OperatorCondition().
WithType(common.ControllerProgressingConditionName(controllerName))

defer func() {
if _, _, updateErr := v1helpers.UpdateStatus(ctx, c.operatorClient, statusUpdates...); updateErr != nil {
status = status.WithConditions(available, progressing)
if updateErr := c.operatorClient.ApplyOperatorStatus(ctx, c.controllerInstanceName, status); updateErr != nil {
// fall through to the generic error handling for degraded and requeue
utilruntime.HandleError(updateErr)
}
Expand All @@ -117,47 +131,48 @@ func (c *wellKnownReadyController) sync(ctx context.Context, controllerContext f
// the well-known endpoint cannot be ready until we know the oauth-server's hostname
_, err = c.routeLister.Routes("openshift-authentication").Get("oauth-openshift")
if apierrors.IsNotFound(err) {
statusUpdates = append(statusUpdates, v1helpers.UpdateConditionFn(operatorv1.OperatorCondition{
Type: "WellKnownAvailable",
Status: operatorv1.ConditionFalse,
Reason: "PrereqsNotReady",
Message: err.Error(),
}))
available = available.
WithStatus(operatorv1.ConditionFalse).
WithReason("PrereqsNotReady").
WithMessage(err.Error())
progressing = progressing.
WithStatus(operatorv1.ConditionTrue)
return err
}
if err != nil {
available = available.
WithStatus(operatorv1.ConditionFalse).
WithReason("SyncError").
WithMessage(err.Error())
progressing = progressing.
WithStatus(operatorv1.ConditionTrue)
return err
}

if err := c.isWellknownEndpointsReady(ctx, operatorSpec, operatorStatus, authConfig, infraConfig); err != nil {
statusUpdates = append(statusUpdates, v1helpers.UpdateConditionFn(operatorv1.OperatorCondition{
Type: "WellKnownAvailable",
Status: operatorv1.ConditionFalse,
Reason: "NotReady",
Message: fmt.Sprintf("The well-known endpoint is not yet available: %s", err.Error()),
}))

available = available.
WithStatus(operatorv1.ConditionFalse).
WithReason("NotReady").
WithMessage(fmt.Sprintf("The well-known endpoint is not yet available: %s", err.Error()))
progressing = progressing.
WithStatus(operatorv1.ConditionTrue)
if progressingErr, ok := err.(*common.ControllerProgressingError); ok {
if progressingErr.IsDegraded(controllerName, operatorStatus) {
return progressingErr.Unwrap()
}
statusUpdates = append(statusUpdates, v1helpers.UpdateConditionFn(progressingErr.ToCondition(controllerName)))
progressing = progressingErr.ToCondition(controllerName)
return nil
} else {
return err
}
}

statusUpdates = append(statusUpdates, v1helpers.UpdateConditionFn(
operatorv1.OperatorCondition{
Type: common.ControllerProgressingConditionName(controllerName),
Status: operatorv1.ConditionFalse,
}),
v1helpers.UpdateConditionFn(operatorv1.OperatorCondition{
Type: "WellKnownAvailable",
Status: operatorv1.ConditionTrue,
Reason: "AsExpected",
}),
)
progressing = progressing.
WithStatus(operatorv1.ConditionFalse)
available = available.
WithStatus(operatorv1.ConditionTrue).
WithReason("AsExpected")

return nil
}

Expand Down
1 change: 1 addition & 0 deletions pkg/operator/starter.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ func prepareOauthOperator(ctx context.Context, controllerContext *controllercmd.
controllerContext.EventRecorder)

wellKnownReadyController := readiness.NewWellKnownReadyController(
"openshift-authentication",
operatorCtx.kubeInformersForNamespaces,
operatorCtx.operatorConfigInformer,
routeInformersNamespaced.Route().V1().Routes(),
Expand Down

0 comments on commit 2d71f16

Please sign in to comment.