Skip to content
Draft
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
13 changes: 13 additions & 0 deletions cmd/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ var operatorCmd = &cobra.Command{

fga := openfgav1.NewOpenFGAServiceClient(conn)

k8sCfg := ctrl.GetConfigOrDie()

runtimeClient, err := client.New(k8sCfg, client.Options{Scheme: scheme})
if err != nil {
log.Error().Err(err).Msg("Failed to create in cluster client")
return err
}

if err = controller.NewStoreReconciler(log, fga, mgr).
SetupWithManager(mgr, defaultCfg); err != nil {
log.Error().Err(err).Str("controller", "store").Msg("unable to create controller")
Expand All @@ -170,6 +178,11 @@ var operatorCmd = &cobra.Command{
log.Error().Err(err).Str("controller", "invite").Msg("unable to create controller")
return err
}

if err = controller.NewWorkspaceReconciler(log, orgClient, operatorCfg, runtimeClient, mgr).SetupWithManager(mgr, defaultCfg, "root:security"); err != nil {
log.Error().Err(err).Str("controller", "workspace").Msg("unable to create controller")
return err
}
// +kubebuilder:scaffold:builder

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
Expand Down
83 changes: 83 additions & 0 deletions internal/controller/workspace_controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package controller

import (
"context"
"slices"
"sync"

kcpcorev1alpha1 "github.com/kcp-dev/kcp/sdk/apis/core/v1alpha1"
platformeshconfig "github.com/platform-mesh/golang-commons/config"
"github.com/platform-mesh/golang-commons/controller/lifecycle/builder"
"github.com/platform-mesh/golang-commons/controller/lifecycle/multicluster"
lifecyclesubroutine "github.com/platform-mesh/golang-commons/controller/lifecycle/subroutine"
"github.com/platform-mesh/golang-commons/logger"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/predicate"
mccontext "sigs.k8s.io/multicluster-runtime/pkg/context"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
mcreconcile "sigs.k8s.io/multicluster-runtime/pkg/reconcile"

"github.com/platform-mesh/security-operator/internal/config"
"github.com/platform-mesh/security-operator/internal/subroutine"
)

var (
shouldReconcileMutex sync.Mutex

Check failure on line 27 in internal/controller/workspace_controller.go

View workflow job for this annotation

GitHub Actions / pipe / lint / lint

var shouldReconcileMutex is unused (unused)
)

type WorkspaceReconciler struct {
log *logger.Logger
mgr mcmanager.Manager
initializer kcpcorev1alpha1.LogicalClusterInitializer
mclifecycle *multicluster.LifecycleManager
}

func NewWorkspaceReconciler(log *logger.Logger, orgClient client.Client, cfg config.Config, inClusterClient client.Client, mgr mcmanager.Manager) *WorkspaceReconciler {
return &WorkspaceReconciler{
log: log,
mgr: mgr,
mclifecycle: builder.NewBuilder("logicalcluster", "LogicalClusterReconciler", []lifecyclesubroutine.Subroutine{
subroutine.NewWorkspaceInitializer(orgClient, cfg, mgr),
subroutine.NewWorkspaceAuthConfigurationSubroutine(orgClient, inClusterClient, cfg),
}, log).WithReadOnly().WithStaticThenExponentialRateLimiter().BuildMultiCluster(mgr),
}
}

func (r *WorkspaceReconciler) Reconcile(ctx context.Context, req mcreconcile.Request) (ctrl.Result, error) {
ctxWithCluster := mccontext.WithCluster(ctx, req.ClusterName)
return r.mclifecycle.Reconcile(ctxWithCluster, req, &kcpcorev1alpha1.LogicalCluster{})
}

func (r *WorkspaceReconciler) SetupWithManager(mgr mcmanager.Manager, cfg *platformeshconfig.CommonServiceConfig, initializerName string, evp ...predicate.Predicate) error {
r.initializer = kcpcorev1alpha1.LogicalClusterInitializer(initializerName)
allPredicates := append([]predicate.Predicate{HasInitializerPredicate(initializerName)}, evp...)
return r.mclifecycle.SetupWithManager(mgr, cfg.MaxConcurrentReconciles, "LogicalCluster", &kcpcorev1alpha1.LogicalCluster{}, cfg.DebugLabelValue, r, r.log, allPredicates...)
}

func HasInitializerPredicate(initializerName string) predicate.Predicate {
initializer := kcpcorev1alpha1.LogicalClusterInitializer(initializerName)
return predicate.Funcs{
CreateFunc: func(e event.CreateEvent) bool {
lc := e.Object.(*kcpcorev1alpha1.LogicalCluster)
return shouldReconcile(lc, initializer)
},
UpdateFunc: func(e event.UpdateEvent) bool {
newLC := e.ObjectNew.(*kcpcorev1alpha1.LogicalCluster)
return shouldReconcile(newLC, initializer)
},
DeleteFunc: func(e event.DeleteEvent) bool {
lc := e.Object.(*kcpcorev1alpha1.LogicalCluster)
return shouldReconcile(lc, initializer)
},
GenericFunc: func(e event.GenericEvent) bool {
lc := e.Object.(*kcpcorev1alpha1.LogicalCluster)
return shouldReconcile(lc, initializer)
},
}
}

func shouldReconcile(lc *kcpcorev1alpha1.LogicalCluster, initializer kcpcorev1alpha1.LogicalClusterInitializer) bool {
return slices.Contains(lc.Spec.Initializers, initializer) && !slices.Contains(lc.Status.Initializers, initializer)
}
Loading