Skip to content
This repository was archived by the owner on Jun 23, 2026. It is now read-only.
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
13 changes: 0 additions & 13 deletions cmd/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,6 @@ var operatorCmd = &cobra.Command{
log.Error().Err(err).Msg("Failed to create in cluster client")
return err
}
providerLister := iclient.NewProviderLister(provider.Provider.Provider)

if err = controller.NewStoreReconciler(ctx, log, fga, mgr, &operatorCfg, providerLister).
SetupWithManager(mgr, defaultCfg); err != nil {
log.Error().Err(err).Str("controller", "store").Msg("unable to create controller")
return err
}
if err = controller.
NewAuthorizationModelReconciler(log, fga, mgr).
SetupWithManager(mgr, defaultCfg); err != nil {
log.Error().Err(err).Str("controller", "authorizationmodel").Msg("unable to create controller")
return err
}

kcpClientGetter := iclient.NewManagerKCPClientGetter(mgr, provider.Provider.Provider)
kcpClientGetterWithConfig := iclient.NewConfigSchemeKCPClientGetter(restCfg, scheme)
Expand Down
15 changes: 14 additions & 1 deletion cmd/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ var systemCmd = &cobra.Command{
Scheme: scheme,
})
if err != nil {
setupLog.Error(err, "unable to create apiexport provider")
setupLog.Error(err, "unable to create system apiexport provider")
return err
}

Expand Down Expand Up @@ -131,6 +131,19 @@ var systemCmd = &cobra.Command{
return err
}

if err = controller.NewStoreReconciler(ctx, log, fgaClient, mgr, &operatorCfg, providerLister, kcpClientGetter).
SetupWithManager(mgr, defaultCfg); err != nil {
log.Error().Err(err).Str("controller", "store").Msg("unable to create controller")
return err
}

if err = controller.
NewAuthorizationModelReconciler(log, fgaClient, mgr, kcpClientGetter).
SetupWithManager(mgr, defaultCfg); err != nil {
log.Error().Err(err).Str("controller", "authorizationmodel").Msg("unable to create controller")
return err
}

if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
log.Error().Err(err).Msg("unable to set up health check")
return err
Expand Down
10 changes: 10 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"os"
"strings"
"time"

"github.com/spf13/pflag"
Expand Down Expand Up @@ -195,3 +196,12 @@ func (config Config) TerminatorName() string {
func MultiProviderName(providerName, clusterName string) multicluster.ClusterName {
return multicluster.ClusterName(providerName + providerSeparator + clusterName)
}

// Strip provider prefix from cluster name ("core#1kar1u6c65ykt4ea" -> "1kar1u6c65ykt4ea")
func StripProviderPrefix(clusterName multicluster.ClusterName) string {
prefixedClusterName := string(clusterName)
if _, ClusteName, found := strings.Cut(prefixedClusterName, providerSeparator); found {
return ClusteName
}
return prefixedClusterName
}
13 changes: 10 additions & 3 deletions internal/controller/authorization_model_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@ package controller

import (
"context"
"strings"
"time"

openfgav1 "github.com/openfga/api/proto/openfga/v1"
platformeshconfig "github.com/platform-mesh/golang-commons/config"
"github.com/platform-mesh/golang-commons/controller/filter"
"github.com/platform-mesh/golang-commons/logger"
corev1alpha1 "github.com/platform-mesh/security-operator/api/v1alpha1"
iclient "github.com/platform-mesh/security-operator/internal/client"
"github.com/platform-mesh/security-operator/internal/config"
"github.com/platform-mesh/security-operator/internal/metrics"
"github.com/platform-mesh/security-operator/internal/subroutine"
"github.com/platform-mesh/subroutines/lifecycle"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/cluster"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/predicate"
mcbuilder "sigs.k8s.io/multicluster-runtime/pkg/builder"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
"sigs.k8s.io/multicluster-runtime/pkg/multicluster"
mcreconcile "sigs.k8s.io/multicluster-runtime/pkg/reconcile"
)

Expand All @@ -26,10 +31,10 @@ type AuthorizationModelReconciler struct {
lifecycle *lifecycle.Lifecycle
}

func NewAuthorizationModelReconciler(log *logger.Logger, fga openfgav1.OpenFGAServiceClient, mcMgr mcmanager.Manager) *AuthorizationModelReconciler {
func NewAuthorizationModelReconciler(log *logger.Logger, fga openfgav1.OpenFGAServiceClient, mcMgr mcmanager.Manager, kcpClientGetter iclient.KCPClientGetter) *AuthorizationModelReconciler {
lc := lifecycle.New(mcMgr, "AuthorizationModelReconciler", func() client.Object {
return &corev1alpha1.AuthorizationModel{}
}, subroutine.NewTupleSubroutine(fga, mcMgr))
}, subroutine.NewTupleSubroutine(fga, kcpClientGetter))

return &AuthorizationModelReconciler{
log: log,
Expand All @@ -56,7 +61,9 @@ func (r *AuthorizationModelReconciler) SetupWithManager(mgr mcmanager.Manager, c
predicates := append([]predicate.Predicate{filter.DebugResourcesBehaviourPredicate(cfg.DebugLabelValue)}, evp...)
return mcbuilder.ControllerManagedBy(mgr).
Named("authorizationmodel").
For(&corev1alpha1.AuthorizationModel{}).
For(&corev1alpha1.AuthorizationModel{}, mcbuilder.WithClusterFilter(func(clusterName multicluster.ClusterName, _ cluster.Cluster) bool {
return strings.HasPrefix(string(clusterName), config.CoreProviderName)
})).
WithOptions(opts).
WithEventFilter(predicate.And(predicates...)).
Complete(r)
Expand Down
19 changes: 15 additions & 4 deletions internal/controller/store_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controller

import (
"context"
"strings"
"time"

openfgav1 "github.com/openfga/api/proto/openfga/v1"
Expand Down Expand Up @@ -40,15 +41,15 @@ type StoreReconciler struct {
lifecycle *lifecycle.Lifecycle
}

func NewStoreReconciler(ctx context.Context, log *logger.Logger, fga openfgav1.OpenFGAServiceClient, mcMgr mcmanager.Manager, cfg *config.Config, lister iclient.Lister) *StoreReconciler {
func NewStoreReconciler(ctx context.Context, log *logger.Logger, fga openfgav1.OpenFGAServiceClient, mcMgr mcmanager.Manager, cfg *config.Config, lister iclient.Lister, kcpClientGetter iclient.KCPClientGetter) *StoreReconciler {
lc := lifecycle.New(mcMgr, "StoreReconciler", func() client.Object {
return &corev1alpha1.Store{}
},
subroutine.NewStoreSubroutine(fga, mcMgr, lister),
subroutine.NewAuthorizationModelSubroutine(fga, mcMgr, lister, func(cfg *rest.Config) discovery.DiscoveryInterface {
return discovery.NewDiscoveryClientForConfigOrDie(cfg)
}, log),
subroutine.NewTupleSubroutine(fga, mcMgr),
subroutine.NewTupleSubroutine(fga, kcpClientGetter),
).WithConditions(conditions.NewManager())

return &StoreReconciler{
Expand All @@ -75,7 +76,11 @@ func (r *StoreReconciler) SetupWithManager(mgr mcmanager.Manager, cfg *platforme
predicates := append([]predicate.Predicate{filter.DebugResourcesBehaviourPredicate(cfg.DebugLabelValue)}, evp...)
b := mcbuilder.ControllerManagedBy(mgr).
Named("store").
For(&corev1alpha1.Store{}).
For(&corev1alpha1.Store{},
mcbuilder.WithClusterFilter(func(clusterName multicluster.ClusterName, _ cluster.Cluster) bool {
return strings.HasPrefix(string(clusterName), config.SystemProviderName)
}),
).
WithOptions(controller.TypedOptions[mcreconcile.Request]{MaxConcurrentReconciles: cfg.MaxConcurrentReconciles}).
WithEventFilter(predicate.And(predicates...))

Expand All @@ -88,6 +93,9 @@ func (r *StoreReconciler) SetupWithManager(mgr mcmanager.Manager, cfg *platforme
if !ok {
return nil
}
// stores are engaged by system provider, to trigger a reconciliation with multi provider
// it's required to use provider's prefix for request
storeClusterName := config.MultiProviderName(config.SystemProviderName, model.Spec.StoreRef.Cluster)

return []mcreconcile.Request{
{
Expand All @@ -96,11 +104,14 @@ func (r *StoreReconciler) SetupWithManager(mgr mcmanager.Manager, cfg *platforme
Name: model.Spec.StoreRef.Name,
},
},
ClusterName: multicluster.ClusterName(model.Spec.StoreRef.Cluster),
ClusterName: storeClusterName,
},
}
})
},
mcbuilder.WithPredicates(predicate.GenerationChangedPredicate{}),
mcbuilder.WithClusterFilter(func(clusterName multicluster.ClusterName, _ cluster.Cluster) bool {
return strings.HasPrefix(string(clusterName), config.CoreProviderName)
}),
).Complete(r)
}
4 changes: 2 additions & 2 deletions internal/subroutine/authorization_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/platform-mesh/golang-commons/logger"
securityv1alpha1 "github.com/platform-mesh/security-operator/api/v1alpha1"
iclient "github.com/platform-mesh/security-operator/internal/client"
"github.com/platform-mesh/security-operator/internal/config"
"github.com/platform-mesh/security-operator/internal/util"
"github.com/platform-mesh/subroutines"
"google.golang.org/protobuf/encoding/protojson"
Expand Down Expand Up @@ -108,7 +109,7 @@ func getRelatedAuthorizationModels(ctx context.Context, lister iclient.Lister, s

var extendingModules securityv1alpha1.AuthorizationModelList
for _, model := range allAuthorizationModels.Items {
if model.Spec.StoreRef.Name != store.Name || model.Spec.StoreRef.Cluster != string(storeClusterKey) {
if model.Spec.StoreRef.Name != store.Name || model.Spec.StoreRef.Cluster != config.StripProviderPrefix(storeClusterKey) {
continue
}

Expand Down Expand Up @@ -203,7 +204,6 @@ func (a *authorizationModelSubroutine) Process(ctx context.Context, obj client.O
if string(currentRaw) == string(desiredRaw) {
return subroutines.OK(), nil
}

}

res, err := a.fga.WriteAuthorizationModel(ctx, &openfgav1.WriteAuthorizationModelRequest{
Expand Down
26 changes: 13 additions & 13 deletions internal/subroutine/tuples.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ import (
openfgav1 "github.com/openfga/api/proto/openfga/v1"
"github.com/platform-mesh/golang-commons/logger"
securityv1alpha1 "github.com/platform-mesh/security-operator/api/v1alpha1"
iclient "github.com/platform-mesh/security-operator/internal/client"
"github.com/platform-mesh/security-operator/internal/config"
"github.com/platform-mesh/security-operator/internal/fga"
"github.com/platform-mesh/subroutines"
"sigs.k8s.io/controller-runtime/pkg/client"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
"sigs.k8s.io/multicluster-runtime/pkg/multicluster"

"k8s.io/apimachinery/pkg/types"
)

type tupleSubroutine struct {
fga openfgav1.OpenFGAServiceClient
mgr mcmanager.Manager
fga openfgav1.OpenFGAServiceClient
kcpClientGetter iclient.KCPClientGetter
}

// Finalize implements subroutines.Finalizer.
Expand All @@ -38,13 +38,13 @@ func (t *tupleSubroutine) Finalize(ctx context.Context, obj client.Object) (subr
case *securityv1alpha1.AuthorizationModel:
managedTuples = o.Status.ManagedTuples

storeCluster, err := t.mgr.GetCluster(ctx, multicluster.ClusterName(o.Spec.StoreRef.Cluster))
storeClient, err := t.kcpClientGetter.NewClientForLogicalCluster(ctx, string(config.MultiProviderName(config.SystemProviderName, o.Spec.StoreRef.Cluster)))
if err != nil {
return subroutines.OK(), fmt.Errorf("unable to get store cluster: %w", err)
return subroutines.OK(), fmt.Errorf("unable to create client to store cluster: %w", err)
}

var store securityv1alpha1.Store
err = storeCluster.GetClient().Get(ctx, types.NamespacedName{
err = storeClient.Get(ctx, types.NamespacedName{
Name: o.Spec.StoreRef.Name,
}, &store)
if err != nil {
Expand Down Expand Up @@ -98,13 +98,13 @@ func (t *tupleSubroutine) Process(ctx context.Context, obj client.Object) (subro
specTuples = o.Spec.Tuples
managedTuples = o.Status.ManagedTuples

storeCluster, err := t.mgr.GetCluster(ctx, multicluster.ClusterName(o.Spec.StoreRef.Cluster))
storeClient, err := t.kcpClientGetter.NewClientForLogicalCluster(ctx, string(config.MultiProviderName(config.SystemProviderName, o.Spec.StoreRef.Cluster)))
if err != nil {
return subroutines.OK(), fmt.Errorf("unable to get store cluster: %w", err)
return subroutines.OK(), fmt.Errorf("unable to create client to store cluster: %w", err)
}

var store securityv1alpha1.Store
err = storeCluster.GetClient().Get(ctx, types.NamespacedName{
err = storeClient.Get(ctx, types.NamespacedName{
Name: o.Spec.StoreRef.Name,
}, &store)
if err != nil {
Expand Down Expand Up @@ -142,10 +142,10 @@ func (t *tupleSubroutine) Process(ctx context.Context, obj client.Object) (subro
return subroutines.OK(), nil
}

func NewTupleSubroutine(fga openfgav1.OpenFGAServiceClient, mgr mcmanager.Manager) *tupleSubroutine {
func NewTupleSubroutine(fga openfgav1.OpenFGAServiceClient, kcpClientGetter iclient.KCPClientGetter) *tupleSubroutine {
return &tupleSubroutine{
fga: fga,
mgr: mgr,
fga: fga,
kcpClientGetter: kcpClientGetter,
}
}

Expand Down
Loading
Loading