diff --git a/apis/refs/v1beta1/computerefs.go b/apis/refs/v1beta1/computerefs.go index 8e5c1959f2..f2c1aa00b6 100644 --- a/apis/refs/v1beta1/computerefs.go +++ b/apis/refs/v1beta1/computerefs.go @@ -19,6 +19,7 @@ import ( "fmt" "strings" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -27,7 +28,7 @@ import ( ) type ComputeNetworkRef struct { - /* The compute network selflink of form "projects//global/networks/", when not managed by KCC. */ + /* The compute network selflink of form "projects//global/networks/", when not managed by Config Connector. */ External string `json:"external,omitempty"` /* The `name` field of a `ComputeNetwork` resource. */ Name string `json:"name,omitempty"` @@ -83,7 +84,7 @@ func ResolveComputeNetwork(ctx context.Context, reader client.Reader, src client }) if err := reader.Get(ctx, key, computenetwork); err != nil { if apierrors.IsNotFound(err) { - return nil, fmt.Errorf("referenced ComputeNetwork %v not found", key) + return nil, k8s.NewReferenceNotFoundError(computenetwork.GroupVersionKind(), key) } return nil, fmt.Errorf("error reading referenced ComputeNetwork %v: %w", key, err) } diff --git a/apis/refs/v1beta1/sqlinstanceref.go b/apis/refs/v1beta1/sqlinstanceref.go new file mode 100644 index 0000000000..ea5daa8ee3 --- /dev/null +++ b/apis/refs/v1beta1/sqlinstanceref.go @@ -0,0 +1,24 @@ +// Copyright 2024 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 v1beta1 + +type SQLInstanceRef struct { + /* The SQLInstance selfLink, when not managed by Config Connector. */ + External string `json:"external,omitempty"` + /* The `name` field of a `SQLInstance` resource. */ + Name string `json:"name,omitempty"` + /* The `namespace` field of a `SQLInstance` resource. */ + Namespace string `json:"namespace,omitempty"` +} diff --git a/apis/refs/v1beta1/storagebucketref.go b/apis/refs/v1beta1/storagebucketref.go new file mode 100644 index 0000000000..4d7a197c82 --- /dev/null +++ b/apis/refs/v1beta1/storagebucketref.go @@ -0,0 +1,24 @@ +// Copyright 2024 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 v1beta1 + +type StorageBucketRef struct { + /* The StorageBucket selfLink, when not managed by Config Connector. */ + External string `json:"external,omitempty"` + /* The `name` field of a `StorageBucket` resource. */ + Name string `json:"name,omitempty"` + /* The `namespace` field of a `StorageBucket` resource. */ + Namespace string `json:"namespace,omitempty"` +} diff --git a/apis/sql/v1beta1/doc.go b/apis/sql/v1beta1/doc.go new file mode 100644 index 0000000000..0fb266f5c4 --- /dev/null +++ b/apis/sql/v1beta1/doc.go @@ -0,0 +1,21 @@ +// Copyright 2024 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. + +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +groupName=sql.cnrm.cloud.google.com + +// +kcc:proto=google.cloud.sql.v1 + +package v1beta1 diff --git a/apis/sql/v1beta1/register.go b/apis/sql/v1beta1/register.go new file mode 100644 index 0000000000..5b0b59c29e --- /dev/null +++ b/apis/sql/v1beta1/register.go @@ -0,0 +1,22 @@ +// Copyright 2024 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 v1beta1 + +import "k8s.io/apimachinery/pkg/runtime/schema" + +var ( + // SchemeGroupVersion is the group version used to register these objects. + SchemeGroupVersion = schema.GroupVersion{Group: "sql.cnrm.cloud.google.com", Version: "v1beta1"} +) diff --git a/apis/sql/v1beta1/sqlinstance_types.go b/apis/sql/v1beta1/sqlinstance_types.go new file mode 100644 index 0000000000..d7f8ca6ecf --- /dev/null +++ b/apis/sql/v1beta1/sqlinstance_types.go @@ -0,0 +1,599 @@ +// Copyright 2020 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 v1beta1 + +import ( + "reflect" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" + + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/k8s/v1alpha1" +) + +var ( + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} + + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = SchemeBuilder.AddToScheme + + SQLInstanceGVK = schema.GroupVersionKind{ + Group: SchemeGroupVersion.Group, + Version: SchemeGroupVersion.Version, + Kind: reflect.TypeOf(SQLInstance{}).Name(), + } +) + +type InstanceActiveDirectoryConfig struct { + /* Domain name of the Active Directory for SQL Server (e.g., mydomain.com). */ + Domain string `json:"domain"` +} + +type InstanceAdvancedMachineFeatures struct { + /* The number of threads per physical core. Can be 1 or 2. */ + // +optional + ThreadsPerCore *int64 `json:"threadsPerCore,omitempty"` +} + +type InstanceAuthorizedNetworks struct { + // +optional + ExpirationTime *string `json:"expirationTime,omitempty"` + + // +optional + Name *string `json:"name,omitempty"` + + Value string `json:"value"` +} + +type InstanceBackupConfiguration struct { + // +optional + BackupRetentionSettings *InstanceBackupRetentionSettings `json:"backupRetentionSettings,omitempty"` + + /* True if binary logging is enabled. If settings.backup_configuration.enabled is false, this must be as well. Can only be used with MySQL. */ + // +optional + BinaryLogEnabled *bool `json:"binaryLogEnabled,omitempty"` + + /* True if backup configuration is enabled. */ + // +optional + Enabled *bool `json:"enabled,omitempty"` + + /* Location of the backup configuration. */ + // +optional + Location *string `json:"location,omitempty"` + + /* True if Point-in-time recovery is enabled. */ + // +optional + PointInTimeRecoveryEnabled *bool `json:"pointInTimeRecoveryEnabled,omitempty"` + + /* HH:MM format time indicating when backup configuration starts. */ + // +optional + StartTime *string `json:"startTime,omitempty"` + + /* The number of days of transaction logs we retain for point in time restore, from 1-7. (For PostgreSQL Enterprise Plus instances, from 1 to 35.). */ + // +optional + TransactionLogRetentionDays *int64 `json:"transactionLogRetentionDays,omitempty"` +} + +type InstanceBackupRetentionSettings struct { + /* Number of backups to retain. */ + RetainedBackups int64 `json:"retainedBackups"` + + /* The unit that 'retainedBackups' represents. Defaults to COUNT. */ + // +optional + RetentionUnit *string `json:"retentionUnit,omitempty"` +} + +type InstanceDataCacheConfig struct { + /* Whether data cache is enabled for the instance. */ + // +optional + DataCacheEnabled *bool `json:"dataCacheEnabled,omitempty"` +} + +type InstanceDatabaseFlags struct { + /* Name of the flag. */ + Name string `json:"name"` + + /* Value of the flag. */ + Value string `json:"value"` +} + +type InstanceDenyMaintenancePeriod struct { + /* End date before which maintenance will not take place. The date is in format yyyy-mm-dd i.e., 2020-11-01, or mm-dd, i.e., 11-01. */ + EndDate string `json:"endDate"` + + /* Start date after which maintenance will not take place. The date is in format yyyy-mm-dd i.e., 2020-11-01, or mm-dd, i.e., 11-01. */ + StartDate string `json:"startDate"` + + /* Time in UTC when the "deny maintenance period" starts on start_date and ends on end_date. The time is in format: HH:mm:SS, i.e., 00:00:00. */ + Time string `json:"time"` +} + +type InstanceInsightsConfig struct { + /* True if Query Insights feature is enabled. */ + // +optional + QueryInsightsEnabled *bool `json:"queryInsightsEnabled,omitempty"` + + /* Number of query execution plans captured by Insights per minute for all queries combined. Between 0 and 20. Default to 5. */ + // +optional + QueryPlansPerMinute *int64 `json:"queryPlansPerMinute,omitempty"` + + /* Maximum query length stored in bytes. Between 256 and 4500. Default to 1024. */ + // +optional + QueryStringLength *int64 `json:"queryStringLength,omitempty"` + + /* True if Query Insights will record application tags from query when enabled. */ + // +optional + RecordApplicationTags *bool `json:"recordApplicationTags,omitempty"` + + /* True if Query Insights will record client address when enabled. */ + // +optional + RecordClientAddress *bool `json:"recordClientAddress,omitempty"` +} + +type InstanceIpConfiguration struct { + /* The name of the allocated ip range for the private ip CloudSQL instance. For example: "google-managed-services-default". If set, the instance ip will be created in the allocated range. The range name must comply with RFC 1035. Specifically, the name must be 1-63 characters long and match the regular expression [a-z]([-a-z0-9]*[a-z0-9])?. */ + // +optional + AllocatedIpRange *string `json:"allocatedIpRange,omitempty"` + + // +optional + AuthorizedNetworks []InstanceAuthorizedNetworks `json:"authorizedNetworks,omitempty"` + + /* Whether Google Cloud services such as BigQuery are allowed to access data in this Cloud SQL instance over a private IP connection. SQLSERVER database type is not supported. */ + // +optional + EnablePrivatePathForGoogleCloudServices *bool `json:"enablePrivatePathForGoogleCloudServices,omitempty"` + + /* Whether this Cloud SQL instance should be assigned a public IPV4 address. At least ipv4_enabled must be enabled or a private_network must be configured. */ + // +optional + Ipv4Enabled *bool `json:"ipv4Enabled,omitempty"` + + // +optional + PrivateNetworkRef *refsv1beta1.ComputeNetworkRef `json:"privateNetworkRef,omitempty"` + + /* PSC settings for a Cloud SQL instance. */ + // +optional + PscConfig []InstancePscConfig `json:"pscConfig,omitempty"` + + // +optional + RequireSsl *bool `json:"requireSsl,omitempty"` + + /* Specify how SSL connection should be enforced in DB connections. This field provides more SSL enforcment options compared to requireSsl. To change this field, also set the correspoding value in requireSsl if it has been set. */ + // +optional + SslMode *string `json:"sslMode,omitempty"` +} + +type InstanceLocationPreference struct { + /* A Google App Engine application whose zone to remain in. Must be in the same region as this instance. */ + // +optional + FollowGaeApplication *string `json:"followGaeApplication,omitempty"` + + /* The preferred Compute Engine zone for the secondary/failover. */ + // +optional + SecondaryZone *string `json:"secondaryZone,omitempty"` + + /* The preferred compute engine zone. */ + // +optional + Zone *string `json:"zone,omitempty"` +} + +type InstanceMaintenanceWindow struct { + /* Day of week (1-7), starting on Monday. */ + // +optional + Day *int64 `json:"day,omitempty"` + + /* Hour of day (0-23), ignored if day not set. */ + // +optional + Hour *int64 `json:"hour,omitempty"` + + /* Receive updates earlier (canary) or later (stable). */ + // +optional + UpdateTrack *string `json:"updateTrack,omitempty"` +} + +// +kubebuilder:validation:XValidation:rule="has(self.value) ? !has(self.valueFrom) : true",message="valueFrom is forbidden when value is specified" +// +kubebuilder:validation:XValidation:rule="has(self.valueFrom) ? !has(self.value): true",message="value is forbidden when valueFrom is specified" +type InstancePassword struct { + /* Value of the field. Cannot be used if 'valueFrom' is specified. */ + // +optional + Value *string `json:"value,omitempty"` + + /* Source for the field's value. Cannot be used if 'value' is specified. */ + // +optional + ValueFrom *InstanceValueFrom `json:"valueFrom,omitempty"` +} + +type InstancePasswordValidationPolicy struct { + /* Password complexity. */ + // +optional + Complexity *string `json:"complexity,omitempty"` + + /* Disallow username as a part of the password. */ + // +optional + DisallowUsernameSubstring *bool `json:"disallowUsernameSubstring,omitempty"` + + /* Whether the password policy is enabled or not. */ + EnablePasswordPolicy bool `json:"enablePasswordPolicy"` + + /* Minimum number of characters allowed. */ + // +optional + MinLength *int64 `json:"minLength,omitempty"` + + /* Minimum interval after which the password can be changed. This flag is only supported for PostgresSQL. */ + // +optional + PasswordChangeInterval *string `json:"passwordChangeInterval,omitempty"` + + /* Number of previous passwords that cannot be reused. */ + // +optional + ReuseInterval *int64 `json:"reuseInterval,omitempty"` +} + +type InstancePscConfig struct { + /* List of consumer projects that are allow-listed for PSC connections to this instance. This instance can be connected to with PSC from any network in these projects. Each consumer project in this list may be represented by a project number (numeric) or by a project id (alphanumeric). */ + // +optional + AllowedConsumerProjects []string `json:"allowedConsumerProjects,omitempty"` + + /* Whether PSC connectivity is enabled for this instance. */ + // +optional + PscEnabled *bool `json:"pscEnabled,omitempty"` +} + +type InstanceReplicaConfiguration struct { + /* Immutable. PEM representation of the trusted CA's x509 certificate. */ + // +optional + CaCertificate *string `json:"caCertificate,omitempty"` + + /* Immutable. PEM representation of the replica's x509 certificate. */ + // +optional + ClientCertificate *string `json:"clientCertificate,omitempty"` + + /* Immutable. PEM representation of the replica's private key. The corresponding public key in encoded in the client_certificate. */ + // +optional + ClientKey *string `json:"clientKey,omitempty"` + + /* Immutable. The number of seconds between connect retries. MySQL's default is 60 seconds. */ + // +optional + ConnectRetryInterval *int64 `json:"connectRetryInterval,omitempty"` + + /* Immutable. Path to a SQL file in Google Cloud Storage from which replica instances are created. Format is gs://bucket/filename. */ + // +optional + DumpFilePath *string `json:"dumpFilePath,omitempty"` + + /* Immutable. Specifies if the replica is the failover target. If the field is set to true the replica will be designated as a failover replica. If the master instance fails, the replica instance will be promoted as the new master instance. Not supported for Postgres. */ + // +optional + FailoverTarget *bool `json:"failoverTarget,omitempty"` + + /* Immutable. Time in ms between replication heartbeats. */ + // +optional + MasterHeartbeatPeriod *int64 `json:"masterHeartbeatPeriod,omitempty"` + + /* Immutable. Password for the replication connection. */ + // +optional + Password *InstancePassword `json:"password,omitempty"` + + /* Immutable. Permissible ciphers for use in SSL encryption. */ + // +optional + SslCipher *string `json:"sslCipher,omitempty"` + + /* Immutable. Username for replication connection. */ + // +optional + Username *string `json:"username,omitempty"` + + /* Immutable. True if the master's common name value is checked during the SSL handshake. */ + // +optional + VerifyServerCertificate *bool `json:"verifyServerCertificate,omitempty"` +} + +// +kubebuilder:validation:XValidation:rule="has(self.value) ? !has(self.valueFrom) : true",message="valueFrom is forbidden when value is specified" +// +kubebuilder:validation:XValidation:rule="has(self.valueFrom) ? !has(self.value): true",message="value is forbidden when valueFrom is specified" +type InstanceRootPassword struct { + /* Value of the field. Cannot be used if 'valueFrom' is specified. */ + // +optional + Value *string `json:"value,omitempty"` + + /* Source for the field's value. Cannot be used if 'value' is specified. */ + // +optional + ValueFrom *InstanceValueFrom `json:"valueFrom,omitempty"` +} + +type InstanceSettings struct { + /* This specifies when the instance should be active. Can be either ALWAYS, NEVER or ON_DEMAND. */ + // +optional + ActivationPolicy *string `json:"activationPolicy,omitempty"` + + // +optional + ActiveDirectoryConfig *InstanceActiveDirectoryConfig `json:"activeDirectoryConfig,omitempty"` + + // +optional + AdvancedMachineFeatures *InstanceAdvancedMachineFeatures `json:"advancedMachineFeatures,omitempty"` + + /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. + Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ + // +optional + AuthorizedGaeApplications []string `json:"authorizedGaeApplications,omitempty"` + + /* The availability type of the Cloud SQL instance, high availability + (REGIONAL) or single zone (ZONAL). For all instances, ensure that + settings.backup_configuration.enabled is set to true. + For MySQL instances, ensure that settings.backup_configuration.binary_log_enabled is set to true. + For Postgres instances, ensure that settings.backup_configuration.point_in_time_recovery_enabled + is set to true. Defaults to ZONAL. */ + // +optional + AvailabilityType *string `json:"availabilityType,omitempty"` + + // +optional + BackupConfiguration *InstanceBackupConfiguration `json:"backupConfiguration,omitempty"` + + /* Immutable. The name of server instance collation. */ + // +optional + Collation *string `json:"collation,omitempty"` + + /* Specifies if connections must use Cloud SQL connectors. */ + // +optional + ConnectorEnforcement *string `json:"connectorEnforcement,omitempty"` + + /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. + Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ + // +optional + CrashSafeReplication *bool `json:"crashSafeReplication,omitempty"` + + /* Data cache configurations. */ + // +optional + DataCacheConfig *InstanceDataCacheConfig `json:"dataCacheConfig,omitempty"` + + // +optional + DatabaseFlags []InstanceDatabaseFlags `json:"databaseFlags,omitempty"` + + /* Configuration to protect against accidental instance deletion. */ + // +optional + DeletionProtectionEnabled *bool `json:"deletionProtectionEnabled,omitempty"` + + // +optional + DenyMaintenancePeriod *InstanceDenyMaintenancePeriod `json:"denyMaintenancePeriod,omitempty"` + + /* Enables auto-resizing of the storage size. Defaults to true. */ + // +optional + DiskAutoresize *bool `json:"diskAutoresize,omitempty"` + + /* The maximum size, in GB, to which storage capacity can be automatically increased. The default value is 0, which specifies that there is no limit. */ + // +optional + DiskAutoresizeLimit *int64 `json:"diskAutoresizeLimit,omitempty"` + + /* The size of data disk, in GB. Size of a running instance cannot be reduced but can be increased. The minimum value is 10GB. */ + // +optional + DiskSize *int64 `json:"diskSize,omitempty"` + + /* Immutable. The type of data disk: PD_SSD or PD_HDD. Defaults to PD_SSD. */ + // +optional + DiskType *string `json:"diskType,omitempty"` + + /* The edition of the instance, can be ENTERPRISE or ENTERPRISE_PLUS. */ + // +optional + Edition *string `json:"edition,omitempty"` + + /* Configuration of Query Insights. */ + // +optional + InsightsConfig *InstanceInsightsConfig `json:"insightsConfig,omitempty"` + + // +optional + IpConfiguration *InstanceIpConfiguration `json:"ipConfiguration,omitempty"` + + // +optional + LocationPreference *InstanceLocationPreference `json:"locationPreference,omitempty"` + + /* Declares a one-hour maintenance window when an Instance can automatically restart to apply updates. The maintenance window is specified in UTC time. */ + // +optional + MaintenanceWindow *InstanceMaintenanceWindow `json:"maintenanceWindow,omitempty"` + + // +optional + PasswordValidationPolicy *InstancePasswordValidationPolicy `json:"passwordValidationPolicy,omitempty"` + + /* Pricing plan for this instance, can only be PER_USE. */ + // +optional + PricingPlan *string `json:"pricingPlan,omitempty"` + + /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. + Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ + // +optional + ReplicationType *string `json:"replicationType,omitempty"` + + // +optional + SqlServerAuditConfig *InstanceSqlServerAuditConfig `json:"sqlServerAuditConfig,omitempty"` + + /* The machine type to use. See tiers for more details and supported versions. Postgres supports only shared-core machine types, and custom machine types such as db-custom-2-13312. See the Custom Machine Type Documentation to learn about specifying custom machine types. */ + Tier string `json:"tier"` + + /* Immutable. The time_zone to be used by the database engine (supported only for SQL Server), in SQL Server timezone format. */ + // +optional + TimeZone *string `json:"timeZone,omitempty"` +} + +type InstanceSqlServerAuditConfig struct { + /* The name of the destination bucket (e.g., gs://mybucket). */ + // +optional + BucketRef *refsv1beta1.StorageBucketRef `json:"bucketRef,omitempty"` + + /* How long to keep generated audit files. A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".. */ + // +optional + RetentionInterval *string `json:"retentionInterval,omitempty"` + + /* How often to upload generated audit files. A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s". */ + // +optional + UploadInterval *string `json:"uploadInterval,omitempty"` +} + +type InstanceValueFrom struct { + /* Reference to a value with the given key in the given Secret in the resource's namespace. */ + // +optional + SecretKeyRef *v1alpha1.SecretKeyRef `json:"secretKeyRef,omitempty"` +} + +type SQLInstanceSpec struct { + /* The MySQL, PostgreSQL or SQL Server (beta) version to use. Supported values include MYSQL_5_6, MYSQL_5_7, MYSQL_8_0, POSTGRES_9_6, POSTGRES_10, POSTGRES_11, POSTGRES_12, POSTGRES_13, POSTGRES_14, POSTGRES_15, SQLSERVER_2017_STANDARD, SQLSERVER_2017_ENTERPRISE, SQLSERVER_2017_EXPRESS, SQLSERVER_2017_WEB. Database Version Policies includes an up-to-date reference of supported versions. */ + // +optional + DatabaseVersion *string `json:"databaseVersion,omitempty"` + + // +optional + EncryptionKMSCryptoKeyRef *refsv1beta1.KMSCryptoKeyRef `json:"encryptionKMSCryptoKeyRef,omitempty"` + + /* The type of the instance. The valid values are:- 'SQL_INSTANCE_TYPE_UNSPECIFIED', 'CLOUD_SQL_INSTANCE', 'ON_PREMISES_INSTANCE' and 'READ_REPLICA_INSTANCE'. */ + // +optional + InstanceType *string `json:"instanceType,omitempty"` + + /* Maintenance version. */ + // +optional + MaintenanceVersion *string `json:"maintenanceVersion,omitempty"` + + // +optional + MasterInstanceRef *refsv1beta1.SQLInstanceRef `json:"masterInstanceRef,omitempty"` + + /* Immutable. The region the instance will sit in. Note, Cloud SQL is not available in all regions. A valid region must be provided to use this resource. If a region is not provided in the resource definition, the provider region will be used instead, but this will be an apply-time error for instances if the provider region is not supported with Cloud SQL. If you choose not to provide the region argument for this resource, make sure you understand this. */ + // +optional + Region *string `json:"region,omitempty"` + + /* The configuration for replication. */ + // +optional + ReplicaConfiguration *InstanceReplicaConfiguration `json:"replicaConfiguration,omitempty"` + + /* Immutable. Optional. The name of the resource. Used for creation and acquisition. When unset, the value of `metadata.name` is used as the default. */ + // +optional + ResourceID *string `json:"resourceID,omitempty"` + + /* Initial root password. Required for MS SQL Server. */ + // +optional + RootPassword *InstanceRootPassword `json:"rootPassword,omitempty"` + + /* The settings to use for the database. The configuration is detailed below. */ + Settings InstanceSettings `json:"settings"` +} + +type InstanceIpAddressStatus struct { + // +optional + IpAddress *string `json:"ipAddress,omitempty"` + + // +optional + TimeToRetire *string `json:"timeToRetire,omitempty"` + + // +optional + Type *string `json:"type,omitempty"` +} + +type InstanceServerCaCertStatus struct { + /* The CA Certificate used to connect to the SQL Instance via SSL. */ + // +optional + Cert *string `json:"cert,omitempty"` + + /* The CN valid for the CA Cert. */ + // +optional + CommonName *string `json:"commonName,omitempty"` + + /* Creation time of the CA Cert. */ + // +optional + CreateTime *string `json:"createTime,omitempty"` + + /* Expiration time of the CA Cert. */ + // +optional + ExpirationTime *string `json:"expirationTime,omitempty"` + + /* SHA Fingerprint of the CA Cert. */ + // +optional + Sha1Fingerprint *string `json:"sha1Fingerprint,omitempty"` +} + +type SQLInstanceStatus struct { + /* Conditions represent the latest available observations of the + SQLInstance's current state. */ + Conditions []v1alpha1.Condition `json:"conditions,omitempty"` + /* Available Maintenance versions. */ + // +optional + AvailableMaintenanceVersions []string `json:"availableMaintenanceVersions,omitempty"` + + /* The connection name of the instance to be used in connection strings. For example, when connecting with Cloud SQL Proxy. */ + // +optional + ConnectionName *string `json:"connectionName,omitempty"` + + /* The dns name of the instance. */ + // +optional + DnsName *string `json:"dnsName,omitempty"` + + // +optional + FirstIpAddress *string `json:"firstIpAddress,omitempty"` + + /* The type of the instance. The valid values are:- 'SQL_INSTANCE_TYPE_UNSPECIFIED', 'CLOUD_SQL_INSTANCE', 'ON_PREMISES_INSTANCE' and 'READ_REPLICA_INSTANCE'. */ + // +optional + InstanceType *string `json:"instanceType,omitempty"` + + // +optional + IpAddress []InstanceIpAddressStatus `json:"ipAddress,omitempty"` + + /* ObservedGeneration is the generation of the resource that was most recently observed by the Config Connector controller. If this is equal to metadata.generation, then that means that the current reported status reflects the most recent desired state of the resource. */ + // +optional + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + + // +optional + PrivateIpAddress *string `json:"privateIpAddress,omitempty"` + + /* The link to service attachment of PSC instance. */ + // +optional + PscServiceAttachmentLink *string `json:"pscServiceAttachmentLink,omitempty"` + + // +optional + PublicIpAddress *string `json:"publicIpAddress,omitempty"` + + /* The URI of the created resource. */ + // +optional + SelfLink *string `json:"selfLink,omitempty"` + + // +optional + ServerCaCert *InstanceServerCaCertStatus `json:"serverCaCert,omitempty"` + + /* The service account email address assigned to the instance. */ + // +optional + ServiceAccountEmailAddress *string `json:"serviceAccountEmailAddress,omitempty"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:resource:categories=gcp,shortName=gcpsqlinstance;gcpsqlinstances +// +kubebuilder:subresource:status +// +kubebuilder:metadata:labels="cnrm.cloud.google.com/managed-by-kcc=true";"cnrm.cloud.google.com/stability-level=stable";"cnrm.cloud.google.com/system=true";"cnrm.cloud.google.com/tf2crd=true" +// +kubebuilder:printcolumn:name="Age",JSONPath=".metadata.creationTimestamp",type="date" +// +kubebuilder:printcolumn:name="Ready",JSONPath=".status.conditions[?(@.type=='Ready')].status",type="string",description="When 'True', the most recent reconcile of the resource succeeded" +// +kubebuilder:printcolumn:name="Status",JSONPath=".status.conditions[?(@.type=='Ready')].reason",type="string",description="The reason for the value in 'Ready'" +// +kubebuilder:printcolumn:name="Status Age",JSONPath=".status.conditions[?(@.type=='Ready')].lastTransitionTime",type="date",description="The last transition time for the value in 'Status'" + +// SQLInstance is the Schema for the sql API +// +k8s:openapi-gen=true +type SQLInstance struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SQLInstanceSpec `json:"spec"` + Status SQLInstanceStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// SQLInstanceList contains a list of SQLInstance +type SQLInstanceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []SQLInstance `json:"items"` +} + +func init() { + SchemeBuilder.Register(&SQLInstance{}, &SQLInstanceList{}) +} diff --git a/apis/sql/v1beta1/zz_generated.deepcopy.go b/apis/sql/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..a4efc1c72c --- /dev/null +++ b/apis/sql/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,1052 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Copyright 2020 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. +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + v1alpha1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/k8s/v1alpha1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceActiveDirectoryConfig) DeepCopyInto(out *InstanceActiveDirectoryConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceActiveDirectoryConfig. +func (in *InstanceActiveDirectoryConfig) DeepCopy() *InstanceActiveDirectoryConfig { + if in == nil { + return nil + } + out := new(InstanceActiveDirectoryConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceAdvancedMachineFeatures) DeepCopyInto(out *InstanceAdvancedMachineFeatures) { + *out = *in + if in.ThreadsPerCore != nil { + in, out := &in.ThreadsPerCore, &out.ThreadsPerCore + *out = new(int64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceAdvancedMachineFeatures. +func (in *InstanceAdvancedMachineFeatures) DeepCopy() *InstanceAdvancedMachineFeatures { + if in == nil { + return nil + } + out := new(InstanceAdvancedMachineFeatures) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceAuthorizedNetworks) DeepCopyInto(out *InstanceAuthorizedNetworks) { + *out = *in + if in.ExpirationTime != nil { + in, out := &in.ExpirationTime, &out.ExpirationTime + *out = new(string) + **out = **in + } + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceAuthorizedNetworks. +func (in *InstanceAuthorizedNetworks) DeepCopy() *InstanceAuthorizedNetworks { + if in == nil { + return nil + } + out := new(InstanceAuthorizedNetworks) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceBackupConfiguration) DeepCopyInto(out *InstanceBackupConfiguration) { + *out = *in + if in.BackupRetentionSettings != nil { + in, out := &in.BackupRetentionSettings, &out.BackupRetentionSettings + *out = new(InstanceBackupRetentionSettings) + (*in).DeepCopyInto(*out) + } + if in.BinaryLogEnabled != nil { + in, out := &in.BinaryLogEnabled, &out.BinaryLogEnabled + *out = new(bool) + **out = **in + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Location != nil { + in, out := &in.Location, &out.Location + *out = new(string) + **out = **in + } + if in.PointInTimeRecoveryEnabled != nil { + in, out := &in.PointInTimeRecoveryEnabled, &out.PointInTimeRecoveryEnabled + *out = new(bool) + **out = **in + } + if in.StartTime != nil { + in, out := &in.StartTime, &out.StartTime + *out = new(string) + **out = **in + } + if in.TransactionLogRetentionDays != nil { + in, out := &in.TransactionLogRetentionDays, &out.TransactionLogRetentionDays + *out = new(int64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceBackupConfiguration. +func (in *InstanceBackupConfiguration) DeepCopy() *InstanceBackupConfiguration { + if in == nil { + return nil + } + out := new(InstanceBackupConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceBackupRetentionSettings) DeepCopyInto(out *InstanceBackupRetentionSettings) { + *out = *in + if in.RetentionUnit != nil { + in, out := &in.RetentionUnit, &out.RetentionUnit + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceBackupRetentionSettings. +func (in *InstanceBackupRetentionSettings) DeepCopy() *InstanceBackupRetentionSettings { + if in == nil { + return nil + } + out := new(InstanceBackupRetentionSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceDataCacheConfig) DeepCopyInto(out *InstanceDataCacheConfig) { + *out = *in + if in.DataCacheEnabled != nil { + in, out := &in.DataCacheEnabled, &out.DataCacheEnabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceDataCacheConfig. +func (in *InstanceDataCacheConfig) DeepCopy() *InstanceDataCacheConfig { + if in == nil { + return nil + } + out := new(InstanceDataCacheConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceDatabaseFlags) DeepCopyInto(out *InstanceDatabaseFlags) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceDatabaseFlags. +func (in *InstanceDatabaseFlags) DeepCopy() *InstanceDatabaseFlags { + if in == nil { + return nil + } + out := new(InstanceDatabaseFlags) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceDenyMaintenancePeriod) DeepCopyInto(out *InstanceDenyMaintenancePeriod) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceDenyMaintenancePeriod. +func (in *InstanceDenyMaintenancePeriod) DeepCopy() *InstanceDenyMaintenancePeriod { + if in == nil { + return nil + } + out := new(InstanceDenyMaintenancePeriod) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceInsightsConfig) DeepCopyInto(out *InstanceInsightsConfig) { + *out = *in + if in.QueryInsightsEnabled != nil { + in, out := &in.QueryInsightsEnabled, &out.QueryInsightsEnabled + *out = new(bool) + **out = **in + } + if in.QueryPlansPerMinute != nil { + in, out := &in.QueryPlansPerMinute, &out.QueryPlansPerMinute + *out = new(int64) + **out = **in + } + if in.QueryStringLength != nil { + in, out := &in.QueryStringLength, &out.QueryStringLength + *out = new(int64) + **out = **in + } + if in.RecordApplicationTags != nil { + in, out := &in.RecordApplicationTags, &out.RecordApplicationTags + *out = new(bool) + **out = **in + } + if in.RecordClientAddress != nil { + in, out := &in.RecordClientAddress, &out.RecordClientAddress + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceInsightsConfig. +func (in *InstanceInsightsConfig) DeepCopy() *InstanceInsightsConfig { + if in == nil { + return nil + } + out := new(InstanceInsightsConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceIpAddressStatus) DeepCopyInto(out *InstanceIpAddressStatus) { + *out = *in + if in.IpAddress != nil { + in, out := &in.IpAddress, &out.IpAddress + *out = new(string) + **out = **in + } + if in.TimeToRetire != nil { + in, out := &in.TimeToRetire, &out.TimeToRetire + *out = new(string) + **out = **in + } + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceIpAddressStatus. +func (in *InstanceIpAddressStatus) DeepCopy() *InstanceIpAddressStatus { + if in == nil { + return nil + } + out := new(InstanceIpAddressStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceIpConfiguration) DeepCopyInto(out *InstanceIpConfiguration) { + *out = *in + if in.AllocatedIpRange != nil { + in, out := &in.AllocatedIpRange, &out.AllocatedIpRange + *out = new(string) + **out = **in + } + if in.AuthorizedNetworks != nil { + in, out := &in.AuthorizedNetworks, &out.AuthorizedNetworks + *out = make([]InstanceAuthorizedNetworks, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EnablePrivatePathForGoogleCloudServices != nil { + in, out := &in.EnablePrivatePathForGoogleCloudServices, &out.EnablePrivatePathForGoogleCloudServices + *out = new(bool) + **out = **in + } + if in.Ipv4Enabled != nil { + in, out := &in.Ipv4Enabled, &out.Ipv4Enabled + *out = new(bool) + **out = **in + } + if in.PrivateNetworkRef != nil { + in, out := &in.PrivateNetworkRef, &out.PrivateNetworkRef + *out = new(refsv1beta1.ComputeNetworkRef) + **out = **in + } + if in.PscConfig != nil { + in, out := &in.PscConfig, &out.PscConfig + *out = make([]InstancePscConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.RequireSsl != nil { + in, out := &in.RequireSsl, &out.RequireSsl + *out = new(bool) + **out = **in + } + if in.SslMode != nil { + in, out := &in.SslMode, &out.SslMode + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceIpConfiguration. +func (in *InstanceIpConfiguration) DeepCopy() *InstanceIpConfiguration { + if in == nil { + return nil + } + out := new(InstanceIpConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceLocationPreference) DeepCopyInto(out *InstanceLocationPreference) { + *out = *in + if in.FollowGaeApplication != nil { + in, out := &in.FollowGaeApplication, &out.FollowGaeApplication + *out = new(string) + **out = **in + } + if in.SecondaryZone != nil { + in, out := &in.SecondaryZone, &out.SecondaryZone + *out = new(string) + **out = **in + } + if in.Zone != nil { + in, out := &in.Zone, &out.Zone + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceLocationPreference. +func (in *InstanceLocationPreference) DeepCopy() *InstanceLocationPreference { + if in == nil { + return nil + } + out := new(InstanceLocationPreference) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceMaintenanceWindow) DeepCopyInto(out *InstanceMaintenanceWindow) { + *out = *in + if in.Day != nil { + in, out := &in.Day, &out.Day + *out = new(int64) + **out = **in + } + if in.Hour != nil { + in, out := &in.Hour, &out.Hour + *out = new(int64) + **out = **in + } + if in.UpdateTrack != nil { + in, out := &in.UpdateTrack, &out.UpdateTrack + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceMaintenanceWindow. +func (in *InstanceMaintenanceWindow) DeepCopy() *InstanceMaintenanceWindow { + if in == nil { + return nil + } + out := new(InstanceMaintenanceWindow) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstancePassword) DeepCopyInto(out *InstancePassword) { + *out = *in + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = new(string) + **out = **in + } + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(InstanceValueFrom) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstancePassword. +func (in *InstancePassword) DeepCopy() *InstancePassword { + if in == nil { + return nil + } + out := new(InstancePassword) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstancePasswordValidationPolicy) DeepCopyInto(out *InstancePasswordValidationPolicy) { + *out = *in + if in.Complexity != nil { + in, out := &in.Complexity, &out.Complexity + *out = new(string) + **out = **in + } + if in.DisallowUsernameSubstring != nil { + in, out := &in.DisallowUsernameSubstring, &out.DisallowUsernameSubstring + *out = new(bool) + **out = **in + } + if in.MinLength != nil { + in, out := &in.MinLength, &out.MinLength + *out = new(int64) + **out = **in + } + if in.PasswordChangeInterval != nil { + in, out := &in.PasswordChangeInterval, &out.PasswordChangeInterval + *out = new(string) + **out = **in + } + if in.ReuseInterval != nil { + in, out := &in.ReuseInterval, &out.ReuseInterval + *out = new(int64) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstancePasswordValidationPolicy. +func (in *InstancePasswordValidationPolicy) DeepCopy() *InstancePasswordValidationPolicy { + if in == nil { + return nil + } + out := new(InstancePasswordValidationPolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstancePscConfig) DeepCopyInto(out *InstancePscConfig) { + *out = *in + if in.AllowedConsumerProjects != nil { + in, out := &in.AllowedConsumerProjects, &out.AllowedConsumerProjects + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PscEnabled != nil { + in, out := &in.PscEnabled, &out.PscEnabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstancePscConfig. +func (in *InstancePscConfig) DeepCopy() *InstancePscConfig { + if in == nil { + return nil + } + out := new(InstancePscConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceReplicaConfiguration) DeepCopyInto(out *InstanceReplicaConfiguration) { + *out = *in + if in.CaCertificate != nil { + in, out := &in.CaCertificate, &out.CaCertificate + *out = new(string) + **out = **in + } + if in.ClientCertificate != nil { + in, out := &in.ClientCertificate, &out.ClientCertificate + *out = new(string) + **out = **in + } + if in.ClientKey != nil { + in, out := &in.ClientKey, &out.ClientKey + *out = new(string) + **out = **in + } + if in.ConnectRetryInterval != nil { + in, out := &in.ConnectRetryInterval, &out.ConnectRetryInterval + *out = new(int64) + **out = **in + } + if in.DumpFilePath != nil { + in, out := &in.DumpFilePath, &out.DumpFilePath + *out = new(string) + **out = **in + } + if in.FailoverTarget != nil { + in, out := &in.FailoverTarget, &out.FailoverTarget + *out = new(bool) + **out = **in + } + if in.MasterHeartbeatPeriod != nil { + in, out := &in.MasterHeartbeatPeriod, &out.MasterHeartbeatPeriod + *out = new(int64) + **out = **in + } + if in.Password != nil { + in, out := &in.Password, &out.Password + *out = new(InstancePassword) + (*in).DeepCopyInto(*out) + } + if in.SslCipher != nil { + in, out := &in.SslCipher, &out.SslCipher + *out = new(string) + **out = **in + } + if in.Username != nil { + in, out := &in.Username, &out.Username + *out = new(string) + **out = **in + } + if in.VerifyServerCertificate != nil { + in, out := &in.VerifyServerCertificate, &out.VerifyServerCertificate + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceReplicaConfiguration. +func (in *InstanceReplicaConfiguration) DeepCopy() *InstanceReplicaConfiguration { + if in == nil { + return nil + } + out := new(InstanceReplicaConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceRootPassword) DeepCopyInto(out *InstanceRootPassword) { + *out = *in + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = new(string) + **out = **in + } + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(InstanceValueFrom) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceRootPassword. +func (in *InstanceRootPassword) DeepCopy() *InstanceRootPassword { + if in == nil { + return nil + } + out := new(InstanceRootPassword) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceServerCaCertStatus) DeepCopyInto(out *InstanceServerCaCertStatus) { + *out = *in + if in.Cert != nil { + in, out := &in.Cert, &out.Cert + *out = new(string) + **out = **in + } + if in.CommonName != nil { + in, out := &in.CommonName, &out.CommonName + *out = new(string) + **out = **in + } + if in.CreateTime != nil { + in, out := &in.CreateTime, &out.CreateTime + *out = new(string) + **out = **in + } + if in.ExpirationTime != nil { + in, out := &in.ExpirationTime, &out.ExpirationTime + *out = new(string) + **out = **in + } + if in.Sha1Fingerprint != nil { + in, out := &in.Sha1Fingerprint, &out.Sha1Fingerprint + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceServerCaCertStatus. +func (in *InstanceServerCaCertStatus) DeepCopy() *InstanceServerCaCertStatus { + if in == nil { + return nil + } + out := new(InstanceServerCaCertStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceSettings) DeepCopyInto(out *InstanceSettings) { + *out = *in + if in.ActivationPolicy != nil { + in, out := &in.ActivationPolicy, &out.ActivationPolicy + *out = new(string) + **out = **in + } + if in.ActiveDirectoryConfig != nil { + in, out := &in.ActiveDirectoryConfig, &out.ActiveDirectoryConfig + *out = new(InstanceActiveDirectoryConfig) + **out = **in + } + if in.AdvancedMachineFeatures != nil { + in, out := &in.AdvancedMachineFeatures, &out.AdvancedMachineFeatures + *out = new(InstanceAdvancedMachineFeatures) + (*in).DeepCopyInto(*out) + } + if in.AuthorizedGaeApplications != nil { + in, out := &in.AuthorizedGaeApplications, &out.AuthorizedGaeApplications + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.AvailabilityType != nil { + in, out := &in.AvailabilityType, &out.AvailabilityType + *out = new(string) + **out = **in + } + if in.BackupConfiguration != nil { + in, out := &in.BackupConfiguration, &out.BackupConfiguration + *out = new(InstanceBackupConfiguration) + (*in).DeepCopyInto(*out) + } + if in.Collation != nil { + in, out := &in.Collation, &out.Collation + *out = new(string) + **out = **in + } + if in.ConnectorEnforcement != nil { + in, out := &in.ConnectorEnforcement, &out.ConnectorEnforcement + *out = new(string) + **out = **in + } + if in.CrashSafeReplication != nil { + in, out := &in.CrashSafeReplication, &out.CrashSafeReplication + *out = new(bool) + **out = **in + } + if in.DataCacheConfig != nil { + in, out := &in.DataCacheConfig, &out.DataCacheConfig + *out = new(InstanceDataCacheConfig) + (*in).DeepCopyInto(*out) + } + if in.DatabaseFlags != nil { + in, out := &in.DatabaseFlags, &out.DatabaseFlags + *out = make([]InstanceDatabaseFlags, len(*in)) + copy(*out, *in) + } + if in.DeletionProtectionEnabled != nil { + in, out := &in.DeletionProtectionEnabled, &out.DeletionProtectionEnabled + *out = new(bool) + **out = **in + } + if in.DenyMaintenancePeriod != nil { + in, out := &in.DenyMaintenancePeriod, &out.DenyMaintenancePeriod + *out = new(InstanceDenyMaintenancePeriod) + **out = **in + } + if in.DiskAutoresize != nil { + in, out := &in.DiskAutoresize, &out.DiskAutoresize + *out = new(bool) + **out = **in + } + if in.DiskAutoresizeLimit != nil { + in, out := &in.DiskAutoresizeLimit, &out.DiskAutoresizeLimit + *out = new(int64) + **out = **in + } + if in.DiskSize != nil { + in, out := &in.DiskSize, &out.DiskSize + *out = new(int64) + **out = **in + } + if in.DiskType != nil { + in, out := &in.DiskType, &out.DiskType + *out = new(string) + **out = **in + } + if in.Edition != nil { + in, out := &in.Edition, &out.Edition + *out = new(string) + **out = **in + } + if in.InsightsConfig != nil { + in, out := &in.InsightsConfig, &out.InsightsConfig + *out = new(InstanceInsightsConfig) + (*in).DeepCopyInto(*out) + } + if in.IpConfiguration != nil { + in, out := &in.IpConfiguration, &out.IpConfiguration + *out = new(InstanceIpConfiguration) + (*in).DeepCopyInto(*out) + } + if in.LocationPreference != nil { + in, out := &in.LocationPreference, &out.LocationPreference + *out = new(InstanceLocationPreference) + (*in).DeepCopyInto(*out) + } + if in.MaintenanceWindow != nil { + in, out := &in.MaintenanceWindow, &out.MaintenanceWindow + *out = new(InstanceMaintenanceWindow) + (*in).DeepCopyInto(*out) + } + if in.PasswordValidationPolicy != nil { + in, out := &in.PasswordValidationPolicy, &out.PasswordValidationPolicy + *out = new(InstancePasswordValidationPolicy) + (*in).DeepCopyInto(*out) + } + if in.PricingPlan != nil { + in, out := &in.PricingPlan, &out.PricingPlan + *out = new(string) + **out = **in + } + if in.ReplicationType != nil { + in, out := &in.ReplicationType, &out.ReplicationType + *out = new(string) + **out = **in + } + if in.SqlServerAuditConfig != nil { + in, out := &in.SqlServerAuditConfig, &out.SqlServerAuditConfig + *out = new(InstanceSqlServerAuditConfig) + (*in).DeepCopyInto(*out) + } + if in.TimeZone != nil { + in, out := &in.TimeZone, &out.TimeZone + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceSettings. +func (in *InstanceSettings) DeepCopy() *InstanceSettings { + if in == nil { + return nil + } + out := new(InstanceSettings) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceSqlServerAuditConfig) DeepCopyInto(out *InstanceSqlServerAuditConfig) { + *out = *in + if in.BucketRef != nil { + in, out := &in.BucketRef, &out.BucketRef + *out = new(refsv1beta1.StorageBucketRef) + **out = **in + } + if in.RetentionInterval != nil { + in, out := &in.RetentionInterval, &out.RetentionInterval + *out = new(string) + **out = **in + } + if in.UploadInterval != nil { + in, out := &in.UploadInterval, &out.UploadInterval + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceSqlServerAuditConfig. +func (in *InstanceSqlServerAuditConfig) DeepCopy() *InstanceSqlServerAuditConfig { + if in == nil { + return nil + } + out := new(InstanceSqlServerAuditConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceValueFrom) DeepCopyInto(out *InstanceValueFrom) { + *out = *in + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(v1alpha1.SecretKeyRef) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceValueFrom. +func (in *InstanceValueFrom) DeepCopy() *InstanceValueFrom { + if in == nil { + return nil + } + out := new(InstanceValueFrom) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SQLInstance) DeepCopyInto(out *SQLInstance) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLInstance. +func (in *SQLInstance) DeepCopy() *SQLInstance { + if in == nil { + return nil + } + out := new(SQLInstance) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SQLInstance) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SQLInstanceList) DeepCopyInto(out *SQLInstanceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SQLInstance, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLInstanceList. +func (in *SQLInstanceList) DeepCopy() *SQLInstanceList { + if in == nil { + return nil + } + out := new(SQLInstanceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SQLInstanceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SQLInstanceSpec) DeepCopyInto(out *SQLInstanceSpec) { + *out = *in + if in.DatabaseVersion != nil { + in, out := &in.DatabaseVersion, &out.DatabaseVersion + *out = new(string) + **out = **in + } + if in.EncryptionKMSCryptoKeyRef != nil { + in, out := &in.EncryptionKMSCryptoKeyRef, &out.EncryptionKMSCryptoKeyRef + *out = new(refsv1beta1.KMSCryptoKeyRef) + **out = **in + } + if in.InstanceType != nil { + in, out := &in.InstanceType, &out.InstanceType + *out = new(string) + **out = **in + } + if in.MaintenanceVersion != nil { + in, out := &in.MaintenanceVersion, &out.MaintenanceVersion + *out = new(string) + **out = **in + } + if in.MasterInstanceRef != nil { + in, out := &in.MasterInstanceRef, &out.MasterInstanceRef + *out = new(refsv1beta1.SQLInstanceRef) + **out = **in + } + if in.Region != nil { + in, out := &in.Region, &out.Region + *out = new(string) + **out = **in + } + if in.ReplicaConfiguration != nil { + in, out := &in.ReplicaConfiguration, &out.ReplicaConfiguration + *out = new(InstanceReplicaConfiguration) + (*in).DeepCopyInto(*out) + } + if in.ResourceID != nil { + in, out := &in.ResourceID, &out.ResourceID + *out = new(string) + **out = **in + } + if in.RootPassword != nil { + in, out := &in.RootPassword, &out.RootPassword + *out = new(InstanceRootPassword) + (*in).DeepCopyInto(*out) + } + in.Settings.DeepCopyInto(&out.Settings) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLInstanceSpec. +func (in *SQLInstanceSpec) DeepCopy() *SQLInstanceSpec { + if in == nil { + return nil + } + out := new(SQLInstanceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SQLInstanceStatus) DeepCopyInto(out *SQLInstanceStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1alpha1.Condition, len(*in)) + copy(*out, *in) + } + if in.AvailableMaintenanceVersions != nil { + in, out := &in.AvailableMaintenanceVersions, &out.AvailableMaintenanceVersions + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ConnectionName != nil { + in, out := &in.ConnectionName, &out.ConnectionName + *out = new(string) + **out = **in + } + if in.DnsName != nil { + in, out := &in.DnsName, &out.DnsName + *out = new(string) + **out = **in + } + if in.FirstIpAddress != nil { + in, out := &in.FirstIpAddress, &out.FirstIpAddress + *out = new(string) + **out = **in + } + if in.InstanceType != nil { + in, out := &in.InstanceType, &out.InstanceType + *out = new(string) + **out = **in + } + if in.IpAddress != nil { + in, out := &in.IpAddress, &out.IpAddress + *out = make([]InstanceIpAddressStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ObservedGeneration != nil { + in, out := &in.ObservedGeneration, &out.ObservedGeneration + *out = new(int64) + **out = **in + } + if in.PrivateIpAddress != nil { + in, out := &in.PrivateIpAddress, &out.PrivateIpAddress + *out = new(string) + **out = **in + } + if in.PscServiceAttachmentLink != nil { + in, out := &in.PscServiceAttachmentLink, &out.PscServiceAttachmentLink + *out = new(string) + **out = **in + } + if in.PublicIpAddress != nil { + in, out := &in.PublicIpAddress, &out.PublicIpAddress + *out = new(string) + **out = **in + } + if in.SelfLink != nil { + in, out := &in.SelfLink, &out.SelfLink + *out = new(string) + **out = **in + } + if in.ServerCaCert != nil { + in, out := &in.ServerCaCert, &out.ServerCaCert + *out = new(InstanceServerCaCertStatus) + (*in).DeepCopyInto(*out) + } + if in.ServiceAccountEmailAddress != nil { + in, out := &in.ServiceAccountEmailAddress, &out.ServiceAccountEmailAddress + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SQLInstanceStatus. +func (in *SQLInstanceStatus) DeepCopy() *SQLInstanceStatus { + if in == nil { + return nil + } + out := new(SQLInstanceStatus) + in.DeepCopyInto(out) + return out +} diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_cloudbuildworkerpools.cloudbuild.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_cloudbuildworkerpools.cloudbuild.cnrm.cloud.google.com.yaml index 07c58ce43f..aa7df4abd2 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_cloudbuildworkerpools.cloudbuild.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_cloudbuildworkerpools.cloudbuild.cnrm.cloud.google.com.yaml @@ -71,7 +71,7 @@ spec: properties: external: description: The compute network selflink of form "projects//global/networks/", - when not managed by KCC. + when not managed by Config Connector. type: string name: description: The `name` field of a `ComputeNetwork` resource. @@ -276,7 +276,7 @@ spec: properties: external: description: The compute network selflink of form "projects//global/networks/", - when not managed by KCC. + when not managed by Config Connector. type: string name: description: The `name` field of a `ComputeNetwork` resource. diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_networkconnectivityserviceconnectionpolicies.networkconnectivity.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_networkconnectivityserviceconnectionpolicies.networkconnectivity.cnrm.cloud.google.com.yaml index 27d6d3e66d..d5ea58db53 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_networkconnectivityserviceconnectionpolicies.networkconnectivity.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_networkconnectivityserviceconnectionpolicies.networkconnectivity.cnrm.cloud.google.com.yaml @@ -79,7 +79,7 @@ spec: properties: external: description: The compute network selflink of form "projects//global/networks/", - when not managed by KCC. + when not managed by Config Connector. type: string name: description: The `name` field of a `ComputeNetwork` resource. diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_redisclusters.redis.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_redisclusters.redis.cnrm.cloud.google.com.yaml index f389d442e1..cf65539464 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_redisclusters.redis.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_redisclusters.redis.cnrm.cloud.google.com.yaml @@ -123,7 +123,7 @@ spec: properties: external: description: The compute network selflink of form "projects//global/networks/", - when not managed by KCC. + when not managed by Config Connector. type: string name: description: The `name` field of a `ComputeNetwork` resource. @@ -264,7 +264,7 @@ spec: external: description: The compute network selflink of form "projects//global/networks/", - when not managed by KCC. + when not managed by Config Connector. type: string name: description: The `name` field of a `ComputeNetwork` diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_sqlinstances.sql.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_sqlinstances.sql.cnrm.cloud.google.com.yaml index c18b9f7715..e3085be2af 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_sqlinstances.sql.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_sqlinstances.sql.cnrm.cloud.google.com.yaml @@ -16,6 +16,7 @@ spec: categories: - gcp kind: SQLInstance + listKind: SQLInstanceList plural: sqlinstances shortNames: - gcpsqlinstance @@ -43,23 +44,23 @@ spec: name: v1beta1 schema: openAPIV3Schema: + description: SQLInstance is the Schema for the sql API properties: apiVersion: - description: 'apiVersion defines the versioned schema of this representation + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: - description: 'kind is a string value representing the REST resource this + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object spec: properties: databaseVersion: - default: MYSQL_5_6 description: The MySQL, PostgreSQL or SQL Server (beta) version to use. Supported values include MYSQL_5_6, MYSQL_5_7, MYSQL_8_0, POSTGRES_9_6, POSTGRES_10, POSTGRES_11, POSTGRES_12, POSTGRES_13, POSTGRES_14, @@ -84,14 +85,14 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a `KMSCryptoKey` - resource.' + description: ' If provided must be in the format `projects/[kms_project_id]/locations/[region]/keyRings/[key_ring_id]/cryptoKeys/[key]`.' type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `KMSCryptoKey` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `metadata.namespace` field of a `KMSCryptoKey` + resource. type: string type: object instanceType: @@ -118,14 +119,14 @@ spec: - external properties: external: - description: 'Allowed value: The `name` field of a `SQLInstance` - resource.' + description: The SQLInstance selfLink, when not managed by Config + Connector. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `SQLInstance` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `SQLInstance` resource. type: string type: object region: @@ -155,6 +156,7 @@ spec: connectRetryInterval: description: Immutable. The number of seconds between connect retries. MySQL's default is 60 seconds. + format: int64 type: integer dumpFilePath: description: Immutable. Path to a SQL file in Google Cloud Storage @@ -169,20 +171,10 @@ spec: type: boolean masterHeartbeatPeriod: description: Immutable. Time in ms between replication heartbeats. + format: int64 type: integer password: description: Immutable. Password for the replication connection. - oneOf: - - not: - required: - - valueFrom - required: - - value - - not: - required: - - value - required: - - valueFrom properties: value: description: Value of the field. Cannot be used if 'valueFrom' @@ -204,11 +196,16 @@ spec: from. type: string required: - - name - key + - name type: object type: object type: object + x-kubernetes-validations: + - message: valueFrom is forbidden when value is specified + rule: 'has(self.value) ? !has(self.valueFrom) : true' + - message: value is forbidden when valueFrom is specified + rule: 'has(self.valueFrom) ? !has(self.value): true' sslCipher: description: Immutable. Permissible ciphers for use in SSL encryption. type: string @@ -227,17 +224,6 @@ spec: type: string rootPassword: description: Initial root password. Required for MS SQL Server. - oneOf: - - not: - required: - - valueFrom - required: - - value - - not: - required: - - value - required: - - valueFrom properties: value: description: Value of the field. Cannot be used if 'valueFrom' @@ -258,11 +244,16 @@ spec: description: Name of the Secret to extract a value from. type: string required: - - name - key + - name type: object type: object type: object + x-kubernetes-validations: + - message: valueFrom is forbidden when value is specified + rule: 'has(self.value) ? !has(self.valueFrom) : true' + - message: value is forbidden when valueFrom is specified + rule: 'has(self.valueFrom) ? !has(self.value): true' settings: description: The settings to use for the database. The configuration is detailed below. @@ -285,22 +276,25 @@ spec: threadsPerCore: description: The number of threads per physical core. Can be 1 or 2. + format: int64 type: integer type: object authorizedGaeApplications: - description: |- - DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. - Specifying this field has no-ops; it's recommended to remove this field from your configuration. + description: DEPRECATED. This property is only applicable to First + Generation instances, and First Generation instances are now + deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice + for information on how to upgrade to Second Generation instances. + Specifying this field has no-ops; it's recommended to remove + this field from your configuration. items: type: string type: array availabilityType: - description: |- - The availability type of the Cloud SQL instance, high availability - (REGIONAL) or single zone (ZONAL). For all instances, ensure that - settings.backup_configuration.enabled is set to true. - For MySQL instances, ensure that settings.backup_configuration.binary_log_enabled is set to true. - For Postgres instances, ensure that settings.backup_configuration.point_in_time_recovery_enabled + description: The availability type of the Cloud SQL instance, + high availability (REGIONAL) or single zone (ZONAL). For all + instances, ensure that settings.backup_configuration.enabled + is set to true. For MySQL instances, ensure that settings.backup_configuration.binary_log_enabled + is set to true. For Postgres instances, ensure that settings.backup_configuration.point_in_time_recovery_enabled is set to true. Defaults to ZONAL. type: string backupConfiguration: @@ -309,6 +303,7 @@ spec: properties: retainedBackups: description: Number of backups to retain. + format: int64 type: integer retentionUnit: description: The unit that 'retainedBackups' represents. @@ -338,6 +333,7 @@ spec: description: The number of days of transaction logs we retain for point in time restore, from 1-7. (For PostgreSQL Enterprise Plus instances, from 1 to 35.). + format: int64 type: integer type: object collation: @@ -347,9 +343,12 @@ spec: description: Specifies if connections must use Cloud SQL connectors. type: string crashSafeReplication: - description: |- - DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. - Specifying this field has no-ops; it's recommended to remove this field from your configuration. + description: DEPRECATED. This property is only applicable to First + Generation instances, and First Generation instances are now + deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice + for information on how to upgrade to Second Generation instances. + Specifying this field has no-ops; it's recommended to remove + this field from your configuration. type: boolean dataCacheConfig: description: Data cache configurations. @@ -406,11 +405,13 @@ spec: description: The maximum size, in GB, to which storage capacity can be automatically increased. The default value is 0, which specifies that there is no limit. + format: int64 type: integer diskSize: description: The size of data disk, in GB. Size of a running instance cannot be reduced but can be increased. The minimum value is 10GB. + format: int64 type: integer diskType: description: 'Immutable. The type of data disk: PD_SSD or PD_HDD. @@ -430,10 +431,12 @@ spec: description: Number of query execution plans captured by Insights per minute for all queries combined. Between 0 and 20. Default to 5. + format: int64 type: integer queryStringLength: description: Maximum query length stored in bytes. Between 256 and 4500. Default to 1024. + format: int64 type: integer recordApplicationTags: description: True if Query Insights will record application @@ -495,14 +498,15 @@ spec: - external properties: external: - description: 'Allowed value: The `selfLink` field of a - `ComputeNetwork` resource.' + description: The compute network selflink of form "projects//global/networks/", + when not managed by Config Connector. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `ComputeNetwork` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `ComputeNetwork` + resource. type: string type: object pscConfig: @@ -555,9 +559,11 @@ spec: properties: day: description: Day of week (1-7), starting on Monday. + format: int64 type: integer hour: description: Hour of day (0-23), ignored if day not set. + format: int64 type: integer updateTrack: description: Receive updates earlier (canary) or later (stable). @@ -576,6 +582,7 @@ spec: type: boolean minLength: description: Minimum number of characters allowed. + format: int64 type: integer passwordChangeInterval: description: Minimum interval after which the password can @@ -583,6 +590,7 @@ spec: type: string reuseInterval: description: Number of previous passwords that cannot be reused. + format: int64 type: integer required: - enablePasswordPolicy @@ -591,9 +599,12 @@ spec: description: Pricing plan for this instance, can only be PER_USE. type: string replicationType: - description: |- - DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. - Specifying this field has no-ops; it's recommended to remove this field from your configuration. + description: DEPRECATED. This property is only applicable to First + Generation instances, and First Generation instances are now + deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice + for information on how to upgrade to Second Generation instances. + Specifying this field has no-ops; it's recommended to remove + this field from your configuration. type: string sqlServerAuditConfig: properties: @@ -615,14 +626,15 @@ spec: - external properties: external: - description: 'Allowed value: The `url` field of a `StorageBucket` - resource.' + description: The StorageBucket selfLink, when not managed + by Config Connector. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `name` field of a `StorageBucket` resource. type: string namespace: - description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + description: The `namespace` field of a `StorageBucket` + resource. type: string type: object retentionInterval: @@ -662,8 +674,8 @@ spec: type: string type: array conditions: - description: Conditions represent the latest available observation - of the resource's current state. + description: Conditions represent the latest available observations + of the SQLInstance's current state. items: properties: lastTransitionTime: @@ -717,6 +729,7 @@ spec: If this is equal to metadata.generation, then that means that the current reported status reflects the most recent desired state of the resource. + format: int64 type: integer privateIpAddress: type: string @@ -758,9 +771,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/hack/compare-mock b/hack/compare-mock index 771dc46573..268920d4ab 100755 --- a/hack/compare-mock +++ b/hack/compare-mock @@ -16,5 +16,6 @@ E2E_GCP_TARGET=mock \ GOLDEN_REQUEST_CHECKS=1 \ GOLDEN_OBJECT_CHECKS=1 \ WRITE_GOLDEN_OUTPUT=1 \ +KCC_USE_DIRECT_RECONCILERS="SQLInstance" \ RUN_E2E=1 \ go test ./tests/e2e -timeout 3600s -v -run $RUN_TESTS \ No newline at end of file diff --git a/hack/record-gcp b/hack/record-gcp index a07b122fb5..f154e789fb 100755 --- a/hack/record-gcp +++ b/hack/record-gcp @@ -24,5 +24,6 @@ E2E_GCP_TARGET=real \ GOLDEN_REQUEST_CHECKS=1 \ GOLDEN_OBJECT_CHECKS=1 \ WRITE_GOLDEN_OUTPUT=1 \ +KCC_USE_DIRECT_RECONCILERS="SQLInstance" \ RUN_E2E=1 \ go test ./tests/e2e -timeout 3600s -v -run $RUN_TESTS \ No newline at end of file diff --git a/pkg/clients/generated/apis/sql/v1beta1/sqlinstance_types.go b/pkg/clients/generated/apis/sql/v1beta1/sqlinstance_types.go index db27c8ca35..010380c053 100644 --- a/pkg/clients/generated/apis/sql/v1beta1/sqlinstance_types.go +++ b/pkg/clients/generated/apis/sql/v1beta1/sqlinstance_types.go @@ -312,17 +312,11 @@ type InstanceSettings struct { // +optional AdvancedMachineFeatures *InstanceAdvancedMachineFeatures `json:"advancedMachineFeatures,omitempty"` - /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. - Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ + /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ // +optional AuthorizedGaeApplications []string `json:"authorizedGaeApplications,omitempty"` - /* The availability type of the Cloud SQL instance, high availability - (REGIONAL) or single zone (ZONAL). For all instances, ensure that - settings.backup_configuration.enabled is set to true. - For MySQL instances, ensure that settings.backup_configuration.binary_log_enabled is set to true. - For Postgres instances, ensure that settings.backup_configuration.point_in_time_recovery_enabled - is set to true. Defaults to ZONAL. */ + /* The availability type of the Cloud SQL instance, high availability (REGIONAL) or single zone (ZONAL). For all instances, ensure that settings.backup_configuration.enabled is set to true. For MySQL instances, ensure that settings.backup_configuration.binary_log_enabled is set to true. For Postgres instances, ensure that settings.backup_configuration.point_in_time_recovery_enabled is set to true. Defaults to ZONAL. */ // +optional AvailabilityType *string `json:"availabilityType,omitempty"` @@ -337,8 +331,7 @@ type InstanceSettings struct { // +optional ConnectorEnforcement *string `json:"connectorEnforcement,omitempty"` - /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. - Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ + /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ // +optional CrashSafeReplication *bool `json:"crashSafeReplication,omitempty"` @@ -397,8 +390,7 @@ type InstanceSettings struct { // +optional PricingPlan *string `json:"pricingPlan,omitempty"` - /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. - Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ + /* DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. Specifying this field has no-ops; it's recommended to remove this field from your configuration. */ // +optional ReplicationType *string `json:"replicationType,omitempty"` diff --git a/pkg/controller/direct/directbase/directbase_controller.go b/pkg/controller/direct/directbase/directbase_controller.go index cc85739fea..447a1d50cf 100644 --- a/pkg/controller/direct/directbase/directbase_controller.go +++ b/pkg/controller/direct/directbase/directbase_controller.go @@ -225,6 +225,10 @@ func (r *reconcileContext) doReconcile(ctx context.Context, u *unstructured.Unst adapter, err := r.Reconciler.model.AdapterForObject(ctx, r.Reconciler.Client, u) if err != nil { + if unwrappedErr, ok := lifecyclehandler.CausedByUnresolvableDeps(err); ok { + logger.Info(unwrappedErr.Error(), "resource", k8s.GetNamespacedName(u)) + return r.handleUnresolvableDeps(ctx, u, unwrappedErr) + } return false, r.handleUpdateFailed(ctx, u, err) } diff --git a/pkg/controller/direct/register/register.go b/pkg/controller/direct/register/register.go index f51dd47ea5..076a22e905 100644 --- a/pkg/controller/direct/register/register.go +++ b/pkg/controller/direct/register/register.go @@ -25,4 +25,5 @@ import ( _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/networkconnectivity" _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/privateca" _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/resourcemanager" + _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/sql" ) diff --git a/pkg/controller/direct/sql/client.go b/pkg/controller/direct/sql/client.go new file mode 100644 index 0000000000..baeb59ecee --- /dev/null +++ b/pkg/controller/direct/sql/client.go @@ -0,0 +1,100 @@ +// Copyright 2024 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 ( + "context" + "fmt" + "net/http" + + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/config" + "google.golang.org/api/option" + api "google.golang.org/api/sqladmin/v1beta4" +) + +type gcpClient struct { + config config.ControllerConfig + service *api.Service +} + +func newGCPClient(ctx context.Context, config *config.ControllerConfig) (*gcpClient, error) { + gcpClient := &gcpClient{ + config: *config, + } + + opts, err := gcpClient.options() + if err != nil { + return nil, err + } + + gcpClient.service, err = api.NewService(ctx, opts...) + if err != nil { + return nil, fmt.Errorf("building gcp service client: %w", err) + } + + return gcpClient, nil +} + +func (m *gcpClient) options() ([]option.ClientOption, error) { + var opts []option.ClientOption + if m.config.UserAgent != "" { + opts = append(opts, option.WithUserAgent(m.config.UserAgent)) + } + if m.config.HTTPClient != nil { + // TODO: Set UserAgent in this scenario (error is: WithHTTPClient is incompatible with gRPC dial options) + + httpClient := &http.Client{} + *httpClient = *m.config.HTTPClient + httpClient.Transport = &optionsRoundTripper{ + config: m.config, + inner: m.config.HTTPClient.Transport, + } + opts = append(opts, option.WithHTTPClient(httpClient)) + } + if m.config.UserProjectOverride && m.config.BillingProject != "" { + opts = append(opts, option.WithQuotaProject(m.config.BillingProject)) + } + + // TODO: support endpoints? + // if m.config.Endpoint != "" { + // opts = append(opts, option.WithEndpoint(m.config.Endpoint)) + // } + + return opts, nil +} + +type optionsRoundTripper struct { + config config.ControllerConfig + inner http.RoundTripper +} + +func (m *optionsRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + if m.config.UserAgent != "" { + req.Header.Set("User-Agent", m.config.UserAgent) + } + return m.inner.RoundTrip(req) +} + +func (m *gcpClient) sqlOperationsClient() *api.OperationsService { + return api.NewOperationsService(m.service) +} + +func (m *gcpClient) sqlInstancesClient() *api.InstancesService { + return api.NewInstancesService(m.service) +} + +func (m *gcpClient) sqlUsersClient() *api.UsersService { + return api.NewUsersService(m.service) +} diff --git a/pkg/controller/direct/sql/mapping.go b/pkg/controller/direct/sql/mapping.go new file mode 100644 index 0000000000..99fff3768c --- /dev/null +++ b/pkg/controller/direct/sql/mapping.go @@ -0,0 +1,531 @@ +// Copyright 2024 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 ( + "fmt" + + api "google.golang.org/api/sqladmin/v1beta4" + + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/sql/v1beta1" +) + +func SQLInstanceKRMToGCP(in *krm.SQLInstance, refs *SQLInstanceInternalRefs) (*api.DatabaseInstance, error) { + out := &api.DatabaseInstance{} + + if in == nil { + return nil, fmt.Errorf("cannot convert nil SQLInstance") + } + + if in.Spec.DatabaseVersion != nil { + out.DatabaseVersion = *in.Spec.DatabaseVersion + } + + if in.Spec.EncryptionKMSCryptoKeyRef != nil { + out.DiskEncryptionConfiguration = &api.DiskEncryptionConfiguration{ + Kind: "sql#diskEncryptionConfiguration", + KmsKeyName: refs.cryptoKey, + } + } + + if in.Spec.InstanceType != nil { + out.InstanceType = *in.Spec.InstanceType + } + + if in.Spec.MaintenanceVersion != nil { + out.MaintenanceVersion = *in.Spec.MaintenanceVersion + } + + if in.Spec.MasterInstanceRef != nil { + out.MasterInstanceName = refs.masterInstance + } + + if in.Spec.Region != nil { + out.Region = *in.Spec.Region + } + + if in.Spec.ReplicaConfiguration != nil { + replicaConfiguration := &api.ReplicaConfiguration{ + Kind: "sql#replicaConfiguration", + } + + if in.Spec.ReplicaConfiguration.FailoverTarget != nil { + replicaConfiguration.FailoverTarget = *in.Spec.ReplicaConfiguration.FailoverTarget + } + + // todo: requires mysql + if in.Spec.ReplicaConfiguration.CaCertificate != nil || + in.Spec.ReplicaConfiguration.ClientCertificate != nil || + in.Spec.ReplicaConfiguration.ClientKey != nil || + in.Spec.ReplicaConfiguration.ConnectRetryInterval != nil || + in.Spec.ReplicaConfiguration.DumpFilePath != nil || + in.Spec.ReplicaConfiguration.MasterHeartbeatPeriod != nil || + in.Spec.ReplicaConfiguration.Password != nil || + in.Spec.ReplicaConfiguration.SslCipher != nil || + in.Spec.ReplicaConfiguration.Username != nil || + in.Spec.ReplicaConfiguration.VerifyServerCertificate != nil { + replicaConfiguration.MysqlReplicaConfiguration = &api.MySqlReplicaConfiguration{} + } + + if in.Spec.ReplicaConfiguration.CaCertificate != nil { + replicaConfiguration.MysqlReplicaConfiguration.CaCertificate = *in.Spec.ReplicaConfiguration.CaCertificate + } + + if in.Spec.ReplicaConfiguration.ClientCertificate != nil { + replicaConfiguration.MysqlReplicaConfiguration.ClientCertificate = *in.Spec.ReplicaConfiguration.ClientCertificate + } + + if in.Spec.ReplicaConfiguration.ClientKey != nil { + replicaConfiguration.MysqlReplicaConfiguration.ClientKey = *in.Spec.ReplicaConfiguration.ClientKey + } + + if in.Spec.ReplicaConfiguration.ConnectRetryInterval != nil { + replicaConfiguration.MysqlReplicaConfiguration.ConnectRetryInterval = *in.Spec.ReplicaConfiguration.ConnectRetryInterval + } + + if in.Spec.ReplicaConfiguration.DumpFilePath != nil { + replicaConfiguration.MysqlReplicaConfiguration.DumpFilePath = *in.Spec.ReplicaConfiguration.DumpFilePath + } + + if in.Spec.ReplicaConfiguration.MasterHeartbeatPeriod != nil { + replicaConfiguration.MysqlReplicaConfiguration.MasterHeartbeatPeriod = *in.Spec.ReplicaConfiguration.MasterHeartbeatPeriod + } + + if in.Spec.ReplicaConfiguration.Password != nil { + replicaConfiguration.MysqlReplicaConfiguration.Password = refs.replicaPassword + } + + if in.Spec.ReplicaConfiguration.SslCipher != nil { + replicaConfiguration.MysqlReplicaConfiguration.SslCipher = *in.Spec.ReplicaConfiguration.SslCipher + } + + if in.Spec.ReplicaConfiguration.Username != nil { + replicaConfiguration.MysqlReplicaConfiguration.Username = *in.Spec.ReplicaConfiguration.Username + } + + if in.Spec.ReplicaConfiguration.VerifyServerCertificate != nil { + replicaConfiguration.MysqlReplicaConfiguration.VerifyServerCertificate = *in.Spec.ReplicaConfiguration.VerifyServerCertificate + } + + out.ReplicaConfiguration = replicaConfiguration + } + + if in.Spec.ResourceID != nil { + out.Name = *in.Spec.ResourceID + } else { + return nil, fmt.Errorf("resourceID is empty") + } + + if in.Spec.RootPassword != nil && refs.rootPassword != "" { + out.RootPassword = refs.rootPassword + } + + out.Settings = &api.Settings{} + + if in.Spec.Settings.ActivationPolicy != nil { + out.Settings.ActivationPolicy = *in.Spec.Settings.ActivationPolicy + } + + if in.Spec.Settings.ActiveDirectoryConfig != nil { + // todo: requires sqlserver + // todo: requires private network + out.Settings.ActiveDirectoryConfig = &api.SqlActiveDirectoryConfig{ + Domain: in.Spec.Settings.ActiveDirectoryConfig.Domain, + } + } + + if in.Spec.Settings.AdvancedMachineFeatures != nil { + // todo: requires sqlserver + // todo: requires >= 6 cpu cores + out.Settings.AdvancedMachineFeatures = &api.AdvancedMachineFeatures{} + if in.Spec.Settings.AdvancedMachineFeatures.ThreadsPerCore != nil { + out.Settings.AdvancedMachineFeatures.ThreadsPerCore = *in.Spec.Settings.AdvancedMachineFeatures.ThreadsPerCore + } + } + + if in.Spec.Settings.AuthorizedGaeApplications != nil { + // todo: deprecated + out.Settings.AuthorizedGaeApplications = in.Spec.Settings.AuthorizedGaeApplications + } + + if in.Spec.Settings.AvailabilityType != nil { + out.Settings.AvailabilityType = *in.Spec.Settings.AvailabilityType + } + + if in.Spec.Settings.BackupConfiguration != nil { + backupConfig := &api.BackupConfiguration{} + + if in.Spec.Settings.BackupConfiguration.BackupRetentionSettings != nil { + retentionSettings := &api.BackupRetentionSettings{ + RetainedBackups: in.Spec.Settings.BackupConfiguration.BackupRetentionSettings.RetainedBackups, + } + if in.Spec.Settings.BackupConfiguration.BackupRetentionSettings.RetentionUnit != nil { + retentionSettings.RetentionUnit = *in.Spec.Settings.BackupConfiguration.BackupRetentionSettings.RetentionUnit + } + backupConfig.BackupRetentionSettings = retentionSettings + } + + if in.Spec.Settings.BackupConfiguration.BinaryLogEnabled != nil { + // todo: requires mysql + backupConfig.BinaryLogEnabled = *in.Spec.Settings.BackupConfiguration.BinaryLogEnabled + } + + if in.Spec.Settings.BackupConfiguration.Enabled != nil { + backupConfig.Enabled = *in.Spec.Settings.BackupConfiguration.Enabled + } + + if in.Spec.Settings.BackupConfiguration.Location != nil { + backupConfig.Location = *in.Spec.Settings.BackupConfiguration.Location + } + + if in.Spec.Settings.BackupConfiguration.PointInTimeRecoveryEnabled != nil { + backupConfig.PointInTimeRecoveryEnabled = *in.Spec.Settings.BackupConfiguration.PointInTimeRecoveryEnabled + } + + if in.Spec.Settings.BackupConfiguration.StartTime != nil { + backupConfig.StartTime = *in.Spec.Settings.BackupConfiguration.StartTime + } + + if in.Spec.Settings.BackupConfiguration.TransactionLogRetentionDays != nil { + backupConfig.TransactionLogRetentionDays = *in.Spec.Settings.BackupConfiguration.TransactionLogRetentionDays + } + + out.Settings.BackupConfiguration = backupConfig + } + + if in.Spec.Settings.Collation != nil { + // todo: requires sqlserver + out.Settings.Collation = *in.Spec.Settings.Collation + } + + if in.Spec.Settings.ConnectorEnforcement != nil { + out.Settings.ConnectorEnforcement = *in.Spec.Settings.ConnectorEnforcement + } + + if in.Spec.Settings.CrashSafeReplication != nil { + // todo: deprecated + out.Settings.CrashSafeReplicationEnabled = *in.Spec.Settings.CrashSafeReplication + } + + if in.Spec.Settings.DataCacheConfig != nil { + // todo: requires ENTERPRISE_PLUS edition + // todo: requires mysql or postgres + out.Settings.DataCacheConfig = &api.DataCacheConfig{ + DataCacheEnabled: *in.Spec.Settings.DataCacheConfig.DataCacheEnabled, + } + } + + if in.Spec.Settings.DatabaseFlags != nil { + dbFlags := []*api.DatabaseFlags{} + for _, dbFlag := range in.Spec.Settings.DatabaseFlags { + dbFlags = append(dbFlags, &api.DatabaseFlags{ + Name: dbFlag.Name, + Value: dbFlag.Value, + }) + } + out.Settings.DatabaseFlags = dbFlags + } + + if in.Spec.Settings.DeletionProtectionEnabled != nil { + out.Settings.DeletionProtectionEnabled = *in.Spec.Settings.DeletionProtectionEnabled + } + + if in.Spec.Settings.DenyMaintenancePeriod != nil { + // todo: handle multiple periods (?) + out.Settings.DenyMaintenancePeriods = []*api.DenyMaintenancePeriod{ + { + EndDate: in.Spec.Settings.DenyMaintenancePeriod.EndDate, + StartDate: in.Spec.Settings.DenyMaintenancePeriod.StartDate, + Time: in.Spec.Settings.DenyMaintenancePeriod.Time, + }, + } + } + + if in.Spec.Settings.DiskAutoresize != nil { + out.Settings.StorageAutoResize = in.Spec.Settings.DiskAutoresize + } + + if in.Spec.Settings.DiskAutoresizeLimit != nil { + // todo: requires DiskAutoresize == true + out.Settings.StorageAutoResizeLimit = *in.Spec.Settings.DiskAutoresizeLimit + } + + if in.Spec.Settings.DiskSize != nil { + out.Settings.DataDiskSizeGb = *in.Spec.Settings.DiskSize + } + + if in.Spec.Settings.DiskType != nil { + out.Settings.DataDiskType = *in.Spec.Settings.DiskType + } + + if in.Spec.Settings.Edition != nil { + out.Settings.Edition = *in.Spec.Settings.Edition + } + + if in.Spec.Settings.InsightsConfig != nil { + insightsConfig := &api.InsightsConfig{} + + if in.Spec.Settings.InsightsConfig.QueryInsightsEnabled != nil { + insightsConfig.QueryInsightsEnabled = *in.Spec.Settings.InsightsConfig.QueryInsightsEnabled + } + + if in.Spec.Settings.InsightsConfig.QueryPlansPerMinute != nil { + insightsConfig.QueryPlansPerMinute = *in.Spec.Settings.InsightsConfig.QueryPlansPerMinute + } + + if in.Spec.Settings.InsightsConfig.QueryStringLength != nil { + insightsConfig.QueryStringLength = *in.Spec.Settings.InsightsConfig.QueryStringLength + } + + if in.Spec.Settings.InsightsConfig.RecordApplicationTags != nil { + insightsConfig.RecordApplicationTags = *in.Spec.Settings.InsightsConfig.RecordApplicationTags + } + + if in.Spec.Settings.InsightsConfig.RecordClientAddress != nil { + insightsConfig.RecordClientAddress = *in.Spec.Settings.InsightsConfig.RecordClientAddress + } + + out.Settings.InsightsConfig = insightsConfig + } + + if in.Spec.Settings.IpConfiguration != nil { + out.Settings.IpConfiguration = &api.IpConfiguration{} + + if in.Spec.Settings.IpConfiguration.AllocatedIpRange != nil { + out.Settings.IpConfiguration.AllocatedIpRange = *in.Spec.Settings.IpConfiguration.AllocatedIpRange + } + + if in.Spec.Settings.IpConfiguration.AuthorizedNetworks != nil { + authorizedNetworks := []*api.AclEntry{} + for _, net := range in.Spec.Settings.IpConfiguration.AuthorizedNetworks { + netEntry := &api.AclEntry{ + Kind: "sql#aclEntry", + Value: net.Value, + } + if net.ExpirationTime != nil { + netEntry.ExpirationTime = *net.ExpirationTime + } + if net.Name != nil { + netEntry.Name = *net.Name + } + authorizedNetworks = append(authorizedNetworks, netEntry) + } + out.Settings.IpConfiguration.AuthorizedNetworks = authorizedNetworks + } + + if in.Spec.Settings.IpConfiguration.EnablePrivatePathForGoogleCloudServices != nil { + out.Settings.IpConfiguration.EnablePrivatePathForGoogleCloudServices = *in.Spec.Settings.IpConfiguration.EnablePrivatePathForGoogleCloudServices + } + + if in.Spec.Settings.IpConfiguration.Ipv4Enabled != nil { + out.Settings.IpConfiguration.Ipv4Enabled = *in.Spec.Settings.IpConfiguration.Ipv4Enabled + } else { + out.Settings.IpConfiguration.Ipv4Enabled = false + } + // todo: must do this for all fields (?) + out.Settings.IpConfiguration.ForceSendFields = []string{"Ipv4Enabled"} + + if in.Spec.Settings.IpConfiguration.PrivateNetworkRef != nil { + out.Settings.IpConfiguration.PrivateNetwork = refs.privateNetwork + } + + if in.Spec.Settings.IpConfiguration.PscConfig != nil { + if len(in.Spec.Settings.IpConfiguration.PscConfig) != 1 { + return nil, fmt.Errorf("only one psc config allowed per instance") + } + out.Settings.IpConfiguration.PscConfig = &api.PscConfig{ + AllowedConsumerProjects: in.Spec.Settings.IpConfiguration.PscConfig[0].AllowedConsumerProjects, + } + if in.Spec.Settings.IpConfiguration.PscConfig[0].PscEnabled != nil { + out.Settings.IpConfiguration.PscConfig.PscEnabled = *in.Spec.Settings.IpConfiguration.PscConfig[0].PscEnabled + } + } + + if in.Spec.Settings.IpConfiguration.RequireSsl != nil { + // todo: deprecated + out.Settings.IpConfiguration.RequireSsl = *in.Spec.Settings.IpConfiguration.RequireSsl + } + + if in.Spec.Settings.IpConfiguration.SslMode != nil { + out.Settings.IpConfiguration.SslMode = *in.Spec.Settings.IpConfiguration.SslMode + } + } + + if in.Spec.Settings.LocationPreference != nil { + out.Settings.LocationPreference = &api.LocationPreference{} + if in.Spec.Settings.LocationPreference.FollowGaeApplication != nil { + // todo: deprecated + out.Settings.LocationPreference.FollowGaeApplication = *in.Spec.Settings.LocationPreference.FollowGaeApplication + } + if in.Spec.Settings.LocationPreference.SecondaryZone != nil { + out.Settings.LocationPreference.SecondaryZone = *in.Spec.Settings.LocationPreference.SecondaryZone + } + if in.Spec.Settings.LocationPreference.Zone != nil { + out.Settings.LocationPreference.Zone = *in.Spec.Settings.LocationPreference.Zone + } + } + + if in.Spec.Settings.MaintenanceWindow != nil { + out.Settings.MaintenanceWindow = &api.MaintenanceWindow{} + if in.Spec.Settings.MaintenanceWindow.Day != nil { + out.Settings.MaintenanceWindow.Day = *in.Spec.Settings.MaintenanceWindow.Day + } + if in.Spec.Settings.MaintenanceWindow.Hour != nil { + out.Settings.MaintenanceWindow.Hour = *in.Spec.Settings.MaintenanceWindow.Hour + } + if in.Spec.Settings.MaintenanceWindow.UpdateTrack != nil { + out.Settings.MaintenanceWindow.UpdateTrack = *in.Spec.Settings.MaintenanceWindow.UpdateTrack + } + } + + if in.Spec.Settings.PasswordValidationPolicy != nil { + policy := &api.PasswordValidationPolicy{ + EnablePasswordPolicy: in.Spec.Settings.PasswordValidationPolicy.EnablePasswordPolicy, + } + + if in.Spec.Settings.PasswordValidationPolicy.Complexity != nil { + policy.Complexity = *in.Spec.Settings.PasswordValidationPolicy.Complexity + } + + if in.Spec.Settings.PasswordValidationPolicy.DisallowUsernameSubstring != nil { + policy.DisallowUsernameSubstring = *in.Spec.Settings.PasswordValidationPolicy.DisallowUsernameSubstring + } + + if in.Spec.Settings.PasswordValidationPolicy.MinLength != nil { + policy.MinLength = *in.Spec.Settings.PasswordValidationPolicy.MinLength + } + + if in.Spec.Settings.PasswordValidationPolicy.PasswordChangeInterval != nil { + policy.PasswordChangeInterval = *in.Spec.Settings.PasswordValidationPolicy.PasswordChangeInterval + } + + if in.Spec.Settings.PasswordValidationPolicy.ReuseInterval != nil { + policy.ReuseInterval = *in.Spec.Settings.PasswordValidationPolicy.ReuseInterval + } + + out.Settings.PasswordValidationPolicy = policy + } + + if in.Spec.Settings.PricingPlan != nil { + // todo: can only be PER_USE + out.Settings.PricingPlan = *in.Spec.Settings.PricingPlan + } + + if in.Spec.Settings.ReplicationType != nil { + // todo: deprecated + out.Settings.ReplicationType = *in.Spec.Settings.ReplicationType + } + + if in.Spec.Settings.SqlServerAuditConfig != nil { + // todo: requires sqlserver + out.Settings.SqlServerAuditConfig = &api.SqlServerAuditConfig{ + Kind: "sql#sqlServerAuditConfig", + } + + if in.Spec.Settings.SqlServerAuditConfig.BucketRef != nil { + // todo: required + out.Settings.SqlServerAuditConfig.Bucket = refs.auditLogBucket + } + + if in.Spec.Settings.SqlServerAuditConfig.RetentionInterval != nil { + out.Settings.SqlServerAuditConfig.RetentionInterval = *in.Spec.Settings.SqlServerAuditConfig.RetentionInterval + } + + if in.Spec.Settings.SqlServerAuditConfig.UploadInterval != nil { + out.Settings.SqlServerAuditConfig.UploadInterval = *in.Spec.Settings.SqlServerAuditConfig.UploadInterval + } + } + + out.Settings.Tier = in.Spec.Settings.Tier + + if in.Spec.Settings.TimeZone != nil { + // todo: requires sqlserver + out.Settings.TimeZone = *in.Spec.Settings.TimeZone + } + + if in.Labels != nil { + out.Settings.UserLabels = make(map[string]string) + for k, v := range in.Labels { + out.Settings.UserLabels[k] = v + } + } + + return out, nil +} + +func Convert_SQLInstance_API_v1_To_KRM_status(in *api.DatabaseInstance, out *krm.SQLInstanceStatus) error { + if in == nil { + return fmt.Errorf("cannot convert nil DatabaseInstance") + } + + if in.AvailableMaintenanceVersions != nil { + out.AvailableMaintenanceVersions = append(out.AvailableMaintenanceVersions, in.AvailableMaintenanceVersions...) + } + + out.ConnectionName = LazyPtr(in.ConnectionName) + + out.DnsName = LazyPtr(in.DnsName) + + if len(in.IpAddresses) >= 1 { + out.FirstIpAddress = LazyPtr(in.IpAddresses[0].IpAddress) + } + + out.InstanceType = LazyPtr(in.InstanceType) + + if in.IpAddresses != nil { + for _, ia := range in.IpAddresses { + ipAddr := krm.InstanceIpAddressStatus{ + IpAddress: LazyPtr(ia.IpAddress), + TimeToRetire: LazyPtr(ia.TimeToRetire), + Type: LazyPtr(ia.Type), + } + out.IpAddress = append(out.IpAddress, ipAddr) + + if ia.Type == "PRIMARY" { + out.PublicIpAddress = LazyPtr(ia.IpAddress) + } + + if ia.Type == "PRIVATE" { + out.PrivateIpAddress = LazyPtr(ia.IpAddress) + } + } + } + + out.PscServiceAttachmentLink = LazyPtr(in.PscServiceAttachmentLink) + + out.SelfLink = LazyPtr(in.SelfLink) + + if in.ServerCaCert != nil { + out.ServerCaCert = &krm.InstanceServerCaCertStatus{ + Cert: LazyPtr(in.ServerCaCert.Cert), + CommonName: LazyPtr(in.ServerCaCert.CommonName), + CreateTime: LazyPtr(in.ServerCaCert.CreateTime), + ExpirationTime: LazyPtr(in.ServerCaCert.ExpirationTime), + Sha1Fingerprint: LazyPtr(in.ServerCaCert.Sha1Fingerprint), + } + } + + out.ServiceAccountEmailAddress = LazyPtr(in.ServiceAccountEmailAddress) + + return nil +} + +func LazyPtr[T comparable](v T) *T { + var defaultValue T + if v == defaultValue { + return nil + } + return &v +} diff --git a/pkg/controller/direct/sql/merge.go b/pkg/controller/direct/sql/merge.go new file mode 100644 index 0000000000..10966dd654 --- /dev/null +++ b/pkg/controller/direct/sql/merge.go @@ -0,0 +1,907 @@ +// Copyright 2024 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 ( + "fmt" + "reflect" + + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/sql/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" + api "google.golang.org/api/sqladmin/v1beta4" +) + +// The goal of this function is to merge the desired state with the actual API state. Some fields in the API are defaulted by GCP. +// Additionally, some fields may be desirable to "unmanage". To handle these quirks, this function implements some merging logic +// for every API field. +func MergeDesiredSQLInstanceWithActual(desired *krm.SQLInstance, refs *SQLInstanceInternalRefs, actual *api.DatabaseInstance) (*api.DatabaseInstance, bool, error) { + merged := &api.DatabaseInstance{} + updateRequired := false + + if desired == nil || actual == nil { + return nil, false, fmt.Errorf("cannot merge nil SQLInstance") + } + + if desired.Spec.ResourceID != nil { + merged.Name = direct.ValueOf(desired.Spec.ResourceID) + } else { + merged.Name = desired.Name + } + if merged.Name != actual.Name { + return nil, false, fmt.Errorf("cannot rename SQLInstance") + } + + if desired.Spec.DatabaseVersion != nil { + if direct.ValueOf(desired.Spec.DatabaseVersion) != actual.DatabaseVersion { + // Change version + updateRequired = true + } + merged.DatabaseVersion = direct.ValueOf(desired.Spec.DatabaseVersion) + } else { + // Keep same version + merged.DatabaseVersion = actual.DatabaseVersion + } + + if desired.Spec.EncryptionKMSCryptoKeyRef != nil { + if actual.DiskEncryptionConfiguration == nil { + // Add key + updateRequired = true + } else if refs.cryptoKey != actual.DiskEncryptionConfiguration.KmsKeyName { + // Change keys + updateRequired = true + } + merged.DiskEncryptionConfiguration = &api.DiskEncryptionConfiguration{ + Kind: "sql#diskEncryptionConfiguration", + KmsKeyName: refs.cryptoKey, + } + } else if actual.DiskEncryptionConfiguration != nil { + // Remove key + updateRequired = true + } + + if desired.Spec.InstanceType != nil { + if direct.ValueOf(desired.Spec.InstanceType) != actual.InstanceType { + // Change instance type + updateRequired = true + } + merged.InstanceType = direct.ValueOf(desired.Spec.InstanceType) + } else { + // Keep instance type + merged.InstanceType = actual.InstanceType + } + + if desired.Spec.MaintenanceVersion != nil { + if direct.ValueOf(desired.Spec.MaintenanceVersion) != actual.MaintenanceVersion { + // Change maintenance version + updateRequired = true + } + merged.MaintenanceVersion = direct.ValueOf(desired.Spec.MaintenanceVersion) + } else { + // Keep maintenance version + merged.MaintenanceVersion = actual.MaintenanceVersion + } + + if desired.Spec.MasterInstanceRef != nil { + if refs.masterInstance != actual.MasterInstanceName { + // Change master + updateRequired = true + } + merged.MasterInstanceName = refs.masterInstance + } else if actual.MasterInstanceName != "" { + // Remove master + updateRequired = true + } + + if desired.Spec.Region != nil { + if direct.ValueOf(desired.Spec.Region) != actual.Region { + // Change region + updateRequired = true + } + merged.Region = direct.ValueOf(desired.Spec.Region) + } else { + // Keep region + merged.Region = actual.Region + } + + existingReplicaConfig := actual.ReplicaConfiguration != nil + if desired.Spec.ReplicaConfiguration != nil { + existingMysqlReplicaConfig := existingReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration != nil + + if !existingReplicaConfig { + // Add replica configuration + updateRequired = true + } + + merged.ReplicaConfiguration = &api.ReplicaConfiguration{ + Kind: "sql#replicaConfiguration", + } + + if desired.Spec.ReplicaConfiguration.FailoverTarget != nil { + if existingReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.FailoverTarget) != actual.ReplicaConfiguration.FailoverTarget { + // Change failover target + updateRequired = true + } + } else { + // Add failover target + updateRequired = true + } + merged.ReplicaConfiguration.FailoverTarget = direct.ValueOf(desired.Spec.ReplicaConfiguration.FailoverTarget) + } else if existingReplicaConfig { + // Remove failover target + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.CaCertificate != nil || + desired.Spec.ReplicaConfiguration.ClientCertificate != nil || + desired.Spec.ReplicaConfiguration.ClientKey != nil || + desired.Spec.ReplicaConfiguration.ConnectRetryInterval != nil || + desired.Spec.ReplicaConfiguration.DumpFilePath != nil || + desired.Spec.ReplicaConfiguration.MasterHeartbeatPeriod != nil || + desired.Spec.ReplicaConfiguration.Password != nil || + desired.Spec.ReplicaConfiguration.SslCipher != nil || + desired.Spec.ReplicaConfiguration.Username != nil || + desired.Spec.ReplicaConfiguration.VerifyServerCertificate != nil { + merged.ReplicaConfiguration.MysqlReplicaConfiguration = &api.MySqlReplicaConfiguration{} + } + + if desired.Spec.ReplicaConfiguration.CaCertificate != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.CaCertificate) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.CaCertificate { + // Change CA certificate + updateRequired = true + } + } else { + // Add CA certificate + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.CaCertificate = direct.ValueOf(desired.Spec.ReplicaConfiguration.CaCertificate) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.CaCertificate != "" { + // Remove CA certificate + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.ClientCertificate != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.ClientCertificate) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.ClientCertificate { + // Change client certificate + updateRequired = true + } + } else { + // Add client certificate + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.ClientCertificate = direct.ValueOf(desired.Spec.ReplicaConfiguration.ClientCertificate) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.ClientCertificate != "" { + // Remove client certificate + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.ClientKey != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.ClientKey) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.ClientKey { + // Change client key + updateRequired = true + } + } else { + // Add client key + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.ClientKey = direct.ValueOf(desired.Spec.ReplicaConfiguration.ClientKey) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.ClientKey != "" { + // Remove client key + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.ConnectRetryInterval != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.ConnectRetryInterval) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.ConnectRetryInterval { + // Change connect retry interval + updateRequired = true + } + } else { + // Add connect retry interval + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.ConnectRetryInterval = direct.ValueOf(desired.Spec.ReplicaConfiguration.ConnectRetryInterval) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.ConnectRetryInterval != 0 { + // Remove connect retry interval + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.DumpFilePath != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.DumpFilePath) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.DumpFilePath { + // Change dump file path + updateRequired = true + } + } else { + // Add dump file path + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.DumpFilePath = direct.ValueOf(desired.Spec.ReplicaConfiguration.DumpFilePath) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.DumpFilePath != "" { + // Remove dump file path + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.MasterHeartbeatPeriod != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.MasterHeartbeatPeriod) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.MasterHeartbeatPeriod { + // Change master heartbeat period + updateRequired = true + } + } else { + // Add master heartbeat period + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.MasterHeartbeatPeriod = direct.ValueOf(desired.Spec.ReplicaConfiguration.MasterHeartbeatPeriod) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.MasterHeartbeatPeriod != 0 { + // Remove master heartbeat period + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.Password != nil { + if existingMysqlReplicaConfig { + if refs.replicaPassword != actual.ReplicaConfiguration.MysqlReplicaConfiguration.Password { + // Change password + updateRequired = true + } + } else { + // Add password + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.Password = refs.replicaPassword + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.Password != "" { + // Remove password + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.SslCipher != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.SslCipher) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.SslCipher { + // Change SSL cipher + updateRequired = true + } + } else { + // Add SSL cipher + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.SslCipher = direct.ValueOf(desired.Spec.ReplicaConfiguration.SslCipher) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.SslCipher != "" { + // Remove SSL cipher + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.Username != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.Username) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.Username { + // Change username + updateRequired = true + } + } else { + // Add username + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.Username = direct.ValueOf(desired.Spec.ReplicaConfiguration.Username) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.Username != "" { + // Remove username + updateRequired = true + } + + if desired.Spec.ReplicaConfiguration.VerifyServerCertificate != nil { + if existingMysqlReplicaConfig { + if direct.ValueOf(desired.Spec.ReplicaConfiguration.VerifyServerCertificate) != actual.ReplicaConfiguration.MysqlReplicaConfiguration.VerifyServerCertificate { + // Change verify server certificate + updateRequired = true + } + } else { + // Add verify server certificate + updateRequired = true + } + merged.ReplicaConfiguration.MysqlReplicaConfiguration.VerifyServerCertificate = direct.ValueOf(desired.Spec.ReplicaConfiguration.VerifyServerCertificate) + } else if existingMysqlReplicaConfig && actual.ReplicaConfiguration.MysqlReplicaConfiguration.VerifyServerCertificate { + // Remove verify server certificate + updateRequired = true + } + } else if existingReplicaConfig { + // Remove replica configuration + updateRequired = true + } + + if desired.Spec.RootPassword != nil && refs.rootPassword != "" { + if refs.rootPassword != actual.RootPassword { + // Change root password + updateRequired = true + } + merged.RootPassword = refs.rootPassword + } else { + // Keep root password + merged.RootPassword = actual.RootPassword + } + + merged.Settings = &api.Settings{ + SettingsVersion: actual.Settings.SettingsVersion, + } + + if desired.Spec.Settings.ActivationPolicy != nil { + if direct.ValueOf(desired.Spec.Settings.ActivationPolicy) != actual.Settings.ActivationPolicy { + // Change activation policy + updateRequired = true + } + merged.Settings.ActivationPolicy = direct.ValueOf(desired.Spec.Settings.ActivationPolicy) + } else { + // Keep activation policy + merged.Settings.ActivationPolicy = actual.Settings.ActivationPolicy + } + + if desired.Spec.Settings.ActiveDirectoryConfig != nil { + if actual.Settings.ActiveDirectoryConfig == nil { + // Add active directory config + updateRequired = true + } else if desired.Spec.Settings.ActiveDirectoryConfig.Domain != actual.Settings.ActiveDirectoryConfig.Domain { + // Change active directory config + updateRequired = true + } + merged.Settings.ActiveDirectoryConfig.Domain = desired.Spec.Settings.ActiveDirectoryConfig.Domain + } else if actual.Settings.ActiveDirectoryConfig != nil { + // Remove active directory config + updateRequired = true + } + + if desired.Spec.Settings.AdvancedMachineFeatures != nil { + if actual.Settings.AdvancedMachineFeatures == nil { + // Add advanced machine features + updateRequired = true + } else if desired.Spec.Settings.AdvancedMachineFeatures.ThreadsPerCore != &actual.Settings.AdvancedMachineFeatures.ThreadsPerCore { + // Change advanced machine features + updateRequired = true + } + merged.Settings.AdvancedMachineFeatures.ThreadsPerCore = direct.ValueOf(desired.Spec.Settings.AdvancedMachineFeatures.ThreadsPerCore) + } else if actual.Settings.AdvancedMachineFeatures != nil { + // Remove advanced machine features + updateRequired = true + } + + if desired.Spec.Settings.AuthorizedGaeApplications != nil { + if actual.Settings.AuthorizedGaeApplications == nil { + // Add authorized gae applications + updateRequired = true + } else if len(desired.Spec.Settings.AuthorizedGaeApplications) != len(actual.Settings.AuthorizedGaeApplications) { + // todo: fix this + // Change authorized gae applications + updateRequired = true + } + merged.Settings.AuthorizedGaeApplications = desired.Spec.Settings.AuthorizedGaeApplications + } else if len(actual.Settings.AuthorizedGaeApplications) > 0 { + // Remove authorized gae applications + updateRequired = true + } + + if desired.Spec.Settings.AvailabilityType != nil { + if direct.ValueOf(desired.Spec.Settings.AvailabilityType) != actual.Settings.AvailabilityType { + // Change availability type + updateRequired = true + } + merged.Settings.AvailabilityType = direct.ValueOf(desired.Spec.Settings.AvailabilityType) + } else { + // Keep availability type + merged.Settings.AvailabilityType = actual.Settings.AvailabilityType + } + + existingBackupConfig := actual.Settings.BackupConfiguration != nil + + if desired.Spec.Settings.BackupConfiguration != nil { + existingRetentionSettings := existingBackupConfig && actual.Settings.BackupConfiguration.BackupRetentionSettings != nil + + if !existingBackupConfig { + // Add backup configuration + updateRequired = true + } + + merged.Settings.BackupConfiguration = &api.BackupConfiguration{ + Kind: "sql#backupConfiguration", + } + + if desired.Spec.Settings.BackupConfiguration.BackupRetentionSettings != nil { + if !existingRetentionSettings { + // Add retention settings + updateRequired = true + } else if (desired.Spec.Settings.BackupConfiguration.BackupRetentionSettings.RetainedBackups != actual.Settings.BackupConfiguration.BackupRetentionSettings.RetainedBackups) || + (direct.ValueOf(desired.Spec.Settings.BackupConfiguration.BackupRetentionSettings.RetentionUnit) != actual.Settings.BackupConfiguration.BackupRetentionSettings.RetentionUnit) { + // Change retention settings + updateRequired = true + } + merged.Settings.BackupConfiguration.BackupRetentionSettings = &api.BackupRetentionSettings{ + RetainedBackups: desired.Spec.Settings.BackupConfiguration.BackupRetentionSettings.RetainedBackups, + RetentionUnit: direct.ValueOf(desired.Spec.Settings.BackupConfiguration.BackupRetentionSettings.RetentionUnit), + } + } else if existingRetentionSettings { + // Keep same retention settings + merged.Settings.BackupConfiguration.BackupRetentionSettings = actual.Settings.BackupConfiguration.BackupRetentionSettings + } + + if desired.Spec.Settings.BackupConfiguration.BinaryLogEnabled != nil { + if existingBackupConfig { + if direct.ValueOf(desired.Spec.Settings.BackupConfiguration.BinaryLogEnabled) != actual.Settings.BackupConfiguration.BinaryLogEnabled { + // Change binary log enabled + updateRequired = true + } + } + merged.Settings.BackupConfiguration.BinaryLogEnabled = direct.ValueOf(desired.Spec.Settings.BackupConfiguration.BinaryLogEnabled) + } else if existingBackupConfig { + // Keep same binary log enabled + merged.Settings.BackupConfiguration.BinaryLogEnabled = actual.Settings.BackupConfiguration.BinaryLogEnabled + } + + if desired.Spec.Settings.BackupConfiguration.Enabled != nil { + if existingBackupConfig { + if direct.ValueOf(desired.Spec.Settings.BackupConfiguration.Enabled) != actual.Settings.BackupConfiguration.Enabled { + // Change enabled + updateRequired = true + } + } + merged.Settings.BackupConfiguration.Enabled = direct.ValueOf(desired.Spec.Settings.BackupConfiguration.Enabled) + } else if existingBackupConfig { + // Keep same enabled + merged.Settings.BackupConfiguration.Enabled = actual.Settings.BackupConfiguration.Enabled + } + + if desired.Spec.Settings.BackupConfiguration.Location != nil { + if existingBackupConfig { + if direct.ValueOf(desired.Spec.Settings.BackupConfiguration.Location) != actual.Settings.BackupConfiguration.Location { + // Change location + updateRequired = true + } + } + merged.Settings.BackupConfiguration.Location = direct.ValueOf(desired.Spec.Settings.BackupConfiguration.Location) + } else if existingBackupConfig { + // Keep same location + merged.Settings.BackupConfiguration.Location = actual.Settings.BackupConfiguration.Location + } + + if desired.Spec.Settings.BackupConfiguration.PointInTimeRecoveryEnabled != nil { + if existingBackupConfig { + if direct.ValueOf(desired.Spec.Settings.BackupConfiguration.PointInTimeRecoveryEnabled) != actual.Settings.BackupConfiguration.PointInTimeRecoveryEnabled { + // Change point in time recovery enabled + updateRequired = true + } + } + merged.Settings.BackupConfiguration.PointInTimeRecoveryEnabled = direct.ValueOf(desired.Spec.Settings.BackupConfiguration.PointInTimeRecoveryEnabled) + } else if existingBackupConfig { + // Keep same point in time recovery enabled + merged.Settings.BackupConfiguration.PointInTimeRecoveryEnabled = actual.Settings.BackupConfiguration.PointInTimeRecoveryEnabled + } + + if desired.Spec.Settings.BackupConfiguration.StartTime != nil { + if existingBackupConfig { + if direct.ValueOf(desired.Spec.Settings.BackupConfiguration.StartTime) != actual.Settings.BackupConfiguration.StartTime { + // Change start time + updateRequired = true + } + } + merged.Settings.BackupConfiguration.StartTime = direct.ValueOf(desired.Spec.Settings.BackupConfiguration.StartTime) + } else if existingBackupConfig { + // Keep same start time + merged.Settings.BackupConfiguration.StartTime = actual.Settings.BackupConfiguration.StartTime + } + + if desired.Spec.Settings.BackupConfiguration.TransactionLogRetentionDays != nil { + if existingBackupConfig { + if direct.ValueOf(desired.Spec.Settings.BackupConfiguration.TransactionLogRetentionDays) != actual.Settings.BackupConfiguration.TransactionLogRetentionDays { + // Change transaction log retention days + updateRequired = true + } + } + merged.Settings.BackupConfiguration.TransactionLogRetentionDays = direct.ValueOf(desired.Spec.Settings.BackupConfiguration.TransactionLogRetentionDays) + } else if existingBackupConfig { + // Keep same transaction log retention days + merged.Settings.BackupConfiguration.TransactionLogRetentionDays = actual.Settings.BackupConfiguration.TransactionLogRetentionDays + } + } else if existingBackupConfig { + // Keep same backup configuration + merged.Settings.BackupConfiguration = actual.Settings.BackupConfiguration + } + if merged.Settings.BackupConfiguration != nil { + merged.Settings.BackupConfiguration.ForceSendFields = []string{ + "BinaryLogEnabled", + "Enabled", + "PointInTimeRecoveryEnabled", + } + } + + if desired.Spec.Settings.Collation != nil { + if direct.ValueOf(desired.Spec.Settings.Collation) != actual.Settings.Collation { + // Change collation + updateRequired = true + } + merged.Settings.Collation = direct.ValueOf(desired.Spec.Settings.Collation) + } else { + // Keep collation + merged.Settings.Collation = actual.Settings.Collation + } + + if desired.Spec.Settings.ConnectorEnforcement != nil { + if direct.ValueOf(desired.Spec.Settings.ConnectorEnforcement) != actual.Settings.ConnectorEnforcement { + // Change connector enforcement + updateRequired = true + } + merged.Settings.ConnectorEnforcement = direct.ValueOf(desired.Spec.Settings.ConnectorEnforcement) + } else { + // Keep connector enforcement + merged.Settings.ConnectorEnforcement = actual.Settings.ConnectorEnforcement + } + + if desired.Spec.Settings.CrashSafeReplication != nil { + if direct.ValueOf(desired.Spec.Settings.CrashSafeReplication) != actual.Settings.CrashSafeReplicationEnabled { + // Change crash safe replication + updateRequired = true + } + merged.Settings.CrashSafeReplicationEnabled = direct.ValueOf(desired.Spec.Settings.CrashSafeReplication) + } else { + // Keep crash safe replication + merged.Settings.CrashSafeReplicationEnabled = actual.Settings.CrashSafeReplicationEnabled + } + + if desired.Spec.Settings.DataCacheConfig != nil { + if actual.Settings.DataCacheConfig == nil { + // Add data cache config + updateRequired = true + } else if direct.ValueOf(desired.Spec.Settings.DataCacheConfig.DataCacheEnabled) != actual.Settings.DataCacheConfig.DataCacheEnabled { + // Change data cache config + updateRequired = true + } + merged.Settings.DataCacheConfig = &api.DataCacheConfig{ + DataCacheEnabled: direct.ValueOf(desired.Spec.Settings.DataCacheConfig.DataCacheEnabled), + } + } else if actual.Settings.DataCacheConfig != nil { + // Remove data cache config + updateRequired = true + } + + if desired.Spec.Settings.DatabaseFlags != nil { + if actual.Settings.DatabaseFlags == nil { + // Add database flags + updateRequired = true + } else if len(desired.Spec.Settings.DatabaseFlags) != len(actual.Settings.DatabaseFlags) { + // todo: fix this + // Change database flags + updateRequired = true + } + merged.Settings.DatabaseFlags = []*api.DatabaseFlags{} + for _, flag := range desired.Spec.Settings.DatabaseFlags { + merged.Settings.DatabaseFlags = append(merged.Settings.DatabaseFlags, &api.DatabaseFlags{ + Name: flag.Name, + Value: flag.Value, + }) + } + } else if actual.Settings.DatabaseFlags != nil { + // Remove database flags + updateRequired = true + } + + if desired.Spec.Settings.DeletionProtectionEnabled != nil { + if direct.ValueOf(desired.Spec.Settings.DeletionProtectionEnabled) != actual.Settings.DeletionProtectionEnabled { + // Change deletion protection enabled + updateRequired = true + } + merged.Settings.DeletionProtectionEnabled = direct.ValueOf(desired.Spec.Settings.DeletionProtectionEnabled) + } else { + // Keep deletion protection enabled + merged.Settings.DeletionProtectionEnabled = actual.Settings.DeletionProtectionEnabled + } + + if desired.Spec.Settings.DenyMaintenancePeriod != nil { + if actual.Settings.DenyMaintenancePeriods == nil { + // Add deny maintenance period + updateRequired = true + } else if (len(actual.Settings.DenyMaintenancePeriods) == 1) && ((desired.Spec.Settings.DenyMaintenancePeriod.EndDate != actual.Settings.DenyMaintenancePeriods[0].EndDate) || + (desired.Spec.Settings.DenyMaintenancePeriod.StartDate != actual.Settings.DenyMaintenancePeriods[0].StartDate) || + (desired.Spec.Settings.DenyMaintenancePeriod.Time != actual.Settings.DenyMaintenancePeriods[0].Time)) { + // Change deny maintenance period + updateRequired = true + } + merged.Settings.DenyMaintenancePeriods = []*api.DenyMaintenancePeriod{ + { + EndDate: desired.Spec.Settings.DenyMaintenancePeriod.EndDate, + StartDate: desired.Spec.Settings.DenyMaintenancePeriod.StartDate, + Time: desired.Spec.Settings.DenyMaintenancePeriod.Time, + }, + } + } else if actual.Settings.DenyMaintenancePeriods != nil { + // Remove deny maintenance period + updateRequired = true + } + + if desired.Spec.Settings.DiskAutoresize != nil { + if desired.Spec.Settings.DiskAutoresize != actual.Settings.StorageAutoResize { + // Change disk autoresize + updateRequired = true + } + merged.Settings.StorageAutoResize = desired.Spec.Settings.DiskAutoresize + } else { + // Keep disk autoresize + merged.Settings.StorageAutoResize = actual.Settings.StorageAutoResize + } + + if desired.Spec.Settings.DiskAutoresizeLimit != nil { + if direct.ValueOf(desired.Spec.Settings.DiskAutoresizeLimit) != actual.Settings.StorageAutoResizeLimit { + // Change disk autoresize limit + updateRequired = true + } + merged.Settings.StorageAutoResizeLimit = direct.ValueOf(desired.Spec.Settings.DiskAutoresizeLimit) + } else { + // Keep disk autoresize limit + merged.Settings.StorageAutoResizeLimit = actual.Settings.StorageAutoResizeLimit + } + + if desired.Spec.Settings.DiskSize != nil { + if direct.ValueOf(desired.Spec.Settings.DiskSize) != actual.Settings.DataDiskSizeGb { + // Change disk size + updateRequired = true + } + merged.Settings.DataDiskSizeGb = direct.ValueOf(desired.Spec.Settings.DiskSize) + } else { + // Keep disk size + merged.Settings.DataDiskSizeGb = actual.Settings.DataDiskSizeGb + } + + if desired.Spec.Settings.DiskType != nil { + if direct.ValueOf(desired.Spec.Settings.DiskType) != actual.Settings.DataDiskType { + // Change disk type + updateRequired = true + } + merged.Settings.DataDiskType = direct.ValueOf(desired.Spec.Settings.DiskType) + } else { + // Keep disk type + merged.Settings.DataDiskType = actual.Settings.DataDiskType + } + + if desired.Spec.Settings.Edition != nil { + if direct.ValueOf(desired.Spec.Settings.Edition) != actual.Settings.Edition { + // Change edition + updateRequired = true + } + merged.Settings.Edition = direct.ValueOf(desired.Spec.Settings.Edition) + } else { + // Keep edition + merged.Settings.Edition = actual.Settings.Edition + } + + if desired.Spec.Settings.InsightsConfig != nil { + if actual.Settings.InsightsConfig == nil { + // Add insights config + updateRequired = true + } else if (direct.ValueOf(desired.Spec.Settings.InsightsConfig.QueryInsightsEnabled) != actual.Settings.InsightsConfig.QueryInsightsEnabled) || + (direct.ValueOf(desired.Spec.Settings.InsightsConfig.QueryPlansPerMinute) != actual.Settings.InsightsConfig.QueryPlansPerMinute) || + (direct.ValueOf(desired.Spec.Settings.InsightsConfig.QueryStringLength) != actual.Settings.InsightsConfig.QueryStringLength) || + (direct.ValueOf(desired.Spec.Settings.InsightsConfig.RecordApplicationTags) != actual.Settings.InsightsConfig.RecordApplicationTags) || + (direct.ValueOf(desired.Spec.Settings.InsightsConfig.RecordClientAddress) != actual.Settings.InsightsConfig.RecordClientAddress) { + // Change insights config + updateRequired = true + } + merged.Settings.InsightsConfig = &api.InsightsConfig{ + QueryInsightsEnabled: direct.ValueOf(desired.Spec.Settings.InsightsConfig.QueryInsightsEnabled), + QueryPlansPerMinute: direct.ValueOf(desired.Spec.Settings.InsightsConfig.QueryPlansPerMinute), + QueryStringLength: direct.ValueOf(desired.Spec.Settings.InsightsConfig.QueryStringLength), + RecordApplicationTags: direct.ValueOf(desired.Spec.Settings.InsightsConfig.RecordApplicationTags), + RecordClientAddress: direct.ValueOf(desired.Spec.Settings.InsightsConfig.RecordClientAddress), + } + } else if actual.Settings.InsightsConfig != nil { + // Keep insights config + merged.Settings.InsightsConfig = actual.Settings.InsightsConfig + } + + if desired.Spec.Settings.IpConfiguration != nil { + if actual.Settings.IpConfiguration == nil { + // Add ip configuration + updateRequired = true + } else if (direct.ValueOf(desired.Spec.Settings.IpConfiguration.AllocatedIpRange) != actual.Settings.IpConfiguration.AllocatedIpRange) || + (len(desired.Spec.Settings.IpConfiguration.AuthorizedNetworks) != len(actual.Settings.IpConfiguration.AuthorizedNetworks)) || + (desired.Spec.Settings.IpConfiguration.EnablePrivatePathForGoogleCloudServices != &actual.Settings.IpConfiguration.EnablePrivatePathForGoogleCloudServices) || + (direct.ValueOf(desired.Spec.Settings.IpConfiguration.Ipv4Enabled) != actual.Settings.IpConfiguration.Ipv4Enabled) || + (refs.privateNetwork != actual.Settings.IpConfiguration.PrivateNetwork) || + (len(desired.Spec.Settings.IpConfiguration.PscConfig) == 1 && + (len(desired.Spec.Settings.IpConfiguration.PscConfig[0].AllowedConsumerProjects) != len(actual.Settings.IpConfiguration.PscConfig.AllowedConsumerProjects)) || + (direct.ValueOf(desired.Spec.Settings.IpConfiguration.PscConfig[0].PscEnabled) != actual.Settings.IpConfiguration.PscConfig.PscEnabled)) || + (direct.ValueOf(desired.Spec.Settings.IpConfiguration.RequireSsl) != actual.Settings.IpConfiguration.RequireSsl) || + (direct.ValueOf(desired.Spec.Settings.IpConfiguration.SslMode) != actual.Settings.IpConfiguration.SslMode) { + // Change ip configuration + updateRequired = true + } + merged.Settings.IpConfiguration = &api.IpConfiguration{ + AllocatedIpRange: direct.ValueOf(desired.Spec.Settings.IpConfiguration.AllocatedIpRange), + EnablePrivatePathForGoogleCloudServices: direct.ValueOf(desired.Spec.Settings.IpConfiguration.EnablePrivatePathForGoogleCloudServices), + Ipv4Enabled: direct.ValueOf(desired.Spec.Settings.IpConfiguration.Ipv4Enabled), + PrivateNetwork: refs.privateNetwork, + RequireSsl: direct.ValueOf(desired.Spec.Settings.IpConfiguration.RequireSsl), + SslMode: direct.ValueOf(desired.Spec.Settings.IpConfiguration.SslMode), + } + if len(desired.Spec.Settings.IpConfiguration.PscConfig) == 1 { + merged.Settings.IpConfiguration.PscConfig = &api.PscConfig{ + PscEnabled: direct.ValueOf(desired.Spec.Settings.IpConfiguration.PscConfig[0].PscEnabled), + } + merged.Settings.IpConfiguration.PscConfig.AllowedConsumerProjects = append(merged.Settings.IpConfiguration.PscConfig.AllowedConsumerProjects, desired.Spec.Settings.IpConfiguration.PscConfig[0].AllowedConsumerProjects...) + } + for _, authorizedNetwork := range desired.Spec.Settings.IpConfiguration.AuthorizedNetworks { + merged.Settings.IpConfiguration.AuthorizedNetworks = append(merged.Settings.IpConfiguration.AuthorizedNetworks, &api.AclEntry{ + Name: direct.ValueOf(authorizedNetwork.Name), + ExpirationTime: direct.ValueOf(authorizedNetwork.ExpirationTime), + Value: authorizedNetwork.Value, + Kind: "sql#aclEntry", + }) + } + } else if actual.Settings.IpConfiguration != nil { + // Keep ip configuration + merged.Settings.IpConfiguration = actual.Settings.IpConfiguration + } + if merged.Settings.IpConfiguration != nil { + merged.Settings.IpConfiguration.ForceSendFields = []string{ + "EnablePrivatePathForGoogleCloudServices", + "Ipv4Enabled", + "RequireSsl", + } + } + + if desired.Spec.Settings.LocationPreference != nil { + if actual.Settings.LocationPreference == nil { + // Add location preference + updateRequired = true + } else if (direct.ValueOf(desired.Spec.Settings.LocationPreference.FollowGaeApplication) != actual.Settings.LocationPreference.FollowGaeApplication) || + (direct.ValueOf(desired.Spec.Settings.LocationPreference.SecondaryZone) != actual.Settings.LocationPreference.SecondaryZone) || + (direct.ValueOf(desired.Spec.Settings.LocationPreference.Zone) != actual.Settings.LocationPreference.Zone) { + // Change location preference + updateRequired = true + } + merged.Settings.LocationPreference = &api.LocationPreference{ + FollowGaeApplication: direct.ValueOf(desired.Spec.Settings.LocationPreference.FollowGaeApplication), + SecondaryZone: direct.ValueOf(desired.Spec.Settings.LocationPreference.SecondaryZone), + Zone: direct.ValueOf(desired.Spec.Settings.LocationPreference.Zone), + } + } else if actual.Settings.LocationPreference != nil { + // Keep location preference + merged.Settings.LocationPreference = actual.Settings.LocationPreference + } + + if desired.Spec.Settings.MaintenanceWindow != nil { + if actual.Settings.MaintenanceWindow == nil { + // Add maintenance window + updateRequired = true + } else if (direct.ValueOf(desired.Spec.Settings.MaintenanceWindow.Day) != actual.Settings.MaintenanceWindow.Day) || + (direct.ValueOf(desired.Spec.Settings.MaintenanceWindow.Hour) != actual.Settings.MaintenanceWindow.Hour) || + (direct.ValueOf(desired.Spec.Settings.MaintenanceWindow.UpdateTrack) != actual.Settings.MaintenanceWindow.UpdateTrack) { + // Change maintenance window + updateRequired = true + } + merged.Settings.MaintenanceWindow = &api.MaintenanceWindow{ + Day: direct.ValueOf(desired.Spec.Settings.MaintenanceWindow.Day), + Hour: direct.ValueOf(desired.Spec.Settings.MaintenanceWindow.Hour), + UpdateTrack: direct.ValueOf(desired.Spec.Settings.MaintenanceWindow.UpdateTrack), + } + } else if actual.Settings.MaintenanceWindow != nil { + // Remove maintenance window + updateRequired = true + } + + if desired.Spec.Settings.PasswordValidationPolicy != nil { + if actual.Settings.PasswordValidationPolicy == nil { + // Add password validation policy + updateRequired = true + } else if (direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.Complexity) != actual.Settings.PasswordValidationPolicy.Complexity) || + (direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.DisallowUsernameSubstring) != actual.Settings.PasswordValidationPolicy.DisallowUsernameSubstring) || + (desired.Spec.Settings.PasswordValidationPolicy.EnablePasswordPolicy != actual.Settings.PasswordValidationPolicy.EnablePasswordPolicy) || + (direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.MinLength) != actual.Settings.PasswordValidationPolicy.MinLength) || + (direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.PasswordChangeInterval) != actual.Settings.PasswordValidationPolicy.PasswordChangeInterval) || + (direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.ReuseInterval) != actual.Settings.PasswordValidationPolicy.ReuseInterval) { + // Change password validation policy + updateRequired = true + } + merged.Settings.PasswordValidationPolicy = &api.PasswordValidationPolicy{ + Complexity: direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.Complexity), + DisallowUsernameSubstring: direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.DisallowUsernameSubstring), + EnablePasswordPolicy: desired.Spec.Settings.PasswordValidationPolicy.EnablePasswordPolicy, + MinLength: direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.MinLength), + PasswordChangeInterval: direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.PasswordChangeInterval), + ReuseInterval: direct.ValueOf(desired.Spec.Settings.PasswordValidationPolicy.ReuseInterval), + } + } else if actual.Settings.PasswordValidationPolicy != nil { + // Remove password validation policy + updateRequired = true + } + + if desired.Spec.Settings.PricingPlan != nil { + if actual.Settings.PricingPlan == "" { + // Add pricing plan + updateRequired = true + } else if direct.ValueOf(desired.Spec.Settings.PricingPlan) != actual.Settings.PricingPlan { + // Change pricing plan + updateRequired = true + } + merged.Settings.PricingPlan = direct.ValueOf(desired.Spec.Settings.PricingPlan) + } else if actual.Settings.PricingPlan != "" { + // Keep pricing plan + merged.Settings.PricingPlan = actual.Settings.PricingPlan + } + + if desired.Spec.Settings.ReplicationType != nil { + if actual.Settings.ReplicationType == "" { + // Add replication type + updateRequired = true + } else if direct.ValueOf(desired.Spec.Settings.ReplicationType) != actual.Settings.ReplicationType { + // Change replication type + updateRequired = true + } + merged.Settings.ReplicationType = direct.ValueOf(desired.Spec.Settings.ReplicationType) + } else if actual.Settings.ReplicationType != "" { + // Keep replication type + merged.Settings.ReplicationType = actual.Settings.ReplicationType + } + + if desired.Spec.Settings.SqlServerAuditConfig != nil { + if actual.Settings.SqlServerAuditConfig == nil { + // Add sql server audit config + updateRequired = true + } else if (refs.auditLogBucket != actual.Settings.SqlServerAuditConfig.Bucket) || + (direct.ValueOf(desired.Spec.Settings.SqlServerAuditConfig.RetentionInterval) != actual.Settings.SqlServerAuditConfig.RetentionInterval) || + (direct.ValueOf(desired.Spec.Settings.SqlServerAuditConfig.UploadInterval) != actual.Settings.SqlServerAuditConfig.UploadInterval) { + // Change sql server audit config + updateRequired = true + } + merged.Settings.SqlServerAuditConfig = &api.SqlServerAuditConfig{ + Bucket: refs.auditLogBucket, + RetentionInterval: direct.ValueOf(desired.Spec.Settings.SqlServerAuditConfig.RetentionInterval), + UploadInterval: direct.ValueOf(desired.Spec.Settings.SqlServerAuditConfig.UploadInterval), + Kind: "sql#sqlServerAuditConfig", + } + } else if actual.Settings.SqlServerAuditConfig != nil { + // Remove sql server audit config + updateRequired = true + } + + if desired.Spec.Settings.Tier != "" { + if actual.Settings.Tier == "" { + // Add tier + updateRequired = true + } else if desired.Spec.Settings.Tier != actual.Settings.Tier { + // Change tier + updateRequired = true + } + merged.Settings.Tier = desired.Spec.Settings.Tier + } else { + // Keep tier + merged.Settings.Tier = actual.Settings.Tier + } + + if desired.Spec.Settings.TimeZone != nil { + if actual.Settings.TimeZone == "" { + // Add time zone + updateRequired = true + } else if direct.ValueOf(desired.Spec.Settings.TimeZone) != actual.Settings.TimeZone { + // Change time zone + updateRequired = true + } + merged.Settings.TimeZone = direct.ValueOf(desired.Spec.Settings.TimeZone) + } else { + // Keep time zone + merged.Settings.TimeZone = actual.Settings.TimeZone + } + + if !reflect.DeepEqual(desired.Labels, actual.Settings.UserLabels) { + updateRequired = true + } + merged.Settings.UserLabels = desired.Labels + + return merged, updateRequired, nil +} diff --git a/pkg/controller/direct/sql/normalize.go b/pkg/controller/direct/sql/normalize.go new file mode 100644 index 0000000000..ccd313a4c7 --- /dev/null +++ b/pkg/controller/direct/sql/normalize.go @@ -0,0 +1,321 @@ +// Copyright 2024 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 ( + "context" + "fmt" + + refs "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/sql/v1beta1" + kmsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/kms/v1beta1" + storagev1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/clients/generated/apis/storage/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type SQLInstanceInternalRefs struct { + cryptoKey string + masterInstance string + replicaPassword string + rootPassword string + privateNetwork string + auditLogBucket string +} + +func NormalizeSQLInstance(ctx context.Context, kube client.Reader, obj *krm.SQLInstance) (*SQLInstanceInternalRefs, error) { + cryptoKeyRef, err := normalizeCryptoKeyRef(ctx, kube, obj) + if err != nil { + return nil, err + } + masterInstanceRef, err := normalizeMasterInstanceRef(ctx, kube, obj) + if err != nil { + return nil, err + } + replicaPassword, err := normalizeReplicaPasswordRef(ctx, kube, obj) + if err != nil { + return nil, err + } + rootPassword, err := normalizeRootPasswordRef(ctx, kube, obj) + if err != nil { + return nil, err + } + privateNetwork, err := normalizePrivateNetworkRef(ctx, kube, obj) + if err != nil { + return nil, err + } + auditLogBucket, err := normalizeAuditLogBucketRef(ctx, kube, obj) + if err != nil { + return nil, err + } + if err := normalizeLabels(obj); err != nil { + return nil, err + } + if err := normalizeTFDefaults(obj); err != nil { + return nil, err + } + return &SQLInstanceInternalRefs{ + cryptoKey: cryptoKeyRef, + masterInstance: masterInstanceRef, + replicaPassword: replicaPassword, + rootPassword: rootPassword, + privateNetwork: privateNetwork, + auditLogBucket: auditLogBucket, + }, nil +} + +func normalizeCryptoKeyRef(ctx context.Context, kube client.Reader, obj *krm.SQLInstance) (string, error) { + if obj.Spec.EncryptionKMSCryptoKeyRef == nil { + return "", nil + } + + keyRef := obj.Spec.EncryptionKMSCryptoKeyRef + + if keyRef.External != "" && keyRef.Name != "" { + return "", fmt.Errorf("cannot specify both spec.encryptionKMSCryptoKeyRef.external and spec.encryptionKMSCryptoKeyRef.name") + } + + if keyRef.External != "" { + return keyRef.External, nil + } else if keyRef.Name != "" { + if keyRef.Namespace == "" { + keyRef.Namespace = obj.Namespace + } + + key := types.NamespacedName{ + Namespace: keyRef.Namespace, + Name: keyRef.Name, + } + + cryptoKey := &unstructured.Unstructured{} + cryptoKey.SetGroupVersionKind(kmsv1beta1.KMSCryptoKeyGVK) + if err := kube.Get(ctx, key, cryptoKey); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewReferenceNotFoundError(kmsv1beta1.KMSCryptoKeyGVK, key) + } + return "", fmt.Errorf("error reading referenced KMSCryptoKey %v: %w", cryptoKey, err) + } + + keyLink, _, err := unstructured.NestedString(cryptoKey.Object, "status", "selfLink") + if err != nil || keyLink == "" { + return "", fmt.Errorf("reading status.selfLink from %v %v/%v: %w", cryptoKey.GroupVersionKind().Kind, cryptoKey.GetNamespace(), cryptoKey.GetName(), err) + } + return keyLink, nil + } else { + return "", fmt.Errorf("must specify either spec.encryptionKMSCryptoKeyRef.external or spec.encryptionKMSCryptoKeyRef.name") + } +} + +func normalizeMasterInstanceRef(ctx context.Context, kube client.Reader, obj *krm.SQLInstance) (string, error) { + if obj.Spec.MasterInstanceRef == nil { + return "", nil + } + + if obj.Spec.MasterInstanceRef.External != "" && obj.Spec.MasterInstanceRef.Name != "" { + return "", fmt.Errorf("cannot specify both spec.masterInstanceRef.external and spec.masterInstanceRef.name") + } + + if obj.Spec.MasterInstanceRef.External != "" { + return obj.Spec.MasterInstanceRef.External, nil + } else if obj.Spec.MasterInstanceRef.Name != "" { + if obj.Spec.MasterInstanceRef.Namespace == "" { + obj.Spec.MasterInstanceRef.Namespace = obj.Namespace + } + + key := types.NamespacedName{ + Namespace: obj.Spec.MasterInstanceRef.Namespace, + Name: obj.Spec.MasterInstanceRef.Name, + } + + masterInstance := &unstructured.Unstructured{} + masterInstance.SetGroupVersionKind(krm.SQLInstanceGVK) + if err := kube.Get(ctx, key, masterInstance); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewReferenceNotFoundError(krm.SQLInstanceGVK, key) + } + return "", fmt.Errorf("error reading referenced master instance %v: %w", key, err) + } + + masterInstanceName, err := refs.GetResourceID(masterInstance) + if err != nil { + return "", err + } + return masterInstanceName, nil + } else { + return "", fmt.Errorf("must specify either spec.masterInstanceRef.external or spec.masterInstanceRef.name") + } +} + +func normalizeReplicaPasswordRef(ctx context.Context, kube client.Reader, obj *krm.SQLInstance) (string, error) { + if obj.Spec.ReplicaConfiguration == nil || obj.Spec.ReplicaConfiguration.Password == nil { + return "", nil + } + + if obj.Spec.ReplicaConfiguration.Password.Value != nil && obj.Spec.ReplicaConfiguration.Password.ValueFrom != nil { + return "", fmt.Errorf("cannot specify both spec.replicaConfiguration.password.value and spec.replicaConfiguration.password.valueFrom") + } + + if obj.Spec.ReplicaConfiguration.Password.Value != nil { + return *obj.Spec.ReplicaConfiguration.Password.Value, nil + } else if obj.Spec.ReplicaConfiguration.Password.ValueFrom != nil { + key := types.NamespacedName{ + Namespace: obj.Namespace, + Name: obj.Spec.ReplicaConfiguration.Password.ValueFrom.SecretKeyRef.Name, + } + + secret := &corev1.Secret{} + if err := kube.Get(ctx, key, secret); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewSecretNotFoundError(key) + } + return "", fmt.Errorf("error reading referenced Secret %v: %w", key, err) + } + + password := string(secret.Data[obj.Spec.ReplicaConfiguration.Password.ValueFrom.SecretKeyRef.Key]) + return password, nil + } + return "", nil +} + +func normalizeRootPasswordRef(ctx context.Context, kube client.Reader, obj *krm.SQLInstance) (string, error) { + if obj.Spec.RootPassword == nil { + return "", nil + } + + if obj.Spec.RootPassword.Value != nil && obj.Spec.RootPassword.ValueFrom != nil { + return "", fmt.Errorf("cannot specify both spec.rootPassword.value and spec.rootPassword.valueFrom") + } + + if obj.Spec.RootPassword.Value != nil { + return *obj.Spec.RootPassword.Value, nil + } else if obj.Spec.RootPassword.ValueFrom != nil { + key := types.NamespacedName{ + Namespace: obj.Namespace, + Name: obj.Spec.RootPassword.ValueFrom.SecretKeyRef.Name, + } + + secret := &corev1.Secret{} + if err := kube.Get(ctx, key, secret); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewSecretNotFoundError(key) + } + return "", fmt.Errorf("error reading referenced Secret %v: %w", key, err) + } + + password := string(secret.Data[obj.Spec.RootPassword.ValueFrom.SecretKeyRef.Key]) + return password, nil + } + return "", nil +} + +func normalizePrivateNetworkRef(ctx context.Context, kube client.Reader, obj *krm.SQLInstance) (string, error) { + if obj.Spec.Settings.IpConfiguration == nil || obj.Spec.Settings.IpConfiguration.PrivateNetworkRef == nil { + return "", nil + } + + resRef := obj.Spec.Settings.IpConfiguration.PrivateNetworkRef + netRef := &refs.ComputeNetworkRef{ + External: resRef.External, + Name: resRef.Name, + Namespace: resRef.Namespace, + } + net, err := refs.ResolveComputeNetwork(ctx, kube, obj, netRef) + if err != nil { + return "", err + } + + return net.String(), nil +} + +func normalizeAuditLogBucketRef(ctx context.Context, kube client.Reader, obj *krm.SQLInstance) (string, error) { + if obj.Spec.Settings.SqlServerAuditConfig == nil { + return "", nil + } + + if obj.Spec.Settings.SqlServerAuditConfig.BucketRef == nil { + return "", fmt.Errorf("must specify bucket for audit config") + } + + bucketRef := obj.Spec.Settings.SqlServerAuditConfig.BucketRef + + if bucketRef.External != "" && bucketRef.Name != "" { + return "", fmt.Errorf("cannot specify both spec.settings.sqlServerAuditConfig.bucketRef.external and spec.settings.sqlServerAuditConfig.bucketRef.name") + } + + if bucketRef.External != "" { + return bucketRef.External, nil + } else if bucketRef.Name != "" { + if bucketRef.Namespace == "" { + bucketRef.Namespace = obj.Namespace + } + + key := types.NamespacedName{ + Namespace: bucketRef.Namespace, + Name: bucketRef.Name, + } + + bucket := &unstructured.Unstructured{} + bucket.SetGroupVersionKind(storagev1beta1.StorageBucketGVK) + if err := kube.Get(ctx, key, bucket); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewReferenceNotFoundError(storagev1beta1.StorageBucketGVK, key) + } + return "", fmt.Errorf("error reading referenced StorageBucket %v: %w", key, err) + } + + storageBucketName, err := refs.GetResourceID(bucket) + if err != nil { + return "", err + } + return "gs://" + storageBucketName, nil + } else { + return "", fmt.Errorf("must specify either spec.settings.sqlServerAuditConfig.bucketRef.external or spec.settings.sqlServerAuditConfig.bucketRef.name") + } +} + +func normalizeLabels(obj *krm.SQLInstance) error { + if obj.Labels == nil { + obj.Labels = make(map[string]string) + } + obj.Labels["managed-by-cnrm"] = "true" + return nil +} + +func normalizeTFDefaults(obj *krm.SQLInstance) error { + if obj.Spec.Settings.ActivationPolicy == nil { + obj.Spec.Settings.ActivationPolicy = direct.PtrTo("ALWAYS") + } + if obj.Spec.Settings.AvailabilityType == nil { + obj.Spec.Settings.AvailabilityType = direct.PtrTo("ZONAL") + } + if obj.Spec.Settings.DiskType == nil { + obj.Spec.Settings.DiskType = direct.PtrTo("PD_SSD") + } + if obj.Spec.Settings.Edition == nil { + obj.Spec.Settings.Edition = direct.PtrTo("ENTERPRISE") + } + if obj.Spec.Settings.PricingPlan == nil { + obj.Spec.Settings.PricingPlan = direct.PtrTo("PER_USE") + } + if obj.Spec.Settings.DiskAutoresize == nil { + obj.Spec.Settings.DiskAutoresize = direct.PtrTo(true) + } + return nil +} diff --git a/pkg/controller/direct/sql/sqlinstance_controller.go b/pkg/controller/direct/sql/sqlinstance_controller.go new file mode 100644 index 0000000000..d6008bd9e1 --- /dev/null +++ b/pkg/controller/direct/sql/sqlinstance_controller.go @@ -0,0 +1,347 @@ +// Copyright 2024 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 ( + "context" + "fmt" + "strings" + "time" + + api "google.golang.org/api/sqladmin/v1beta4" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client" + + refs "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/sql/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/config" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/directbase" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/registry" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s" + "github.com/googleapis/gax-go/v2" +) + +const ctrlName = "sqlinstance-controller" + +func init() { + registry.RegisterModel(krm.SQLInstanceGVK, newSQLInstanceModel) +} + +func newSQLInstanceModel(ctx context.Context, config *config.ControllerConfig) (directbase.Model, error) { + return &sqlInstanceModel{config: config}, nil +} + +type sqlInstanceModel struct { + config *config.ControllerConfig +} + +var _ directbase.Model = &sqlInstanceModel{} + +type sqlInstanceAdapter struct { + projectID string + resourceID string + + desired *krm.SQLInstance + refs *SQLInstanceInternalRefs + actual *api.DatabaseInstance + + sqlOperationsClient *api.OperationsService + sqlInstancesClient *api.InstancesService + sqlUsersClient *api.UsersService +} + +var _ directbase.Adapter = &sqlInstanceAdapter{} + +func (m *sqlInstanceModel) AdapterForObject(ctx context.Context, kube client.Reader, u *unstructured.Unstructured) (directbase.Adapter, error) { + obj := &krm.SQLInstance{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &obj); err != nil { + return nil, fmt.Errorf("error converting to %T: %w", obj, err) + } + + resourceID, err := refs.GetResourceID(u) + if err != nil { + return nil, err + } + obj.Spec.ResourceID = &resourceID + + projectID, ok := u.GetAnnotations()[k8s.ProjectIDAnnotation] + if !ok { + projectID = u.GetNamespace() + } + + gcpClient, err := newGCPClient(ctx, m.config) + if err != nil { + return nil, fmt.Errorf("building gcp client: %w", err) + } + + refs, err := NormalizeSQLInstance(ctx, kube, obj) + if err != nil { + return nil, err + } + + return &sqlInstanceAdapter{ + projectID: projectID, + resourceID: resourceID, + desired: obj.DeepCopy(), + refs: refs, + sqlOperationsClient: gcpClient.sqlOperationsClient(), + sqlInstancesClient: gcpClient.sqlInstancesClient(), + sqlUsersClient: gcpClient.sqlUsersClient(), + }, nil +} + +func (m *sqlInstanceModel) AdapterForURL(ctx context.Context, url string) (directbase.Adapter, error) { + // TODO: Support URLs + return nil, nil +} + +func (a *sqlInstanceAdapter) Find(ctx context.Context) (bool, error) { + if a.resourceID == "" { + return false, nil + } + + instance, err := a.sqlInstancesClient.Get(a.projectID, a.resourceID).Context(ctx).Do() + if err != nil { + return false, nil + } + + a.actual = instance + + log := klog.FromContext(ctx).WithName(ctrlName) + log.V(2).Info("found cloudsql instance", "actual", a.actual) + + return true, nil +} + +func (a *sqlInstanceAdapter) Create(ctx context.Context, u *unstructured.Unstructured) error { + log := klog.FromContext(ctx).WithName(ctrlName) + log.V(2).Info("creating instance", "desired", a.desired) + + if a.projectID == "" { + return fmt.Errorf("project is empty") + } + if a.resourceID == "" { + return fmt.Errorf("resourceID is empty") + } + + desiredGCP, err := SQLInstanceKRMToGCP(a.desired, a.refs) + if err != nil { + return err + } + + op, err := a.sqlInstancesClient.Insert(a.projectID, desiredGCP).Context(ctx).Do() + if err != nil { + return fmt.Errorf("create SQLInstance %s failed: %w", a.desired.Name, err) + } + + pollingBackoff := gax.Backoff{ + Initial: time.Second, + Max: time.Minute, + Multiplier: 2, + } + for { + log.V(2).Info("polling", "op", op) + + if op.Status == "DONE" { + break + } + if err := gax.Sleep(ctx, pollingBackoff.Pause()); err != nil { + return fmt.Errorf("wait SQLInstance %s creation failed: %w", a.desired.Name, err) + } + op, err = a.sqlOperationsClient.Get(a.projectID, op.Name).Do() + if err != nil { + return fmt.Errorf("get SQLInstance %s create operation %s failed: %w", a.desired.Name, op.Name, err) + } + } + + created, err := a.sqlInstancesClient.Get(a.projectID, a.resourceID).Context(ctx).Do() + if err != nil { + return fmt.Errorf("get SQLInstance %s failed: %w", a.desired.Name, err) + } + + users, err := a.sqlUsersClient.List(a.projectID, a.resourceID).Context(ctx).Do() + if err != nil { + return fmt.Errorf("list SQLInstance %s users failed: %w", a.desired.Name, err) + } + + if users != nil { + for _, user := range users.Items { + if user.Name == "root" && strings.HasPrefix(created.DatabaseVersion, "MYSQL") { + // Delete "root" user to match Terraform behavior, to improve default security. + // Ref: https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance + op, err := a.sqlUsersClient.Delete(a.projectID, a.resourceID).Context(ctx).Name(user.Name).Do() + if err != nil { + return fmt.Errorf("delete SQLInstance %s root user failed: %w", a.desired.Name, err) + } + for { + log.V(2).Info("polling", "op", op) + + if op.Status == "DONE" { + break + } + if err := gax.Sleep(ctx, pollingBackoff.Pause()); err != nil { + return fmt.Errorf("wait SQLInstance %s delete user failed: %w", a.desired.Name, err) + } + op, err = a.sqlOperationsClient.Get(a.projectID, op.Name).Do() + if err != nil { + return fmt.Errorf("get SQLInstance %s delete root user operation %s failed: %w", a.desired.Name, op.Name, err) + } + } + } + } + } + + log.V(2).Info("instance created", "op", op, "instance", created) + + status := &krm.SQLInstanceStatus{} + if err := Convert_SQLInstance_API_v1_To_KRM_status(created, status); err != nil { + return fmt.Errorf("update SQLInstance status failed: %w", err) + } + return setStatus(u, status) +} + +func (a *sqlInstanceAdapter) Update(ctx context.Context, u *unstructured.Unstructured) error { + log := klog.FromContext(ctx) + log.V(2).Info("updating instance", "desired", a.desired) + + // First, handle database version updates + if a.desired.Spec.DatabaseVersion != nil && *a.desired.Spec.DatabaseVersion != a.actual.DatabaseVersion { + newVersionDb := &api.DatabaseInstance{ + DatabaseVersion: *a.desired.Spec.DatabaseVersion, + } + op, err := a.sqlInstancesClient.Patch(a.projectID, *a.desired.Spec.ResourceID, newVersionDb).Context(ctx).Do() + if err != nil { + return fmt.Errorf("patch SQLInstance %s version failed: %w", *a.desired.Spec.ResourceID, err) + } + + pollingBackoff := gax.Backoff{ + Initial: time.Second, + Max: time.Minute, + Multiplier: 2, + } + for { + log.V(2).Info("polling", "op", op) + + if op.Status == "DONE" { + break + } + if err := gax.Sleep(ctx, pollingBackoff.Pause()); err != nil { + return fmt.Errorf("wait SQLInstance %s version patch failed: %w", *a.desired.Spec.ResourceID, err) + } + op, err = a.sqlOperationsClient.Get(a.projectID, op.Name).Do() + if err != nil { + return fmt.Errorf("get SQLInstance %s version patch operation %s failed: %w", *a.desired.Spec.ResourceID, op.Name, err) + } + } + + updated, err := a.sqlInstancesClient.Get(a.projectID, a.resourceID).Context(ctx).Do() + if err != nil { + return fmt.Errorf("get SQLInstance %s failed: %w", *a.desired.Spec.ResourceID, err) + } + + log.V(2).Info("instance version updated", "op", op, "instance", updated) + + a.actual = updated + } + + // Next, update rest of the fields + merged, diffDetected, err := MergeDesiredSQLInstanceWithActual(a.desired, a.refs, a.actual) + if err != nil { + return fmt.Errorf("diff SQL instances failed: %w", err) + } + + if diffDetected { + op, err := a.sqlInstancesClient.Update(a.projectID, merged.Name, merged).Context(ctx).Do() + if err != nil { + return fmt.Errorf("update SQLInstance %s failed: %w", merged.Name, err) + } + + pollingBackoff := gax.Backoff{ + Initial: time.Second, + Max: time.Minute, + Multiplier: 2, + } + for { + log.V(2).Info("polling", "op", op) + + if op.Status == "DONE" { + break + } + if err := gax.Sleep(ctx, pollingBackoff.Pause()); err != nil { + return fmt.Errorf("wait SQLInstance %s update failed: %w", merged.Name, err) + } + op, err = a.sqlOperationsClient.Get(a.projectID, op.Name).Do() + if err != nil { + return fmt.Errorf("get SQLInstance %s update operation %s failed: %w", merged.Name, op.Name, err) + } + } + + updated, err := a.sqlInstancesClient.Get(a.projectID, a.resourceID).Context(ctx).Do() + if err != nil { + return fmt.Errorf("get SQLInstance %s failed: %w", merged.Name, err) + } + + log.V(2).Info("instance updated", "op", op, "instance", updated) + + status := &krm.SQLInstanceStatus{} + if err := Convert_SQLInstance_API_v1_To_KRM_status(updated, status); err != nil { + return fmt.Errorf("update SQLInstance status failed: %w", err) + } + return setStatus(u, status) + } + + return nil +} + +// Delete implements the Adapter interface. +func (a *sqlInstanceAdapter) Delete(ctx context.Context) (bool, error) { + log := klog.FromContext(ctx).WithName(ctrlName) + log.V(2).Info("deleting instance", "actual", a.actual) + + if a.resourceID == "" { + return false, nil + } + op, err := a.sqlInstancesClient.Delete(a.projectID, a.resourceID).Context(ctx).Do() + if err != nil { + return false, fmt.Errorf("deleting SQLInstance %s: %w", a.resourceID, err) + } + + log.V(2).Info("deleted instance", "op", op) + + return true, nil +} + +func (a *sqlInstanceAdapter) Export(ctx context.Context) (*unstructured.Unstructured, error) { + return nil, nil +} + +func setStatus(u *unstructured.Unstructured, typedStatus any) error { + status, err := runtime.DefaultUnstructuredConverter.ToUnstructured(typedStatus) + if err != nil { + return fmt.Errorf("error converting status to unstructured: %w", err) + } + + old, _, _ := unstructured.NestedMap(u.Object, "status") + if old != nil { + status["conditions"] = old["conditions"] + status["observedGeneration"] = old["observedGeneration"] + } + + u.Object["status"] = status + + return nil +} diff --git a/pkg/controller/direct/sql/utils.go b/pkg/controller/direct/sql/utils.go new file mode 100644 index 0000000000..7120b1d516 --- /dev/null +++ b/pkg/controller/direct/sql/utils.go @@ -0,0 +1,23 @@ +// Copyright 2024 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 + +func ValueOf[T any](p *T) T { + var v T + if p != nil { + v = *p + } + return v +} diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_generated_object_mysqlinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_generated_object_mysqlinstance.golden.yaml index 7d3d6a3264..7141856536 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_generated_object_mysqlinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_generated_object_mysqlinstance.golden.yaml @@ -3,14 +3,11 @@ kind: SQLInstance metadata: annotations: cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/mutable-but-unreadable-fields: '{}' - cnrm.cloud.google.com/observed-secret-versions: (removed) cnrm.cloud.google.com/project-id: ${projectId} - cnrm.cloud.google.com/state-into-spec: merge finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 3 + generation: 2 labels: cnrm-test: "true" label-one: value-one @@ -19,29 +16,10 @@ metadata: spec: databaseVersion: MYSQL_5_7 instanceType: CLOUD_SQL_INSTANCE - maintenanceVersion: MYSQL_5_7_44.R20231105.01_03 region: us-central1 - resourceID: sqlinstance-sample-${uniqueId} settings: - activationPolicy: ALWAYS - availabilityType: ZONAL - backupConfiguration: - backupRetentionSettings: - retainedBackups: 7 - retentionUnit: COUNT - startTime: "12:00" - transactionLogRetentionDays: 7 - connectorEnforcement: NOT_REQUIRED diskAutoresize: false - diskAutoresizeLimit: 0 diskSize: 20 - diskType: PD_SSD - edition: ENTERPRISE - ipConfiguration: - ipv4Enabled: true - locationPreference: - zone: us-central1-a - pricingPlan: PER_USE tier: db-n1-standard-1 status: conditions: @@ -54,7 +32,7 @@ status: firstIpAddress: 10.1.2.3 instanceType: CLOUD_SQL_INSTANCE ipAddress: 10.1.2.3 - observedGeneration: 3 + observedGeneration: 2 publicIpAddress: 10.1.2.3 selfLink: https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId} serverCaCert: diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_http.log index 0af2360b9e..c2d9b787fb 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstance/_http.log @@ -1,5 +1,5 @@ GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -30,7 +30,7 @@ X-Xss-Protection: 0 POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "MYSQL_5_7", @@ -81,7 +81,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -110,8 +110,180 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "backendType": "SECOND_GEN", + "connectionName": "${projectId}:us-central1:sqlinstance-sample-${uniqueId}", + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseInstalledVersion": "MYSQL_5_7_44", + "databaseVersion": "MYSQL_5_7", + "etag": "abcdef0123A=", + "gceZone": "us-central1-a", + "geminiConfig": { + "entitled": false, + "flagRecommenderEnabled": false, + "indexAdvisorEnabled": false + }, + "instanceType": "CLOUD_SQL_INSTANCE", + "ipAddresses": [ + { + "ipAddress": "10.1.2.3", + "type": "PRIMARY" + } + ], + "kind": "sql#instance", + "maintenanceVersion": "MYSQL_5_7_44.R20231105.01_03", + "name": "sqlinstance-sample-${uniqueId}", + "project": "${projectId}", + "region": "us-central1", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}", + "serverCaCert": { + "cert": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", + "certSerialNumber": "0", + "commonName": "common-name", + "createTime": "2024-04-01T12:34:56.123456Z", + "expirationTime": "2024-04-01T12:34:56.123456Z", + "instance": "sqlinstance-sample-${uniqueId}", + "kind": "sql#sslCert", + "sha1Fingerprint": "12345678" + }, + "serviceAccountEmailAddress": "p${projectNumber}-abcdef@gcp-sa-cloud-sql.iam.gserviceaccount.com", + "settings": { + "activationPolicy": "ALWAYS", + "authorizedGaeApplications": [], + "availabilityType": "ZONAL", + "backupConfiguration": { + "backupRetentionSettings": { + "retainedBackups": 7, + "retentionUnit": "COUNT" + }, + "enabled": false, + "kind": "sql#backupConfiguration", + "startTime": "12:00", + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" + }, + "connectorEnforcement": "NOT_REQUIRED", + "dataDiskSizeGb": "10", + "dataDiskType": "PD_SSD", + "deletionProtectionEnabled": false, + "edition": "ENTERPRISE", + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": true, + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" + }, + "kind": "sql#settings", + "locationPreference": { + "kind": "sql#locationPreference", + "zone": "us-central1-a" + }, + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "settingsVersion": "123", + "storageAutoResize": false, + "storageAutoResizeLimit": "0", + "tier": "db-n1-standard-1", + "userLabels": { + "cnrm-test": "true", + "label-one": "value-one", + "managed-by-cnrm": "true" + } + }, + "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE", + "state": "RUNNABLE", + "upgradableDatabaseVersions": [ + { + "displayName": "MySQL 8.0", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0" + }, + { + "displayName": "MySQL 8.0.18", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_18" + }, + { + "displayName": "MySQL 8.0.26", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_26" + }, + { + "displayName": "MySQL 8.0.27", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_27" + }, + { + "displayName": "MySQL 8.0.28", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_28" + }, + { + "displayName": "MySQL 8.0.29", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_29" + }, + { + "displayName": "MySQL 8.0.30", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_30" + }, + { + "displayName": "MySQL 8.0.31", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_31" + }, + { + "displayName": "MySQL 8.0.32", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_32" + }, + { + "displayName": "MySQL 8.0.33", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_33" + }, + { + "displayName": "MySQL 8.0.34", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_34" + }, + { + "displayName": "MySQL 8.0.35", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_35" + }, + { + "displayName": "MySQL 8.0.36", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_36" + }, + { + "displayName": "MySQL 8.0.37", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_37" + } + ] +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -140,8 +312,8 @@ X-Xss-Protection: 0 --- -DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}/users?alt=json&host=%25&name=root&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}/users?alt=json&name=root&prettyPrint=false +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -170,7 +342,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -200,7 +372,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -373,10 +545,14 @@ X-Xss-Protection: 0 PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { + "databaseVersion": "MYSQL_5_7", "instanceType": "CLOUD_SQL_INSTANCE", + "maintenanceVersion": "MYSQL_5_7_44.R20231105.01_03", + "name": "sqlinstance-sample-${uniqueId}", + "region": "us-central1", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "ZONAL", @@ -387,9 +563,11 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr }, "binaryLogEnabled": false, "enabled": false, + "kind": "sql#backupConfiguration", "pointInTimeRecoveryEnabled": false, "startTime": "12:00", - "transactionLogRetentionDays": 7 + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" }, "connectorEnforcement": "NOT_REQUIRED", "dataDiskSizeGb": "20", @@ -398,12 +576,15 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "ipConfiguration": { "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": true, - "requireSsl": false + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" }, "locationPreference": { + "kind": "sql#locationPreference", "zone": "us-central1-a" }, "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "storageAutoResize": false, "tier": "db-n1-standard-1", @@ -442,7 +623,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -472,7 +653,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -646,7 +827,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -670,34 +851,4 @@ X-Xss-Protection: 0 "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}", "targetProject": "${projectId}", "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlinstance-sample-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" } \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_generated_object_mysqlinstancebasic.golden.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_generated_object_mysqlinstancebasic.golden.yaml index ce7b5cc438..513a13329e 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_generated_object_mysqlinstancebasic.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_generated_object_mysqlinstancebasic.golden.yaml @@ -3,14 +3,12 @@ kind: SQLInstance metadata: annotations: cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/mutable-but-unreadable-fields: '{}' - cnrm.cloud.google.com/observed-secret-versions: (removed) cnrm.cloud.google.com/project-id: ${projectId} cnrm.cloud.google.com/state-into-spec: absent finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 3 + generation: 2 labels: cnrm-test: "true" name: mysqlbasic-${uniqueId} @@ -18,7 +16,6 @@ metadata: spec: databaseVersion: MYSQL_8_0 region: us-central1 - resourceID: mysqlbasic-${uniqueId} settings: locationPreference: zone: us-central1-a @@ -34,7 +31,7 @@ status: firstIpAddress: 10.1.2.3 instanceType: CLOUD_SQL_INSTANCE ipAddress: 10.1.2.3 - observedGeneration: 3 + observedGeneration: 2 publicIpAddress: 10.1.2.3 selfLink: https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId} serverCaCert: diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_http.log index ca18f3623b..0c65595b37 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/mysqlinstancebasic/_http.log @@ -1,5 +1,5 @@ GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -30,7 +30,7 @@ X-Xss-Protection: 0 POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "MYSQL_5_7", @@ -81,7 +81,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -110,8 +110,179 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "backendType": "SECOND_GEN", + "connectionName": "${projectId}:us-central1:mysqlbasic-${uniqueId}", + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseInstalledVersion": "MYSQL_5_7_44", + "databaseVersion": "MYSQL_5_7", + "etag": "abcdef0123A=", + "gceZone": "us-central1-a", + "geminiConfig": { + "entitled": false, + "flagRecommenderEnabled": false, + "indexAdvisorEnabled": false + }, + "instanceType": "CLOUD_SQL_INSTANCE", + "ipAddresses": [ + { + "ipAddress": "10.1.2.3", + "type": "PRIMARY" + } + ], + "kind": "sql#instance", + "maintenanceVersion": "MYSQL_5_7_44.R20231105.01_03", + "name": "mysqlbasic-${uniqueId}", + "project": "${projectId}", + "region": "us-central1", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}", + "serverCaCert": { + "cert": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", + "certSerialNumber": "0", + "commonName": "common-name", + "createTime": "2024-04-01T12:34:56.123456Z", + "expirationTime": "2024-04-01T12:34:56.123456Z", + "instance": "mysqlbasic-${uniqueId}", + "kind": "sql#sslCert", + "sha1Fingerprint": "12345678" + }, + "serviceAccountEmailAddress": "p${projectNumber}-abcdef@gcp-sa-cloud-sql.iam.gserviceaccount.com", + "settings": { + "activationPolicy": "ALWAYS", + "authorizedGaeApplications": [], + "availabilityType": "ZONAL", + "backupConfiguration": { + "backupRetentionSettings": { + "retainedBackups": 7, + "retentionUnit": "COUNT" + }, + "enabled": false, + "kind": "sql#backupConfiguration", + "startTime": "12:00", + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" + }, + "connectorEnforcement": "NOT_REQUIRED", + "dataDiskSizeGb": "10", + "dataDiskType": "PD_SSD", + "deletionProtectionEnabled": false, + "edition": "ENTERPRISE", + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": true, + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" + }, + "kind": "sql#settings", + "locationPreference": { + "kind": "sql#locationPreference", + "zone": "us-central1-a" + }, + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "settingsVersion": "123", + "storageAutoResize": true, + "storageAutoResizeLimit": "0", + "tier": "db-custom-1-3840", + "userLabels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + } + }, + "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE", + "state": "RUNNABLE", + "upgradableDatabaseVersions": [ + { + "displayName": "MySQL 8.0", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0" + }, + { + "displayName": "MySQL 8.0.18", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_18" + }, + { + "displayName": "MySQL 8.0.26", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_26" + }, + { + "displayName": "MySQL 8.0.27", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_27" + }, + { + "displayName": "MySQL 8.0.28", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_28" + }, + { + "displayName": "MySQL 8.0.29", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_29" + }, + { + "displayName": "MySQL 8.0.30", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_30" + }, + { + "displayName": "MySQL 8.0.31", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_31" + }, + { + "displayName": "MySQL 8.0.32", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_32" + }, + { + "displayName": "MySQL 8.0.33", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_33" + }, + { + "displayName": "MySQL 8.0.34", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_34" + }, + { + "displayName": "MySQL 8.0.35", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_35" + }, + { + "displayName": "MySQL 8.0.36", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_36" + }, + { + "displayName": "MySQL 8.0.37", + "majorVersion": "MYSQL_8_0", + "name": "MYSQL_8_0_37" + } + ] +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -140,8 +311,8 @@ X-Xss-Protection: 0 --- -DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}/users?alt=json&host=%25&name=root&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}/users?alt=json&name=root&prettyPrint=false +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -170,7 +341,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -200,7 +371,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -372,7 +543,7 @@ X-Xss-Protection: 0 PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "MYSQL_8_0" @@ -405,7 +576,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -435,7 +606,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -597,10 +768,14 @@ X-Xss-Protection: 0 PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { + "databaseVersion": "MYSQL_8_0", "instanceType": "CLOUD_SQL_INSTANCE", + "maintenanceVersion": "MYSQL_8_0_31.R20240527.01_00", + "name": "mysqlbasic-${uniqueId}", + "region": "us-central1", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "ZONAL", @@ -611,9 +786,11 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr }, "binaryLogEnabled": false, "enabled": false, + "kind": "sql#backupConfiguration", "pointInTimeRecoveryEnabled": false, "startTime": "12:00", - "transactionLogRetentionDays": 7 + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" }, "connectorEnforcement": "NOT_REQUIRED", "dataDiskSizeGb": "10", @@ -622,12 +799,14 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "ipConfiguration": { "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": true, - "requireSsl": false + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" }, "locationPreference": { "zone": "us-central1-a" }, "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "storageAutoResize": true, "tier": "db-custom-2-7680", @@ -665,7 +844,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -695,7 +874,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -858,7 +1037,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -882,34 +1061,4 @@ X-Xss-Protection: 0 "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}", "targetProject": "${projectId}", "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "mysqlbasic-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/mysqlbasic-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" } \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_generated_object_postgresinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_generated_object_postgresinstance.golden.yaml index a8e72557ab..9518f0d2e1 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_generated_object_postgresinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_generated_object_postgresinstance.golden.yaml @@ -3,25 +3,19 @@ kind: SQLInstance metadata: annotations: cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/mutable-but-unreadable-fields: '{"spec":{"settings":{"ipConfiguration":{"sslMode":"ENCRYPTED_ONLY"}}}}' - cnrm.cloud.google.com/observed-secret-versions: (removed) cnrm.cloud.google.com/project-id: ${projectId} - cnrm.cloud.google.com/state-into-spec: merge finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 3 + generation: 2 labels: cnrm-test: "true" name: sqlinstance-${uniqueId} namespace: ${uniqueId} spec: databaseVersion: POSTGRES_9_6 - instanceType: CLOUD_SQL_INSTANCE region: us-central1 - resourceID: sqlinstance-${uniqueId} settings: - activationPolicy: ALWAYS availabilityType: REGIONAL backupConfiguration: backupRetentionSettings: @@ -31,7 +25,6 @@ spec: pointInTimeRecoveryEnabled: true startTime: "05:00" transactionLogRetentionDays: 3 - connectorEnforcement: NOT_REQUIRED databaseFlags: - name: cloudsql.iam_authentication value: "on" @@ -44,7 +37,6 @@ spec: diskAutoresizeLimit: 0 diskSize: 100 diskType: PD_SSD - edition: ENTERPRISE insightsConfig: queryInsightsEnabled: true queryStringLength: 1024 @@ -56,9 +48,6 @@ spec: name: computenetwork-${uniqueId} requireSsl: false sslMode: ENCRYPTED_ONLY - locationPreference: - zone: us-central1-a - pricingPlan: PER_USE tier: db-custom-1-3840 status: conditions: @@ -71,7 +60,7 @@ status: firstIpAddress: 10.1.2.3 instanceType: CLOUD_SQL_INSTANCE ipAddress: 10.1.2.3 - observedGeneration: 3 + observedGeneration: 2 publicIpAddress: 10.1.2.3 selfLink: https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId} serverCaCert: diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_http.log index 9904f2893a..f6cd48a616 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstance/_http.log @@ -479,7 +479,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -508,61 +508,9 @@ X-Xss-Protection: 0 --- -GET https://cloudresourcemanager.googleapis.com/v1/projects/${projectId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "createTime": "2024-04-01T12:34:56.123456Z", - "lifecycleState": "ACTIVE", - "projectId": "${projectId}", - "projectNumber": "${projectNumber}" -} - ---- - -GET https://servicenetworking.googleapis.com/v1/services/servicenetworking.googleapis.com/connections?alt=json&network=projects%2F${projectNumber}%2Fglobal%2Fnetworks%2Fcomputenetwork-${uniqueId}&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "connections": [ - { - "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}", - "peering": "servicenetworking-googleapis-com", - "reservedPeeringRanges": [ - "computeaddress-${uniqueId}" - ], - "service": "services/servicenetworking.googleapis.com" - } - ] -} - ---- - POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "POSTGRES_9_6", @@ -576,7 +524,6 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "retainedBackups": 7, "retentionUnit": "COUNT" }, - "binaryLogEnabled": false, "enabled": true, "pointInTimeRecoveryEnabled": true, "startTime": "12:00", @@ -606,10 +553,8 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "recordClientAddress": true }, "ipConfiguration": { - "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": false, - "privateNetwork": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", - "requireSsl": false, + "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", "sslMode": "ENCRYPTED_ONLY" }, "pricingPlan": "PER_USE", @@ -649,7 +594,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -678,8 +623,135 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "backendType": "SECOND_GEN", + "connectionName": "${projectId}:us-central1:sqlinstance-${uniqueId}", + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseInstalledVersion": "POSTGRES_9_6", + "databaseVersion": "POSTGRES_9_6", + "etag": "abcdef0123A=", + "gceZone": "us-central1-a", + "geminiConfig": { + "activeQueryEnabled": false, + "entitled": false, + "googleVacuumMgmtEnabled": false, + "indexAdvisorEnabled": false, + "oomSessionCancelEnabled": false + }, + "instanceType": "CLOUD_SQL_INSTANCE", + "ipAddresses": [ + { + "ipAddress": "10.1.2.3", + "type": "PRIMARY" + }, + { + "ipAddress": "10.1.2.3", + "type": "OUTGOING" + } + ], + "kind": "sql#instance", + "name": "sqlinstance-${uniqueId}", + "project": "${projectId}", + "region": "us-central1", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", + "serverCaCert": { + "cert": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", + "certSerialNumber": "0", + "commonName": "common-name", + "createTime": "2024-04-01T12:34:56.123456Z", + "expirationTime": "2024-04-01T12:34:56.123456Z", + "instance": "sqlinstance-${uniqueId}", + "kind": "sql#sslCert", + "sha1Fingerprint": "12345678" + }, + "serviceAccountEmailAddress": "p${projectNumber}-abcdef@gcp-sa-cloud-sql.iam.gserviceaccount.com", + "settings": { + "activationPolicy": "ALWAYS", + "authorizedGaeApplications": [], + "availabilityType": "REGIONAL", + "backupConfiguration": { + "backupRetentionSettings": { + "retainedBackups": 7, + "retentionUnit": "COUNT" + }, + "enabled": true, + "kind": "sql#backupConfiguration", + "pointInTimeRecoveryEnabled": true, + "replicationLogArchivingEnabled": false, + "startTime": "12:00", + "transactionLogRetentionDays": 3, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" + }, + "connectorEnforcement": "NOT_REQUIRED", + "dataDiskSizeGb": "100", + "dataDiskType": "PD_SSD", + "databaseFlags": [ + { + "name": "cloudsql.iam_authentication", + "value": "on" + }, + { + "name": "max_connections", + "value": "1000" + }, + { + "name": "max_worker_processes", + "value": "8" + } + ], + "deletionProtectionEnabled": false, + "edition": "ENTERPRISE", + "insightsConfig": { + "queryInsightsEnabled": true, + "queryStringLength": 1024, + "recordApplicationTags": true, + "recordClientAddress": true + }, + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": false, + "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "requireSsl": false, + "sslMode": "ENCRYPTED_ONLY" + }, + "kind": "sql#settings", + "locationPreference": { + "kind": "sql#locationPreference", + "zone": "us-central1-a" + }, + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "settingsVersion": "123", + "storageAutoResize": false, + "storageAutoResizeLimit": "0", + "tier": "db-custom-1-3840", + "userLabels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + } + }, + "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE", + "state": "RUNNABLE" +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -709,7 +781,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -808,9 +880,8 @@ X-Xss-Protection: 0 }, "ipConfiguration": { "authorizedNetworks": [], - "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": false, - "privateNetwork": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", "requireSsl": false, "sslMode": "ENCRYPTED_ONLY" }, @@ -838,10 +909,13 @@ X-Xss-Protection: 0 PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { + "databaseVersion": "POSTGRES_9_6", "instanceType": "CLOUD_SQL_INSTANCE", + "name": "sqlinstance-${uniqueId}", + "region": "us-central1", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "REGIONAL", @@ -852,6 +926,7 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr }, "binaryLogEnabled": false, "enabled": true, + "kind": "sql#backupConfiguration", "pointInTimeRecoveryEnabled": true, "startTime": "12:00", "transactionLogRetentionDays": 3 @@ -883,14 +958,16 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "ipConfiguration": { "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": false, - "privateNetwork": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", "requireSsl": false, "sslMode": "ENCRYPTED_ONLY" }, "locationPreference": { + "kind": "sql#locationPreference", "zone": "us-central1-a" }, "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "storageAutoResize": false, "tier": "db-custom-1-3840", @@ -928,7 +1005,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -958,7 +1035,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1059,7 +1136,7 @@ X-Xss-Protection: 0 "authorizedNetworks": [], "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": false, - "privateNetwork": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", "requireSsl": false, "sslMode": "ENCRYPTED_ONLY" }, @@ -1086,7 +1163,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1114,36 +1191,6 @@ X-Xss-Protection: 0 --- -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlinstance-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - GET https://cloudresourcemanager.googleapis.com/v1/projects/${projectId}?alt=json&prettyPrint=false User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_generated_object_postgresinstancebasic.golden.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_generated_object_postgresinstancebasic.golden.yaml index 31e151bf73..57f45a3b6e 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_generated_object_postgresinstancebasic.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_generated_object_postgresinstancebasic.golden.yaml @@ -3,14 +3,12 @@ kind: SQLInstance metadata: annotations: cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/mutable-but-unreadable-fields: '{}' - cnrm.cloud.google.com/observed-secret-versions: (removed) cnrm.cloud.google.com/project-id: ${projectId} cnrm.cloud.google.com/state-into-spec: absent finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 3 + generation: 2 labels: cnrm-test: "true" name: postgresbasic-${uniqueId} @@ -18,7 +16,6 @@ metadata: spec: databaseVersion: POSTGRES_16 region: us-central1 - resourceID: postgresbasic-${uniqueId} settings: locationPreference: zone: us-central1-a @@ -34,7 +31,7 @@ status: firstIpAddress: 10.1.2.3 instanceType: CLOUD_SQL_INSTANCE ipAddress: 10.1.2.3 - observedGeneration: 3 + observedGeneration: 2 publicIpAddress: 10.1.2.3 selfLink: https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId} serverCaCert: diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_http.log index ea32ef137d..0a896528ca 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/postgresinstancebasic/_http.log @@ -1,5 +1,5 @@ GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -30,7 +30,7 @@ X-Xss-Protection: 0 POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "POSTGRES_15", @@ -81,7 +81,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -110,8 +110,120 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "backendType": "SECOND_GEN", + "connectionName": "${projectId}:us-central1:postgresbasic-${uniqueId}", + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseInstalledVersion": "POSTGRES_15_7", + "databaseVersion": "POSTGRES_15", + "etag": "abcdef0123A=", + "gceZone": "us-central1-a", + "geminiConfig": { + "activeQueryEnabled": false, + "entitled": false, + "googleVacuumMgmtEnabled": false, + "indexAdvisorEnabled": false, + "oomSessionCancelEnabled": false + }, + "instanceType": "CLOUD_SQL_INSTANCE", + "ipAddresses": [ + { + "ipAddress": "10.1.2.3", + "type": "PRIMARY" + }, + { + "ipAddress": "10.1.2.3", + "type": "OUTGOING" + } + ], + "kind": "sql#instance", + "maintenanceVersion": "POSTGRES_15_7.R20240514.00_08", + "name": "postgresbasic-${uniqueId}", + "project": "${projectId}", + "region": "us-central1", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}", + "serverCaCert": { + "cert": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", + "certSerialNumber": "0", + "commonName": "common-name", + "createTime": "2024-04-01T12:34:56.123456Z", + "expirationTime": "2024-04-01T12:34:56.123456Z", + "instance": "postgresbasic-${uniqueId}", + "kind": "sql#sslCert", + "sha1Fingerprint": "12345678" + }, + "serviceAccountEmailAddress": "p${projectNumber}-abcdef@gcp-sa-cloud-sql.iam.gserviceaccount.com", + "settings": { + "activationPolicy": "ALWAYS", + "authorizedGaeApplications": [], + "availabilityType": "ZONAL", + "backupConfiguration": { + "backupRetentionSettings": { + "retainedBackups": 7, + "retentionUnit": "COUNT" + }, + "enabled": false, + "kind": "sql#backupConfiguration", + "startTime": "12:00", + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" + }, + "connectorEnforcement": "NOT_REQUIRED", + "dataDiskSizeGb": "10", + "dataDiskType": "PD_SSD", + "deletionProtectionEnabled": false, + "edition": "ENTERPRISE", + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": true, + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" + }, + "kind": "sql#settings", + "locationPreference": { + "kind": "sql#locationPreference", + "zone": "us-central1-a" + }, + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "settingsVersion": "123", + "storageAutoResize": true, + "storageAutoResizeLimit": "0", + "tier": "db-custom-1-3840", + "userLabels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + } + }, + "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE", + "state": "RUNNABLE", + "upgradableDatabaseVersions": [ + { + "displayName": "PostgreSQL 16", + "majorVersion": "POSTGRES_16", + "name": "POSTGRES_16" + } + ] +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -141,7 +253,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -254,7 +366,7 @@ X-Xss-Protection: 0 PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "POSTGRES_16" @@ -287,7 +399,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -317,7 +429,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -423,10 +535,14 @@ X-Xss-Protection: 0 PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { + "databaseVersion": "POSTGRES_16", "instanceType": "CLOUD_SQL_INSTANCE", + "maintenanceVersion": "POSTGRES_16_3.R20240527.01_10", + "name": "postgresbasic-${uniqueId}", + "region": "us-central1", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "ZONAL", @@ -437,9 +553,11 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr }, "binaryLogEnabled": false, "enabled": false, + "kind": "sql#backupConfiguration", "pointInTimeRecoveryEnabled": false, "startTime": "12:00", - "transactionLogRetentionDays": 7 + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" }, "connectorEnforcement": "NOT_REQUIRED", "dataDiskSizeGb": "10", @@ -448,12 +566,14 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "ipConfiguration": { "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": true, - "requireSsl": false + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" }, "locationPreference": { "zone": "us-central1-a" }, "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "storageAutoResize": true, "tier": "db-custom-2-7680", @@ -491,7 +611,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -521,7 +641,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -629,7 +749,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -653,34 +773,4 @@ X-Xss-Protection: 0 "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}", "targetProject": "${projectId}", "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "postgresbasic-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/postgresbasic-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" } \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_generated_object_sqlinstanceencryptionkey.golden.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_generated_object_sqlinstanceencryptionkey.golden.yaml index 71ee26dcbd..581730a028 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_generated_object_sqlinstanceencryptionkey.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_generated_object_sqlinstanceencryptionkey.golden.yaml @@ -3,14 +3,11 @@ kind: SQLInstance metadata: annotations: cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/mutable-but-unreadable-fields: '{}' - cnrm.cloud.google.com/observed-secret-versions: (removed) cnrm.cloud.google.com/project-id: ${projectId} - cnrm.cloud.google.com/state-into-spec: merge finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 2 + generation: 1 labels: cnrm-test: "true" label-one: new-value @@ -20,28 +17,22 @@ spec: databaseVersion: POSTGRES_15 encryptionKMSCryptoKeyRef: external: projects/${projectId}/locations/us-central1/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId} - instanceType: CLOUD_SQL_INSTANCE - maintenanceVersion: POSTGRES_15_7.R20240514.00_08 region: us-central1 - resourceID: sqlinstance-sample-${uniqueId} settings: activationPolicy: ALWAYS availabilityType: REGIONAL backupConfiguration: backupRetentionSettings: retainedBackups: 5 - retentionUnit: COUNT enabled: true pointInTimeRecoveryEnabled: true startTime: "01:00" transactionLogRetentionDays: 5 - connectorEnforcement: NOT_REQUIRED databaseFlags: - name: cloudsql.iam_authentication value: "on" deletionProtectionEnabled: false diskAutoresize: true - diskAutoresizeLimit: 0 diskSize: 100 diskType: PD_SSD edition: ENTERPRISE @@ -62,7 +53,6 @@ spec: day: 6 hour: 2 updateTrack: stable - pricingPlan: PER_USE tier: db-custom-8-30720 status: conditions: @@ -75,7 +65,7 @@ status: firstIpAddress: 10.1.2.3 instanceType: CLOUD_SQL_INSTANCE ipAddress: 10.1.2.3 - observedGeneration: 2 + observedGeneration: 1 publicIpAddress: 10.1.2.3 selfLink: https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId} serverCaCert: diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_http.log index 30f229b936..ce982b9b55 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlinstanceencryptionkey/_http.log @@ -929,7 +929,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -958,65 +958,14 @@ X-Xss-Protection: 0 --- -GET https://cloudresourcemanager.googleapis.com/v1/projects/${projectId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "createTime": "2024-04-01T12:34:56.123456Z", - "lifecycleState": "ACTIVE", - "projectId": "${projectId}", - "projectNumber": "${projectNumber}" -} - ---- - -GET https://servicenetworking.googleapis.com/v1/services/servicenetworking.googleapis.com/connections?alt=json&network=projects%2F${projectNumber}%2Fglobal%2Fnetworks%2Fcomputenetwork-${uniqueId}&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "connections": [ - { - "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}", - "peering": "servicenetworking-googleapis-com", - "reservedPeeringRanges": [ - "computeaddress-${uniqueId}" - ], - "service": "services/servicenetworking.googleapis.com" - } - ] -} - ---- - POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "POSTGRES_15", "diskEncryptionConfiguration": { + "kind": "sql#diskEncryptionConfiguration", "kmsKeyName": "projects/${projectId}/locations/us-central1/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId}" }, "name": "sqlinstance-sample-${uniqueId}", @@ -1026,10 +975,8 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "availabilityType": "REGIONAL", "backupConfiguration": { "backupRetentionSettings": { - "retainedBackups": 5, - "retentionUnit": "COUNT" + "retainedBackups": 5 }, - "binaryLogEnabled": false, "enabled": true, "pointInTimeRecoveryEnabled": true, "startTime": "12:00", @@ -1052,7 +999,6 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "recordClientAddress": true }, "ipConfiguration": { - "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": false, "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", "requireSsl": true @@ -1103,7 +1049,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1132,8 +1078,146 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "backendType": "SECOND_GEN", + "connectionName": "${projectId}:us-central1:sqlinstance-sample-${uniqueId}", + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseInstalledVersion": "POSTGRES_15_7", + "databaseVersion": "POSTGRES_15", + "diskEncryptionConfiguration": { + "kind": "sql#diskEncryptionConfiguration", + "kmsKeyName": "projects/${projectId}/locations/us-central1/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId}" + }, + "etag": "abcdef0123A=", + "gceZone": "us-central1-a", + "geminiConfig": { + "activeQueryEnabled": false, + "entitled": false, + "googleVacuumMgmtEnabled": false, + "indexAdvisorEnabled": false, + "oomSessionCancelEnabled": false + }, + "instanceType": "CLOUD_SQL_INSTANCE", + "ipAddresses": [ + { + "ipAddress": "10.1.2.3", + "type": "PRIMARY" + }, + { + "ipAddress": "10.1.2.3", + "type": "OUTGOING" + } + ], + "kind": "sql#instance", + "maintenanceVersion": "POSTGRES_15_7.R20240514.00_08", + "name": "sqlinstance-sample-${uniqueId}", + "project": "${projectId}", + "region": "us-central1", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}", + "serverCaCert": { + "cert": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", + "certSerialNumber": "0", + "commonName": "common-name", + "createTime": "2024-04-01T12:34:56.123456Z", + "expirationTime": "2024-04-01T12:34:56.123456Z", + "instance": "sqlinstance-sample-${uniqueId}", + "kind": "sql#sslCert", + "sha1Fingerprint": "12345678" + }, + "serviceAccountEmailAddress": "p${projectNumber}-abcdef@gcp-sa-cloud-sql.iam.gserviceaccount.com", + "settings": { + "activationPolicy": "ALWAYS", + "authorizedGaeApplications": [], + "availabilityType": "REGIONAL", + "backupConfiguration": { + "backupRetentionSettings": { + "retainedBackups": 5, + "retentionUnit": "COUNT" + }, + "enabled": true, + "kind": "sql#backupConfiguration", + "pointInTimeRecoveryEnabled": true, + "replicationLogArchivingEnabled": false, + "startTime": "12:00", + "transactionLogRetentionDays": 5, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" + }, + "connectorEnforcement": "NOT_REQUIRED", + "dataDiskSizeGb": "100", + "dataDiskType": "PD_SSD", + "databaseFlags": [ + { + "name": "cloudsql.iam_authentication", + "value": "on" + } + ], + "deletionProtectionEnabled": false, + "edition": "ENTERPRISE", + "insightsConfig": { + "queryInsightsEnabled": true, + "queryPlansPerMinute": 20, + "queryStringLength": 4500, + "recordApplicationTags": true, + "recordClientAddress": true + }, + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": false, + "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "requireSsl": true, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" + }, + "kind": "sql#settings", + "locationPreference": { + "kind": "sql#locationPreference", + "zone": "us-central1-a" + }, + "maintenanceWindow": { + "day": 6, + "hour": 2, + "updateTrack": "stable" + }, + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "settingsVersion": "123", + "storageAutoResize": true, + "storageAutoResizeLimit": "0", + "tier": "db-custom-8-30720", + "userLabels": { + "cnrm-test": "true", + "label-one": "value-one", + "managed-by-cnrm": "true" + } + }, + "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE", + "state": "RUNNABLE", + "upgradableDatabaseVersions": [ + { + "displayName": "PostgreSQL 16", + "majorVersion": "POSTGRES_16", + "name": "POSTGRES_16" + } + ] +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1163,7 +1247,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1183,6 +1267,7 @@ X-Xss-Protection: 0 "databaseInstalledVersion": "POSTGRES_15_7", "databaseVersion": "POSTGRES_15", "diskEncryptionConfiguration": { + "kind": "sql#diskEncryptionConfiguration", "kmsKeyName": "projects/${projectId}/locations/us-central1/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId}" }, "etag": "abcdef0123A=", @@ -1259,7 +1344,6 @@ X-Xss-Protection: 0 }, "ipConfiguration": { "authorizedNetworks": [], - "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": false, "privateNetwork": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", "requireSsl": true, @@ -1302,20 +1386,28 @@ X-Xss-Protection: 0 PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { + "databaseVersion": "POSTGRES_15", + "diskEncryptionConfiguration": { + "kind": "sql#diskEncryptionConfiguration", + "kmsKeyName": "projects/${projectId}/locations/us-central1/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId}" + }, "instanceType": "CLOUD_SQL_INSTANCE", + "maintenanceVersion": "POSTGRES_15_7.R20240514.00_08", + "name": "sqlinstance-sample-${uniqueId}", + "region": "us-central1", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "REGIONAL", "backupConfiguration": { "backupRetentionSettings": { - "retainedBackups": 5, - "retentionUnit": "COUNT" + "retainedBackups": 5 }, "binaryLogEnabled": false, "enabled": true, + "kind": "sql#backupConfiguration", "pointInTimeRecoveryEnabled": true, "startTime": "12:00", "transactionLogRetentionDays": 5 @@ -1352,12 +1444,13 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "updateTrack": "stable" }, "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "storageAutoResize": true, "tier": "db-custom-8-30720", "userLabels": { "cnrm-test": "true", - "label-one": "value-one", + "label-one": "new-value", "managed-by-cnrm": "true" } } @@ -1390,7 +1483,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1420,7 +1513,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1439,6 +1532,10 @@ X-Xss-Protection: 0 "createTime": "2024-04-01T12:34:56.123456Z", "databaseInstalledVersion": "POSTGRES_15_7", "databaseVersion": "POSTGRES_15", + "diskEncryptionConfiguration": { + "kind": "sql#diskEncryptionConfiguration", + "kmsKeyName": "projects/${projectId}/locations/us-central1/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId}" + }, "etag": "abcdef0123A=", "gceZone": "us-central1-a", "geminiConfig": { @@ -1537,7 +1634,7 @@ X-Xss-Protection: 0 "tier": "db-custom-8-30720", "userLabels": { "cnrm-test": "true", - "label-one": "value-one", + "label-one": "new-value", "managed-by-cnrm": "true" } }, @@ -1555,7 +1652,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1583,36 +1680,6 @@ X-Xss-Protection: 0 --- -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlinstance-sample-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - GET https://cloudresourcemanager.googleapis.com/v1/projects/${projectId}?alt=json&prettyPrint=false User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_generated_object_sqlserverinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_generated_object_sqlserverinstance.golden.yaml index 3239777480..bda468bf92 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_generated_object_sqlserverinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_generated_object_sqlserverinstance.golden.yaml @@ -3,47 +3,25 @@ kind: SQLInstance metadata: annotations: cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/mutable-but-unreadable-fields: '{"spec":{"rootPassword":{"value":"1234"}}}' - cnrm.cloud.google.com/observed-secret-versions: (removed) cnrm.cloud.google.com/project-id: ${projectId} - cnrm.cloud.google.com/state-into-spec: merge finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 3 + generation: 2 labels: cnrm-test: "true" label-one: value-one + label-two: value-two name: sqlinstance-sample-${uniqueId} namespace: ${uniqueId} spec: databaseVersion: SQLSERVER_2017_EXPRESS - instanceType: CLOUD_SQL_INSTANCE - maintenanceVersion: SQLSERVER_2017_EXPRESS_CU31_GDR.R20231029.00_02 region: us-central1 - resourceID: sqlinstance-sample-${uniqueId} rootPassword: value: "1234" settings: - activationPolicy: ALWAYS - availabilityType: ZONAL - backupConfiguration: - backupRetentionSettings: - retainedBackups: 7 - retentionUnit: COUNT - startTime: "12:00" - transactionLogRetentionDays: 7 - connectorEnforcement: NOT_REQUIRED diskAutoresize: false - diskAutoresizeLimit: 0 diskSize: 20 - diskType: PD_SSD - edition: ENTERPRISE - ipConfiguration: - ipv4Enabled: true - locationPreference: - zone: us-central1-a - pricingPlan: PER_USE sqlServerAuditConfig: bucketRef: name: storagebucket-${uniqueId} @@ -59,7 +37,7 @@ status: firstIpAddress: 10.1.2.3 instanceType: CLOUD_SQL_INSTANCE ipAddress: 10.1.2.3 - observedGeneration: 3 + observedGeneration: 2 publicIpAddress: 10.1.2.3 selfLink: https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId} serverCaCert: diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_http.log index 11faf6cf01..bb9ad24154 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/_http.log @@ -140,7 +140,7 @@ Vary: X-Origin --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -171,7 +171,7 @@ X-Xss-Protection: 0 POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "SQLSERVER_2017_EXPRESS", @@ -186,7 +186,8 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr "edition": "ENTERPRISE", "pricingPlan": "PER_USE", "sqlServerAuditConfig": { - "bucket": "gs://storagebucket-${uniqueId}" + "bucket": "gs://storagebucket-${uniqueId}", + "kind": "sql#sqlServerAuditConfig" }, "storageAutoResize": false, "tier": "db-custom-1-3840", @@ -225,7 +226,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -254,8 +255,107 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "backendType": "SECOND_GEN", + "connectionName": "${projectId}:us-central1:sqlinstance-sample-${uniqueId}", + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseInstalledVersion": "SQLSERVER_2017_EXPRESS_CU31_GDR", + "databaseVersion": "SQLSERVER_2017_EXPRESS", + "etag": "abcdef0123A=", + "gceZone": "us-central1-a", + "instanceType": "CLOUD_SQL_INSTANCE", + "ipAddresses": [ + { + "ipAddress": "10.1.2.3", + "type": "PRIMARY" + } + ], + "kind": "sql#instance", + "maintenanceVersion": "SQLSERVER_2017_EXPRESS_CU31_GDR.R20231029.00_02", + "name": "sqlinstance-sample-${uniqueId}", + "project": "${projectId}", + "region": "us-central1", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}", + "serverCaCert": { + "cert": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", + "certSerialNumber": "0", + "commonName": "common-name", + "createTime": "2024-04-01T12:34:56.123456Z", + "expirationTime": "2024-04-01T12:34:56.123456Z", + "instance": "sqlinstance-sample-${uniqueId}", + "kind": "sql#sslCert", + "sha1Fingerprint": "12345678" + }, + "serviceAccountEmailAddress": "p${projectNumber}-abcdef@gcp-sa-cloud-sql.iam.gserviceaccount.com", + "settings": { + "activationPolicy": "ALWAYS", + "authorizedGaeApplications": [], + "availabilityType": "ZONAL", + "backupConfiguration": { + "backupRetentionSettings": { + "retainedBackups": 7, + "retentionUnit": "COUNT" + }, + "enabled": false, + "kind": "sql#backupConfiguration", + "startTime": "12:00", + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" + }, + "connectorEnforcement": "NOT_REQUIRED", + "dataDiskSizeGb": "10", + "dataDiskType": "PD_SSD", + "deletionProtectionEnabled": false, + "edition": "ENTERPRISE", + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": true, + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" + }, + "kind": "sql#settings", + "locationPreference": { + "kind": "sql#locationPreference", + "zone": "us-central1-a" + }, + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "settingsVersion": "123", + "sqlServerAuditConfig": { + "bucket": "gs://storagebucket-${uniqueId}", + "kind": "sql#sqlServerAuditConfig" + }, + "storageAutoResize": false, + "storageAutoResizeLimit": "0", + "tier": "db-custom-1-3840", + "userLabels": { + "cnrm-test": "true", + "label-one": "value-one", + "managed-by-cnrm": "true" + } + }, + "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE", + "state": "RUNNABLE" +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -312,7 +412,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -392,7 +492,8 @@ X-Xss-Protection: 0 "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "sqlServerAuditConfig": { - "bucket": "gs://storagebucket-${uniqueId}" + "bucket": "gs://storagebucket-${uniqueId}", + "kind": "sql#sqlServerAuditConfig" }, "storageAutoResize": false, "storageAutoResizeLimit": "0", @@ -411,10 +512,15 @@ X-Xss-Protection: 0 PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { + "databaseVersion": "SQLSERVER_2017_EXPRESS", "instanceType": "CLOUD_SQL_INSTANCE", + "maintenanceVersion": "SQLSERVER_2017_EXPRESS_CU31_GDR.R20231029.00_02", + "name": "sqlinstance-sample-${uniqueId}", + "region": "us-central1", + "rootPassword": "1234", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "ZONAL", @@ -425,31 +531,39 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr }, "binaryLogEnabled": false, "enabled": false, + "kind": "sql#backupConfiguration", "pointInTimeRecoveryEnabled": false, "startTime": "12:00", - "transactionLogRetentionDays": 7 + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" }, "connectorEnforcement": "NOT_REQUIRED", "dataDiskSizeGb": "20", "dataDiskType": "PD_SSD", "edition": "ENTERPRISE", "ipConfiguration": { + "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": true, - "requireSsl": false + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" }, "locationPreference": { + "kind": "sql#locationPreference", "zone": "us-central1-a" }, "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "sqlServerAuditConfig": { - "bucket": "gs://storagebucket-${uniqueId}" + "bucket": "gs://storagebucket-${uniqueId}", + "kind": "sql#sqlServerAuditConfig" }, "storageAutoResize": false, "tier": "db-custom-1-3840", "userLabels": { "cnrm-test": "true", "label-one": "value-one", + "label-two": "value-two", "managed-by-cnrm": "true" } } @@ -482,7 +596,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -512,7 +626,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -580,6 +694,7 @@ X-Xss-Protection: 0 "edition": "ENTERPRISE", "ipConfiguration": { "authorizedNetworks": [], + "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": true, "requireSsl": false, "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" @@ -593,7 +708,8 @@ X-Xss-Protection: 0 "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "sqlServerAuditConfig": { - "bucket": "gs://storagebucket-${uniqueId}" + "bucket": "gs://storagebucket-${uniqueId}", + "kind": "sql#sqlServerAuditConfig" }, "storageAutoResize": false, "storageAutoResizeLimit": "0", @@ -601,6 +717,7 @@ X-Xss-Protection: 0 "userLabels": { "cnrm-test": "true", "label-one": "value-one", + "label-two": "value-two", "managed-by-cnrm": "true" } }, @@ -611,7 +728,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -639,36 +756,6 @@ X-Xss-Protection: 0 --- -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlinstance-sample-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-sample-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - GET https://storage.googleapis.com/storage/v1/b/storagebucket-${uniqueId}?alt=json&prettyPrint=false User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/update.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/update.yaml index 26bdc40570..4f0360d9aa 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/update.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstance/update.yaml @@ -17,6 +17,7 @@ kind: SQLInstance metadata: labels: label-one: "value-one" + label-two: "value-two" name: sqlinstance-sample-${uniqueId} spec: region: us-central1 diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_generated_object_sqlserverinstancebasic.golden.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_generated_object_sqlserverinstancebasic.golden.yaml index de6b8d121c..8364391735 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_generated_object_sqlserverinstancebasic.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_generated_object_sqlserverinstancebasic.golden.yaml @@ -3,14 +3,12 @@ kind: SQLInstance metadata: annotations: cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/mutable-but-unreadable-fields: '{"spec":{"rootPassword":{"value":"4321"}}}' - cnrm.cloud.google.com/observed-secret-versions: (removed) cnrm.cloud.google.com/project-id: ${projectId} cnrm.cloud.google.com/state-into-spec: absent finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 3 + generation: 2 labels: cnrm-test: "true" name: sqlserverbasic-${uniqueId} @@ -18,9 +16,11 @@ metadata: spec: databaseVersion: SQLSERVER_2022_EXPRESS region: us-central1 - resourceID: sqlserverbasic-${uniqueId} rootPassword: - value: "4321" + valueFrom: + secretKeyRef: + key: password + name: secret-${uniqueId} settings: locationPreference: zone: us-central1-a @@ -36,7 +36,7 @@ status: firstIpAddress: 10.1.2.3 instanceType: CLOUD_SQL_INSTANCE ipAddress: 10.1.2.3 - observedGeneration: 3 + observedGeneration: 2 publicIpAddress: 10.1.2.3 selfLink: https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId} serverCaCert: diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_http.log index 114157807c..c477cb10a1 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/_http.log @@ -1,5 +1,5 @@ GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -30,13 +30,13 @@ X-Xss-Protection: 0 POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "SQLSERVER_2019_EXPRESS", "name": "sqlserverbasic-${uniqueId}", "region": "us-central1", - "rootPassword": "1234", + "rootPassword": "1234!@#$asdf", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "ZONAL", @@ -82,7 +82,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -111,8 +111,139 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "backendType": "SECOND_GEN", + "connectionName": "${projectId}:us-central1:sqlserverbasic-${uniqueId}", + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseInstalledVersion": "SQLSERVER_2019_EXPRESS_CU26", + "databaseVersion": "SQLSERVER_2019_EXPRESS", + "etag": "abcdef0123A=", + "gceZone": "us-central1-a", + "instanceType": "CLOUD_SQL_INSTANCE", + "ipAddresses": [ + { + "ipAddress": "10.1.2.3", + "type": "PRIMARY" + } + ], + "kind": "sql#instance", + "maintenanceVersion": "SQLSERVER_2019_EXPRESS_CU26.R20240501.00_05", + "name": "sqlserverbasic-${uniqueId}", + "project": "${projectId}", + "region": "us-central1", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}", + "serverCaCert": { + "cert": "-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----\n", + "certSerialNumber": "0", + "commonName": "common-name", + "createTime": "2024-04-01T12:34:56.123456Z", + "expirationTime": "2024-04-01T12:34:56.123456Z", + "instance": "sqlserverbasic-${uniqueId}", + "kind": "sql#sslCert", + "sha1Fingerprint": "12345678" + }, + "serviceAccountEmailAddress": "p${projectNumber}-abcdef@gcp-sa-cloud-sql.iam.gserviceaccount.com", + "settings": { + "activationPolicy": "ALWAYS", + "authorizedGaeApplications": [], + "availabilityType": "ZONAL", + "backupConfiguration": { + "backupRetentionSettings": { + "retainedBackups": 7, + "retentionUnit": "COUNT" + }, + "enabled": false, + "kind": "sql#backupConfiguration", + "startTime": "12:00", + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" + }, + "connectorEnforcement": "NOT_REQUIRED", + "dataDiskSizeGb": "10", + "dataDiskType": "PD_SSD", + "deletionProtectionEnabled": false, + "edition": "ENTERPRISE", + "ipConfiguration": { + "authorizedNetworks": [], + "ipv4Enabled": true, + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" + }, + "kind": "sql#settings", + "locationPreference": { + "kind": "sql#locationPreference", + "zone": "us-central1-a" + }, + "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", + "settingsVersion": "123", + "storageAutoResize": true, + "storageAutoResizeLimit": "0", + "tier": "db-custom-1-3840", + "userLabels": { + "cnrm-test": "true", + "managed-by-cnrm": "true" + } + }, + "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE", + "state": "RUNNABLE", + "upgradableDatabaseVersions": [ + { + "displayName": "SQL Server 2019 Standard", + "majorVersion": "SQLSERVER_2019_STANDARD", + "name": "SQLSERVER_2019_STANDARD" + }, + { + "displayName": "SQL Server 2019 Enterprise", + "majorVersion": "SQLSERVER_2019_ENTERPRISE", + "name": "SQLSERVER_2019_ENTERPRISE" + }, + { + "displayName": "SQL Server 2019 Web", + "majorVersion": "SQLSERVER_2019_WEB", + "name": "SQLSERVER_2019_WEB" + }, + { + "displayName": "SQL Server 2022 Standard", + "majorVersion": "SQLSERVER_2022_STANDARD", + "name": "SQLSERVER_2022_STANDARD" + }, + { + "displayName": "SQL Server 2022 Enterprise", + "majorVersion": "SQLSERVER_2022_ENTERPRISE", + "name": "SQLSERVER_2022_ENTERPRISE" + }, + { + "displayName": "SQL Server 2022 Express", + "majorVersion": "SQLSERVER_2022_EXPRESS", + "name": "SQLSERVER_2022_EXPRESS" + }, + { + "displayName": "SQL Server 2022 Web", + "majorVersion": "SQLSERVER_2022_WEB", + "name": "SQLSERVER_2022_WEB" + } + ] +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -169,7 +300,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -301,7 +432,7 @@ X-Xss-Protection: 0 PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "SQLSERVER_2022_EXPRESS" @@ -334,7 +465,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -364,7 +495,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -474,78 +605,17 @@ X-Xss-Protection: 0 --- -PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}/users?alt=json&host=&name=sqlserver&prettyPrint=false -Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -{ - "instance": "sqlserverbasic-${uniqueId}", - "name": "sqlserver", - "password": "4321" -} - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "UPDATE_USER", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "PENDING", - "targetId": "sqlserverbasic-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "UPDATE_USER", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlserverbasic-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - PUT https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { + "databaseVersion": "SQLSERVER_2022_EXPRESS", "instanceType": "CLOUD_SQL_INSTANCE", + "maintenanceVersion": "SQLSERVER_2022_EXPRESS_CU12_GDR.R20240501.00_05", + "name": "sqlserverbasic-${uniqueId}", + "region": "us-central1", + "rootPassword": "1234!@#$asdf", "settings": { "activationPolicy": "ALWAYS", "availabilityType": "ZONAL", @@ -556,22 +626,27 @@ User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terr }, "binaryLogEnabled": false, "enabled": false, + "kind": "sql#backupConfiguration", "pointInTimeRecoveryEnabled": false, "startTime": "12:00", - "transactionLogRetentionDays": 7 + "transactionLogRetentionDays": 7, + "transactionalLogStorageState": "TRANSACTIONAL_LOG_STORAGE_STATE_UNSPECIFIED" }, "connectorEnforcement": "NOT_REQUIRED", "dataDiskSizeGb": "10", "dataDiskType": "PD_SSD", "edition": "ENTERPRISE", "ipConfiguration": { + "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": true, - "requireSsl": false + "requireSsl": false, + "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" }, "locationPreference": { "zone": "us-central1-a" }, "pricingPlan": "PER_USE", + "replicationType": "SYNCHRONOUS", "settingsVersion": "123", "storageAutoResize": true, "tier": "db-custom-2-7680", @@ -609,7 +684,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -639,7 +714,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -707,6 +782,7 @@ X-Xss-Protection: 0 "edition": "ENTERPRISE", "ipConfiguration": { "authorizedNetworks": [], + "enablePrivatePathForGoogleCloudServices": false, "ipv4Enabled": true, "requireSsl": false, "sslMode": "ALLOW_UNENCRYPTED_AND_ENCRYPTED" @@ -751,7 +827,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -775,34 +851,4 @@ X-Xss-Protection: 0 "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}", "targetProject": "${projectId}", "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlserverbasic-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlserverbasic-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" } \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/create.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/create.yaml index da70e92a7f..37ba487ced 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/create.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/create.yaml @@ -23,7 +23,10 @@ spec: region: us-central1 # rootPassword is only a required field for SQL Server instances. rootPassword: - value: "1234" + valueFrom: + secretKeyRef: + key: password + name: secret-${uniqueId} settings: # Location preference is not actually a required field. However, setting it for tests # helps with with normalizing the GCP responses, because otherwise GCP chooses a zone diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/dependencies.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/dependencies.yaml new file mode 100644 index 0000000000..771e87572a --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/dependencies.yaml @@ -0,0 +1,21 @@ +# Copyright 2024 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: v1 +kind: Secret +metadata: + name: secret-${uniqueId} +data: + password: MTIzNCFAIyRhc2Rm \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/update.yaml b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/update.yaml index 165025a006..facfddc200 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/update.yaml +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqlinstance/sqlserverinstancebasic/update.yaml @@ -23,7 +23,10 @@ spec: region: us-central1 # rootPassword is only a required field for SQL Server instances. rootPassword: - value: "4321" + valueFrom: + secretKeyRef: + key: password + name: secret-${uniqueId} settings: # Location preference is not actually a required field. However, setting it for tests # helps with with normalizing the GCP responses, because otherwise GCP chooses a zone diff --git a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqluser/_http.log b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqluser/_http.log index 028108cc53..a39d3cfd43 100644 --- a/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqluser/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/sql/v1beta1/sqluser/_http.log @@ -1,5 +1,5 @@ GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -30,7 +30,7 @@ X-Xss-Protection: 0 POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "MYSQL_5_7", @@ -78,7 +78,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -107,97 +107,8 @@ X-Xss-Protection: 0 --- -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "items": [ - { - "etag": "abcdef0123A=", - "host": "", - "instance": "sqluser-dep-${uniqueId}", - "kind": "sql#user", - "name": "root", - "project": "${projectId}" - } - ], - "kind": "sql#usersList" -} - ---- - -DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}/users?alt=json&host=%25&name=root&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE_USER", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "PENDING", - "targetId": "sqluser-dep-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE_USER", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqluser-dep-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -367,6 +278,95 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}/users?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "items": [ + { + "etag": "abcdef0123A=", + "host": "", + "instance": "sqluser-dep-${uniqueId}", + "kind": "sql#user", + "name": "root", + "project": "${projectId}" + } + ], + "kind": "sql#usersList" +} + +--- + +DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}/users?alt=json&name=root&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "sql#operation", + "name": "${operationID}", + "operationType": "DELETE_USER", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", + "status": "PENDING", + "targetId": "sqluser-dep-${uniqueId}", + "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}", + "targetProject": "${projectId}", + "user": "user@example.com" +} + +--- + +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "sql#operation", + "name": "${operationID}", + "operationType": "DELETE_USER", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", + "status": "DONE", + "targetId": "sqluser-dep-${uniqueId}", + "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}", + "targetProject": "${projectId}", + "user": "user@example.com" +} + +--- + GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}/users?alt=json&prettyPrint=false User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager @@ -1291,7 +1291,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1462,7 +1462,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -1486,34 +1486,4 @@ X-Xss-Protection: 0 "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}", "targetProject": "${projectId}", "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqluser-dep-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqluser-dep-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" } \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/iammemberreferences/sqlinstanceref/_http.log b/pkg/test/resourcefixture/testdata/iammemberreferences/sqlinstanceref/_http.log index e054363295..a44ee336e5 100644 --- a/pkg/test/resourcefixture/testdata/iammemberreferences/sqlinstanceref/_http.log +++ b/pkg/test/resourcefixture/testdata/iammemberreferences/sqlinstanceref/_http.log @@ -1,5 +1,5 @@ GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 404 Not Found Cache-Control: private @@ -30,7 +30,7 @@ X-Xss-Protection: 0 POST https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances?alt=json&prettyPrint=false Content-Type: application/json -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager { "databaseVersion": "MYSQL_5_7", @@ -78,7 +78,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -107,97 +107,8 @@ X-Xss-Protection: 0 --- -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}/users?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "items": [ - { - "etag": "abcdef0123A=", - "host": "", - "instance": "sqlinstance-${uniqueId}", - "kind": "sql#user", - "name": "root", - "project": "${projectId}" - } - ], - "kind": "sql#usersList" -} - ---- - -DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}/users?alt=json&host=%25&name=root&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE_USER", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "PENDING", - "targetId": "sqlinstance-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE_USER", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlinstance-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" -} - ---- - GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -367,6 +278,95 @@ X-Xss-Protection: 0 --- +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}/users?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "items": [ + { + "etag": "abcdef0123A=", + "host": "", + "instance": "sqlinstance-${uniqueId}", + "kind": "sql#user", + "name": "root", + "project": "${projectId}" + } + ], + "kind": "sql#usersList" +} + +--- + +DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}/users?alt=json&name=root&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "sql#operation", + "name": "${operationID}", + "operationType": "DELETE_USER", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", + "status": "PENDING", + "targetId": "sqlinstance-${uniqueId}", + "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", + "targetProject": "${projectId}", + "user": "user@example.com" +} + +--- + +GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: kcc/controller-manager + +200 OK +Cache-Control: private +Content-Type: application/json; charset=UTF-8 +Server: ESF +Vary: Origin +Vary: X-Origin +Vary: Referer +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Xss-Protection: 0 + +{ + "endTime": "2024-04-01T12:34:56.123456Z", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "sql#operation", + "name": "${operationID}", + "operationType": "DELETE_USER", + "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", + "status": "DONE", + "targetId": "sqlinstance-${uniqueId}", + "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", + "targetProject": "${projectId}", + "user": "user@example.com" +} + +--- + GET https://pubsub.googleapis.com/v1/projects/${projectId}/topics/pubsubtopic-${uniqueId}?alt=json Content-Type: application/json User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager @@ -641,7 +641,7 @@ X-Xss-Protection: 0 --- GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -812,7 +812,7 @@ X-Xss-Protection: 0 --- DELETE https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager 200 OK Cache-Control: private @@ -836,34 +836,4 @@ X-Xss-Protection: 0 "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", "targetProject": "${projectId}", "user": "user@example.com" -} - ---- - -GET https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}?alt=json&prettyPrint=false -User-Agent: google-api-go-client/0.5 Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager - -200 OK -Cache-Control: private -Content-Type: application/json; charset=UTF-8 -Server: ESF -Vary: Origin -Vary: X-Origin -Vary: Referer -X-Content-Type-Options: nosniff -X-Frame-Options: SAMEORIGIN -X-Xss-Protection: 0 - -{ - "endTime": "2024-04-01T12:34:56.123456Z", - "insertTime": "2024-04-01T12:34:56.123456Z", - "kind": "sql#operation", - "name": "${operationID}", - "operationType": "DELETE", - "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/operations/${operationID}", - "status": "DONE", - "targetId": "sqlinstance-${uniqueId}", - "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/${projectId}/instances/sqlinstance-${uniqueId}", - "targetProject": "${projectId}", - "user": "user@example.com" } \ No newline at end of file diff --git a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/cloudbuild/cloudbuildworkerpool.md b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/cloudbuild/cloudbuildworkerpool.md index e4ef20ae6f..0e1683a3d0 100644 --- a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/cloudbuild/cloudbuildworkerpool.md +++ b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/cloudbuild/cloudbuildworkerpool.md @@ -168,7 +168,7 @@ resourceID: string

string

-

{% verbatim %}The compute network selflink of form "projects//global/networks/", when not managed by KCC.{% endverbatim %}

+

{% verbatim %}The compute network selflink of form "projects//global/networks/", when not managed by Config Connector.{% endverbatim %}

diff --git a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/sql/sqlinstance.md b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/sql/sqlinstance.md index 94f17cbac9..2ea411a0b9 100644 --- a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/sql/sqlinstance.md +++ b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/sql/sqlinstance.md @@ -242,7 +242,7 @@ settings:

string

-

{% verbatim %}Allowed value: The `selfLink` field of a `KMSCryptoKey` resource.{% endverbatim %}

+

{% verbatim %} If provided must be in the format `projects/[kms_project_id]/locations/[region]/keyRings/[key_ring_id]/cryptoKeys/[key]`.{% endverbatim %}

@@ -252,7 +252,7 @@ settings:

string

-

{% verbatim %}Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names{% endverbatim %}

+

{% verbatim %}The `name` field of a `KMSCryptoKey` resource.{% endverbatim %}

@@ -262,7 +262,7 @@ settings:

string

-

{% verbatim %}Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/{% endverbatim %}

+

{% verbatim %}The `metadata.namespace` field of a `KMSCryptoKey` resource.{% endverbatim %}

@@ -302,7 +302,7 @@ settings:

string

-

{% verbatim %}Allowed value: The `name` field of a `SQLInstance` resource.{% endverbatim %}

+

{% verbatim %}The SQLInstance selfLink, when not managed by Config Connector.{% endverbatim %}

@@ -312,7 +312,7 @@ settings:

string

-

{% verbatim %}Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names{% endverbatim %}

+

{% verbatim %}The `name` field of a `SQLInstance` resource.{% endverbatim %}

@@ -322,7 +322,7 @@ settings:

string

-

{% verbatim %}Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/{% endverbatim %}

+

{% verbatim %}The `namespace` field of a `SQLInstance` resource.{% endverbatim %}

@@ -642,8 +642,7 @@ settings:

list (string)

-

{% verbatim %}DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. -Specifying this field has no-ops; it's recommended to remove this field from your configuration.{% endverbatim %}

+

{% verbatim %}DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. Specifying this field has no-ops; it's recommended to remove this field from your configuration.{% endverbatim %}

@@ -663,12 +662,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}The availability type of the Cloud SQL instance, high availability -(REGIONAL) or single zone (ZONAL). For all instances, ensure that -settings.backup_configuration.enabled is set to true. -For MySQL instances, ensure that settings.backup_configuration.binary_log_enabled is set to true. -For Postgres instances, ensure that settings.backup_configuration.point_in_time_recovery_enabled -is set to true. Defaults to ZONAL.{% endverbatim %}

+

{% verbatim %}The availability type of the Cloud SQL instance, high availability (REGIONAL) or single zone (ZONAL). For all instances, ensure that settings.backup_configuration.enabled is set to true. For MySQL instances, ensure that settings.backup_configuration.binary_log_enabled is set to true. For Postgres instances, ensure that settings.backup_configuration.point_in_time_recovery_enabled is set to true. Defaults to ZONAL.{% endverbatim %}

@@ -798,8 +792,7 @@ is set to true. Defaults to ZONAL.{% endverbatim %}

boolean

-

{% verbatim %}DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. -Specifying this field has no-ops; it's recommended to remove this field from your configuration.{% endverbatim %}

+

{% verbatim %}DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. Specifying this field has no-ops; it's recommended to remove this field from your configuration.{% endverbatim %}

@@ -1129,7 +1122,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}Allowed value: The `selfLink` field of a `ComputeNetwork` resource.{% endverbatim %}

+

{% verbatim %}The compute network selflink of form "projects//global/networks/", when not managed by Config Connector.{% endverbatim %}

@@ -1139,7 +1132,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names{% endverbatim %}

+

{% verbatim %}The `name` field of a `ComputeNetwork` resource.{% endverbatim %}

@@ -1149,7 +1142,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/{% endverbatim %}

+

{% verbatim %}The `namespace` field of a `ComputeNetwork` resource.{% endverbatim %}

@@ -1389,8 +1382,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. -Specifying this field has no-ops; it's recommended to remove this field from your configuration.{% endverbatim %}

+

{% verbatim %}DEPRECATED. This property is only applicable to First Generation instances, and First Generation instances are now deprecated. see https://cloud.google.com/sql/docs/mysql/deprecation-notice for information on how to upgrade to Second Generation instances. Specifying this field has no-ops; it's recommended to remove this field from your configuration.{% endverbatim %}

@@ -1420,7 +1412,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}Allowed value: The `url` field of a `StorageBucket` resource.{% endverbatim %}

+

{% verbatim %}The StorageBucket selfLink, when not managed by Config Connector.{% endverbatim %}

@@ -1430,7 +1422,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names{% endverbatim %}

+

{% verbatim %}The `name` field of a `StorageBucket` resource.{% endverbatim %}

@@ -1440,7 +1432,7 @@ Specifying this field has no-ops; it's recommended to remove this field from you

string

-

{% verbatim %}Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/{% endverbatim %}

+

{% verbatim %}The `namespace` field of a `StorageBucket` resource.{% endverbatim %}

@@ -1548,7 +1540,7 @@ serviceAccountEmailAddress: string conditions

list (object)

-

{% verbatim %}Conditions represent the latest available observation of the resource's current state.{% endverbatim %}

+

{% verbatim %}Conditions represent the latest available observations of the SQLInstance's current state.{% endverbatim %}

diff --git a/scripts/github-actions/tests-e2e-fixtures b/scripts/github-actions/tests-e2e-fixtures index 32469d584b..368a7afd36 100755 --- a/scripts/github-actions/tests-e2e-fixtures +++ b/scripts/github-actions/tests-e2e-fixtures @@ -34,4 +34,5 @@ GOLDEN_OBJECT_CHECKS=1 \ GOLDEN_REQUEST_CHECKS=1 \ E2E_KUBE_TARGET=envtest \ E2E_GCP_TARGET=mock \ +KCC_USE_DIRECT_RECONCILERS="SQLInstance" \ go test -test.count=1 -timeout 3600s -v ./tests/e2e -run TestAllInSeries/fixtures \ No newline at end of file diff --git a/scripts/github-actions/tests-e2e-samples b/scripts/github-actions/tests-e2e-samples index a1e7229d9a..5aa602d6e3 100755 --- a/scripts/github-actions/tests-e2e-samples +++ b/scripts/github-actions/tests-e2e-samples @@ -29,4 +29,5 @@ echo "Running fixtures in tests/e2e..." RUN_E2E=1 \ E2E_KUBE_TARGET=envtest \ E2E_GCP_TARGET=mock \ +KCC_USE_DIRECT_RECONCILERS="SQLInstance" \ go test -test.count=1 -timeout 3600s -v ./tests/e2e -run TestAllInSeries/samples \ No newline at end of file