From adcb37c0b01d8387a2bf8dc42c7bae2564331633 Mon Sep 17 00:00:00 2001 From: Carl Henrik Lunde Date: Thu, 27 Nov 2025 08:31:48 +0100 Subject: [PATCH] Add safe-start capability This allows cluster operators to disable namespaced or clusterwide resources, and disable database types that they do not require. * Providers create ManagedResourceDefinitions but CRDs only when activated * Users activate only needed resources through ManagedResourceActivationPolicies * Significant reduction in cluster resource overhead https://docs.crossplane.io/latest/guides/implementing-safe-start/ Signed-off-by: Carl Henrik Lunde --- cluster/local/integration_tests.sh | 54 ++++++++++++++++++- cmd/provider/main.go | 53 +++++++++++++++++- .../activation-policy-no-cluster-mssql.yaml | 14 +++++ go.mod | 2 +- package/crossplane.yaml | 3 ++ pkg/controller/cluster/mssql/config/config.go | 6 +++ .../cluster/mssql/database/reconciler.go | 11 ++++ .../cluster/mssql/grant/reconciler.go | 11 ++++ pkg/controller/cluster/mssql/mssql.go | 22 ++++++-- .../cluster/mssql/user/reconciler.go | 11 ++++ pkg/controller/cluster/mysql/config/config.go | 6 +++ .../cluster/mysql/database/reconciler.go | 11 ++++ .../cluster/mysql/grant/reconciler.go | 11 ++++ pkg/controller/cluster/mysql/mysql.go | 22 ++++++-- .../cluster/mysql/user/reconciler.go | 11 ++++ .../cluster/postgresql/config/config.go | 6 +++ .../cluster/postgresql/database/reconciler.go | 11 ++++ .../default_privileges/reconciler.go | 13 ++++- .../postgresql/extension/reconciler.go | 11 ++++ .../cluster/postgresql/grant/reconciler.go | 11 ++++ .../cluster/postgresql/postgresql.go | 29 ++++++++-- .../cluster/postgresql/role/reconciler.go | 11 ++++ .../cluster/postgresql/schema/reconciler.go | 11 ++++ .../namespaced/mssql/config/config.go | 6 +++ .../namespaced/mssql/database/reconciler.go | 11 ++++ .../namespaced/mssql/grant/reconciler.go | 11 ++++ pkg/controller/namespaced/mssql/mssql.go | 22 ++++++-- .../namespaced/mssql/user/reconciler.go | 11 ++++ .../namespaced/mysql/config/config.go | 6 +++ .../namespaced/mysql/database/reconciler.go | 11 ++++ .../namespaced/mysql/grant/reconciler.go | 11 ++++ pkg/controller/namespaced/mysql/mysql.go | 22 ++++++-- .../namespaced/mysql/user/reconciler.go | 11 ++++ .../namespaced/postgresql/config/config.go | 6 +++ .../postgresql/database/reconciler.go | 11 ++++ .../default_privileges/reconciler.go | 13 ++++- .../postgresql/extension/reconciler.go | 11 ++++ .../namespaced/postgresql/grant/reconciler.go | 11 ++++ .../namespaced/postgresql/postgresql.go | 29 ++++++++-- .../namespaced/postgresql/role/reconciler.go | 11 ++++ .../postgresql/schema/reconciler.go | 11 ++++ pkg/controller/sql.go | 24 +++++++-- 42 files changed, 570 insertions(+), 30 deletions(-) create mode 100644 examples/activation-policy-no-cluster-mssql.yaml diff --git a/cluster/local/integration_tests.sh b/cluster/local/integration_tests.sh index 86bd536a..78a2afc2 100755 --- a/cluster/local/integration_tests.sh +++ b/cluster/local/integration_tests.sh @@ -178,12 +178,17 @@ setup_crossplane() { echo # we replace empty dir with our PVC so that the /cache dir in the kind node # container is exposed to the crossplane pod - "${HELM}" install crossplane --namespace crossplane-system crossplane-stable/crossplane --version ${chart_version} --wait --set packageCache.pvc=package-cache + # Disable the default ManagedResourceActivationPolicy that activates all resources, + # so we can test safe-start with selective activation policies. + "${HELM}" install crossplane --namespace crossplane-system crossplane-stable/crossplane --version ${chart_version} --wait --set packageCache.pvc=package-cache --set 'provider.defaultActivations={}' } setup_provider() { echo_step "installing provider" + echo_sub_step "applying ManagedResourceActivationPolicy to disable cluster-wide MSSQL" + "${KUBECTL}" apply -f "${projectdir}/examples/activation-policy-no-cluster-mssql.yaml" + local yaml="$( cat </dev/null; then + echo_error "cluster-wide MSSQL Database CRD should not be installed" + fi + if "${KUBECTL}" get crd grants.mssql.sql.crossplane.io 2>/dev/null; then + echo_error "cluster-wide MSSQL Grant CRD should not be installed" + fi + if "${KUBECTL}" get crd users.mssql.sql.crossplane.io 2>/dev/null; then + echo_error "cluster-wide MSSQL User CRD should not be installed" + fi + echo_step_completed + + echo_step "verifying namespaced MSSQL CRDs ARE installed" + "${KUBECTL}" get crd databases.mssql.sql.m.crossplane.io || echo_error "namespaced MSSQL Database CRD should be installed" + "${KUBECTL}" get crd grants.mssql.sql.m.crossplane.io || echo_error "namespaced MSSQL Grant CRD should be installed" + "${KUBECTL}" get crd users.mssql.sql.m.crossplane.io || echo_error "namespaced MSSQL User CRD should be installed" + echo_step_completed } cleanup_provider() { @@ -227,6 +250,8 @@ cleanup_provider() { "${KUBECTL}" delete provider.pkg.crossplane.io "${PACKAGE_NAME}" "${KUBECTL}" delete deploymentruntimeconfig.pkg.crossplane.io debug-config + "${KUBECTL}" delete managedresourceactivationpolicy.apiextensions.crossplane.io disable-cluster-mssql --ignore-not-found=true + "${KUBECTL}" delete managedresourceactivationpolicy.apiextensions.crossplane.io enable-cluster-mssql --ignore-not-found=true echo_step "waiting for provider pods to be deleted" timeout=60 @@ -459,6 +484,33 @@ TLS=false API_TYPE="cluster" run_test integration_tests_postgres TLS=false API_TYPE="namespaced" run_test integration_tests_postgres # no TLS=false variant - MSSQL uses built-in encryption +# Enable cluster-wide MSSQL CRDs before running cluster MSSQL tests. +# The initial activation policy excludes them to test safe-start. +echo_step "creating activation policy to enable cluster-wide MSSQL" +"${KUBECTL}" apply -f - </dev/null; do + echo "waiting another $step seconds for MSSQL CRDs..." + current=$((current + step)) + if [[ $current -ge $timeout ]]; then + echo_error "timeout of ${timeout}s waiting for MSSQL CRDs" + fi + sleep $step +done +echo_step_completed + TLS=true API_TYPE="cluster" run_test integration_tests_mssql TLS=true API_TYPE="namespaced" run_test integration_tests_mssql diff --git a/cmd/provider/main.go b/cmd/provider/main.go index b01c0848..b0868ccb 100644 --- a/cmd/provider/main.go +++ b/cmd/provider/main.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "context" "os" "path/filepath" @@ -25,19 +26,51 @@ import ( _ "github.com/lib/pq" "github.com/alecthomas/kingpin/v2" + authv1 "k8s.io/api/authorization/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log/zap" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" "github.com/crossplane/crossplane-runtime/v2/pkg/feature" + "github.com/crossplane/crossplane-runtime/v2/pkg/gate" "github.com/crossplane/crossplane-runtime/v2/pkg/logging" "github.com/crossplane/crossplane-runtime/v2/pkg/ratelimiter" + "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/customresourcesgate" "github.com/crossplane-contrib/provider-sql/apis" "github.com/crossplane-contrib/provider-sql/pkg/controller" ) +// canWatchCRD checks if the provider has the necessary RBAC permissions to watch CustomResourceDefinitions. +// This is used to determine if we can use the SafeStart pattern with gated controller initialization. +func canWatchCRD(ctx context.Context, c client.Client) (bool, error) { + for _, verb := range []string{"get", "list", "watch"} { + review := &authv1.SelfSubjectAccessReview{ + Spec: authv1.SelfSubjectAccessReviewSpec{ + ResourceAttributes: &authv1.ResourceAttributes{ + Group: apiextensionsv1.GroupName, + Resource: "customresourcedefinitions", + Verb: verb, + }, + }, + } + + if err := c.Create(ctx, review); err != nil { + return false, err + } + + if !review.Status.Allowed { + return false, nil + } + } + + return true, nil +} + func main() { var ( app = kingpin.New(filepath.Base(os.Args[0]), "SQL support for Crossplane.").DefaultEnvars() @@ -73,6 +106,7 @@ func main() { }) kingpin.FatalIfError(err, "Cannot create controller manager") kingpin.FatalIfError(apis.AddToScheme(mgr.GetScheme()), "Cannot add SQL APIs to scheme") + kingpin.FatalIfError(apiextensionsv1.AddToScheme(mgr.GetScheme()), "Cannot add CRD types to scheme") o := xpcontroller.Options{ Logger: log, @@ -86,6 +120,23 @@ func main() { log.Info("Beta feature enabled", "flag", feature.EnableBetaManagementPolicies) } - kingpin.FatalIfError(controller.Setup(mgr, o), "Cannot setup SQL controllers") + // Check if we have permission to watch CRDs for SafeStart support + ctx := context.Background() + canWatch, err := canWatchCRD(ctx, mgr.GetClient()) + switch { + case err != nil: + log.Info("Failed to check CRD watch permissions, using immediate controller setup", "error", err) + kingpin.FatalIfError(controller.Setup(mgr, o), "Cannot setup SQL controllers") + case canWatch: + log.Info("SafeStart enabled: using gated controller initialization") + o.Gate = new(gate.Gate[schema.GroupVersionKind]) + + kingpin.FatalIfError(customresourcesgate.Setup(mgr, o), "Cannot setup CRD gate") + kingpin.FatalIfError(controller.SetupGated(mgr, o), "Cannot setup SQL controllers") + default: + log.Info("SafeStart disabled: insufficient CRD watch permissions, using immediate controller setup") + kingpin.FatalIfError(controller.Setup(mgr, o), "Cannot setup SQL controllers") + } + kingpin.FatalIfError(mgr.Start(ctrl.SetupSignalHandler()), "Cannot start controller manager") } diff --git a/examples/activation-policy-no-cluster-mssql.yaml b/examples/activation-policy-no-cluster-mssql.yaml new file mode 100644 index 00000000..cebcbfa0 --- /dev/null +++ b/examples/activation-policy-no-cluster-mssql.yaml @@ -0,0 +1,14 @@ +apiVersion: apiextensions.crossplane.io/v1alpha1 +kind: ManagedResourceActivationPolicy +metadata: + name: disable-cluster-mssql +spec: + activate: + # Activate all MySQL resources (both cluster and namespaced) + - "*.mysql.sql.crossplane.io" + - "*.mysql.sql.m.crossplane.io" + # Activate all PostgreSQL resources (both cluster and namespaced) + - "*.postgresql.sql.crossplane.io" + - "*.postgresql.sql.m.crossplane.io" + # Activate only namespaced MSSQL resources (cluster-wide MSSQL is excluded) + - "*.mssql.sql.m.crossplane.io" diff --git a/go.mod b/go.mod index 84a43435..a05b2bab 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/lib/pq v1.11.2 github.com/pkg/errors v0.9.1 k8s.io/api v0.34.0 + k8s.io/apiextensions-apiserver v0.34.0 k8s.io/apimachinery v0.34.0 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 sigs.k8s.io/controller-runtime v0.22.0 @@ -100,7 +101,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.34.0 // indirect k8s.io/client-go v0.34.0 // indirect k8s.io/code-generator v0.34.0 // indirect k8s.io/component-base v0.34.0 // indirect diff --git a/package/crossplane.yaml b/package/crossplane.yaml index 09c0fd9a..99100ed2 100644 --- a/package/crossplane.yaml +++ b/package/crossplane.yaml @@ -30,3 +30,6 @@ metadata: friendly-kind-name.meta.crossplane.io/role.postgresql.sql.crossplane.io: Role friendly-kind-name.meta.crossplane.io/user.mysql.sql.crossplane.io: User friendly-kind-name.meta.crossplane.io/defaultprivileges.postgresql.sql.crossplane.io: DefaultPrivileges +spec: + capabilities: + - safe-start diff --git a/pkg/controller/cluster/mssql/config/config.go b/pkg/controller/cluster/mssql/config/config.go index fb3e12d1..3c472bec 100644 --- a/pkg/controller/cluster/mssql/config/config.go +++ b/pkg/controller/cluster/mssql/config/config.go @@ -46,3 +46,9 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { providerconfig.WithLogger(o.Logger.WithValues("controller", name)), providerconfig.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))))) } + +// SetupGated adds a controller that reconciles ProviderConfigs. +// ProviderConfig resources are always available, so this is equivalent to Setup. +func SetupGated(mgr ctrl.Manager, o controller.Options) error { + return Setup(mgr, o) +} diff --git a/pkg/controller/cluster/mssql/database/reconciler.go b/pkg/controller/cluster/mssql/database/reconciler.go index c81a76aa..08482b57 100644 --- a/pkg/controller/cluster/mssql/database/reconciler.go +++ b/pkg/controller/cluster/mssql/database/reconciler.go @@ -83,6 +83,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Database managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", clusterv1alpha1.DatabaseGroupVersionKind) + } + }, clusterv1alpha1.DatabaseGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/mssql/grant/reconciler.go b/pkg/controller/cluster/mssql/grant/reconciler.go index 8f327bdc..445becd4 100644 --- a/pkg/controller/cluster/mssql/grant/reconciler.go +++ b/pkg/controller/cluster/mssql/grant/reconciler.go @@ -84,6 +84,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Grant managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.GrantGroupVersionKind) + } + }, v1alpha1.GrantGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/mssql/mssql.go b/pkg/controller/cluster/mssql/mssql.go index 32a66d02..eaf15361 100644 --- a/pkg/controller/cluster/mssql/mssql.go +++ b/pkg/controller/cluster/mssql/mssql.go @@ -19,7 +19,7 @@ package mssql import ( ctrl "sigs.k8s.io/controller-runtime" - "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mssql/config" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mssql/database" @@ -29,8 +29,8 @@ import ( // Setup creates all MSSQL controllers with the supplied logger and adds // them to the supplied manager. -func Setup(mgr ctrl.Manager, o controller.Options) error { - for _, setup := range []func(ctrl.Manager, controller.Options) error{ +func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ config.Setup, database.Setup, user.Setup, @@ -42,3 +42,19 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { } return nil } + +// SetupGated creates all MSSQL controllers with gated initialization, +// waiting for their required CRDs to be available before starting. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ + config.SetupGated, + database.SetupGated, + user.SetupGated, + grant.SetupGated, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + return nil +} diff --git a/pkg/controller/cluster/mssql/user/reconciler.go b/pkg/controller/cluster/mssql/user/reconciler.go index 2d96d1ca..a67b6ba4 100644 --- a/pkg/controller/cluster/mssql/user/reconciler.go +++ b/pkg/controller/cluster/mssql/user/reconciler.go @@ -90,6 +90,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles User managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.UserGroupVersionKind) + } + }, v1alpha1.UserGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/mysql/config/config.go b/pkg/controller/cluster/mysql/config/config.go index d572dd67..cdc7f297 100644 --- a/pkg/controller/cluster/mysql/config/config.go +++ b/pkg/controller/cluster/mysql/config/config.go @@ -46,3 +46,9 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { providerconfig.WithLogger(o.Logger.WithValues("controller", name)), providerconfig.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))))) } + +// SetupGated adds a controller that reconciles ProviderConfigs. +// ProviderConfig resources are always available, so this is equivalent to Setup. +func SetupGated(mgr ctrl.Manager, o controller.Options) error { + return Setup(mgr, o) +} diff --git a/pkg/controller/cluster/mysql/database/reconciler.go b/pkg/controller/cluster/mysql/database/reconciler.go index dd006748..fa1d0b8a 100644 --- a/pkg/controller/cluster/mysql/database/reconciler.go +++ b/pkg/controller/cluster/mysql/database/reconciler.go @@ -83,6 +83,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Database managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.DatabaseGroupVersionKind) + } + }, v1alpha1.DatabaseGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/mysql/grant/reconciler.go b/pkg/controller/cluster/mysql/grant/reconciler.go index 4acb2cde..d7373448 100644 --- a/pkg/controller/cluster/mysql/grant/reconciler.go +++ b/pkg/controller/cluster/mysql/grant/reconciler.go @@ -92,6 +92,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Grant managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.GrantGroupVersionKind) + } + }, v1alpha1.GrantGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/mysql/mysql.go b/pkg/controller/cluster/mysql/mysql.go index 55b1b3f5..5fe29d1f 100644 --- a/pkg/controller/cluster/mysql/mysql.go +++ b/pkg/controller/cluster/mysql/mysql.go @@ -19,7 +19,7 @@ package mysql import ( ctrl "sigs.k8s.io/controller-runtime" - "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mysql/config" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mysql/database" @@ -29,8 +29,8 @@ import ( // Setup creates all MySQL controllers with the supplied logger and adds // them to the supplied manager. -func Setup(mgr ctrl.Manager, o controller.Options) error { - for _, setup := range []func(ctrl.Manager, controller.Options) error{ +func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ config.Setup, database.Setup, user.Setup, @@ -42,3 +42,19 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { } return nil } + +// SetupGated creates all MySQL controllers with gated initialization, +// waiting for their required CRDs to be available before starting. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ + config.SetupGated, + database.SetupGated, + user.SetupGated, + grant.SetupGated, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + return nil +} diff --git a/pkg/controller/cluster/mysql/user/reconciler.go b/pkg/controller/cluster/mysql/user/reconciler.go index dc65d910..441a26c8 100644 --- a/pkg/controller/cluster/mysql/user/reconciler.go +++ b/pkg/controller/cluster/mysql/user/reconciler.go @@ -87,6 +87,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles User managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.UserGroupVersionKind) + } + }, v1alpha1.UserGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/postgresql/config/config.go b/pkg/controller/cluster/postgresql/config/config.go index 67534029..f25d5c39 100644 --- a/pkg/controller/cluster/postgresql/config/config.go +++ b/pkg/controller/cluster/postgresql/config/config.go @@ -46,3 +46,9 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { providerconfig.WithLogger(o.Logger.WithValues("controller", name)), providerconfig.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))))) } + +// SetupGated adds a controller that reconciles ProviderConfigs. +// ProviderConfig resources are always available, so this is equivalent to Setup. +func SetupGated(mgr ctrl.Manager, o controller.Options) error { + return Setup(mgr, o) +} diff --git a/pkg/controller/cluster/postgresql/database/reconciler.go b/pkg/controller/cluster/postgresql/database/reconciler.go index aa11ff00..0a0944e6 100644 --- a/pkg/controller/cluster/postgresql/database/reconciler.go +++ b/pkg/controller/cluster/postgresql/database/reconciler.go @@ -89,6 +89,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Database managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.DatabaseGroupVersionKind) + } + }, v1alpha1.DatabaseGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/postgresql/default_privileges/reconciler.go b/pkg/controller/cluster/postgresql/default_privileges/reconciler.go index 6581e1d0..af20cd3c 100644 --- a/pkg/controller/cluster/postgresql/default_privileges/reconciler.go +++ b/pkg/controller/cluster/postgresql/default_privileges/reconciler.go @@ -59,7 +59,18 @@ const ( maxConcurrency = 5 ) -// Setup adds a controller that reconciles Grant managed resources. +// SetupGated adds a controller that reconciles DefaultPrivileges managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.DefaultPrivilegesGroupVersionKind) + } + }, v1alpha1.DefaultPrivilegesGroupVersionKind) + return nil +} + +// Setup adds a controller that reconciles DefaultPrivileges managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { name := managed.ControllerName(v1alpha1.DefaultPrivilegesGroupKind) diff --git a/pkg/controller/cluster/postgresql/extension/reconciler.go b/pkg/controller/cluster/postgresql/extension/reconciler.go index c8a0b4e8..7387ef5e 100644 --- a/pkg/controller/cluster/postgresql/extension/reconciler.go +++ b/pkg/controller/cluster/postgresql/extension/reconciler.go @@ -81,6 +81,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Extension managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.ExtensionGroupVersionKind) + } + }, v1alpha1.ExtensionGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/postgresql/grant/reconciler.go b/pkg/controller/cluster/postgresql/grant/reconciler.go index 044fe4be..a2f80657 100644 --- a/pkg/controller/cluster/postgresql/grant/reconciler.go +++ b/pkg/controller/cluster/postgresql/grant/reconciler.go @@ -90,6 +90,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Grant managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.GrantGroupVersionKind) + } + }, v1alpha1.GrantGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/postgresql/postgresql.go b/pkg/controller/cluster/postgresql/postgresql.go index f5759560..0dc46a40 100644 --- a/pkg/controller/cluster/postgresql/postgresql.go +++ b/pkg/controller/cluster/postgresql/postgresql.go @@ -19,7 +19,7 @@ package postgresql import ( ctrl "sigs.k8s.io/controller-runtime" - "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/postgresql/config" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/postgresql/database" @@ -27,19 +27,19 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/postgresql/extension" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/postgresql/grant" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/postgresql/role" - "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/postgresql/schema" + schemacontroller "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/postgresql/schema" ) // Setup creates all PostgreSQL controllers with the supplied logger and adds // them to the supplied manager. -func Setup(mgr ctrl.Manager, o controller.Options) error { - for _, setup := range []func(ctrl.Manager, controller.Options) error{ +func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ config.Setup, database.Setup, role.Setup, grant.Setup, extension.Setup, - schema.Setup, + schemacontroller.Setup, default_privileges.Setup, } { if err := setup(mgr, o); err != nil { @@ -48,3 +48,22 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { } return nil } + +// SetupGated creates all PostgreSQL controllers with gated initialization, +// waiting for their required CRDs to be available before starting. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ + config.SetupGated, + database.SetupGated, + role.SetupGated, + grant.SetupGated, + extension.SetupGated, + schemacontroller.SetupGated, + default_privileges.SetupGated, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + return nil +} diff --git a/pkg/controller/cluster/postgresql/role/reconciler.go b/pkg/controller/cluster/postgresql/role/reconciler.go index d0adb591..c9845a96 100644 --- a/pkg/controller/cluster/postgresql/role/reconciler.go +++ b/pkg/controller/cluster/postgresql/role/reconciler.go @@ -91,6 +91,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Role managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.RoleGroupVersionKind) + } + }, v1alpha1.RoleGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.LegacyManaged) error diff --git a/pkg/controller/cluster/postgresql/schema/reconciler.go b/pkg/controller/cluster/postgresql/schema/reconciler.go index 7563cefc..221f1170 100644 --- a/pkg/controller/cluster/postgresql/schema/reconciler.go +++ b/pkg/controller/cluster/postgresql/schema/reconciler.go @@ -84,6 +84,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Schema managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.SchemaGroupVersionKind) + } + }, v1alpha1.SchemaGroupVersionKind) + return nil +} + var _ managed.TypedExternalConnector[*v1alpha1.Schema] = &connector{} type connector struct { diff --git a/pkg/controller/namespaced/mssql/config/config.go b/pkg/controller/namespaced/mssql/config/config.go index 772686c1..f6241f58 100644 --- a/pkg/controller/namespaced/mssql/config/config.go +++ b/pkg/controller/namespaced/mssql/config/config.go @@ -46,3 +46,9 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { providerconfig.WithLogger(o.Logger.WithValues("controller", name)), providerconfig.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))))) } + +// SetupGated adds a controller that reconciles ProviderConfigs. +// ProviderConfig resources are always available, so this is equivalent to Setup. +func SetupGated(mgr ctrl.Manager, o controller.Options) error { + return Setup(mgr, o) +} diff --git a/pkg/controller/namespaced/mssql/database/reconciler.go b/pkg/controller/namespaced/mssql/database/reconciler.go index 2da20c35..cbe72f86 100644 --- a/pkg/controller/namespaced/mssql/database/reconciler.go +++ b/pkg/controller/namespaced/mssql/database/reconciler.go @@ -77,6 +77,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Database managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.DatabaseGroupVersionKind) + } + }, namespacedv1alpha1.DatabaseGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/mssql/grant/reconciler.go b/pkg/controller/namespaced/mssql/grant/reconciler.go index 0ced15b7..1a9dba94 100644 --- a/pkg/controller/namespaced/mssql/grant/reconciler.go +++ b/pkg/controller/namespaced/mssql/grant/reconciler.go @@ -80,6 +80,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Grant managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.GrantGroupVersionKind) + } + }, namespacedv1alpha1.GrantGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/mssql/mssql.go b/pkg/controller/namespaced/mssql/mssql.go index 39d6706a..e20cd4cb 100644 --- a/pkg/controller/namespaced/mssql/mssql.go +++ b/pkg/controller/namespaced/mssql/mssql.go @@ -19,7 +19,7 @@ package mssql import ( ctrl "sigs.k8s.io/controller-runtime" - "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mssql/config" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mssql/database" @@ -29,8 +29,8 @@ import ( // Setup creates all MSSQL controllers with the supplied logger and adds // them to the supplied manager. -func Setup(mgr ctrl.Manager, o controller.Options) error { - for _, setup := range []func(ctrl.Manager, controller.Options) error{ +func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ config.Setup, database.Setup, user.Setup, @@ -42,3 +42,19 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { } return nil } + +// SetupGated creates all MSSQL controllers with gated initialization, +// waiting for their required CRDs to be available before starting. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ + config.SetupGated, + database.SetupGated, + user.SetupGated, + grant.SetupGated, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + return nil +} diff --git a/pkg/controller/namespaced/mssql/user/reconciler.go b/pkg/controller/namespaced/mssql/user/reconciler.go index 854ad1e7..bea04178 100644 --- a/pkg/controller/namespaced/mssql/user/reconciler.go +++ b/pkg/controller/namespaced/mssql/user/reconciler.go @@ -86,6 +86,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles User managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.UserGroupVersionKind) + } + }, namespacedv1alpha1.UserGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/mysql/config/config.go b/pkg/controller/namespaced/mysql/config/config.go index ac4bcaa1..56988bad 100644 --- a/pkg/controller/namespaced/mysql/config/config.go +++ b/pkg/controller/namespaced/mysql/config/config.go @@ -77,3 +77,9 @@ func setupClusterProviderConfig(mgr ctrl.Manager, o controller.Options) error { providerconfig.WithLogger(o.Logger.WithValues("controller", name)), providerconfig.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))))) } + +// SetupGated adds a controller that reconciles ProviderConfigs. +// ProviderConfig resources are always available, so this is equivalent to Setup. +func SetupGated(mgr ctrl.Manager, o controller.Options) error { + return Setup(mgr, o) +} diff --git a/pkg/controller/namespaced/mysql/database/reconciler.go b/pkg/controller/namespaced/mysql/database/reconciler.go index 1d5c36d2..d9343483 100644 --- a/pkg/controller/namespaced/mysql/database/reconciler.go +++ b/pkg/controller/namespaced/mysql/database/reconciler.go @@ -79,6 +79,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Database managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.DatabaseGroupVersionKind) + } + }, namespacedv1alpha1.DatabaseGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/mysql/grant/reconciler.go b/pkg/controller/namespaced/mysql/grant/reconciler.go index 61d156a8..62f59703 100644 --- a/pkg/controller/namespaced/mysql/grant/reconciler.go +++ b/pkg/controller/namespaced/mysql/grant/reconciler.go @@ -89,6 +89,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Grant managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.GrantGroupVersionKind) + } + }, namespacedv1alpha1.GrantGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/mysql/mysql.go b/pkg/controller/namespaced/mysql/mysql.go index 24fae805..be6e9c7b 100644 --- a/pkg/controller/namespaced/mysql/mysql.go +++ b/pkg/controller/namespaced/mysql/mysql.go @@ -19,7 +19,7 @@ package mysql import ( ctrl "sigs.k8s.io/controller-runtime" - "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/config" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/database" @@ -29,8 +29,8 @@ import ( // Setup creates all MySQL controllers with the supplied logger and adds // them to the supplied manager. -func Setup(mgr ctrl.Manager, o controller.Options) error { - for _, setup := range []func(ctrl.Manager, controller.Options) error{ +func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ config.Setup, database.Setup, user.Setup, @@ -42,3 +42,19 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { } return nil } + +// SetupGated creates all MySQL controllers with gated initialization, +// waiting for their required CRDs to be available before starting. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ + config.SetupGated, + database.SetupGated, + user.SetupGated, + grant.SetupGated, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + return nil +} diff --git a/pkg/controller/namespaced/mysql/user/reconciler.go b/pkg/controller/namespaced/mysql/user/reconciler.go index 7485c077..6f952de6 100644 --- a/pkg/controller/namespaced/mysql/user/reconciler.go +++ b/pkg/controller/namespaced/mysql/user/reconciler.go @@ -84,6 +84,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles User managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.UserGroupVersionKind) + } + }, namespacedv1alpha1.UserGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/postgresql/config/config.go b/pkg/controller/namespaced/postgresql/config/config.go index 9986547e..bf33c03d 100644 --- a/pkg/controller/namespaced/postgresql/config/config.go +++ b/pkg/controller/namespaced/postgresql/config/config.go @@ -46,3 +46,9 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { providerconfig.WithLogger(o.Logger.WithValues("controller", name)), providerconfig.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))))) } + +// SetupGated adds a controller that reconciles ProviderConfigs. +// ProviderConfig resources are always available, so this is equivalent to Setup. +func SetupGated(mgr ctrl.Manager, o controller.Options) error { + return Setup(mgr, o) +} diff --git a/pkg/controller/namespaced/postgresql/database/reconciler.go b/pkg/controller/namespaced/postgresql/database/reconciler.go index bb34a177..d984ab1d 100644 --- a/pkg/controller/namespaced/postgresql/database/reconciler.go +++ b/pkg/controller/namespaced/postgresql/database/reconciler.go @@ -86,6 +86,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Database managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.DatabaseGroupVersionKind) + } + }, namespacedv1alpha1.DatabaseGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go b/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go index 163c0635..2fac1ce2 100644 --- a/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go +++ b/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go @@ -59,7 +59,18 @@ const ( maxConcurrency = 5 ) -// Setup adds a controller that reconciles Grant managed resources. +// SetupGated adds a controller that reconciles DefaultPrivileges managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", v1alpha1.DefaultPrivilegesGroupVersionKind) + } + }, v1alpha1.DefaultPrivilegesGroupVersionKind) + return nil +} + +// Setup adds a controller that reconciles DefaultPrivileges managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { name := managed.ControllerName(v1alpha1.DefaultPrivilegesGroupKind) diff --git a/pkg/controller/namespaced/postgresql/extension/reconciler.go b/pkg/controller/namespaced/postgresql/extension/reconciler.go index 3411dbc6..8ef5518a 100644 --- a/pkg/controller/namespaced/postgresql/extension/reconciler.go +++ b/pkg/controller/namespaced/postgresql/extension/reconciler.go @@ -78,6 +78,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Extension managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.ExtensionGroupVersionKind) + } + }, namespacedv1alpha1.ExtensionGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/postgresql/grant/reconciler.go b/pkg/controller/namespaced/postgresql/grant/reconciler.go index 4684e77f..68135089 100644 --- a/pkg/controller/namespaced/postgresql/grant/reconciler.go +++ b/pkg/controller/namespaced/postgresql/grant/reconciler.go @@ -87,6 +87,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Grant managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.GrantGroupVersionKind) + } + }, namespacedv1alpha1.GrantGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/postgresql/postgresql.go b/pkg/controller/namespaced/postgresql/postgresql.go index beb952da..23a69a5c 100644 --- a/pkg/controller/namespaced/postgresql/postgresql.go +++ b/pkg/controller/namespaced/postgresql/postgresql.go @@ -19,7 +19,7 @@ package postgresql import ( ctrl "sigs.k8s.io/controller-runtime" - "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/config" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/database" @@ -27,19 +27,19 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/extension" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/grant" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/role" - "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/schema" + schemacontroller "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/schema" ) // Setup creates all PostgreSQL controllers with the supplied logger and adds // them to the supplied manager. -func Setup(mgr ctrl.Manager, o controller.Options) error { - for _, setup := range []func(ctrl.Manager, controller.Options) error{ +func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ config.Setup, database.Setup, role.Setup, grant.Setup, extension.Setup, - schema.Setup, + schemacontroller.Setup, default_privileges.Setup, } { if err := setup(mgr, o); err != nil { @@ -48,3 +48,22 @@ func Setup(mgr ctrl.Manager, o controller.Options) error { } return nil } + +// SetupGated creates all PostgreSQL controllers with gated initialization, +// waiting for their required CRDs to be available before starting. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ + config.SetupGated, + database.SetupGated, + role.SetupGated, + grant.SetupGated, + extension.SetupGated, + schemacontroller.SetupGated, + default_privileges.SetupGated, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + return nil +} diff --git a/pkg/controller/namespaced/postgresql/role/reconciler.go b/pkg/controller/namespaced/postgresql/role/reconciler.go index 3831eb37..eaf3eb25 100644 --- a/pkg/controller/namespaced/postgresql/role/reconciler.go +++ b/pkg/controller/namespaced/postgresql/role/reconciler.go @@ -88,6 +88,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Role managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.RoleGroupVersionKind) + } + }, namespacedv1alpha1.RoleGroupVersionKind) + return nil +} + type connector struct { kube client.Client track func(ctx context.Context, mg resource.ModernManaged) error diff --git a/pkg/controller/namespaced/postgresql/schema/reconciler.go b/pkg/controller/namespaced/postgresql/schema/reconciler.go index 9118c1c9..d281fe0e 100644 --- a/pkg/controller/namespaced/postgresql/schema/reconciler.go +++ b/pkg/controller/namespaced/postgresql/schema/reconciler.go @@ -81,6 +81,17 @@ func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { Complete(r) } +// SetupGated adds a controller that reconciles Schema managed resources +// with gated initialization, waiting for the resource's CRD to be available. +func SetupGated(mgr ctrl.Manager, o xpcontroller.Options) error { + o.Gate.Register(func() { + if err := Setup(mgr, o); err != nil { + mgr.GetLogger().Error(err, "unable to setup controller", "gvk", namespacedv1alpha1.SchemaGroupVersionKind) + } + }, namespacedv1alpha1.SchemaGroupVersionKind) + return nil +} + var _ managed.TypedExternalConnector[*namespacedv1alpha1.Schema] = &connector{} type connector struct { diff --git a/pkg/controller/sql.go b/pkg/controller/sql.go index 2f4c7d51..7328ee14 100644 --- a/pkg/controller/sql.go +++ b/pkg/controller/sql.go @@ -19,7 +19,7 @@ package controller import ( ctrl "sigs.k8s.io/controller-runtime" - "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" clustermssql "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mssql" clustermysql "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mysql" @@ -31,8 +31,8 @@ import ( // Setup creates all controllers with the supplied logger and adds // them to the supplied manager. -func Setup(mgr ctrl.Manager, l controller.Options) error { - for _, setup := range []func(ctrl.Manager, controller.Options) error{ +func Setup(mgr ctrl.Manager, l xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ clustermssql.Setup, clustermysql.Setup, clusterpostgresql.Setup, @@ -46,3 +46,21 @@ func Setup(mgr ctrl.Manager, l controller.Options) error { } return nil } + +// SetupGated creates all controllers with gated initialization, waiting for +// their required CRDs to be available before starting. +func SetupGated(mgr ctrl.Manager, l xpcontroller.Options) error { + for _, setup := range []func(ctrl.Manager, xpcontroller.Options) error{ + clustermssql.SetupGated, + clustermysql.SetupGated, + clusterpostgresql.SetupGated, + namespacedmssql.SetupGated, + namespacedmysql.SetupGated, + namespacedpostgresql.SetupGated, + } { + if err := setup(mgr, l); err != nil { + return err + } + } + return nil +}