Skip to content
Open
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
5 changes: 0 additions & 5 deletions cmd/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,6 @@ var operatorCmd = &cobra.Command{
return err
}

if err = controller.NewStoreReconciler(ctx, log, fga, mgr, &operatorCfg).
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 {
Expand Down
29 changes: 26 additions & 3 deletions cmd/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
openfgav1 "github.com/openfga/api/proto/openfga/v1"
platformeshcontext "github.com/platform-mesh/golang-commons/context"
iclient "github.com/platform-mesh/security-operator/internal/client"
"github.com/platform-mesh/security-operator/internal/config"
"github.com/platform-mesh/security-operator/internal/controller"
"github.com/platform-mesh/security-operator/internal/fga"
"github.com/spf13/cobra"
Expand All @@ -16,6 +17,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/healthz"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
multiprovider "sigs.k8s.io/multicluster-runtime/providers/multi"

"k8s.io/client-go/rest"

Expand Down Expand Up @@ -63,15 +65,30 @@ var systemCmd = &cobra.Command{
opts.LeaderElectionConfig = inClusterCfg
}

provider, err := apiexport.New(restCfg, systemCfg.APIExportEndpointSlices.SystemPlatformMeshIO, apiexport.Options{
systemProvider, err := apiexport.New(restCfg, systemCfg.APIExportEndpointSlices.SystemPlatformMeshIO, apiexport.Options{
Scheme: scheme,
})
if err != nil {
setupLog.Error(err, "unable to create apiexport provider")
setupLog.Error(err, "unable to create system apiexport provider")
return err
}

mgr, err := mcmanager.New(restCfg, provider, opts)
coreProvider, err := apiexport.New(restCfg, systemCfg.APIExportEndpointSlices.CorePlatformMeshIO, apiexport.Options{
Scheme: scheme,
})
if err != nil {
setupLog.Error(err, "unable to create core apiexport provider")
return err
}
multiProv := multiprovider.New(multiprovider.Options{})
if err := multiProv.AddProvider(config.SystemProviderName, systemProvider); err != nil {
return err
}
if err := multiProv.AddProvider(config.CoreProviderName, coreProvider); err != nil {
return err
}

mgr, err := mcmanager.New(restCfg, multiProv, opts)
if err != nil {
setupLog.Error(err, "unable to create manager")
return err
Expand Down Expand Up @@ -113,6 +130,12 @@ var systemCmd = &cobra.Command{
return err
}

if err = controller.NewStoreReconciler(ctx, log, fgaClient, mgr, &operatorCfg).
SetupWithManager(mgr, defaultCfg); err != nil {
log.Error().Err(err).Str("controller", "store").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
6 changes: 6 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import (
"github.com/spf13/pflag"
)

const (
CoreProviderName = "core"
SystemProviderName = "system"
ProviderSeparator = "#"
)

type KeycloakConfig struct {
BaseURL string
ClientID string
Expand Down
12 changes: 9 additions & 3 deletions internal/controller/apiexportpolicy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ func (r *APIExportPolicyReconciler) SetupWithManager(mgr mcmanager.Manager, cfg

return mcbuilder.ControllerManagedBy(mgr).
Named("apiexportpolicy").
For(&corev1alpha1.APIExportPolicy{}).
For(&corev1alpha1.APIExportPolicy{},
mcbuilder.WithClusterFilter(func(clusterName string, _ cluster.Cluster) bool {
return strings.HasPrefix(clusterName, config.SystemProviderName)
}),
).
WithOptions(opts).
WithEventFilter(predicate.And(predicates...)).
Watches(
Expand Down Expand Up @@ -112,14 +116,16 @@ func (r *APIExportPolicyReconciler) enqueueAllAPIExportPolicies(ctx context.Cont
trimmedExpr := strings.TrimPrefix(expr, ":")

if trimmedExpr == "root:orgs:*" {
clusterName := logicalcluster.From(&policy)
// apiExportPolicies are engaged by system provider
clusterName := multiProviderName(config.SystemProviderName, logicalcluster.From(&policy).String())

requests = append(requests, mcreconcile.Request{
Request: reconcile.Request{
NamespacedName: types.NamespacedName{
Name: policy.Name,
},
},
ClusterName: clusterName.String(),
ClusterName: clusterName,
})
break
}
Expand Down
4 changes: 3 additions & 1 deletion internal/controller/authorization_model_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"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/subroutine"
"github.com/platform-mesh/subroutines/lifecycle"
ctrl "sigs.k8s.io/controller-runtime"
Expand All @@ -25,9 +26,10 @@ type AuthorizationModelReconciler struct {
}

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

return &AuthorizationModelReconciler{
log: log,
Expand Down
6 changes: 5 additions & 1 deletion internal/controller/idp_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controller
import (
"context"
"fmt"
"strings"

platformeshconfig "github.com/platform-mesh/golang-commons/config"
"github.com/platform-mesh/golang-commons/controller/filter"
Expand All @@ -15,6 +16,7 @@ import (
"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"
Expand Down Expand Up @@ -65,7 +67,9 @@ func (r *IdentityProviderConfigurationReconciler) SetupWithManager(mgr mcmanager
predicates := append([]predicate.Predicate{filter.DebugResourcesBehaviourPredicate(cfg.DebugLabelValue)}, evp...)
return mcbuilder.ControllerManagedBy(mgr).
Named("identityprovider").
For(&corev1alpha1.IdentityProviderConfiguration{}).
For(&corev1alpha1.IdentityProviderConfiguration{}, mcbuilder.WithClusterFilter(func(clusterName string, _ cluster.Cluster) bool {
return strings.HasPrefix(clusterName, config.SystemProviderName)
})).
WithOptions(opts).
WithEventFilter(predicate.And(predicates...)).
Complete(r)
Expand Down
24 changes: 21 additions & 3 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"

openfgav1 "github.com/openfga/api/proto/openfga/v1"
platformeshconfig "github.com/platform-mesh/golang-commons/config"
Expand Down Expand Up @@ -42,6 +43,7 @@ func NewStoreReconciler(ctx context.Context, log *logger.Logger, fga openfgav1.O
if err != nil {
log.Fatal().Err(err).Msg("unable to create new client")
}
kcpClientHelper := iclient.NewKcpHelper(mcMgr.GetLocalManager().GetConfig(), mcMgr.GetLocalManager().GetScheme())

lc := lifecycle.New(mcMgr, "StoreReconciler", func() client.Object {
return &corev1alpha1.Store{}
Expand All @@ -50,7 +52,7 @@ func NewStoreReconciler(ctx context.Context, log *logger.Logger, fga openfgav1.O
subroutine.NewAuthorizationModelSubroutine(fga, mcMgr, allClient, func(cfg *rest.Config) discovery.DiscoveryInterface {
return discovery.NewDiscoveryClientForConfigOrDie(cfg)
}, log),
subroutine.NewTupleSubroutine(fga, mcMgr),
subroutine.NewTupleSubroutine(fga, mcMgr, kcpClientHelper),
).WithConditions(conditions.NewManager())

return &StoreReconciler{
Expand All @@ -69,7 +71,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 string, _ cluster.Cluster) bool {
return strings.HasPrefix(clusterName, config.SystemProviderName)
}),
).
WithOptions(controller.TypedOptions[mcreconcile.Request]{MaxConcurrentReconciles: cfg.MaxConcurrentReconciles}).
WithEventFilter(predicate.And(predicates...))

Expand All @@ -82,6 +88,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 := multiProviderName(config.SystemProviderName, model.Spec.StoreRef.Cluster)

return []mcreconcile.Request{
{
Expand All @@ -90,11 +99,20 @@ func (r *StoreReconciler) SetupWithManager(mgr mcmanager.Manager, cfg *platforme
Name: model.Spec.StoreRef.Name,
},
},
ClusterName: model.Spec.StoreRef.Cluster,
ClusterName: storeClusterName,
},
}
})
},
mcbuilder.WithPredicates(predicate.GenerationChangedPredicate{}),
mcbuilder.WithClusterFilter(func(clusterName string, _ cluster.Cluster) bool {
return strings.HasPrefix(clusterName, config.CoreProviderName)
}),
).Complete(r)
}

// multiProviderName returns a cluster name with provider prefix and separator for multi provider.
// The multi.Provider prefixes cluster names as "providerName#clusterName"
func multiProviderName(providerName, clusterName string) string {
return providerName + config.ProviderSeparator + clusterName
}
8 changes: 1 addition & 7 deletions internal/subroutine/authorization_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,6 @@ var _ subroutines.Processor = &authorizationModelSubroutine{}
func (a *authorizationModelSubroutine) GetName() string { return "AuthorizationModel" }

func getRelatedAuthorizationModels(ctx context.Context, k8s client.Client, store *securityv1alpha1.Store) (securityv1alpha1.AuthorizationModelList, error) {

storeClusterKey, ok := mccontext.ClusterFrom(ctx)
if !ok {
return securityv1alpha1.AuthorizationModelList{}, fmt.Errorf("unable to get cluster key from context")
}

allCtx := mccontext.WithCluster(ctx, "")
allAuthorizationModels := securityv1alpha1.AuthorizationModelList{}

Expand All @@ -110,7 +104,7 @@ func getRelatedAuthorizationModels(ctx context.Context, k8s client.Client, store

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

Expand Down
27 changes: 16 additions & 11 deletions internal/subroutine/tuples.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@ 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/fga"
"github.com/platform-mesh/subroutines"
"sigs.k8s.io/controller-runtime/pkg/client"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"

"k8s.io/apimachinery/pkg/types"

"github.com/kcp-dev/logicalcluster/v3"
)

type tupleSubroutine struct {
fga openfgav1.OpenFGAServiceClient
mgr mcmanager.Manager
fga openfgav1.OpenFGAServiceClient
mgr mcmanager.Manager
kcpHelper iclient.KcpClientHelper
}

// Finalize implements subroutines.Finalizer.
Expand All @@ -37,13 +41,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, o.Spec.StoreRef.Cluster)
cl, err := t.kcpHelper.NewClientForLogicalCluster(logicalcluster.Name(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 = cl.Get(ctx, types.NamespacedName{
Name: o.Spec.StoreRef.Name,
}, &store)
if err != nil {
Expand Down Expand Up @@ -97,13 +101,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, o.Spec.StoreRef.Cluster)
cl, err := t.kcpHelper.NewClientForLogicalCluster(logicalcluster.Name(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 = cl.Get(ctx, types.NamespacedName{
Name: o.Spec.StoreRef.Name,
}, &store)
if err != nil {
Expand Down Expand Up @@ -141,10 +145,11 @@ 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, mgr mcmanager.Manager, kcpHelper iclient.KcpClientHelper) *tupleSubroutine {
return &tupleSubroutine{
fga: fga,
mgr: mgr,
fga: fga,
mgr: mgr,
kcpHelper: kcpHelper,
}
}

Expand Down
Loading
Loading