This commit is contained in:
133
pkg/controller/system/controller.go
Normal file
133
pkg/controller/system/controller.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
condition "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||
health "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/health"
|
||||
zitadelClient "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/zitadel"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
type SystemReconciler struct {
|
||||
Client client.Client
|
||||
RefResolver *zitadelv1alpha1.RefResolver
|
||||
ConditionReady *condition.Ready
|
||||
|
||||
WrappedReconciler WrappedSystemReconciler
|
||||
Finalizer Finalizer
|
||||
RequeueInterval time.Duration
|
||||
}
|
||||
|
||||
func NewSystemReconciler(client client.Client, cr *condition.Ready, wr WrappedSystemReconciler, f Finalizer,
|
||||
requeueInterval time.Duration) Reconciler {
|
||||
return &SystemReconciler{
|
||||
Client: client,
|
||||
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
||||
ConditionReady: cr,
|
||||
WrappedReconciler: wr,
|
||||
Finalizer: f,
|
||||
RequeueInterval: requeueInterval,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *SystemReconciler) Reconcile(ctx context.Context, resource Resource) (ctrl.Result, error) {
|
||||
if resource.IsBeingDeleted() {
|
||||
if err := r.Finalizer.Finalize(ctx, resource); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error finalizing %s: %v", resource.GetName(), err)
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
clusterRef, err := resource.ClusterRef(ctx, r.RefResolver)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
cluster, err := r.RefResolver.Cluster(ctx, clusterRef, resource.GetNamespace())
|
||||
if err != nil {
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherRefResolver(err, cluster))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
return ctrl.Result{}, fmt.Errorf("error getting Cluster: %v", errBundle)
|
||||
}
|
||||
|
||||
if err := waitForCluster(ctx, r.Client, resource, cluster); err != nil {
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
err := r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherWithError(err))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
return ctrl.Result{}, fmt.Errorf("error waiting for Cluster: %v", errBundle)
|
||||
}
|
||||
|
||||
ztdClient, err := zitadelClient.NewSystemClient(ctx, cluster, *r.RefResolver)
|
||||
if err != nil {
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
msg := fmt.Sprintf("Error connecting to System: %v", err)
|
||||
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherFailed(msg))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
return r.retryResult(ctx, resource, errBundle)
|
||||
}
|
||||
defer ztdClient.Connection.Close()
|
||||
err = r.WrappedReconciler.Reconcile(ctx, ztdClient)
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
if err := errBundle.ErrorOrNil(); err != nil {
|
||||
msg := fmt.Sprintf("Error creating %s: %v", resource.GetName(), err)
|
||||
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherFailed(msg))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
return r.retryResult(ctx, resource, errBundle)
|
||||
}
|
||||
|
||||
if err = r.Finalizer.AddFinalizer(ctx); err != nil {
|
||||
errBundle = multierror.Append(errBundle, fmt.Errorf("error adding finalizer to %s: %v", resource.GetName(), err))
|
||||
}
|
||||
|
||||
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherWithError(errBundle.ErrorOrNil()))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
if err := errBundle.ErrorOrNil(); err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return r.requeueResult(ctx, resource)
|
||||
}
|
||||
|
||||
func (r *SystemReconciler) retryResult(ctx context.Context, resource Resource, err error) (ctrl.Result, error) {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
func (r *SystemReconciler) requeueResult(ctx context.Context, resource Resource) (ctrl.Result, error) {
|
||||
if r.RequeueInterval > 0 {
|
||||
log.FromContext(ctx).V(1).Info("Requeuing SYSTEM resource")
|
||||
return ctrl.Result{RequeueAfter: r.RequeueInterval}, nil
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func waitForCluster(ctx context.Context, client client.Client, resource Resource,
|
||||
system *zitadelv1alpha1.Cluster) error {
|
||||
var systemErr *multierror.Error
|
||||
healthy, err := health.IsClusterHealthy(ctx, client, system)
|
||||
if err != nil {
|
||||
systemErr = multierror.Append(systemErr, err)
|
||||
}
|
||||
if !healthy {
|
||||
systemErr = multierror.Append(systemErr, errors.New("System not healthy"))
|
||||
}
|
||||
return systemErr.ErrorOrNil()
|
||||
}
|
||||
76
pkg/controller/system/finalizer.go
Normal file
76
pkg/controller/system/finalizer.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
zitadelClient "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/zitadel"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
type SystemFinalizer struct {
|
||||
Client client.Client
|
||||
RefResolver *zitadelv1alpha1.RefResolver
|
||||
|
||||
WrappedFinalizer WrappedSystemFinalizer
|
||||
}
|
||||
|
||||
func NewSystemFinalizer(client client.Client, wf WrappedSystemFinalizer) Finalizer {
|
||||
return &SystemFinalizer{
|
||||
Client: client,
|
||||
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
||||
WrappedFinalizer: wf,
|
||||
}
|
||||
}
|
||||
|
||||
func (tf *SystemFinalizer) AddFinalizer(ctx context.Context) error {
|
||||
if tf.WrappedFinalizer.ContainsFinalizer() {
|
||||
return nil
|
||||
}
|
||||
if err := tf.WrappedFinalizer.AddFinalizer(ctx); err != nil {
|
||||
return fmt.Errorf("error adding finalizer in TemplateFinalizer: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tf *SystemFinalizer) Finalize(ctx context.Context, resource Resource) error {
|
||||
if !tf.WrappedFinalizer.ContainsFinalizer() {
|
||||
return nil
|
||||
}
|
||||
|
||||
clusterRef, err := resource.ClusterRef(ctx, tf.RefResolver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
system, err := tf.RefResolver.Cluster(ctx, clusterRef, resource.GetNamespace())
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
if err := tf.WrappedFinalizer.RemoveFinalizer(ctx); err != nil {
|
||||
return fmt.Errorf("error removing %s finalizer: %v", resource.GetName(), err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("error getting System: %v", err)
|
||||
}
|
||||
|
||||
if err := waitForCluster(ctx, tf.Client, resource, system); err != nil {
|
||||
return fmt.Errorf("error waiting for System: %v", err)
|
||||
}
|
||||
|
||||
ztdClient, err := zitadelClient.NewSystemClient(ctx, system, *tf.RefResolver)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error connecting to System: %v", err)
|
||||
}
|
||||
defer ztdClient.Connection.Close()
|
||||
|
||||
if err := tf.WrappedFinalizer.Reconcile(ctx, ztdClient); err != nil {
|
||||
return fmt.Errorf("error reconciling in TemplateFinalizer: %v", err)
|
||||
}
|
||||
|
||||
if err := tf.WrappedFinalizer.RemoveFinalizer(ctx); err != nil {
|
||||
return fmt.Errorf("error removing finalizer in TemplateFinalizer: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
39
pkg/controller/system/types.go
Normal file
39
pkg/controller/system/types.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
"github.com/zitadel/zitadel-go/v3/pkg/client/system"
|
||||
|
||||
condition "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
)
|
||||
|
||||
type Resource interface {
|
||||
v1.Object
|
||||
ClusterRef(context.Context, *zitadelv1alpha1.RefResolver) (*zitadelv1alpha1.ClusterRef, error)
|
||||
IsBeingDeleted() bool
|
||||
}
|
||||
|
||||
type Reconciler interface {
|
||||
Reconcile(ctx context.Context, resource Resource) (ctrl.Result, error)
|
||||
}
|
||||
|
||||
type WrappedSystemReconciler interface {
|
||||
Reconcile(context.Context, *system.Client) error
|
||||
PatchStatus(context.Context, condition.Patcher) error
|
||||
}
|
||||
|
||||
type Finalizer interface {
|
||||
AddFinalizer(context.Context) error
|
||||
Finalize(context.Context, Resource) error
|
||||
}
|
||||
|
||||
type WrappedSystemFinalizer interface {
|
||||
AddFinalizer(context.Context) error
|
||||
RemoveFinalizer(context.Context) error
|
||||
ContainsFinalizer() bool
|
||||
Reconcile(context.Context, *system.Client) error
|
||||
}
|
||||
Reference in New Issue
Block a user