diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 998b2e82..e2e526eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,16 +9,30 @@ on: workflow_dispatch: inputs: postgres_version: - description: 'PostgreSQL major version to test against (e.g. 16, 17, 18)' + description: "PostgreSQL major version to test against (e.g. 16, 17, 18)" required: false - default: '18' + default: "18" type: string + mariadb_version: + description: "MariaDB major version to test against (e.g. 11, 12)" + required: false + default: "12" + type: string + mssql_version: + description: "MSSQL Server image tag (e.g. 2022-CU24-ubuntu-22.04)" + required: false + default: "2022-CU24-ubuntu-22.04" + type: string + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: # Common versions - GO_VERSION: '1.26' - GOLANGCI_VERSION: 'v2.10.1' - DOCKER_BUILDX_VERSION: 'v0.23.0' + GO_VERSION: "1.26" + GOLANGCI_VERSION: "v2.10.1" + DOCKER_BUILDX_VERSION: "v0.23.0" # Common users. We can't run a step 'if secrets.AWS_USR != ""' but we can run # a step 'if env.AWS_USR' != ""', so we copy these to succinctly test whether @@ -42,7 +56,6 @@ jobs: do_not_skip: '["workflow_dispatch", "schedule", "push"]' concurrent_skipping: false - lint: runs-on: ubuntu-24.04 needs: detect-noop @@ -245,7 +258,11 @@ jobs: # BUILD_ARGS: "--load" - name: Run E2E Tests - run: make e2e USE_HELM=true POSTGRES_VERSION=${{ inputs.postgres_version || '18' }} + run: >- + make e2e USE_HELM=true + POSTGRES_VERSION=${{ inputs.postgres_version }} + MARIADB_VERSION=${{ inputs.mariadb_version }} + MSSQL_VERSION=${{ inputs.mssql_version }} publish-artifacts: runs-on: ubuntu-24.04 diff --git a/Makefile b/Makefile index dfaac434..2dc97967 100644 --- a/Makefile +++ b/Makefile @@ -87,6 +87,8 @@ e2e.run: test-integration CROSSPLANE_HELM_CHANNEL ?= stable CROSSPLANE_HELM_CHART_VERSION ?= POSTGRES_VERSION ?= 18 +MARIADB_VERSION ?= 12 +MSSQL_VERSION ?= 2022-CU24-ubuntu-22.04 # Run integration tests. test-integration: $(KIND) $(KUBECTL) $(CROSSPLANE_CLI) $(HELM) @@ -95,6 +97,8 @@ test-integration: $(KIND) $(KUBECTL) $(CROSSPLANE_CLI) $(HELM) CROSSPLANE_HELM_CHANNEL=${CROSSPLANE_HELM_CHANNEL} \ CROSSPLANE_HELM_CHART_VERSION=${CROSSPLANE_HELM_CHART_VERSION} \ POSTGRES_VERSION=${POSTGRES_VERSION} \ + MARIADB_VERSION=${MARIADB_VERSION} \ + MSSQL_VERSION=${MSSQL_VERSION} \ $(ROOT_DIR)/cluster/local/integration_tests.sh || $(FAIL) @$(OK) integration tests passed diff --git a/cluster/local/integration_tests.sh b/cluster/local/integration_tests.sh index 903eb896..296c1a55 100755 --- a/cluster/local/integration_tests.sh +++ b/cluster/local/integration_tests.sh @@ -203,7 +203,7 @@ setup_mariadb_no_tls() { --from-literal endpoint="mariadb.default.svc.cluster.local" \ --from-literal port="3306" - "${KUBECTL}" apply -f ${scriptdir}/mariadb.server.yaml + MARIADB_VERSION="${MARIADB_VERSION:-12}" envsubst '${MARIADB_VERSION}' < "${scriptdir}/mariadb.server.yaml" | "${KUBECTL}" apply -f - echo_step "Waiting for MariaDB to be ready" "${KUBECTL}" rollout status statefulset/mariadb --timeout=120s @@ -228,7 +228,7 @@ setup_mariadb_tls() { " # Deploy MariaDB using official mariadb image with TLS - "${KUBECTL}" apply -f "${scriptdir}/mariadb.tls.server.yaml" + MARIADB_VERSION="${MARIADB_VERSION:-12}" envsubst '${MARIADB_VERSION}' < "${scriptdir}/mariadb.tls.server.yaml" | "${KUBECTL}" apply -f - echo_step "Waiting for MariaDB to be ready" "${KUBECTL}" rollout status statefulset/mariadb --timeout=120s diff --git a/cluster/local/mariadb.server.yaml b/cluster/local/mariadb.server.yaml index dc60ec1b..0662e8e1 100644 --- a/cluster/local/mariadb.server.yaml +++ b/cluster/local/mariadb.server.yaml @@ -28,7 +28,7 @@ spec: spec: containers: - name: mariadb - image: mariadb:12 + image: mariadb:${MARIADB_VERSION} env: - name: MARIADB_ROOT_PASSWORD valueFrom: diff --git a/cluster/local/mariadb.tls.server.yaml b/cluster/local/mariadb.tls.server.yaml index ed4a2094..81b5edca 100644 --- a/cluster/local/mariadb.tls.server.yaml +++ b/cluster/local/mariadb.tls.server.yaml @@ -28,7 +28,7 @@ spec: spec: containers: - name: mariadb - image: mariadb:12 + image: mariadb:${MARIADB_VERSION} args: - --ssl - --require-secure-transport=ON diff --git a/cluster/local/mssql.server.yaml b/cluster/local/mssql.server.yaml index 9168416b..80b76b0b 100644 --- a/cluster/local/mssql.server.yaml +++ b/cluster/local/mssql.server.yaml @@ -28,7 +28,7 @@ spec: spec: containers: - name: mssql - image: mcr.microsoft.com/mssql/server:2019-CU32-ubuntu-20.04 + image: mcr.microsoft.com/mssql/server:${MSSQL_VERSION} env: - name: SA_PASSWORD valueFrom: diff --git a/cluster/local/mssqldb_functions.sh b/cluster/local/mssqldb_functions.sh index d7941cc4..7dd0637a 100644 --- a/cluster/local/mssqldb_functions.sh +++ b/cluster/local/mssqldb_functions.sh @@ -13,7 +13,7 @@ setup_mssql() { echo_step "Verifying secret creation" "${KUBECTL}" get secret mssql-creds -o yaml - "${KUBECTL}" apply -f ${scriptdir}/mssql.server.yaml + MSSQL_VERSION="${MSSQL_VERSION:-2022-CU24-ubuntu-22.04}" envsubst '${MSSQL_VERSION}' < "${scriptdir}/mssql.server.yaml" | "${KUBECTL}" apply -f - echo_step "Waiting for MSSQL Server to be ready" "${KUBECTL}" rollout status statefulset/mssql --timeout=300s diff --git a/go.mod b/go.mod index 4295bebd..a4a8ac38 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/lib/pq v1.12.3 github.com/microsoft/go-mssqldb v1.10.0 github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.11.1 k8s.io/api v0.35.0 k8s.io/apimachinery v0.35.0 k8s.io/utils v0.0.0-20260108192941-914a6e750570 diff --git a/pkg/clients/mssql/mssql.go b/pkg/clients/mssql/mssql.go index 1c0a5ac0..cac81d3b 100644 --- a/pkg/clients/mssql/mssql.go +++ b/pkg/clients/mssql/mssql.go @@ -119,11 +119,22 @@ func (c mssqlDB) GetConnectionDetails(username, password string) managed.Connect } } -// GetServerVersion is not supported by the MSSQL client (only used by PostgreSQL). +// GetServerVersion returns the MSSQL server version as an integer. +// For example, SQL Server 2022 (16.0.1125) returns 160000 (major*10000 + minor*100). +// Build number is ignored as it exceeds the encoding range. func (c mssqlDB) GetServerVersion(ctx context.Context) (int, error) { - // This method should never be called for MSSQL clients - // but is implemented to satisfy the xsql.DB interface - return 0, nil + db, err := sql.Open(driverName, c.dsn) + if err != nil { + return 0, err + } + defer db.Close() //nolint:errcheck + + var version string + if err := db.QueryRowContext(ctx, "SELECT SERVERPROPERTY('ProductVersion')").Scan(&version); err != nil { + return 0, err + } + + return xsql.ParseVersion(version) } // QuoteIdentifier for mssql queries diff --git a/pkg/clients/mysql/mysql.go b/pkg/clients/mysql/mysql.go index 4ab55902..220dea01 100644 --- a/pkg/clients/mysql/mysql.go +++ b/pkg/clients/mysql/mysql.go @@ -7,9 +7,10 @@ import ( "strconv" "strings" - "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" "github.com/pkg/errors" + "github.com/crossplane-contrib/provider-sql/pkg/clients/xsql" + xpv1 "github.com/crossplane/crossplane-runtime/v2/apis/common/v1" "github.com/crossplane/crossplane-runtime/v2/pkg/reconciler/managed" ) @@ -117,11 +118,21 @@ func (c mySQLDB) GetConnectionDetails(username, password string) managed.Connect } } -// GetServerVersion is not supported by the MySQL client (only used by PostgreSQL). +// GetServerVersion returns the MySQL server version as an integer. +// For example, MySQL 8.0.35 returns 80035 (major*10000 + minor*100 + patch). func (c mySQLDB) GetServerVersion(ctx context.Context) (int, error) { - // This method should never be called for MySQL clients - // but is implemented to satisfy the xsql.DB interface - return 0, nil + db, err := sql.Open("mysql", c.dsn) + if err != nil { + return 0, err + } + defer db.Close() //nolint:errcheck + + var version string + if err := db.QueryRowContext(ctx, "SELECT VERSION()").Scan(&version); err != nil { + return 0, err + } + + return xsql.ParseVersion(version) } // QuoteIdentifier for MySQL queries diff --git a/pkg/clients/postgresql/postgresql.go b/pkg/clients/postgresql/postgresql.go index 97ef36cc..e76a0986 100644 --- a/pkg/clients/postgresql/postgresql.go +++ b/pkg/clients/postgresql/postgresql.go @@ -138,7 +138,7 @@ func (c postgresDB) GetConnectionDetails(username, password string) managed.Conn } } -// GetServerVersion returns the PostgreSQL server version as an integer +// GetServerVersion returns the PostgreSQL server version as an integer. // For example, PostgreSQL 16.2 would return 160200. func (c postgresDB) GetServerVersion(ctx context.Context) (int, error) { db, err := sql.Open("postgres", c.dsn) @@ -148,8 +148,11 @@ func (c postgresDB) GetServerVersion(ctx context.Context) (int, error) { defer db.Close() //nolint:errcheck var version int - err = db.QueryRowContext(ctx, "SELECT current_setting('server_version_num')::int").Scan(&version) - return version, err + if err := db.QueryRowContext(ctx, "SELECT current_setting('server_version_num')::int").Scan(&version); err != nil { + return 0, err + } + + return version, nil } // IsInvalidCatalog returns true if passed a pq error indicating diff --git a/pkg/clients/xsql/common.go b/pkg/clients/xsql/common.go index b1c78444..6bf3a8b5 100644 --- a/pkg/clients/xsql/common.go +++ b/pkg/clients/xsql/common.go @@ -3,6 +3,9 @@ package xsql import ( "context" "errors" + "fmt" + "strconv" + "strings" "database/sql" @@ -25,6 +28,41 @@ type DB interface { GetServerVersion(ctx context.Context) (int, error) } +// ParseVersion parses a database version string into an integer +// encoded as major*10000 + minor*100 + patch. +// Suffixes after '-' are stripped (e.g. "8.0.35-ubuntu" → 80035). +// Patch values above 99 are ignored (e.g. MSSQL build numbers). +func ParseVersion(version string) (int, error) { + if idx := strings.IndexByte(version, '-'); idx >= 0 { + version = version[:idx] + } + + parts := strings.SplitN(version, ".", 3) + if len(parts) < 2 { + return 0, fmt.Errorf("unexpected version format: %s", version) + } + + major, err := strconv.Atoi(parts[0]) + if err != nil { + return 0, fmt.Errorf("parsing major version %q: %w", parts[0], err) + } + + minor, err := strconv.Atoi(parts[1]) + if err != nil { + return 0, fmt.Errorf("parsing minor version %q: %w", parts[1], err) + } + + var patch int + if len(parts) == 3 { + p, err := strconv.Atoi(parts[2]) + if err == nil && p <= 99 { + patch = p + } + } + + return major*10000 + minor*100 + patch, nil +} + // IsNoRows returns true if the supplied error indicates no rows were returned. func IsNoRows(err error) bool { return errors.Is(err, sql.ErrNoRows) diff --git a/pkg/clients/xsql/common_test.go b/pkg/clients/xsql/common_test.go index 89fad36e..a077435f 100644 --- a/pkg/clients/xsql/common_test.go +++ b/pkg/clients/xsql/common_test.go @@ -4,6 +4,8 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestRemapCredentialKeys(t *testing.T) { @@ -110,3 +112,44 @@ func TestRemapCredentialKeys(t *testing.T) { } }) } + +func TestParseVersion(t *testing.T) { + tests := []struct { + name string + version string + want int + wantErr bool + }{ + // MySQL-style versions + {name: "MySQL_Standard", version: "8.0.35", want: 80035}, + {name: "MySQL_WithSuffix", version: "8.0.35-0ubuntu0.22.04.1", want: 80035}, + {name: "MySQL_MajorMinorOnly", version: "8.0", want: 80000}, + {name: "MySQL_9", version: "9.1.0", want: 90100}, + {name: "MariaDB", version: "10.11.6-MariaDB", want: 101106}, + + // MSSQL-style versions (build number > 99, ignored) + {name: "MSSQL_2022", version: "16.0.1125.1", want: 160000}, + {name: "MSSQL_2019", version: "15.0.4355.3", want: 150000}, + {name: "MSSQL_NonZeroMinor", version: "16.5.100.1", want: 160500}, + + // PostgreSQL-style (for reference, PG uses its own query) + {name: "ThreeDigitPatch", version: "14.2.1", want: 140201}, + {name: "PatchExactly99", version: "14.0.99", want: 140099}, + {name: "PatchOver99", version: "14.0.100", want: 140000}, + + // Errors + {name: "InvalidFormat", version: "invalid", wantErr: true}, + {name: "EmptyString", version: "", wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ParseVersion(tt.version) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/controller/cluster/mssql/database/reconciler.go b/pkg/controller/cluster/mssql/database/reconciler.go index bf28ad01..e82642de 100644 --- a/pkg/controller/cluster/mssql/database/reconciler.go +++ b/pkg/controller/cluster/mssql/database/reconciler.go @@ -124,6 +124,8 @@ func (c *connector) Connect(ctx context.Context, mg *clusterv1alpha1.Database) ( } secretData := xsql.RemapCredentialKeys(s.Data, pc.Spec.Credentials.SecretKeyMapping.ToMap()) + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newClient(secretData, "")}, nil } diff --git a/pkg/controller/cluster/mssql/database/reconciler_test.go b/pkg/controller/cluster/mssql/database/reconciler_test.go index a0d77a67..5ae28e93 100644 --- a/pkg/controller/cluster/mssql/database/reconciler_test.go +++ b/pkg/controller/cluster/mssql/database/reconciler_test.go @@ -59,6 +59,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/cluster/mssql/grant/reconciler.go b/pkg/controller/cluster/mssql/grant/reconciler.go index 7549077b..86a1958b 100644 --- a/pkg/controller/cluster/mssql/grant/reconciler.go +++ b/pkg/controller/cluster/mssql/grant/reconciler.go @@ -125,6 +125,8 @@ func (c *connector) Connect(ctx context.Context, mg *v1alpha1.Grant) (managed.Ty } secretData := xsql.RemapCredentialKeys(s.Data, pc.Spec.Credentials.SecretKeyMapping.ToMap()) + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newClient(secretData, ptr.Deref(mg.Spec.ForProvider.Database, ""))}, nil } diff --git a/pkg/controller/cluster/mssql/grant/reconciler_test.go b/pkg/controller/cluster/mssql/grant/reconciler_test.go index b47ea255..1145df0f 100644 --- a/pkg/controller/cluster/mssql/grant/reconciler_test.go +++ b/pkg/controller/cluster/mssql/grant/reconciler_test.go @@ -68,6 +68,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/cluster/mssql/user/reconciler.go b/pkg/controller/cluster/mssql/user/reconciler.go index 5f766f73..c5909346 100644 --- a/pkg/controller/cluster/mssql/user/reconciler.go +++ b/pkg/controller/cluster/mssql/user/reconciler.go @@ -137,6 +137,8 @@ func (c *connector) Connect(ctx context.Context, mg *v1alpha1.User) (managed.Typ loginDB = c.newClient(secretData, ptr.Deref(mg.Spec.ForProvider.LoginDatabase, "")) } + // To add version-gated logic, call userDB.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{ userDB: userDB, loginDB: loginDB, diff --git a/pkg/controller/cluster/mssql/user/reconciler_test.go b/pkg/controller/cluster/mssql/user/reconciler_test.go index f560515e..faf16585 100644 --- a/pkg/controller/cluster/mssql/user/reconciler_test.go +++ b/pkg/controller/cluster/mssql/user/reconciler_test.go @@ -70,6 +70,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti } } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/cluster/mysql/database/reconciler.go b/pkg/controller/cluster/mysql/database/reconciler.go index 86443b59..cb0402f1 100644 --- a/pkg/controller/cluster/mysql/database/reconciler.go +++ b/pkg/controller/cluster/mysql/database/reconciler.go @@ -131,6 +131,8 @@ func (c *connector) Connect(ctx context.Context, mg *v1alpha1.Database) (managed } secretData := xsql.RemapCredentialKeys(s.Data, pc.Spec.Credentials.SecretKeyMapping.ToMap()) + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newDB(secretData, tlsName, mg.Spec.ForProvider.BinLog)}, nil } diff --git a/pkg/controller/cluster/mysql/database/reconciler_test.go b/pkg/controller/cluster/mysql/database/reconciler_test.go index 2928bda1..287ea7e1 100644 --- a/pkg/controller/cluster/mysql/database/reconciler_test.go +++ b/pkg/controller/cluster/mysql/database/reconciler_test.go @@ -59,6 +59,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/cluster/mysql/grant/reconciler.go b/pkg/controller/cluster/mysql/grant/reconciler.go index 50546675..718eeb05 100644 --- a/pkg/controller/cluster/mysql/grant/reconciler.go +++ b/pkg/controller/cluster/mysql/grant/reconciler.go @@ -139,6 +139,8 @@ func (c *connector) Connect(ctx context.Context, mg *v1alpha1.Grant) (managed.Ty } secretData := xsql.RemapCredentialKeys(s.Data, pc.Spec.Credentials.SecretKeyMapping.ToMap()) + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newDB(secretData, tlsName, mg.Spec.ForProvider.BinLog)}, nil } diff --git a/pkg/controller/cluster/mysql/grant/reconciler_test.go b/pkg/controller/cluster/mysql/grant/reconciler_test.go index 39d95b3a..ca983b44 100644 --- a/pkg/controller/cluster/mysql/grant/reconciler_test.go +++ b/pkg/controller/cluster/mysql/grant/reconciler_test.go @@ -69,6 +69,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/cluster/mysql/user/reconciler.go b/pkg/controller/cluster/mysql/user/reconciler.go index 3eba36a6..827804b6 100644 --- a/pkg/controller/cluster/mysql/user/reconciler.go +++ b/pkg/controller/cluster/mysql/user/reconciler.go @@ -134,6 +134,8 @@ func (c *connector) Connect(ctx context.Context, mg *v1alpha1.User) (managed.Typ } secretData := xsql.RemapCredentialKeys(s.Data, pc.Spec.Credentials.SecretKeyMapping.ToMap()) + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{ db: c.newDB(secretData, tlsName, mg.Spec.ForProvider.BinLog), kube: c.kube, diff --git a/pkg/controller/cluster/mysql/user/reconciler_test.go b/pkg/controller/cluster/mysql/user/reconciler_test.go index 8d88abd0..9f62c055 100644 --- a/pkg/controller/cluster/mysql/user/reconciler_test.go +++ b/pkg/controller/cluster/mysql/user/reconciler_test.go @@ -67,6 +67,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti } } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/namespaced/mssql/database/reconciler.go b/pkg/controller/namespaced/mssql/database/reconciler.go index fcad40b7..d9154c9b 100644 --- a/pkg/controller/namespaced/mssql/database/reconciler.go +++ b/pkg/controller/namespaced/mssql/database/reconciler.go @@ -104,6 +104,8 @@ func (c *connector) Connect(ctx context.Context, mg *namespacedv1alpha1.Database return nil, err } + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newClient(providerInfo.SecretData, "")}, nil } diff --git a/pkg/controller/namespaced/mssql/database/reconciler_test.go b/pkg/controller/namespaced/mssql/database/reconciler_test.go index bfee3cee..65e8c437 100644 --- a/pkg/controller/namespaced/mssql/database/reconciler_test.go +++ b/pkg/controller/namespaced/mssql/database/reconciler_test.go @@ -62,6 +62,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/namespaced/mssql/grant/reconciler.go b/pkg/controller/namespaced/mssql/grant/reconciler.go index bba34f77..3bdb031e 100644 --- a/pkg/controller/namespaced/mssql/grant/reconciler.go +++ b/pkg/controller/namespaced/mssql/grant/reconciler.go @@ -107,6 +107,8 @@ func (c *connector) Connect(ctx context.Context, mg *namespacedv1alpha1.Grant) ( return nil, err } + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newClient(providerInfo.SecretData, ptr.Deref(mg.Spec.ForProvider.Database, ""))}, nil } diff --git a/pkg/controller/namespaced/mssql/grant/reconciler_test.go b/pkg/controller/namespaced/mssql/grant/reconciler_test.go index 7cddc966..7123da19 100644 --- a/pkg/controller/namespaced/mssql/grant/reconciler_test.go +++ b/pkg/controller/namespaced/mssql/grant/reconciler_test.go @@ -71,6 +71,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/namespaced/mssql/user/reconciler.go b/pkg/controller/namespaced/mssql/user/reconciler.go index 20f62de4..29d9455a 100644 --- a/pkg/controller/namespaced/mssql/user/reconciler.go +++ b/pkg/controller/namespaced/mssql/user/reconciler.go @@ -119,6 +119,8 @@ func (c *connector) Connect(ctx context.Context, mg *namespacedv1alpha1.User) (m loginDB = c.newClient(providerInfo.SecretData, ptr.Deref(mg.Spec.ForProvider.LoginDatabase, "")) } + // To add version-gated logic, call userDB.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{ userDB: userDB, loginDB: loginDB, diff --git a/pkg/controller/namespaced/mssql/user/reconciler_test.go b/pkg/controller/namespaced/mssql/user/reconciler_test.go index 976aae78..950c34ea 100644 --- a/pkg/controller/namespaced/mssql/user/reconciler_test.go +++ b/pkg/controller/namespaced/mssql/user/reconciler_test.go @@ -73,6 +73,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti } } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/namespaced/mysql/database/reconciler.go b/pkg/controller/namespaced/mysql/database/reconciler.go index 55d94991..40641dca 100644 --- a/pkg/controller/namespaced/mysql/database/reconciler.go +++ b/pkg/controller/namespaced/mysql/database/reconciler.go @@ -112,6 +112,8 @@ func (c *connector) Connect(ctx context.Context, mg *namespacedv1alpha1.Database return nil, errors.Wrap(err, errTLSConfig) } + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newDB(providerInfo.SecretData, tlsName, mg.Spec.ForProvider.BinLog)}, nil } diff --git a/pkg/controller/namespaced/mysql/database/reconciler_test.go b/pkg/controller/namespaced/mysql/database/reconciler_test.go index 8d0abd2c..b473dfc6 100644 --- a/pkg/controller/namespaced/mysql/database/reconciler_test.go +++ b/pkg/controller/namespaced/mysql/database/reconciler_test.go @@ -62,6 +62,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/namespaced/mysql/grant/reconciler.go b/pkg/controller/namespaced/mysql/grant/reconciler.go index fd431e85..678283ec 100644 --- a/pkg/controller/namespaced/mysql/grant/reconciler.go +++ b/pkg/controller/namespaced/mysql/grant/reconciler.go @@ -121,6 +121,8 @@ func (c *connector) Connect(ctx context.Context, mg *namespacedv1alpha1.Grant) ( return nil, errors.Wrap(err, errTLSConfig) } + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{db: c.newDB(providerInfo.SecretData, tlsName, mg.Spec.ForProvider.BinLog)}, nil } diff --git a/pkg/controller/namespaced/mysql/grant/reconciler_test.go b/pkg/controller/namespaced/mysql/grant/reconciler_test.go index 41fb1802..f6ba7bf2 100644 --- a/pkg/controller/namespaced/mysql/grant/reconciler_test.go +++ b/pkg/controller/namespaced/mysql/grant/reconciler_test.go @@ -71,6 +71,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti return m.MockGetConnectionDetails(username, password) } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) } diff --git a/pkg/controller/namespaced/mysql/user/reconciler.go b/pkg/controller/namespaced/mysql/user/reconciler.go index de6f2189..182fc77e 100644 --- a/pkg/controller/namespaced/mysql/user/reconciler.go +++ b/pkg/controller/namespaced/mysql/user/reconciler.go @@ -116,6 +116,8 @@ func (c *connector) Connect(ctx context.Context, mg *namespacedv1alpha1.User) (m return nil, errors.Wrap(err, errTLSConfig) } + // To add version-gated logic, call db.GetServerVersion(ctx) here + // and store it in the external struct (see PostgreSQL grant reconciler). return &external{ db: c.newDB(providerInfo.SecretData, tlsName, mg.Spec.ForProvider.BinLog), kube: c.kube, diff --git a/pkg/controller/namespaced/mysql/user/reconciler_test.go b/pkg/controller/namespaced/mysql/user/reconciler_test.go index 23e9cb56..fe67177a 100644 --- a/pkg/controller/namespaced/mysql/user/reconciler_test.go +++ b/pkg/controller/namespaced/mysql/user/reconciler_test.go @@ -70,6 +70,9 @@ func (m mockDB) GetConnectionDetails(username, password string) managed.Connecti } } func (m mockDB) GetServerVersion(ctx context.Context) (int, error) { + if m.MockGetServerVersion == nil { + return 0, nil + } return m.MockGetServerVersion(ctx) }