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
8 changes: 4 additions & 4 deletions cmd/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ func RunController(_ *cobra.Command, _ []string) { // coverage-ignore
log.Fatal().Err(err).Msg("unable to create orgs client")
}

accountReconciler := controller.NewAccountReconciler(log, mgr, operatorCfg, orgsClient)
if err := accountReconciler.SetupWithManager(mgr, defaultCfg, log); err != nil {
accountReconciler := controller.NewAccountReconciler(mgr, operatorCfg, orgsClient)
if err := accountReconciler.SetupWithManager(mgr); err != nil {
log.Fatal().Err(err).Str("controller", "Account").Msg("unable to create controller")
}

if operatorCfg.Controllers.AccountInfo.Enabled {
accountInfoReconciler := controller.NewAccountInfoReconciler(log, mgr, operatorCfg)
if err := accountInfoReconciler.SetupWithManager(mgr, defaultCfg, log); err != nil {
accountInfoReconciler := controller.NewAccountInfoReconciler(mgr, operatorCfg)
if err := accountInfoReconciler.SetupWithManager(mgr); err != nil {
log.Fatal().Err(err).Str("controller", "AccountInfo").Msg("unable to create controller")
}
}
Expand Down
12 changes: 3 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@ module github.com/platform-mesh/account-operator

go 1.25.7

replace (
k8s.io/api => k8s.io/api v0.35.2
k8s.io/apimachinery => k8s.io/apimachinery v0.35.2
k8s.io/client-go => k8s.io/client-go v0.35.2
)
replace github.com/platform-mesh/subroutines => ../subroutines

require (
github.com/go-logr/logr v1.4.3
github.com/kcp-dev/logicalcluster/v3 v3.0.5
github.com/kcp-dev/multicluster-provider v0.5.1
github.com/kcp-dev/sdk v0.30.0
github.com/platform-mesh/golang-commons v0.13.2
github.com/platform-mesh/subroutines v0.0.0
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
Expand All @@ -29,7 +26,6 @@ require (
)

require (
github.com/99designs/gqlgen v0.17.87 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
Expand Down Expand Up @@ -64,16 +60,13 @@ require (
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/gomega v1.38.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rs/zerolog v1.34.0 // indirect
github.com/sosodev/duration v1.3.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/vektah/gqlparser/v2 v2.5.32 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel v1.41.0 // indirect
Expand All @@ -93,6 +86,7 @@ require (
golang.org/x/term v0.40.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.42.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect
Expand Down
12 changes: 0 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
github.com/99designs/gqlgen v0.17.87 h1:pSnCIMhBQezAE8bc1GNmfdLXFmnWtWl1GRDFEE/nHP8=
github.com/99designs/gqlgen v0.17.87/go.mod h1:fK05f1RqSNfQpd4CfW5qk/810Tqi4/56Wf6Nem0khAg=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM=
github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
Expand Down Expand Up @@ -151,10 +145,6 @@ github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4=
github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
Expand All @@ -167,8 +157,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/vektah/gqlparser/v2 v2.5.32 h1:k9QPJd4sEDTL+qB4ncPLflqTJ3MmjB9SrVzJrawpFSc=
github.com/vektah/gqlparser/v2 v2.5.32/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
Expand Down
52 changes: 28 additions & 24 deletions internal/controller/account_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ package controller
import (
"context"

platformmeshconfig "github.com/platform-mesh/golang-commons/config"
"github.com/platform-mesh/golang-commons/controller/lifecycle/builder"
mclifecycle "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"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
"github.com/platform-mesh/subroutines"
"github.com/platform-mesh/subroutines/conditions"
"github.com/platform-mesh/subroutines/lifecycle"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/predicate"
mccontext "sigs.k8s.io/multicluster-runtime/pkg/context"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
mcbuilder "sigs.k8s.io/multicluster-runtime/pkg/builder"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
mcreconcile "sigs.k8s.io/multicluster-runtime/pkg/reconcile"

"k8s.io/client-go/rest"

"github.com/platform-mesh/account-operator/api/v1alpha1"
"github.com/platform-mesh/account-operator/internal/config"
"github.com/platform-mesh/account-operator/pkg/subroutines/manageaccountinfo"
Expand All @@ -25,23 +23,20 @@ import (
"github.com/platform-mesh/account-operator/pkg/subroutines/workspacetype"
)

const (
operatorName = "account-operator"
accountReconcilerName = "AccountReconciler"
)
const accountReconcilerName = "AccountReconciler"

// AccountReconciler orchestrates Account resources across logical clusters.
type AccountReconciler struct {
cfg config.OperatorConfig
lifecycle *mclifecycle.LifecycleManager
lifecycle *lifecycle.Lifecycle
}

func NewAccountReconciler(log *logger.Logger, mgr mcmanager.Manager, cfg config.OperatorConfig, orgsClient client.Client) *AccountReconciler { // coverage-ignore
func NewAccountReconciler(mgr mcmanager.Manager, cfg config.OperatorConfig, orgsClient client.Client) *AccountReconciler { // coverage-ignore
localMgr := mgr.GetLocalManager()
localCfg := rest.CopyConfig(localMgr.GetConfig())
serverCA := string(localCfg.CAData)

subs := []lifecyclesubroutine.Subroutine{}
subs := []subroutines.Subroutine{}

if cfg.Subroutines.WorkspaceType.Enabled {
subs = append(subs, workspacetype.New(orgsClient))
Expand All @@ -59,18 +54,27 @@ func NewAccountReconciler(log *logger.Logger, mgr mcmanager.Manager, cfg config.
subs = append(subs, workspaceready.New(mgr))
}

lc := lifecycle.New(mgr, accountReconcilerName, func() client.Object { return &v1alpha1.Account{} }, subs...).
WithConditions(conditions.NewManager())

return &AccountReconciler{
cfg: cfg,
lifecycle: builder.NewBuilder(operatorName, accountReconcilerName, subs, log).
WithConditionManagement().
BuildMultiCluster(mgr),
cfg: cfg,
lifecycle: lc,
}
}

func (r *AccountReconciler) SetupWithManager(mgr mcmanager.Manager, cfg *platformmeshconfig.CommonServiceConfig, log *logger.Logger, eventPredicates ...predicate.Predicate) error { // coverage-ignore
return r.lifecycle.SetupWithManager(mgr, cfg.MaxConcurrentReconciles, accountReconcilerName, &v1alpha1.Account{}, cfg.DebugLabelValue, r, log, eventPredicates...)
func (r *AccountReconciler) SetupWithManager(mgr mcmanager.Manager, eventPredicates ...predicate.Predicate) error { // coverage-ignore
builder := mcbuilder.ControllerManagedBy(mgr).
Named(accountReconcilerName).
For(&v1alpha1.Account{})

for _, p := range eventPredicates {
builder = builder.WithEventFilter(p)
}

return builder.Complete(r)
}

func (r *AccountReconciler) Reconcile(ctx context.Context, req mcreconcile.Request) (ctrl.Result, error) { // coverage-ignore
return r.lifecycle.Reconcile(mccontext.WithCluster(ctx, req.ClusterName), req, &v1alpha1.Account{})
func (r *AccountReconciler) Reconcile(ctx context.Context, req mcreconcile.Request) (reconcile.Result, error) { // coverage-ignore
return r.lifecycle.Reconcile(ctx, req)
}
12 changes: 5 additions & 7 deletions internal/controller/account_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
ctrl "sigs.k8s.io/controller-runtime"

kcptenancyv1alpha "github.com/kcp-dev/sdk/apis/tenancy/v1alpha1"
platformmeshconfig "github.com/platform-mesh/golang-commons/config"
platformmeshcontext "github.com/platform-mesh/golang-commons/context"
"github.com/platform-mesh/golang-commons/logger"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -98,9 +97,8 @@ func (s *AccountTestSuite) SetupSuite() {
cfg.Subroutines.AccountInfo.Enabled = true
cfg.Subroutines.WorkspaceType.Enabled = true
cfg.Kcp.ProviderWorkspace = core.RootCluster.Path().String()
dCfg := &platformmeshconfig.CommonServiceConfig{}
accountReconciler := controller.NewAccountReconciler(logger, s.mgr, cfg, s.rootOrgsClient)
s.Require().NoError(accountReconciler.SetupWithManager(s.mgr, dCfg, logger))
accountReconciler := controller.NewAccountReconciler(s.mgr, cfg, s.rootOrgsClient)
s.Require().NoError(accountReconciler.SetupWithManager(s.mgr))
s.startManager()

s.setupDefaultOrg()
Expand Down Expand Up @@ -158,11 +156,11 @@ func (s *AccountTestSuite) TestWorkspaceCreation() {
if err := s.rootOrgsDefaultClient.Get(testContext, types.NamespacedName{Name: accountName}, updatedAccount); err != nil {
return false
}
return meta.IsStatusConditionTrue(updatedAccount.Status.Conditions, "WorkspaceSubroutine_Ready")
return meta.IsStatusConditionTrue(updatedAccount.Status.Conditions, "WorkspaceSubroutine")
}, defaultTestTimeout, defaultTickInterval)

s.verifyWorkspace(testContext, "default", accountName)
s.verifyCondition(updatedAccount.Status.Conditions, "WorkspaceSubroutine_Ready", metav1.ConditionTrue, "Complete")
s.verifyCondition(updatedAccount.Status.Conditions, "WorkspaceSubroutine", metav1.ConditionTrue, "Complete")
}

func (s *AccountTestSuite) TestAccountInfoCreationForOrganization() {
Expand All @@ -177,7 +175,7 @@ func (s *AccountTestSuite) TestAccountInfoCreationForOrganization() {
if err := s.rootOrgsClient.Get(testContext, types.NamespacedName{Name: accountName}, createdAccount); err != nil {
return false
}
return meta.IsStatusConditionTrue(createdAccount.Status.Conditions, "ManageAccountInfoSubroutine_Ready")
return meta.IsStatusConditionTrue(createdAccount.Status.Conditions, "ManageAccountInfoSubroutine")
}, defaultTestTimeout, defaultTickInterval)

accountInfo := &v1alpha1.AccountInfo{}
Expand Down
41 changes: 24 additions & 17 deletions internal/controller/accountinfo_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ package controller
import (
"context"

platformmeshconfig "github.com/platform-mesh/golang-commons/config"
"github.com/platform-mesh/golang-commons/controller/lifecycle/builder"
mclifecycle "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"
"github.com/platform-mesh/subroutines"
"github.com/platform-mesh/subroutines/lifecycle"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/predicate"
mccontext "sigs.k8s.io/multicluster-runtime/pkg/context"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
mcbuilder "sigs.k8s.io/multicluster-runtime/pkg/builder"
mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
mcreconcile "sigs.k8s.io/multicluster-runtime/pkg/reconcile"

Expand All @@ -24,27 +22,36 @@ const accountInfoReconcilerName = "AccountInfoReconciler"
// AccountInfoReconciler orchestrates AccountInfo resources across logical clusters.
type AccountInfoReconciler struct {
cfg config.OperatorConfig
lifecycle *mclifecycle.LifecycleManager
lifecycle *lifecycle.Lifecycle
}

func NewAccountInfoReconciler(log *logger.Logger, mgr mcmanager.Manager, cfg config.OperatorConfig) *AccountInfoReconciler { // coverage-ignore
subs := []lifecyclesubroutine.Subroutine{}
func NewAccountInfoReconciler(mgr mcmanager.Manager, cfg config.OperatorConfig) *AccountInfoReconciler { // coverage-ignore
subs := []subroutines.Subroutine{}

if cfg.Controllers.AccountInfo.Enabled {
subs = append(subs, finalizeaccountinfo.New(mgr))
}

lc := lifecycle.New(mgr, accountInfoReconcilerName, func() client.Object { return &v1alpha1.AccountInfo{} }, subs...)

return &AccountInfoReconciler{
cfg: cfg,
lifecycle: builder.NewBuilder(operatorName, accountInfoReconcilerName, subs, log).
BuildMultiCluster(mgr),
cfg: cfg,
lifecycle: lc,
}
}

func (r *AccountInfoReconciler) SetupWithManager(mgr mcmanager.Manager, cfg *platformmeshconfig.CommonServiceConfig, log *logger.Logger, eventPredicates ...predicate.Predicate) error { // coverage-ignore
return r.lifecycle.SetupWithManager(mgr, cfg.MaxConcurrentReconciles, accountInfoReconcilerName, &v1alpha1.AccountInfo{}, cfg.DebugLabelValue, r, log, eventPredicates...)
func (r *AccountInfoReconciler) SetupWithManager(mgr mcmanager.Manager, eventPredicates ...predicate.Predicate) error { // coverage-ignore
builder := mcbuilder.ControllerManagedBy(mgr).
Named(accountInfoReconcilerName).
For(&v1alpha1.AccountInfo{})

for _, p := range eventPredicates {
builder = builder.WithEventFilter(p)
}

return builder.Complete(r)
}

func (r *AccountInfoReconciler) Reconcile(ctx context.Context, req mcreconcile.Request) (ctrl.Result, error) { // coverage-ignore
return r.lifecycle.Reconcile(mccontext.WithCluster(ctx, req.ClusterName), req, &v1alpha1.AccountInfo{})
func (r *AccountInfoReconciler) Reconcile(ctx context.Context, req mcreconcile.Request) (reconcile.Result, error) { // coverage-ignore
return r.lifecycle.Reconcile(ctx, req)
}
7 changes: 4 additions & 3 deletions pkg/clusteredname/clusteredname.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import (
"context"

"github.com/kcp-dev/logicalcluster/v3"
"github.com/platform-mesh/golang-commons/controller/lifecycle/runtimeobject"
"sigs.k8s.io/controller-runtime/pkg/client"

"k8s.io/apimachinery/pkg/types"
mccontext "sigs.k8s.io/multicluster-runtime/pkg/context"
)
Expand All @@ -14,7 +15,7 @@ type ClusteredName struct {
ClusterID logicalcluster.Name
}

func GetClusteredName(ctx context.Context, instance runtimeobject.RuntimeObject) (ClusteredName, bool) {
func GetClusteredName(ctx context.Context, instance client.Object) (ClusteredName, bool) {
clusterName, ok := mccontext.ClusterFrom(ctx)
cn := ClusteredName{
NamespacedName: types.NamespacedName{
Expand All @@ -28,7 +29,7 @@ func GetClusteredName(ctx context.Context, instance runtimeobject.RuntimeObject)
return cn, ok
}

func MustGetClusteredName(ctx context.Context, instance runtimeobject.RuntimeObject) ClusteredName {
func MustGetClusteredName(ctx context.Context, instance client.Object) ClusteredName {
if cn, ok := GetClusteredName(ctx, instance); ok {
return cn
}
Expand Down
Loading