diff --git a/cluster/local/integration_tests.sh b/cluster/local/integration_tests.sh index 903eb896..da5b5b2d 100755 --- a/cluster/local/integration_tests.sh +++ b/cluster/local/integration_tests.sh @@ -110,17 +110,40 @@ setup_crossplane() { echo_info "using crossplane version ${chart_version}" echo + # Disable the default ManagedResourceActivationPolicy that activates all resources, + # so we can test safe-start with selective activation policies. "${HELM}" install crossplane --namespace crossplane-system --create-namespace \ crossplane-channel/crossplane \ - --version "${chart_version}" --wait + --version "${chart_version}" --wait --set 'provider.defaultActivations={}' } setup_provider() { + echo_sub_step "applying ManagedResourceActivationPolicy to disable cluster-wide MSSQL" + "${KUBECTL}" apply -f "${projectdir}/examples/activation-policy-no-cluster-mssql.yaml" + echo_step "deploying provider via local.xpkg.deploy" make -C "${projectdir}" local.xpkg.deploy.provider.${PACKAGE_NAME} KIND_CLUSTER_NAME="${K8S_CLUSTER}" echo_step "waiting for provider to be installed" "${KUBECTL}" wait "provider.pkg.crossplane.io/${PACKAGE_NAME}" --for=condition=healthy --timeout=60s + + echo_step "verifying cluster-wide MSSQL CRDs are NOT installed" + if "${KUBECTL}" get crd databases.mssql.sql.crossplane.io 2>/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() { @@ -128,6 +151,8 @@ cleanup_provider() { "${KUBECTL}" delete provider.pkg.crossplane.io "${PACKAGE_NAME}" "${KUBECTL}" delete deploymentruntimeconfig.pkg.crossplane.io runtimeconfig-${PACKAGE_NAME} + "${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 @@ -458,6 +483,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 b6c6266c..3408cd88 100644 --- a/cmd/provider/main.go +++ b/cmd/provider/main.go @@ -33,9 +33,13 @@ import ( 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/crossplane-runtime/v2/pkg/statemetrics" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "github.com/crossplane-contrib/provider-sql/apis" "github.com/crossplane-contrib/provider-sql/pkg/controller" @@ -81,6 +85,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 CustomResourceDefinition to scheme") mrStateMetrics := statemetrics.NewMRStateMetrics() metrics.Registry.MustRegister(mrStateMetrics) @@ -96,6 +101,7 @@ func main() { PollInterval: *pollInterval, GlobalRateLimiter: ratelimiter.NewGlobal(*maxReconcileRate), Features: &feature.Flags{}, + Gate: new(gate.Gate[schema.GroupVersionKind]), MetricOptions: &mo, } if *enableManagementPolicies { @@ -103,6 +109,7 @@ func main() { log.Info("Beta feature enabled", "flag", feature.EnableBetaManagementPolicies) } + kingpin.FatalIfError(customresourcesgate.Setup(mgr, o), "Cannot setup CRD gate controller") 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 f5047592..7bf9301f 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/microsoft/go-mssqldb v1.10.0 github.com/pkg/errors v0.9.1 k8s.io/api v0.35.0 + k8s.io/apiextensions-apiserver v0.35.0 k8s.io/apimachinery v0.35.0 k8s.io/utils v0.0.0-20260108192941-914a6e750570 sigs.k8s.io/controller-runtime v0.23.1 @@ -110,7 +111,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.35.0 // indirect k8s.io/client-go v0.35.0 // indirect k8s.io/code-generator v0.35.0 // indirect k8s.io/component-base v0.35.0 // indirect diff --git a/package/crossplane.yaml b/package/crossplane.yaml index 09c0fd9a..b82cf1de 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/database/reconciler.go b/pkg/controller/cluster/mssql/database/reconciler.go index bf28ad01..79e48379 100644 --- a/pkg/controller/cluster/mssql/database/reconciler.go +++ b/pkg/controller/cluster/mssql/database/reconciler.go @@ -19,18 +19,14 @@ package database import ( "context" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -38,6 +34,7 @@ import ( clusterv1alpha1 "github.com/crossplane-contrib/provider-sql/apis/cluster/mssql/v1alpha1" "github.com/crossplane-contrib/provider-sql/pkg/clients/mssql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -52,42 +49,21 @@ const ( errSelectDB = "cannot select database" errCreateDB = "cannot create database" errDropDB = "cannot drop database" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Database managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(clusterv1alpha1.DatabaseGroupKind) - t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &clusterv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newClient: mssql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(clusterv1alpha1.DatabaseGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &clusterv1alpha1.DatabaseList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&clusterv1alpha1.Database{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: clusterv1alpha1.DatabaseGroupVersionKind, + Resource: &clusterv1alpha1.Database{}, + List: &clusterv1alpha1.DatabaseList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newClient: mssql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/mssql/grant/reconciler.go b/pkg/controller/cluster/mssql/grant/reconciler.go index 7549077b..4d755523 100644 --- a/pkg/controller/cluster/mssql/grant/reconciler.go +++ b/pkg/controller/cluster/mssql/grant/reconciler.go @@ -22,25 +22,22 @@ import ( "sort" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" "github.com/crossplane-contrib/provider-sql/apis/cluster/mssql/v1alpha1" "github.com/crossplane-contrib/provider-sql/pkg/clients/mssql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -52,43 +49,24 @@ const ( errGrant = "cannot grant" errRevoke = "cannot revoke" errCannotGetGrants = "cannot get current grants" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Grant managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.GrantGroupKind) - t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newClient: mssql.New}), - managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.GrantGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.GrantList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Grant{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.GrantGroupVersionKind, + Resource: &v1alpha1.Grant{}, + List: &v1alpha1.GrantList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newClient: mssql.New, + }), + ExtraOpts: []managed.ReconcilerOption{ + managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), + }, + }) } type connector struct { diff --git a/pkg/controller/cluster/mssql/user/reconciler.go b/pkg/controller/cluster/mssql/user/reconciler.go index 5f766f73..c90091c2 100644 --- a/pkg/controller/cluster/mssql/user/reconciler.go +++ b/pkg/controller/cluster/mssql/user/reconciler.go @@ -20,19 +20,15 @@ import ( "context" "fmt" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/password" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" @@ -41,6 +37,7 @@ import ( "github.com/crossplane-contrib/provider-sql/apis/cluster/mssql/v1alpha1" "github.com/crossplane-contrib/provider-sql/pkg/clients/mssql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -59,42 +56,21 @@ const ( errUpdateUser = "cannot update user" errGetPasswordSecretFailed = "cannot get password secret" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles User managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.UserGroupKind) - t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newClient: mssql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.UserGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.UserList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.User{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.UserGroupVersionKind, + Resource: &v1alpha1.User{}, + List: &v1alpha1.UserList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newClient: mssql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/mysql/database/reconciler.go b/pkg/controller/cluster/mysql/database/reconciler.go index 86443b59..f9083bfc 100644 --- a/pkg/controller/cluster/mysql/database/reconciler.go +++ b/pkg/controller/cluster/mysql/database/reconciler.go @@ -19,18 +19,14 @@ package database import ( "context" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -39,6 +35,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/mysql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mysql/tls" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -52,43 +49,21 @@ const ( errCreateDB = "cannot create database" errDropDB = "cannot drop database" errUpdateDB = "cannot update database" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Database managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.DatabaseGroupKind) - t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: mysql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.DatabaseGroupVersionKind), - reconcilerOptions..., - ) - - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.DatabaseList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Database{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.DatabaseGroupVersionKind, + Resource: &v1alpha1.Database{}, + List: &v1alpha1.DatabaseList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: mysql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/mysql/grant/reconciler.go b/pkg/controller/cluster/mysql/grant/reconciler.go index 50546675..76935fc5 100644 --- a/pkg/controller/cluster/mysql/grant/reconciler.go +++ b/pkg/controller/cluster/mysql/grant/reconciler.go @@ -23,19 +23,15 @@ import ( "sort" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" mysqldriver "github.com/go-sql-driver/mysql" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -43,6 +39,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/mysql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mysql/tls" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -58,7 +55,6 @@ const ( allPrivileges = "ALL PRIVILEGES" errCodeNoSuchGrant = 1141 - maxConcurrency = 5 ) var ( @@ -67,36 +63,20 @@ var ( // Setup adds a controller that reconciles Grant managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.GrantGroupKind) t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: mysql.New}), - managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.GrantGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.GrantList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Grant{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.GrantGroupVersionKind, + Resource: &v1alpha1.Grant{}, + List: &v1alpha1.GrantList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: mysql.New, + }), + ExtraOpts: []managed.ReconcilerOption{ + managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), + }, + }) } type connector struct { diff --git a/pkg/controller/cluster/mysql/user/reconciler.go b/pkg/controller/cluster/mysql/user/reconciler.go index 3eba36a6..acca6042 100644 --- a/pkg/controller/cluster/mysql/user/reconciler.go +++ b/pkg/controller/cluster/mysql/user/reconciler.go @@ -21,18 +21,14 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/password" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" @@ -42,6 +38,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/mysql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/cluster/mysql/tls" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -57,41 +54,21 @@ const ( errUpdateUser = "cannot update user" errGetPasswordSecretFailed = "cannot get password secret" errCompareResourceOptions = "cannot compare desired and observed resource options" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles User managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.UserGroupKind) t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: mysql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.UserGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.UserList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.User{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.UserGroupVersionKind, + Resource: &v1alpha1.User{}, + List: &v1alpha1.UserList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: mysql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/postgresql/database/reconciler.go b/pkg/controller/cluster/postgresql/database/reconciler.go index 0bcafae5..1c748d1c 100644 --- a/pkg/controller/cluster/postgresql/database/reconciler.go +++ b/pkg/controller/cluster/postgresql/database/reconciler.go @@ -21,7 +21,6 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/lib/pq" @@ -30,12 +29,9 @@ import ( "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -44,6 +40,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients" "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -61,41 +58,22 @@ const ( errAlterDBIsTmpl = "cannot alter database is template" errDropDB = "cannot drop database" - maxConcurrency = 5 minDatabaseStrategyServerVersion = 150000 ) // Setup adds a controller that reconciles Database managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.DatabaseGroupKind) t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.DatabaseGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.DatabaseList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Database{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.DatabaseGroupVersionKind, + Resource: &v1alpha1.Database{}, + List: &v1alpha1.DatabaseList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/postgresql/default_privileges/reconciler.go b/pkg/controller/cluster/postgresql/default_privileges/reconciler.go index 13e3b34b..e47b2874 100644 --- a/pkg/controller/cluster/postgresql/default_privileges/reconciler.go +++ b/pkg/controller/cluster/postgresql/default_privileges/reconciler.go @@ -22,19 +22,15 @@ import ( "sort" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -42,6 +38,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients" "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -56,42 +53,21 @@ const ( errNoRole = "role not passed or could not be resolved" errNoTargetRole = "target role not passed or could not be resolved" errNoObjectType = "object type not passed" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Grant managed resources. +// Setup adds a controller that reconciles DefaultPrivileges managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.DefaultPrivilegesGroupKind) - t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.DefaultPrivilegesGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.DefaultPrivilegesList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.DefaultPrivileges{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.DefaultPrivilegesGroupVersionKind, + Resource: &v1alpha1.DefaultPrivileges{}, + List: &v1alpha1.DefaultPrivilegesList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/postgresql/extension/reconciler.go b/pkg/controller/cluster/postgresql/extension/reconciler.go index be93e002..10d72b7e 100644 --- a/pkg/controller/cluster/postgresql/extension/reconciler.go +++ b/pkg/controller/cluster/postgresql/extension/reconciler.go @@ -20,19 +20,15 @@ import ( "context" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -40,6 +36,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients" "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -51,41 +48,21 @@ const ( errSelectExtension = "cannot select extension" errCreateExtension = "cannot create extension" errDropExtension = "cannot drop extension" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Extension managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.ExtensionGroupKind) t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.ExtensionGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.ExtensionList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Extension{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.ExtensionGroupVersionKind, + Resource: &v1alpha1.Extension{}, + List: &v1alpha1.ExtensionList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/postgresql/grant/reconciler.go b/pkg/controller/cluster/postgresql/grant/reconciler.go index 81c716b1..ffd30bfe 100644 --- a/pkg/controller/cluster/postgresql/grant/reconciler.go +++ b/pkg/controller/cluster/postgresql/grant/reconciler.go @@ -21,19 +21,15 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/reference" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -42,6 +38,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients" "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -61,8 +58,6 @@ const ( errInvalidParams = "invalid parameters for grant type %s" errGetServerVersion = "cannot get server version" errMemberOfWithDatabaseOrPrivileges = "cannot set privileges or database in the same grant as memberOf" - - maxConcurrency = 5 ) type connector struct { @@ -959,35 +954,17 @@ func selectTableGrantQueryWithVersion(gp v1alpha1.GrantParameters, q *xsql.Query // Setup adds a controller that reconciles Grant managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.GrantGroupKind) t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.GrantGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.GrantList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Grant{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.GrantGroupVersionKind, + Resource: &v1alpha1.Grant{}, + List: &v1alpha1.GrantList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } func (c *external) Update(ctx context.Context, mg *v1alpha1.Grant) (managed.ExternalUpdate, error) { diff --git a/pkg/controller/cluster/postgresql/role/reconciler.go b/pkg/controller/cluster/postgresql/role/reconciler.go index ae88ba5d..31c6f6eb 100644 --- a/pkg/controller/cluster/postgresql/role/reconciler.go +++ b/pkg/controller/cluster/postgresql/role/reconciler.go @@ -24,19 +24,15 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/password" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" @@ -46,6 +42,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients" "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -61,41 +58,21 @@ const ( errGetPasswordSecretFailed = "cannot get password secret" errComparePrivileges = "cannot compare desired and observed privileges" errSetRoleConfigs = "cannot set role configuration parameters" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Role managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.RoleGroupKind) t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.RoleGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.RoleList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Role{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.RoleGroupVersionKind, + Resource: &v1alpha1.Role{}, + List: &v1alpha1.RoleList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/cluster/postgresql/schema/reconciler.go b/pkg/controller/cluster/postgresql/schema/reconciler.go index 6fd4e769..c3c8eae5 100644 --- a/pkg/controller/cluster/postgresql/schema/reconciler.go +++ b/pkg/controller/cluster/postgresql/schema/reconciler.go @@ -21,19 +21,15 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -42,6 +38,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients" "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -55,41 +52,21 @@ const ( errDropSchema = "cannot drop schema" errNoDatabase = "database must be specified" errAlterSchema = "cannot alter schema" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Schema managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.SchemaGroupKind) t := resource.NewLegacyProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.SchemaGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.SchemaList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Schema{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.SchemaGroupVersionKind, + Resource: &v1alpha1.Schema{}, + List: &v1alpha1.SchemaList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } var _ managed.TypedExternalConnector[*v1alpha1.Schema] = &connector{} diff --git a/pkg/controller/namespaced/mssql/database/reconciler.go b/pkg/controller/namespaced/mssql/database/reconciler.go index fcad40b7..23ebd193 100644 --- a/pkg/controller/namespaced/mssql/database/reconciler.go +++ b/pkg/controller/namespaced/mssql/database/reconciler.go @@ -19,16 +19,12 @@ package database import ( "context" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -37,6 +33,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/mssql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mssql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -46,42 +43,21 @@ const ( errSelectDB = "cannot select database" errCreateDB = "cannot create database" errDropDB = "cannot drop database" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Database managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.DatabaseGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newClient: mssql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.DatabaseGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.DatabaseList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Database{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.DatabaseGroupVersionKind, + Resource: &namespacedv1alpha1.Database{}, + List: &namespacedv1alpha1.DatabaseList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newClient: mssql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/mssql/grant/reconciler.go b/pkg/controller/namespaced/mssql/grant/reconciler.go index bba34f77..fe0e2596 100644 --- a/pkg/controller/namespaced/mssql/grant/reconciler.go +++ b/pkg/controller/namespaced/mssql/grant/reconciler.go @@ -22,17 +22,13 @@ import ( "sort" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -40,6 +36,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/mssql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mssql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -48,43 +45,24 @@ const ( errGrant = "cannot grant" errRevoke = "cannot revoke" errCannotGetGrants = "cannot get current grants" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Database managed resources. +// Setup adds a controller that reconciles Grant managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.GrantGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newClient: mssql.New}), - managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.GrantGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.GrantList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Grant{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.GrantGroupVersionKind, + Resource: &namespacedv1alpha1.Grant{}, + List: &namespacedv1alpha1.GrantList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newClient: mssql.New, + }), + ExtraOpts: []managed.ReconcilerOption{ + managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), + }, + }) } type connector struct { diff --git a/pkg/controller/namespaced/mssql/user/reconciler.go b/pkg/controller/namespaced/mssql/user/reconciler.go index 20f62de4..6f374c31 100644 --- a/pkg/controller/namespaced/mssql/user/reconciler.go +++ b/pkg/controller/namespaced/mssql/user/reconciler.go @@ -20,17 +20,13 @@ import ( "context" "fmt" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/password" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" @@ -40,6 +36,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/mssql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mssql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -55,42 +52,21 @@ const ( errUpdateUser = "cannot update user" errGetPasswordSecretFailed = "cannot get password secret" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Database managed resources. +// Setup adds a controller that reconciles User managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.UserGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newClient: mssql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.UserGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.UserList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.User{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.UserGroupVersionKind, + Resource: &namespacedv1alpha1.User{}, + List: &namespacedv1alpha1.UserList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newClient: mssql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/mysql/database/reconciler.go b/pkg/controller/namespaced/mysql/database/reconciler.go index 55d94991..e715c1b4 100644 --- a/pkg/controller/namespaced/mysql/database/reconciler.go +++ b/pkg/controller/namespaced/mysql/database/reconciler.go @@ -19,16 +19,12 @@ package database import ( "context" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -38,6 +34,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/provider" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/tls" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -48,43 +45,21 @@ const ( errCreateDB = "cannot create database" errDropDB = "cannot drop database" errUpdateDB = "cannot update database" - - maxConcurrency = 5 ) // Setup adds a controller that reconciles Database managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.DatabaseGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: mysql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.DatabaseGroupVersionKind), - reconcilerOptions..., - ) - - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.DatabaseList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Database{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.DatabaseGroupVersionKind, + Resource: &namespacedv1alpha1.Database{}, + List: &namespacedv1alpha1.DatabaseList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: mysql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/mysql/grant/reconciler.go b/pkg/controller/namespaced/mysql/grant/reconciler.go index fd431e85..98de1c0b 100644 --- a/pkg/controller/namespaced/mysql/grant/reconciler.go +++ b/pkg/controller/namespaced/mysql/grant/reconciler.go @@ -23,17 +23,13 @@ import ( "sort" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" mysqldriver "github.com/go-sql-driver/mysql" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -42,6 +38,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/provider" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/tls" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -54,46 +51,28 @@ const ( allPrivileges = "ALL PRIVILEGES" errCodeNoSuchGrant = 1141 - maxConcurrency = 5 ) var ( grantRegex = regexp.MustCompile(`^GRANT (.+) ON (\S+)\.(\S+) TO \S+@\S+?(\sWITH GRANT OPTION)?$`) ) -// Setup adds a controller that reconciles Database managed resources. +// Setup adds a controller that reconciles Grant managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.GrantGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: mysql.New}), - managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.GrantGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.GrantList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Grant{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.GrantGroupVersionKind, + Resource: &namespacedv1alpha1.Grant{}, + List: &namespacedv1alpha1.GrantList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: mysql.New, + }), + ExtraOpts: []managed.ReconcilerOption{ + managed.WithReferenceResolver(managed.NewAPISimpleReferenceResolver(mgr.GetClient())), + }, + }) } type connector struct { diff --git a/pkg/controller/namespaced/mysql/user/reconciler.go b/pkg/controller/namespaced/mysql/user/reconciler.go index de6f2189..d3c94efd 100644 --- a/pkg/controller/namespaced/mysql/user/reconciler.go +++ b/pkg/controller/namespaced/mysql/user/reconciler.go @@ -21,16 +21,12 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/password" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" @@ -41,6 +37,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/provider" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/mysql/tls" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -53,42 +50,21 @@ const ( errUpdateUser = "cannot update user" errGetPasswordSecretFailed = "cannot get password secret" errCompareResourceOptions = "cannot compare desired and observed resource options" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Database managed resources. +// Setup adds a controller that reconciles User managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.UserGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: mysql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.UserGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.UserList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.User{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.UserGroupVersionKind, + Resource: &namespacedv1alpha1.User{}, + List: &namespacedv1alpha1.UserList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: mysql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/postgresql/database/reconciler.go b/pkg/controller/namespaced/postgresql/database/reconciler.go index 534a9c63..00371984 100644 --- a/pkg/controller/namespaced/postgresql/database/reconciler.go +++ b/pkg/controller/namespaced/postgresql/database/reconciler.go @@ -21,19 +21,15 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/lib/pq" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -43,6 +39,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -57,42 +54,22 @@ const ( errAlterDBIsTmpl = "cannot alter database is template" errDropDB = "cannot drop database" - maxConcurrency = 5 minDatabaseStrategyServerVersion = 150000 ) // Setup adds a controller that reconciles Database managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.DatabaseGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.DatabaseGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.DatabaseList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Database{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.DatabaseGroupVersionKind, + Resource: &namespacedv1alpha1.Database{}, + List: &namespacedv1alpha1.DatabaseList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go b/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go index a9a29f93..8e5a2b14 100644 --- a/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go +++ b/pkg/controller/namespaced/postgresql/default_privileges/reconciler.go @@ -22,17 +22,13 @@ import ( "sort" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -41,6 +37,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -56,42 +53,21 @@ const ( errNoDatabase = "database not passed or could not be resolved" errNoPrivileges = "privileges not passed" errUnknownGrant = "cannot identify grant type based on passed params" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Grant managed resources. +// Setup adds a controller that reconciles DefaultPrivileges managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.DefaultPrivilegesGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.DefaultPrivilegesGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.DefaultPrivilegesList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.DefaultPrivileges{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.DefaultPrivilegesGroupVersionKind, + Resource: &v1alpha1.DefaultPrivileges{}, + List: &v1alpha1.DefaultPrivilegesList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/postgresql/extension/reconciler.go b/pkg/controller/namespaced/postgresql/extension/reconciler.go index 3cee5076..0b4afeb7 100644 --- a/pkg/controller/namespaced/postgresql/extension/reconciler.go +++ b/pkg/controller/namespaced/postgresql/extension/reconciler.go @@ -20,17 +20,13 @@ import ( "context" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -39,6 +35,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -47,42 +44,21 @@ const ( errSelectExtension = "cannot select extension" errCreateExtension = "cannot create extension" errDropExtension = "cannot drop extension" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Database managed resources. +// Setup adds a controller that reconciles Extension managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.ExtensionGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.ExtensionGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.ExtensionList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Extension{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.ExtensionGroupVersionKind, + Resource: &namespacedv1alpha1.Extension{}, + List: &namespacedv1alpha1.ExtensionList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/postgresql/grant/reconciler.go b/pkg/controller/namespaced/postgresql/grant/reconciler.go index b1908f22..eac381bf 100644 --- a/pkg/controller/namespaced/postgresql/grant/reconciler.go +++ b/pkg/controller/namespaced/postgresql/grant/reconciler.go @@ -21,17 +21,13 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -40,6 +36,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -56,8 +53,6 @@ const ( errInvalidParams = "invalid parameters for grant type %s" errGetServerVersion = "cannot get server version" errMemberOfWithDatabaseOrPrivileges = "cannot set privileges or database in the same grant as memberOf" - - maxConcurrency = 5 ) type connector struct { @@ -917,35 +912,17 @@ func selectTableGrantQueryWithVersion(gp v1alpha1.GrantParameters, q *xsql.Query // Setup adds a controller that reconciles Grant managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(v1alpha1.GrantGroupKind) t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &v1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(v1alpha1.GrantGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &v1alpha1.GrantList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&v1alpha1.Grant{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: v1alpha1.GrantGroupVersionKind, + Resource: &v1alpha1.Grant{}, + List: &v1alpha1.GrantList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } func (c *external) Update(ctx context.Context, mg *v1alpha1.Grant) (managed.ExternalUpdate, error) { diff --git a/pkg/controller/namespaced/postgresql/role/reconciler.go b/pkg/controller/namespaced/postgresql/role/reconciler.go index 95430342..ffcc6daa 100644 --- a/pkg/controller/namespaced/postgresql/role/reconciler.go +++ b/pkg/controller/namespaced/postgresql/role/reconciler.go @@ -24,17 +24,13 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/password" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" @@ -45,6 +41,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -57,42 +54,21 @@ const ( errGetPasswordSecretFailed = "cannot get password secret" errComparePrivileges = "cannot compare desired and observed privileges" errSetRoleConfigs = "cannot set role configuration parameters" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Database managed resources. +// Setup adds a controller that reconciles Role managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.RoleGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.RoleGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.RoleList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Role{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.RoleGroupVersionKind, + Resource: &namespacedv1alpha1.Role{}, + List: &namespacedv1alpha1.RoleList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } type connector struct { diff --git a/pkg/controller/namespaced/postgresql/schema/reconciler.go b/pkg/controller/namespaced/postgresql/schema/reconciler.go index 7d27dbfd..9c25f66f 100644 --- a/pkg/controller/namespaced/postgresql/schema/reconciler.go +++ b/pkg/controller/namespaced/postgresql/schema/reconciler.go @@ -21,17 +21,13 @@ import ( "fmt" "strings" - "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" "github.com/lib/pq" "github.com/pkg/errors" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/controller" xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" - "github.com/crossplane/crossplane-runtime/v2/pkg/event" - "github.com/crossplane/crossplane-runtime/v2/pkg/feature" "github.com/crossplane/crossplane-runtime/v2/pkg/meta" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/v2/pkg/resource" @@ -41,6 +37,7 @@ import ( "github.com/crossplane-contrib/provider-sql/pkg/clients/postgresql" "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/crossplane-contrib/provider-sql/pkg/controller/namespaced/postgresql/provider" + "github.com/crossplane-contrib/provider-sql/pkg/controller/setup" ) const ( @@ -51,42 +48,21 @@ const ( errDropSchema = "cannot drop schema" errNoDatabase = "database must be specified" errAlterSchema = "cannot alter schema" - - maxConcurrency = 5 ) -// Setup adds a controller that reconciles Database managed resources. +// Setup adds a controller that reconciles Schema managed resources. func Setup(mgr ctrl.Manager, o xpcontroller.Options) error { - name := managed.ControllerName(namespacedv1alpha1.SchemaGroupKind) - t := resource.NewProviderConfigUsageTracker(mgr.GetClient(), &namespacedv1alpha1.ProviderConfigUsage{}) - - reconcilerOptions := []managed.ReconcilerOption{ - managed.WithTypedExternalConnector(&connector{kube: mgr.GetClient(), track: t.Track, newDB: postgresql.New}), - managed.WithLogger(o.Logger.WithValues("controller", name)), - managed.WithPollInterval(o.PollInterval), - managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), - } - if o.Features.Enabled(feature.EnableBetaManagementPolicies) { - reconcilerOptions = append(reconcilerOptions, managed.WithManagementPolicies()) - } - r := managed.NewReconciler(mgr, - resource.ManagedKind(namespacedv1alpha1.SchemaGroupVersionKind), - reconcilerOptions..., - ) - if err := mgr.Add(statemetrics.NewMRStateRecorder( - mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, - &namespacedv1alpha1.SchemaList{}, o.MetricOptions.PollStateMetricInterval, - )); err != nil { - return err - } - return ctrl.NewControllerManagedBy(mgr). - Named(name). - For(&namespacedv1alpha1.Schema{}). - WithOptions(controller.Options{ - MaxConcurrentReconciles: maxConcurrency, - }). - Complete(r) + return setup.Setup(mgr, o, setup.ControllerConfig{ + GVK: namespacedv1alpha1.SchemaGroupVersionKind, + Resource: &namespacedv1alpha1.Schema{}, + List: &namespacedv1alpha1.SchemaList{}, + Connector: managed.WithTypedExternalConnector(&connector{ + kube: mgr.GetClient(), + track: t.Track, + newDB: postgresql.New, + }), + }) } var _ managed.TypedExternalConnector[*namespacedv1alpha1.Schema] = &connector{} diff --git a/pkg/controller/setup/setup.go b/pkg/controller/setup/setup.go new file mode 100644 index 00000000..82db5c7c --- /dev/null +++ b/pkg/controller/setup/setup.go @@ -0,0 +1,82 @@ +/* +Copyright 2025 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package setup + +import ( + "fmt" + + xpcontroller "github.com/crossplane/crossplane-runtime/v2/pkg/controller" + "github.com/crossplane/crossplane-runtime/v2/pkg/event" + "github.com/crossplane/crossplane-runtime/v2/pkg/feature" + "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" + "github.com/crossplane/crossplane-runtime/v2/pkg/resource" + "github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics" + "k8s.io/apimachinery/pkg/runtime/schema" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" +) + +const maxConcurrency = 5 + +// ControllerConfig holds the resource-specific parameters needed to set up a managed resource controller. +type ControllerConfig struct { + GVK schema.GroupVersionKind + Resource client.Object + List resource.ManagedList + Connector managed.ReconcilerOption + ExtraOpts []managed.ReconcilerOption +} + +// Setup registers a managed resource controller with safe-start support. +// The actual controller creation is deferred until the corresponding CRD becomes available. +func Setup(mgr ctrl.Manager, o xpcontroller.Options, cfg ControllerConfig) error { + o.Gate.Register(func() { + name := managed.ControllerName(cfg.GVK.GroupKind().String()) + + opts := []managed.ReconcilerOption{ + cfg.Connector, + managed.WithLogger(o.Logger.WithValues("controller", name)), + managed.WithPollInterval(o.PollInterval), + managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), + } + opts = append(opts, cfg.ExtraOpts...) + if o.Features.Enabled(feature.EnableBetaManagementPolicies) { + opts = append(opts, managed.WithManagementPolicies()) + } + + r := managed.NewReconciler(mgr, resource.ManagedKind(cfg.GVK), opts...) + + if err := mgr.Add(statemetrics.NewMRStateRecorder( + mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, + cfg.List, o.MetricOptions.PollStateMetricInterval, + )); err != nil { + panic(fmt.Errorf("cannot setup %s controller: %w", cfg.GVK.Kind, err)) + } + + if err := ctrl.NewControllerManagedBy(mgr). + Named(name). + For(cfg.Resource). + WithOptions(controller.Options{ + MaxConcurrentReconciles: maxConcurrency, + }). + Complete(r); err != nil { + panic(fmt.Errorf("cannot setup %s controller: %w", cfg.GVK.Kind, err)) + } + }, cfg.GVK) + return nil +}