diff --git a/cluster/local/integration_tests.sh b/cluster/local/integration_tests.sh index 48ea2b82..5c0b58c7 100755 --- a/cluster/local/integration_tests.sh +++ b/cluster/local/integration_tests.sh @@ -176,6 +176,12 @@ setup_crossplane() { 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" + + echo_sub_step "deleting default ManagedResourceActivationPolicy that activates everything" + "${KUBECTL}" delete managedresourceactivationpolicy default --ignore-not-found=true + 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() { @@ -219,6 +243,7 @@ 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 echo_step "waiting for provider pods to be deleted" timeout=60 diff --git a/cmd/provider/main.go b/cmd/provider/main.go index b01c0848..12a952f8 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,46 @@ 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) { + review := &authv1.SelfSubjectAccessReview{ + Spec: authv1.SelfSubjectAccessReviewSpec{ + ResourceAttributes: &authv1.ResourceAttributes{ + Group: apiextensionsv1.GroupName, + Version: "*", + Resource: "customresourcedefinitions", + Verb: "list", + }, + }, + } + + if err := c.Create(ctx, review); err != nil { + return false, err + } + + return review.Status.Allowed, nil +} + func main() { var ( app = kingpin.New(filepath.Base(os.Args[0]), "SQL support for Crossplane.").DefaultEnvars() @@ -73,6 +101,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 +115,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 a2089dab..3dc197ca 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.7 require ( github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/crossplane/crossplane-runtime/v2 v2.0.0 + github.com/crossplane/crossplane-runtime/v2 v2.1.0 github.com/crossplane/crossplane-tools v0.0.0-20250731192036-00d407d8b7ec github.com/crossplane/upjet/v2 v2.1.0 github.com/denisenkom/go-mssqldb v0.11.0 @@ -13,10 +13,11 @@ require ( github.com/google/go-cmp v0.7.0 github.com/lib/pq v1.10.9 github.com/pkg/errors v0.9.1 - k8s.io/api v0.33.0 - k8s.io/apimachinery v0.33.0 - k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e - sigs.k8s.io/controller-runtime v0.19.0 + 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 sigs.k8s.io/controller-tools v0.18.0 ) @@ -33,13 +34,13 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dave/jennifer v1.7.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch v5.9.11+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/fatih/color v1.18.0 // indirect - github.com/fsnotify/fsnotify v1.8.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect @@ -48,7 +49,8 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/gnostic-models v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl/v2 v2.23.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -59,8 +61,9 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.22.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect @@ -77,8 +80,9 @@ require ( go.opentelemetry.io/otel/trace v1.35.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.45.0 // indirect - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.29.0 // indirect golang.org/x/net v0.47.0 // indirect golang.org/x/oauth2 v0.29.0 // indirect @@ -90,22 +94,21 @@ require ( golang.org/x/tools v0.38.0 // indirect golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect google.golang.org/grpc v1.72.1 // indirect google.golang.org/protobuf v1.36.6 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect 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.33.0 // indirect - k8s.io/client-go v0.33.0 // indirect - k8s.io/code-generator v0.33.0 // indirect - k8s.io/component-base v0.33.0 // indirect - k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 // 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 + k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/go.sum b/go.sum index 589a1bef..7d8d403c 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/crossplane/crossplane-runtime/v2 v2.0.0 h1:PK2pTKfshdDZ5IfoiMRiCi0PBnIjqbS0KGXEJgRdrb4= -github.com/crossplane/crossplane-runtime/v2 v2.0.0/go.mod h1:pkd5UzmE8esaZAApevMutR832GjJ1Qgc5Ngr78ByxrI= +github.com/crossplane/crossplane-runtime/v2 v2.1.0 h1:JBMhL9T+/PfyjLAQEdZWlKLvA3jJVtza8zLLwd9Gs4k= +github.com/crossplane/crossplane-runtime/v2 v2.1.0/go.mod h1:j78pmk0qlI//Ur7zHhqTr8iePHFcwJKrZnzZB+Fg4t0= github.com/crossplane/crossplane-tools v0.0.0-20250731192036-00d407d8b7ec h1:+51Et4UW8XrvGne8RAqn9qEIfhoqPXYqIp/kQvpMaAo= github.com/crossplane/crossplane-tools v0.0.0-20250731192036-00d407d8b7ec/go.mod h1:8etxwmP4cZwJDwen4+PQlnc1tggltAhEfyyigmdHulQ= github.com/crossplane/upjet/v2 v2.1.0 h1:ua06MsexmTSLcih3gvOTGzGNV47TAa15GqMnjp/a85E= @@ -42,20 +42,20 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI= github.com/denisenkom/go-mssqldb v0.11.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= -github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8= github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= -github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= -github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -87,11 +87,12 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -141,16 +142,17 @@ github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTS github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -229,6 +231,10 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -236,8 +242,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= @@ -297,8 +301,8 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA= google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= @@ -318,36 +322,35 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= -k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= -k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= -k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= -k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= -k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= -k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= -k8s.io/code-generator v0.33.0 h1:B212FVl6EFqNmlgdOZYWNi77yBv+ed3QgQsMR8YQCw4= -k8s.io/code-generator v0.33.0/go.mod h1:KnJRokGxjvbBQkSJkbVuBbu6z4B0rC7ynkpY5Aw6m9o= -k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk= -k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU= -k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 h1:2OX19X59HxDprNCVrWi6jb7LW1PoqTlYqEq5H2oetog= -k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= +k8s.io/api v0.34.0 h1:L+JtP2wDbEYPUeNGbeSa/5GwFtIA662EmT2YSLOkAVE= +k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug= +k8s.io/apiextensions-apiserver v0.34.0 h1:B3hiB32jV7BcyKcMU5fDaDxk882YrJ1KU+ZSkA9Qxoc= +k8s.io/apiextensions-apiserver v0.34.0/go.mod h1:hLI4GxE1BDBy9adJKxUxCEHBGZtGfIg98Q+JmTD7+g0= +k8s.io/apimachinery v0.34.0 h1:eR1WO5fo0HyoQZt1wdISpFDffnWOvFLOOeJ7MgIv4z0= +k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.0 h1:YoWv5r7bsBfb0Hs2jh8SOvFbKzzxyNo0nSb0zC19KZo= +k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY= +k8s.io/code-generator v0.34.0 h1:Ze2i1QsvUprIlX3oHiGv09BFQRLCz+StA8qKwwFzees= +k8s.io/code-generator v0.34.0/go.mod h1:Py2+4w2HXItL8CGhks8uI/wS3Y93wPKO/9mBQUYNua0= +k8s.io/component-base v0.34.0 h1:bS8Ua3zlJzapklsB1dZgjEJuJEeHjj8yTu1gxE2zQX8= +k8s.io/component-base v0.34.0/go.mod h1:RSCqUdvIjjrEm81epPcjQ/DS+49fADvGSCkIP3IC6vg= +k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f h1:SLb+kxmzfA87x4E4brQzB33VBbT2+x7Zq9ROIHmGn9Q= +k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= -k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= +k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.22.0 h1:mTOfibb8Hxwpx3xEkR56i7xSjB+nH4hZG37SrlCY5e0= +sigs.k8s.io/controller-runtime v0.22.0/go.mod h1:FwiwRjkRPbiN+zp2QRp7wlTCzbUXxZ/D4OzuQUDwBHY= sigs.k8s.io/controller-tools v0.18.0 h1:rGxGZCZTV2wJreeRgqVoWab/mfcumTMmSwKzoM9xrsE= sigs.k8s.io/controller-tools v0.18.0/go.mod h1:gLKoiGBriyNh+x1rWtUQnakUYEujErjXs9pf+x/8n1U= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/package/crossplane.yaml b/package/crossplane.yaml index c146ae27..1e725db1 100644 --- a/package/crossplane.yaml +++ b/package/crossplane.yaml @@ -29,3 +29,6 @@ metadata: friendly-kind-name.meta.crossplane.io/grant.postgresql.sql.crossplane.io: Grant friendly-kind-name.meta.crossplane.io/role.postgresql.sql.crossplane.io: Role friendly-kind-name.meta.crossplane.io/user.mysql.sql.crossplane.io: User +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 0b4739b2..fdc0442a 100644 --- a/pkg/controller/cluster/mssql/database/reconciler.go +++ b/pkg/controller/cluster/mssql/database/reconciler.go @@ -97,6 +97,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 usage resource.Tracker diff --git a/pkg/controller/cluster/mssql/grant/reconciler.go b/pkg/controller/cluster/mssql/grant/reconciler.go index 7b1649ba..85b908ab 100644 --- a/pkg/controller/cluster/mssql/grant/reconciler.go +++ b/pkg/controller/cluster/mssql/grant/reconciler.go @@ -98,6 +98,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 usage resource.Tracker 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 3c18bfc7..3522a24f 100644 --- a/pkg/controller/cluster/mssql/user/reconciler.go +++ b/pkg/controller/cluster/mssql/user/reconciler.go @@ -104,6 +104,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 usage resource.Tracker 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 72d86444..913b926f 100644 --- a/pkg/controller/cluster/mysql/database/reconciler.go +++ b/pkg/controller/cluster/mysql/database/reconciler.go @@ -97,6 +97,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 usage resource.Tracker diff --git a/pkg/controller/cluster/mysql/grant/reconciler.go b/pkg/controller/cluster/mysql/grant/reconciler.go index 3c8ac7c8..60f272a2 100644 --- a/pkg/controller/cluster/mysql/grant/reconciler.go +++ b/pkg/controller/cluster/mysql/grant/reconciler.go @@ -107,6 +107,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 usage resource.Tracker 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 c3ffdd87..18ebf2a0 100644 --- a/pkg/controller/cluster/mysql/user/reconciler.go +++ b/pkg/controller/cluster/mysql/user/reconciler.go @@ -102,6 +102,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 usage resource.Tracker 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 ddba2447..d7c4d79c 100644 --- a/pkg/controller/cluster/postgresql/database/reconciler.go +++ b/pkg/controller/cluster/postgresql/database/reconciler.go @@ -104,6 +104,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 usage resource.Tracker diff --git a/pkg/controller/cluster/postgresql/extension/reconciler.go b/pkg/controller/cluster/postgresql/extension/reconciler.go index 0a99bb13..64614af8 100644 --- a/pkg/controller/cluster/postgresql/extension/reconciler.go +++ b/pkg/controller/cluster/postgresql/extension/reconciler.go @@ -96,6 +96,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 usage resource.Tracker diff --git a/pkg/controller/cluster/postgresql/grant/reconciler.go b/pkg/controller/cluster/postgresql/grant/reconciler.go index bf8e4c84..a97dbad2 100644 --- a/pkg/controller/cluster/postgresql/grant/reconciler.go +++ b/pkg/controller/cluster/postgresql/grant/reconciler.go @@ -105,6 +105,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 usage resource.Tracker diff --git a/pkg/controller/cluster/postgresql/postgresql.go b/pkg/controller/cluster/postgresql/postgresql.go index 46a41f74..47641669 100644 --- a/pkg/controller/cluster/postgresql/postgresql.go +++ b/pkg/controller/cluster/postgresql/postgresql.go @@ -19,26 +19,44 @@ 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" "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, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + 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, } { if err := setup(mgr, o); err != nil { return err diff --git a/pkg/controller/cluster/postgresql/role/reconciler.go b/pkg/controller/cluster/postgresql/role/reconciler.go index 9e34d3e8..b0aa901d 100644 --- a/pkg/controller/cluster/postgresql/role/reconciler.go +++ b/pkg/controller/cluster/postgresql/role/reconciler.go @@ -106,6 +106,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 usage resource.Tracker diff --git a/pkg/controller/cluster/postgresql/schema/reconciler.go b/pkg/controller/cluster/postgresql/schema/reconciler.go index ec54f92b..861cc9eb 100644 --- a/pkg/controller/cluster/postgresql/schema/reconciler.go +++ b/pkg/controller/cluster/postgresql/schema/reconciler.go @@ -99,6 +99,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[resource.Managed] = &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 cf2d3fa6..1797f742 100644 --- a/pkg/controller/namespaced/mssql/database/reconciler.go +++ b/pkg/controller/namespaced/mssql/database/reconciler.go @@ -90,6 +90,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 usage resource.Tracker diff --git a/pkg/controller/namespaced/mssql/grant/reconciler.go b/pkg/controller/namespaced/mssql/grant/reconciler.go index e574293f..3f950d67 100644 --- a/pkg/controller/namespaced/mssql/grant/reconciler.go +++ b/pkg/controller/namespaced/mssql/grant/reconciler.go @@ -93,6 +93,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 usage resource.Tracker 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 67009c2d..f221bf11 100644 --- a/pkg/controller/namespaced/mssql/user/reconciler.go +++ b/pkg/controller/namespaced/mssql/user/reconciler.go @@ -99,6 +99,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 usage resource.Tracker 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 8bfcf6cd..f114a94a 100644 --- a/pkg/controller/namespaced/mysql/database/reconciler.go +++ b/pkg/controller/namespaced/mysql/database/reconciler.go @@ -92,6 +92,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 usage resource.Tracker diff --git a/pkg/controller/namespaced/mysql/grant/reconciler.go b/pkg/controller/namespaced/mysql/grant/reconciler.go index 9857220b..fd1bf9f8 100644 --- a/pkg/controller/namespaced/mysql/grant/reconciler.go +++ b/pkg/controller/namespaced/mysql/grant/reconciler.go @@ -102,6 +102,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 usage resource.Tracker 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 843011ec..6312e7c9 100644 --- a/pkg/controller/namespaced/mysql/user/reconciler.go +++ b/pkg/controller/namespaced/mysql/user/reconciler.go @@ -97,6 +97,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 usage resource.Tracker 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 d13c10e2..d944dd3f 100644 --- a/pkg/controller/namespaced/postgresql/database/reconciler.go +++ b/pkg/controller/namespaced/postgresql/database/reconciler.go @@ -99,6 +99,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 usage resource.Tracker diff --git a/pkg/controller/namespaced/postgresql/extension/reconciler.go b/pkg/controller/namespaced/postgresql/extension/reconciler.go index 109afd53..03b7e63e 100644 --- a/pkg/controller/namespaced/postgresql/extension/reconciler.go +++ b/pkg/controller/namespaced/postgresql/extension/reconciler.go @@ -91,6 +91,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 usage resource.Tracker diff --git a/pkg/controller/namespaced/postgresql/grant/reconciler.go b/pkg/controller/namespaced/postgresql/grant/reconciler.go index 39b0bcb4..81cd779b 100644 --- a/pkg/controller/namespaced/postgresql/grant/reconciler.go +++ b/pkg/controller/namespaced/postgresql/grant/reconciler.go @@ -100,6 +100,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 usage resource.Tracker diff --git a/pkg/controller/namespaced/postgresql/postgresql.go b/pkg/controller/namespaced/postgresql/postgresql.go index ac511a9f..eb410595 100644 --- a/pkg/controller/namespaced/postgresql/postgresql.go +++ b/pkg/controller/namespaced/postgresql/postgresql.go @@ -19,26 +19,44 @@ 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" "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, + } { + if err := setup(mgr, o); err != nil { + return err + } + } + 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, } { if err := setup(mgr, o); err != nil { return err diff --git a/pkg/controller/namespaced/postgresql/role/reconciler.go b/pkg/controller/namespaced/postgresql/role/reconciler.go index 5e78f02f..799e8848 100644 --- a/pkg/controller/namespaced/postgresql/role/reconciler.go +++ b/pkg/controller/namespaced/postgresql/role/reconciler.go @@ -101,6 +101,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 usage resource.Tracker diff --git a/pkg/controller/namespaced/postgresql/schema/reconciler.go b/pkg/controller/namespaced/postgresql/schema/reconciler.go index eb36bc19..1621eabb 100644 --- a/pkg/controller/namespaced/postgresql/schema/reconciler.go +++ b/pkg/controller/namespaced/postgresql/schema/reconciler.go @@ -94,6 +94,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[resource.Managed] = &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 +}