Skip to content

fix: PointersMatch for SQLInstance #7198

@acpana

Description

@acpana

Objective: Fix "Strict Pointers Match" issue for multiple fields in SQLInstance.

Context:
A class of diff errors has been identified where PointersMatch in pkg/controller/direct/sql/sqlinstance_equality.go is too strict. It returns false when a field is nil in KRM but populated with an "empty" object by GCP. This affects at least 7 fields.

Reproduction:
Your first task is to ensure reproduction by having the following tests in place. If they do not exist, create them exactly as shown.

  1. Unit Test: pkg/controller/direct/sql/sqlinstance_equality_test.go
# Copyright 2026 Google LLC
#
# 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 sql

import (
	"testing"

	api "google.golang.org/api/sqladmin/v1beta4"
)

func TestDiffInstances_StrictPointersMatch(t *testing.T) {
	// desired has all optional struct pointers as nil (typical for a minimal KRM spec)
	desired := &api.DatabaseInstance{
		Settings: &api.Settings{},
	}

	// actual has these fields populated with "empty" defaults by the GCP API
	actual := &api.DatabaseInstance{
		DiskEncryptionConfiguration: &api.DiskEncryptionConfiguration{
			Kind: "sql#diskEncryptionConfiguration",
		},
		ReplicaConfiguration: &api.ReplicaConfiguration{
			Kind: "sql#replicaConfiguration",
		},
		ReplicationCluster: &api.ReplicationCluster{},
		Settings: &api.Settings{
			BackupConfiguration: &api.BackupConfiguration{
				Kind: "sql#backupConfiguration",
			},
			DataCacheConfig: &api.DataCacheConfig{},
			IpConfiguration: &api.IpConfiguration{
				Ipv4Enabled: true,
				SslMode:     "ALLOW_UNENCRYPTED_AND_ENCRYPTED",
			},
			LocationPreference: &api.LocationPreference{
				Kind: "sql#locationPreference",
			},
		},
	}

	diff := DiffInstances(desired, actual)

	// Currently, this fails because PointersMatch is too strict.
	// We want HasDiff() to be false because these are semantically equivalent.
	if diff.HasDiff() {
		t.Errorf("DiffInstances() identified unexpected diffs: %v", diff.Fields)
	}
}
  1. E2E Scenario: tests/e2e/testdata/scenarios/sqlinstance-pointers-match/script.yaml
# Copyright 2026 Google LLC
#
# 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.

apiVersion: sql.cnrm.cloud.google.com/v1beta1
kind: SQLInstance
metadata:
  name: sqlinstance-minimal-${uniqueId}
  annotations:
    alpha.cnrm.cloud.google.com/reconciler: "direct"
spec:
  databaseVersion: MYSQL_8_0
  region: us-central1
  settings:
    tier: db-f1-micro
---
# TOUCH forces a re-reconciliation without changing the spec.
# The re-reconciliation test in harness will fail if any non-GET requests are made to GCP.
apiVersion: sql.cnrm.cloud.google.com/v1beta1
kind: SQLInstance
metadata:
  name: sqlinstance-minimal-${uniqueId}
TEST: TOUCH

Tasks:

  1. Fix: Update the following matching functions in pkg/controller/direct/sql/sqlinstance_equality.go to be "semantically aware" (treat nil as equivalent to an empty/default object):
    • DiskEncryptionConfigurationsMatch
    • ReplicaConfigurationsMatch
    • ReplicationClustersMatch
    • BackupConfigurationsMatch
    • DataCacheConfigsMatch
    • IpConfigurationsMatch
    • LocationPreferencesMatch
  2. Verify:
    • Run go test -v pkg/controller/direct/sql/sqlinstance_equality_test.go pkg/controller/direct/sql/sqlinstance_equality.go and ensure TestDiffInstances_StrictPointersMatch now passes.
    • Run the E2E scenario: RUN_E2E=1 E2E_KUBE_TARGET=envtest E2E_GCP_TARGET=mock go test -v ./tests/e2e -run TestE2EScript/scenarios/sqlinstance-pointers-match and ensure it passes (the TOUCH step should not trigger an update).

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions