From 6ae6bb75de021300b5e0003620852d5ca7408cae Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Thu, 28 Nov 2024 07:48:19 +0000 Subject: [PATCH 1/8] Support AlloyDBInstance type, mapper and direct controller --- apis/alloydb/v1alpha1/doc.go | 16 + apis/alloydb/v1alpha1/groupversion_info.go | 33 + apis/alloydb/v1alpha1/instance_identity.go | 123 ++++ apis/alloydb/v1alpha1/instance_reference.go | 83 +++ apis/alloydb/v1alpha1/instance_types.go | 196 ++++++ apis/alloydb/v1alpha1/types.generated.go | 181 +++++ .../alloydb/v1alpha1/zz_generated.deepcopy.go | 630 ++++++++++++++++++ apis/alloydb/v1beta1/doc.go | 16 + apis/alloydb/v1beta1/groupversion_info.go | 33 + apis/alloydb/v1beta1/instance_identity.go | 123 ++++ apis/alloydb/v1beta1/instance_reference.go | 83 +++ apis/alloydb/v1beta1/instance_types.go | 195 ++++++ apis/alloydb/v1beta1/types.generated.go | 181 +++++ apis/alloydb/v1beta1/zz_generated.deepcopy.go | 630 ++++++++++++++++++ apis/refs/v1beta1/alloydbref.go | 283 ++++++++ apis/refs/v1beta1/helper.go | 8 + ...stances.alloydb.cnrm.cloud.google.com.yaml | 193 +++--- go.mod | 1 + go.sum | 2 + .../direct/alloydb/instance_controller.go | 402 +++++++++++ .../direct/alloydb/instance_mappings.go | 124 ++++ .../direct/alloydb/mapper.generated.go | 255 +++++++ pkg/gvks/supportedgvks/gvks_generated.go | 4 +- .../resource-docs/alloydb/alloydbinstance.md | 47 +- 24 files changed, 3734 insertions(+), 108 deletions(-) create mode 100644 apis/alloydb/v1alpha1/doc.go create mode 100644 apis/alloydb/v1alpha1/groupversion_info.go create mode 100644 apis/alloydb/v1alpha1/instance_identity.go create mode 100644 apis/alloydb/v1alpha1/instance_reference.go create mode 100644 apis/alloydb/v1alpha1/instance_types.go create mode 100644 apis/alloydb/v1alpha1/types.generated.go create mode 100644 apis/alloydb/v1alpha1/zz_generated.deepcopy.go create mode 100644 apis/alloydb/v1beta1/doc.go create mode 100644 apis/alloydb/v1beta1/groupversion_info.go create mode 100644 apis/alloydb/v1beta1/instance_identity.go create mode 100644 apis/alloydb/v1beta1/instance_reference.go create mode 100644 apis/alloydb/v1beta1/instance_types.go create mode 100644 apis/alloydb/v1beta1/types.generated.go create mode 100644 apis/alloydb/v1beta1/zz_generated.deepcopy.go create mode 100644 apis/refs/v1beta1/alloydbref.go create mode 100644 pkg/controller/direct/alloydb/instance_controller.go create mode 100644 pkg/controller/direct/alloydb/instance_mappings.go create mode 100644 pkg/controller/direct/alloydb/mapper.generated.go diff --git a/apis/alloydb/v1alpha1/doc.go b/apis/alloydb/v1alpha1/doc.go new file mode 100644 index 0000000000..4dd8f835c1 --- /dev/null +++ b/apis/alloydb/v1alpha1/doc.go @@ -0,0 +1,16 @@ +// 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. + +// +kcc:proto=google.cloud.alloydb.v1beta +package v1alpha1 diff --git a/apis/alloydb/v1alpha1/groupversion_info.go b/apis/alloydb/v1alpha1/groupversion_info.go new file mode 100644 index 0000000000..fa8c1c21bb --- /dev/null +++ b/apis/alloydb/v1alpha1/groupversion_info.go @@ -0,0 +1,33 @@ +// 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. + +// +kubebuilder:object:generate=true +// +groupName=alloydb.cnrm.cloud.google.com +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "alloydb.cnrm.cloud.google.com", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/apis/alloydb/v1alpha1/instance_identity.go b/apis/alloydb/v1alpha1/instance_identity.go new file mode 100644 index 0000000000..16542ff1ec --- /dev/null +++ b/apis/alloydb/v1alpha1/instance_identity.go @@ -0,0 +1,123 @@ +// 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 v1alpha1 + +import ( + "context" + "fmt" + "strings" + + "github.com/GoogleCloudPlatform/k8s-config-connector/apis/common" + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const serviceDomain = "//alloydb.googleapis.com" + +// InstanceIdentity defines the resource reference to AlloyDBInstance, which "External" field +// holds the GCP identifier for the KRM object. +type InstanceIdentity struct { + parent *InstanceParent + id string +} + +func (i *InstanceIdentity) String() string { + return i.parent.String() + "/instances/" + i.id +} + +func (i *InstanceIdentity) ID() string { + return i.id +} + +func (i *InstanceIdentity) Parent() *InstanceParent { + return i.parent +} + +// AsExternalRef builds a externalRef from a PrivilegedAccessManagerEntitlement. +func (i *InstanceIdentity) AsExternalRef() *string { + er := serviceDomain + "/" + i.String() + return &er +} + +type InstanceParent struct { + clusterName string +} + +func (p *InstanceParent) String() string { + return p.clusterName +} + +// New builds a InstanceIdentity from the Config Connector Instance object. +func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDBInstance) (*InstanceIdentity, error) { + + // Get Parent + clusterRef, err := refsv1beta1.ResolveAlloyDBCluster(ctx, reader, obj, obj.Spec.ClusterRef) + if err != nil { + return nil, fmt.Errorf("cannot resolve AlloyDBCluster ref: %w", err) + } + + // Get desired ID + resourceID := common.ValueOf(obj.Spec.ResourceID) + if resourceID == "" { + resourceID = obj.GetName() + } + if resourceID == "" { + return nil, fmt.Errorf("cannot resolve resource ID") + } + + // Use approved ExternalRef + externalRef := common.ValueOf(obj.Status.ExternalRef) + if externalRef != "" { + // Validate desired with actual + actualParent, actualResourceID, err := ParseInstanceExternalRef(externalRef) + if err != nil { + return nil, err + } + if actualParent.clusterName != clusterRef.String() { + return nil, fmt.Errorf("spec.clusterRef changed, expect %s, got %s", actualParent.clusterName, clusterRef) + } + if actualResourceID != resourceID { + return nil, fmt.Errorf("cannot reset `metadata.name` or `spec.resourceID` to %s, since it has already assigned to %s", + resourceID, actualResourceID) + } + } + return &InstanceIdentity{ + parent: &InstanceParent{ + clusterName: clusterRef.String(), + }, + id: resourceID, + }, nil +} + +func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { + if !strings.HasPrefix(externalRef, serviceDomain) { + return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) + } + path := strings.TrimPrefix(externalRef, serviceDomain+"/") + return ParseInstanceExternal(path) +} + +func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { + tokens := strings.Split(external, "/") + if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { + return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) + } + parent = &InstanceParent{ + clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), + } + resourceID = tokens[7] + return parent, resourceID, nil +} diff --git a/apis/alloydb/v1alpha1/instance_reference.go b/apis/alloydb/v1alpha1/instance_reference.go new file mode 100644 index 0000000000..e2b6055c6b --- /dev/null +++ b/apis/alloydb/v1alpha1/instance_reference.go @@ -0,0 +1,83 @@ +// 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 v1alpha1 + +import ( + "context" + "fmt" + + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "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/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ refsv1beta1.ExternalNormalizer = &InstanceRef{} + +// InstanceRef defines the resource reference to AlloyDBInstance, which "External" field +// holds the GCP identifier for the KRM object. +type InstanceRef struct { + // A reference to an externally managed AlloyDBInstance resource. + // Should be in the format "projects//locations//instances/". + External string `json:"external,omitempty"` + + // The name of a AlloyDBInstance resource. + Name string `json:"name,omitempty"` + + // The namespace of a AlloyDBInstance resource. + Namespace string `json:"namespace,omitempty"` +} + +// NormalizedExternal provision the "External" value for other resource that depends on AlloyDBInstance. +// If the "External" is given in the other resource's spec.AlloyDBInstanceRef, the given value will be used. +// Otherwise, the "Name" and "Namespace" will be used to query the actual AlloyDBInstance object from the cluster. +func (r *InstanceRef) NormalizedExternal(ctx context.Context, reader client.Reader, otherNamespace string) (string, error) { + if r.External != "" && r.Name != "" { + return "", fmt.Errorf("cannot specify both name and external on %s reference", AlloyDBInstanceGVK.Kind) + } + // From given External + if r.External != "" { + if _, _, err := ParseInstanceExternal(r.External); err != nil { + return "", err + } + return r.External, nil + } + + // From the Config Connector object + if r.Namespace == "" { + r.Namespace = otherNamespace + } + key := types.NamespacedName{Name: r.Name, Namespace: r.Namespace} + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(AlloyDBInstanceGVK) + if err := reader.Get(ctx, key, u); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewReferenceNotFoundError(u.GroupVersionKind(), key) + } + return "", fmt.Errorf("reading referenced %s %s: %w", AlloyDBInstanceGVK, key, err) + } + // Get external from status.externalRef. This is the most trustworthy place. + actualExternalRef, _, err := unstructured.NestedString(u.Object, "status", "externalRef") + if err != nil { + return "", fmt.Errorf("reading status.externalRef: %w", err) + } + if actualExternalRef == "" { + return "", k8s.NewReferenceNotReadyError(u.GroupVersionKind(), key) + } + r.External = actualExternalRef + return r.External, nil +} diff --git a/apis/alloydb/v1alpha1/instance_types.go b/apis/alloydb/v1alpha1/instance_types.go new file mode 100644 index 0000000000..5210a86ba3 --- /dev/null +++ b/apis/alloydb/v1alpha1/instance_types.go @@ -0,0 +1,196 @@ +// 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 v1alpha1 + +import ( + refs "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var AlloyDBInstanceGVK = GroupVersion.WithKind("AlloyDBInstance") + +// AlloyDBInstanceSpec defines the desired state of AlloyDBInstance +// +kcc:proto=google.cloud.alloydb.v1beta.Instance +type AlloyDBInstanceSpec struct { + + // The AlloyDBInstance cluster that this resource belongs to. + // +required + ClusterRef *refs.AlloyDBClusterRef `json:"clusterRef,omitempty"` + + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ResourceID field is immutable" + // Immutable. + // Optional. The instanceId of the resource. If not given, the metadata.name will be used. + ResourceID *string `json:"resourceID,omitempty"` + + // Annotations to allow client tools to store small amount + // of arbitrary data. This is distinct from labels. + Annotations map[string]string `json:"annotations,omitempty"` + + // Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + // + // Note that primary and read instances can have different availability types. + // Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. + // Zone is automatically chosen from the list of zones in the region specified. + // Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more + // can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + AvailabilityType *string `json:"availabilityType,omitempty"` + + // Database flags. Set at instance level. * They are copied + // from primary instance on read instance creation. * Read instances + // can set new or override existing flags that are relevant for reads, + // e.g. for enabling columnar cache on a read instance. Flags set on + // read instance may or may not be present on primary. + DatabaseFlags map[string]string `json:"databaseFlags,omitempty"` + + // User-settable and human-readable display name for the + // Instance. + DisplayName *string `json:"displayName,omitempty"` + + // The Compute Engine zone that the instance should serve + // from, per https://cloud.google.com/compute/docs/regions-zones This + // can ONLY be specified for ZONAL instances. If present for a REGIONAL + // instance, an error will be thrown. If this is absent for a ZONAL + // instance, instance is created in a random zone with available capacity. + GceZone *string `json:"gceZone,omitempty"` + + // We recommend that you use `instanceTypeRef` instead. + // The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY] + InstanceType *string `json:"instanceType,omitempty"` + + // The type of instance. + // Possible values: ["PRIMARY", "READ_POOL", "SECONDARY"] + // + // For PRIMARY and SECONDARY instances, set the value to refer to the name of the associated cluster. + // This is recommended because the instance type of primary and secondary instances is tied to the cluster type of the associated cluster. + // If the secondary cluster is promoted to primary cluster, then the associated secondary instance also becomes primary instance. + // Example: + // instanceTypeRef: + // name: clusterName + // For instances of type READ_POOL, set the value using external keyword. + // Example: + // instanceTypeRef: + // external: READ_POOL + // If the instance type is SECONDARY, the delete instance operation does not delete the secondary instance but abandons it instead. + // Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the cluster forcefully to delete the secondary cluster as well its associated secondary instance. + InstanceTypeRef *refs.AlloyDBClusterTypeRef `json:"instanceTypeRef,omitempty"` + + // Configurations for the machines that host the underlying + // database engine. + MachineConfig *Instance_MachineConfig `json:"machineConfig,omitempty"` + + // Instance level network configuration. + NetworkConfig *Instance_InstanceNetworkConfig `json:"networkConfig,omitempty"` + + // Read pool specific config. If the instance type is READ_POOL, + // this configuration must be provided. + ReadPoolConfig *Instance_ReadPoolConfig `json:"readPoolConfig,omitempty"` +} + +// AlloyDBInstanceStatus defines the config connector machine state of AlloyDBInstance +type AlloyDBInstanceStatus struct { + /* Conditions represent the latest available observations of the + object's current state. */ + Conditions []v1alpha1.Condition `json:"conditions,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. + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + + // A unique specifier for the AlloyDBInstance resource in GCP. + ExternalRef *string `json:"externalRef,omitempty"` + + /* NOTYET + // ObservedState is the state of the resource as most recently observed in GCP. + ObservedState *AlloyDBInstanceObservedState `json:"observedState,omitempty"` + */ + + // Time the Instance was created in UTC. + CreateTime *string `json:"createTime,omitempty"` + + // The IP address for the Instance. This is the connection + // endpoint for an end-user application. + IpAddress *string `json:"ipAddress,omitempty"` + + // The name of the instance resource. + Name *string `json:"name,omitempty"` + + // The outbound public IP addresses for the instance. This is available ONLY when + // networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used + // for outbound connections. + OutboundPublicIpAddresses []string `json:"outboundPublicIpAddresses,omitempty"` + + // The public IP addresses for the Instance. This is available + // ONLY when networkConfig.enablePublicIp is set to true. This is the + // connection endpoint for an end-user application. + PublicIpAddress *string `json:"publicIpAddress,omitempty"` + + // Set to true if the current state of Instance does not + // match the user's intended state, and the service is actively updating + // the resource to reconcile them. This can happen due to user-triggered + // updates or system actions like failover or maintenance. + Reconciling *bool `json:"reconciling,omitempty"` + + // The current state of the alloydb instance. + State *string `json:"state,omitempty"` + + // The system-generated UID of the resource. + Uid *string `json:"uid,omitempty"` + + // Time the Instance was updated in UTC. + UpdateTime *string `json:"updateTime,omitempty"` +} + +/* NOTYET +// AlloyDBInstanceSpec defines the desired state of AlloyDBInstance +// +kcc:proto=google.cloud.alloydb.v1beta.Instance +// AlloyDBInstanceObservedState is the state of the AlloyDBInstance resource as most recently observed in GCP. +type AlloyDBInstanceObservedState struct { +} +*/ + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// TODO(user): make sure the pluralizaiton below is correct +// +kubebuilder:resource:categories=gcp,shortName=gcpalloydbinstance;gcpalloydbinstances +// +kubebuilder:subresource:status +// +kubebuilder:metadata:labels="cnrm.cloud.google.com/tf2crd=true";"cnrm.cloud.google.com/managed-by-kcc=true";"cnrm.cloud.google.com/stability-level=stable";"cnrm.cloud.google.com/system=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'" + +// AlloyDBInstance is the Schema for the AlloyDBInstance API +// +k8s:openapi-gen=true +// +kubebuilder:storageversion +type AlloyDBInstance struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +required + Spec AlloyDBInstanceSpec `json:"spec,omitempty"` + Status AlloyDBInstanceStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// AlloyDBInstanceList contains a list of AlloyDBInstance +type AlloyDBInstanceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []AlloyDBInstance `json:"items"` +} + +func init() { + SchemeBuilder.Register(&AlloyDBInstance{}, &AlloyDBInstanceList{}) +} diff --git a/apis/alloydb/v1alpha1/types.generated.go b/apis/alloydb/v1alpha1/types.generated.go new file mode 100644 index 0000000000..fac1677e73 --- /dev/null +++ b/apis/alloydb/v1alpha1/types.generated.go @@ -0,0 +1,181 @@ +// 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 v1alpha1 + +// +kcc:proto=google.cloud.alloydb.v1beta.GeminiInstanceConfig +type GeminiInstanceConfig struct { + // Output only. Whether the Gemini in Databases add-on is enabled for the + // instance. It will be true only if the add-on has been enabled for the + // billing account corresponding to the instance. Its status is toggled from + // the Admin Control Center (ACC) and cannot be toggled using AlloyDBInstance's APIs. + Entitled *bool `json:"entitled,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.ClientConnectionConfig +type Instance_ClientConnectionConfig struct { + // Optional. Configuration to enforce connectors only (ex: AuthProxy) + // connections to the database. + RequireConnectors *bool `json:"requireConnectors,omitempty"` + + // Optional. SSL configuration option for this instance. + SslConfig *SslConfig `json:"sslConfig,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig +type Instance_InstanceNetworkConfig struct { + // Optional. A list of external network authorized to access this instance. + // This field is only allowed to be set when 'enablePublicIp' is set to true. + AuthorizedExternalNetworks []Instance_InstanceNetworkConfig_AuthorizedNetwork `json:"authorizedExternalNetworks,omitempty"` + + // Optional. Enabling public ip for the instance. If a user wishes + // to disable this, please also clear the list of the authorized + // external networks set on the same instance. + EnablePublicIp *bool `json:"enablePublicIp,omitempty"` + + // Optional. Enabling an outbound public IP address to support a database + // server sending requests out into the internet. + EnableOutboundPublicIp *bool `json:"enableOutboundPublicIp,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig.AuthorizedNetwork +type Instance_InstanceNetworkConfig_AuthorizedNetwork struct { + // CIDR range for one authorzied network of the instance. + CidrRange *string `json:"cidrRange,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.MachineConfig +type Instance_MachineConfig struct { + // The number of CPU's in the VM instance. + CpuCount *int32 `json:"cpuCount,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.Node +type Instance_Node struct { + // The Compute Engine zone of the VM e.g. "us-central1-b". + ZoneID *string `json:"zoneID,omitempty"` + + // The identifier of the VM e.g. "test-read-0601-407e52be-ms3l". + ID *string `json:"id,omitempty"` + + // The private IP address of the VM e.g. "10.57.0.34". + Ip *string `json:"ip,omitempty"` + + // Determined by state of the compute VM and postgres-service health. + // Compute VM state can have values listed in + // https://cloud.google.com/compute/docs/instances/instance-life-cycle and + // postgres-service health can have values: HEALTHY and UNHEALTHY. + State *string `json:"state,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.ObservabilityInstanceConfig +type Instance_ObservabilityInstanceConfig struct { + // Observability feature status for an instance. + // This flag is turned "off" by default. + Enabled *bool `json:"enabled,omitempty"` + + // Preserve comments in query string for an instance. + // This flag is turned "off" by default. + PreserveComments *bool `json:"preserveComments,omitempty"` + + // Track wait events during query execution for an instance. + // This flag is turned "on" by default but tracking is enabled only after + // observability enabled flag is also turned on. + TrackWaitEvents *bool `json:"trackWaitEvents,omitempty"` + + // Output only. Track wait event types during query execution for an + // instance. This flag is turned "on" by default but tracking is enabled + // only after observability enabled flag is also turned on. This is + // read-only flag and only modifiable by producer API. + TrackWaitEventTypes *bool `json:"trackWaitEventTypes,omitempty"` + + // Query string length. The default value is 10k. + MaxQueryStringLength *int32 `json:"maxQueryStringLength,omitempty"` + + // Record application tags for an instance. + // This flag is turned "off" by default. + RecordApplicationTags *bool `json:"recordApplicationTags,omitempty"` + + // Number of query execution plans captured by Insights per minute + // for all queries combined. The default value is 200. + // Any integer between 0 to 200 is considered valid. + QueryPlansPerMinute *int32 `json:"queryPlansPerMinute,omitempty"` + + // Track actively running queries on the instance. + // If not set, this flag is "off" by default. + TrackActiveQueries *bool `json:"trackActiveQueries,omitempty"` + + // Track client address for an instance. + // If not set, default value is "off". + TrackClientAddress *bool `json:"trackClientAddress,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.PscInstanceConfig +type Instance_PscInstanceConfig struct { + // Output only. The service attachment created when Private + // Service Connect (PSC) is enabled for the instance. + // The name of the resource will be in the format of + // `projects//regions//serviceAttachments/` + ServiceAttachmentLink *string `json:"serviceAttachmentLink,omitempty"` + + // Optional. List of consumer projects that are allowed to create + // PSC endpoints to service-attachments to this instance. + AllowedConsumerProjects []string `json:"allowedConsumerProjects,omitempty"` + + // Output only. The DNS name of the instance for PSC connectivity. + // Name convention: ...alloydb-psc.goog + PscDnsName *string `json:"pscDnsName,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.QueryInsightsInstanceConfig +type Instance_QueryInsightsInstanceConfig struct { + // Record application tags for an instance. + // This flag is turned "on" by default. + RecordApplicationTags *bool `json:"recordApplicationTags,omitempty"` + + // Record client address for an instance. Client address is PII information. + // This flag is turned "on" by default. + RecordClientAddress *bool `json:"recordClientAddress,omitempty"` + + // Query string length. The default value is 1024. + // Any integer between 256 and 4500 is considered valid. + QueryStringLength *uint32 `json:"queryStringLength,omitempty"` + + // Number of query execution plans captured by Insights per minute + // for all queries combined. The default value is 5. + // Any integer between 0 and 20 is considered valid. + QueryPlansPerMinute *uint32 `json:"queryPlansPerMinute,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.ReadPoolConfig +type Instance_ReadPoolConfig struct { + // Read capacity, i.e. number of nodes in a read pool instance. + NodeCount *int32 `json:"nodeCount,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.UpdatePolicy +type Instance_UpdatePolicy struct { + // Mode for updating the instance. + Mode *string `json:"mode,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.SslConfig +type SslConfig struct { + // Optional. SSL mode. Specifies client-server SSL/TLS connection behavior. + SslMode *string `json:"sslMode,omitempty"` + + // Optional. Certificate Authority (CA) source. Only CA_SOURCE_MANAGED is + // supported currently, and is the default value. + CaSource *string `json:"caSource,omitempty"` +} diff --git a/apis/alloydb/v1alpha1/zz_generated.deepcopy.go b/apis/alloydb/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..c9fc8953f9 --- /dev/null +++ b/apis/alloydb/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,630 @@ +//go: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 controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + k8sv1alpha1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/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 *AlloyDBInstance) DeepCopyInto(out *AlloyDBInstance) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstance. +func (in *AlloyDBInstance) DeepCopy() *AlloyDBInstance { + if in == nil { + return nil + } + out := new(AlloyDBInstance) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AlloyDBInstance) 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 *AlloyDBInstanceList) DeepCopyInto(out *AlloyDBInstanceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AlloyDBInstance, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstanceList. +func (in *AlloyDBInstanceList) DeepCopy() *AlloyDBInstanceList { + if in == nil { + return nil + } + out := new(AlloyDBInstanceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AlloyDBInstanceList) 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 *AlloyDBInstanceSpec) DeepCopyInto(out *AlloyDBInstanceSpec) { + *out = *in + if in.ClusterRef != nil { + in, out := &in.ClusterRef, &out.ClusterRef + *out = new(v1beta1.AlloyDBClusterRef) + **out = **in + } + if in.ResourceID != nil { + in, out := &in.ResourceID, &out.ResourceID + *out = new(string) + **out = **in + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.AvailabilityType != nil { + in, out := &in.AvailabilityType, &out.AvailabilityType + *out = new(string) + **out = **in + } + if in.DatabaseFlags != nil { + in, out := &in.DatabaseFlags, &out.DatabaseFlags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.DisplayName != nil { + in, out := &in.DisplayName, &out.DisplayName + *out = new(string) + **out = **in + } + if in.GceZone != nil { + in, out := &in.GceZone, &out.GceZone + *out = new(string) + **out = **in + } + if in.InstanceType != nil { + in, out := &in.InstanceType, &out.InstanceType + *out = new(string) + **out = **in + } + if in.InstanceTypeRef != nil { + in, out := &in.InstanceTypeRef, &out.InstanceTypeRef + *out = new(v1beta1.AlloyDBClusterTypeRef) + **out = **in + } + if in.MachineConfig != nil { + in, out := &in.MachineConfig, &out.MachineConfig + *out = new(Instance_MachineConfig) + (*in).DeepCopyInto(*out) + } + if in.NetworkConfig != nil { + in, out := &in.NetworkConfig, &out.NetworkConfig + *out = new(Instance_InstanceNetworkConfig) + (*in).DeepCopyInto(*out) + } + if in.ReadPoolConfig != nil { + in, out := &in.ReadPoolConfig, &out.ReadPoolConfig + *out = new(Instance_ReadPoolConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstanceSpec. +func (in *AlloyDBInstanceSpec) DeepCopy() *AlloyDBInstanceSpec { + if in == nil { + return nil + } + out := new(AlloyDBInstanceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AlloyDBInstanceStatus) DeepCopyInto(out *AlloyDBInstanceStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]k8sv1alpha1.Condition, len(*in)) + copy(*out, *in) + } + if in.ObservedGeneration != nil { + in, out := &in.ObservedGeneration, &out.ObservedGeneration + *out = new(int64) + **out = **in + } + if in.ExternalRef != nil { + in, out := &in.ExternalRef, &out.ExternalRef + *out = new(string) + **out = **in + } + if in.CreateTime != nil { + in, out := &in.CreateTime, &out.CreateTime + *out = new(string) + **out = **in + } + if in.IpAddress != nil { + in, out := &in.IpAddress, &out.IpAddress + *out = new(string) + **out = **in + } + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.OutboundPublicIpAddresses != nil { + in, out := &in.OutboundPublicIpAddresses, &out.OutboundPublicIpAddresses + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PublicIpAddress != nil { + in, out := &in.PublicIpAddress, &out.PublicIpAddress + *out = new(string) + **out = **in + } + if in.Reconciling != nil { + in, out := &in.Reconciling, &out.Reconciling + *out = new(bool) + **out = **in + } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } + if in.Uid != nil { + in, out := &in.Uid, &out.Uid + *out = new(string) + **out = **in + } + if in.UpdateTime != nil { + in, out := &in.UpdateTime, &out.UpdateTime + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstanceStatus. +func (in *AlloyDBInstanceStatus) DeepCopy() *AlloyDBInstanceStatus { + if in == nil { + return nil + } + out := new(AlloyDBInstanceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GeminiInstanceConfig) DeepCopyInto(out *GeminiInstanceConfig) { + *out = *in + if in.Entitled != nil { + in, out := &in.Entitled, &out.Entitled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeminiInstanceConfig. +func (in *GeminiInstanceConfig) DeepCopy() *GeminiInstanceConfig { + if in == nil { + return nil + } + out := new(GeminiInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceIdentity) DeepCopyInto(out *InstanceIdentity) { + *out = *in + if in.parent != nil { + in, out := &in.parent, &out.parent + *out = new(InstanceParent) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceIdentity. +func (in *InstanceIdentity) DeepCopy() *InstanceIdentity { + if in == nil { + return nil + } + out := new(InstanceIdentity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceParent) DeepCopyInto(out *InstanceParent) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceParent. +func (in *InstanceParent) DeepCopy() *InstanceParent { + if in == nil { + return nil + } + out := new(InstanceParent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceRef) DeepCopyInto(out *InstanceRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceRef. +func (in *InstanceRef) DeepCopy() *InstanceRef { + if in == nil { + return nil + } + out := new(InstanceRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_ClientConnectionConfig) DeepCopyInto(out *Instance_ClientConnectionConfig) { + *out = *in + if in.RequireConnectors != nil { + in, out := &in.RequireConnectors, &out.RequireConnectors + *out = new(bool) + **out = **in + } + if in.SslConfig != nil { + in, out := &in.SslConfig, &out.SslConfig + *out = new(SslConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_ClientConnectionConfig. +func (in *Instance_ClientConnectionConfig) DeepCopy() *Instance_ClientConnectionConfig { + if in == nil { + return nil + } + out := new(Instance_ClientConnectionConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_InstanceNetworkConfig) DeepCopyInto(out *Instance_InstanceNetworkConfig) { + *out = *in + if in.AuthorizedExternalNetworks != nil { + in, out := &in.AuthorizedExternalNetworks, &out.AuthorizedExternalNetworks + *out = make([]Instance_InstanceNetworkConfig_AuthorizedNetwork, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EnablePublicIp != nil { + in, out := &in.EnablePublicIp, &out.EnablePublicIp + *out = new(bool) + **out = **in + } + if in.EnableOutboundPublicIp != nil { + in, out := &in.EnableOutboundPublicIp, &out.EnableOutboundPublicIp + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_InstanceNetworkConfig. +func (in *Instance_InstanceNetworkConfig) DeepCopy() *Instance_InstanceNetworkConfig { + if in == nil { + return nil + } + out := new(Instance_InstanceNetworkConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_InstanceNetworkConfig_AuthorizedNetwork) DeepCopyInto(out *Instance_InstanceNetworkConfig_AuthorizedNetwork) { + *out = *in + if in.CidrRange != nil { + in, out := &in.CidrRange, &out.CidrRange + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_InstanceNetworkConfig_AuthorizedNetwork. +func (in *Instance_InstanceNetworkConfig_AuthorizedNetwork) DeepCopy() *Instance_InstanceNetworkConfig_AuthorizedNetwork { + if in == nil { + return nil + } + out := new(Instance_InstanceNetworkConfig_AuthorizedNetwork) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_MachineConfig) DeepCopyInto(out *Instance_MachineConfig) { + *out = *in + if in.CpuCount != nil { + in, out := &in.CpuCount, &out.CpuCount + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_MachineConfig. +func (in *Instance_MachineConfig) DeepCopy() *Instance_MachineConfig { + if in == nil { + return nil + } + out := new(Instance_MachineConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_Node) DeepCopyInto(out *Instance_Node) { + *out = *in + if in.ZoneID != nil { + in, out := &in.ZoneID, &out.ZoneID + *out = new(string) + **out = **in + } + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Ip != nil { + in, out := &in.Ip, &out.Ip + *out = new(string) + **out = **in + } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_Node. +func (in *Instance_Node) DeepCopy() *Instance_Node { + if in == nil { + return nil + } + out := new(Instance_Node) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_ObservabilityInstanceConfig) DeepCopyInto(out *Instance_ObservabilityInstanceConfig) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.PreserveComments != nil { + in, out := &in.PreserveComments, &out.PreserveComments + *out = new(bool) + **out = **in + } + if in.TrackWaitEvents != nil { + in, out := &in.TrackWaitEvents, &out.TrackWaitEvents + *out = new(bool) + **out = **in + } + if in.TrackWaitEventTypes != nil { + in, out := &in.TrackWaitEventTypes, &out.TrackWaitEventTypes + *out = new(bool) + **out = **in + } + if in.MaxQueryStringLength != nil { + in, out := &in.MaxQueryStringLength, &out.MaxQueryStringLength + *out = new(int32) + **out = **in + } + if in.RecordApplicationTags != nil { + in, out := &in.RecordApplicationTags, &out.RecordApplicationTags + *out = new(bool) + **out = **in + } + if in.QueryPlansPerMinute != nil { + in, out := &in.QueryPlansPerMinute, &out.QueryPlansPerMinute + *out = new(int32) + **out = **in + } + if in.TrackActiveQueries != nil { + in, out := &in.TrackActiveQueries, &out.TrackActiveQueries + *out = new(bool) + **out = **in + } + if in.TrackClientAddress != nil { + in, out := &in.TrackClientAddress, &out.TrackClientAddress + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_ObservabilityInstanceConfig. +func (in *Instance_ObservabilityInstanceConfig) DeepCopy() *Instance_ObservabilityInstanceConfig { + if in == nil { + return nil + } + out := new(Instance_ObservabilityInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_PscInstanceConfig) DeepCopyInto(out *Instance_PscInstanceConfig) { + *out = *in + if in.ServiceAttachmentLink != nil { + in, out := &in.ServiceAttachmentLink, &out.ServiceAttachmentLink + *out = new(string) + **out = **in + } + if in.AllowedConsumerProjects != nil { + in, out := &in.AllowedConsumerProjects, &out.AllowedConsumerProjects + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PscDnsName != nil { + in, out := &in.PscDnsName, &out.PscDnsName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_PscInstanceConfig. +func (in *Instance_PscInstanceConfig) DeepCopy() *Instance_PscInstanceConfig { + if in == nil { + return nil + } + out := new(Instance_PscInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_QueryInsightsInstanceConfig) DeepCopyInto(out *Instance_QueryInsightsInstanceConfig) { + *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 + } + if in.QueryStringLength != nil { + in, out := &in.QueryStringLength, &out.QueryStringLength + *out = new(uint32) + **out = **in + } + if in.QueryPlansPerMinute != nil { + in, out := &in.QueryPlansPerMinute, &out.QueryPlansPerMinute + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_QueryInsightsInstanceConfig. +func (in *Instance_QueryInsightsInstanceConfig) DeepCopy() *Instance_QueryInsightsInstanceConfig { + if in == nil { + return nil + } + out := new(Instance_QueryInsightsInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_ReadPoolConfig) DeepCopyInto(out *Instance_ReadPoolConfig) { + *out = *in + if in.NodeCount != nil { + in, out := &in.NodeCount, &out.NodeCount + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_ReadPoolConfig. +func (in *Instance_ReadPoolConfig) DeepCopy() *Instance_ReadPoolConfig { + if in == nil { + return nil + } + out := new(Instance_ReadPoolConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_UpdatePolicy) DeepCopyInto(out *Instance_UpdatePolicy) { + *out = *in + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_UpdatePolicy. +func (in *Instance_UpdatePolicy) DeepCopy() *Instance_UpdatePolicy { + if in == nil { + return nil + } + out := new(Instance_UpdatePolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SslConfig) DeepCopyInto(out *SslConfig) { + *out = *in + if in.SslMode != nil { + in, out := &in.SslMode, &out.SslMode + *out = new(string) + **out = **in + } + if in.CaSource != nil { + in, out := &in.CaSource, &out.CaSource + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SslConfig. +func (in *SslConfig) DeepCopy() *SslConfig { + if in == nil { + return nil + } + out := new(SslConfig) + in.DeepCopyInto(out) + return out +} diff --git a/apis/alloydb/v1beta1/doc.go b/apis/alloydb/v1beta1/doc.go new file mode 100644 index 0000000000..c08dd82333 --- /dev/null +++ b/apis/alloydb/v1beta1/doc.go @@ -0,0 +1,16 @@ +// 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. + +// +kcc:proto=google.cloud.alloydb.v1beta +package v1beta1 diff --git a/apis/alloydb/v1beta1/groupversion_info.go b/apis/alloydb/v1beta1/groupversion_info.go new file mode 100644 index 0000000000..331999fe7c --- /dev/null +++ b/apis/alloydb/v1beta1/groupversion_info.go @@ -0,0 +1,33 @@ +// 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. + +// +kubebuilder:object:generate=true +// +groupName=alloydb.cnrm.cloud.google.com +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "alloydb.cnrm.cloud.google.com", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/apis/alloydb/v1beta1/instance_identity.go b/apis/alloydb/v1beta1/instance_identity.go new file mode 100644 index 0000000000..9ee7c11a1a --- /dev/null +++ b/apis/alloydb/v1beta1/instance_identity.go @@ -0,0 +1,123 @@ +// 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 ( + "context" + "fmt" + "strings" + + "github.com/GoogleCloudPlatform/k8s-config-connector/apis/common" + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const serviceDomain = "//alloydb.googleapis.com" + +// InstanceIdentity defines the resource reference to AlloyDBInstance, which "External" field +// holds the GCP identifier for the KRM object. +type InstanceIdentity struct { + parent *InstanceParent + id string +} + +func (i *InstanceIdentity) String() string { + return i.parent.String() + "/instances/" + i.id +} + +func (i *InstanceIdentity) ID() string { + return i.id +} + +func (i *InstanceIdentity) Parent() *InstanceParent { + return i.parent +} + +// AsExternalRef builds a externalRef from a PrivilegedAccessManagerEntitlement. +func (i *InstanceIdentity) AsExternalRef() *string { + er := serviceDomain + "/" + i.String() + return &er +} + +type InstanceParent struct { + clusterName string +} + +func (p *InstanceParent) String() string { + return p.clusterName +} + +// New builds a InstanceIdentity from the Config Connector Instance object. +func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDBInstance) (*InstanceIdentity, error) { + + // Get Parent + clusterRef, err := refsv1beta1.ResolveAlloyDBCluster(ctx, reader, obj, obj.Spec.ClusterRef) + if err != nil { + return nil, fmt.Errorf("cannot resolve AlloyDBCluster ref: %w", err) + } + + // Get desired ID + resourceID := common.ValueOf(obj.Spec.ResourceID) + if resourceID == "" { + resourceID = obj.GetName() + } + if resourceID == "" { + return nil, fmt.Errorf("cannot resolve resource ID") + } + + // Use approved ExternalRef + externalRef := common.ValueOf(obj.Status.ExternalRef) + if externalRef != "" { + // Validate desired with actual + actualParent, actualResourceID, err := ParseInstanceExternalRef(externalRef) + if err != nil { + return nil, err + } + if actualParent.clusterName != clusterRef.String() { + return nil, fmt.Errorf("spec.clusterRef changed, expect %s, got %s", actualParent.clusterName, clusterRef) + } + if actualResourceID != resourceID { + return nil, fmt.Errorf("cannot reset `metadata.name` or `spec.resourceID` to %s, since it has already assigned to %s", + resourceID, actualResourceID) + } + } + return &InstanceIdentity{ + parent: &InstanceParent{ + clusterName: clusterRef.String(), + }, + id: resourceID, + }, nil +} + +func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { + if !strings.HasPrefix(externalRef, serviceDomain) { + return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) + } + path := strings.TrimPrefix(externalRef, serviceDomain+"/") + return ParseInstanceExternal(path) +} + +func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { + tokens := strings.Split(external, "/") + if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { + return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) + } + parent = &InstanceParent{ + clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), + } + resourceID = tokens[7] + return parent, resourceID, nil +} diff --git a/apis/alloydb/v1beta1/instance_reference.go b/apis/alloydb/v1beta1/instance_reference.go new file mode 100644 index 0000000000..0518e62537 --- /dev/null +++ b/apis/alloydb/v1beta1/instance_reference.go @@ -0,0 +1,83 @@ +// 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 ( + "context" + "fmt" + + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "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/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ refsv1beta1.ExternalNormalizer = &InstanceRef{} + +// InstanceRef defines the resource reference to AlloyDBInstance, which "External" field +// holds the GCP identifier for the KRM object. +type InstanceRef struct { + // A reference to an externally managed AlloyDBInstance resource. + // Should be in the format "projects//locations//instances/". + External string `json:"external,omitempty"` + + // The name of a AlloyDBInstance resource. + Name string `json:"name,omitempty"` + + // The namespace of a AlloyDBInstance resource. + Namespace string `json:"namespace,omitempty"` +} + +// NormalizedExternal provision the "External" value for other resource that depends on AlloyDBInstance. +// If the "External" is given in the other resource's spec.AlloyDBInstanceRef, the given value will be used. +// Otherwise, the "Name" and "Namespace" will be used to query the actual AlloyDBInstance object from the cluster. +func (r *InstanceRef) NormalizedExternal(ctx context.Context, reader client.Reader, otherNamespace string) (string, error) { + if r.External != "" && r.Name != "" { + return "", fmt.Errorf("cannot specify both name and external on %s reference", AlloyDBInstanceGVK.Kind) + } + // From given External + if r.External != "" { + if _, _, err := ParseInstanceExternal(r.External); err != nil { + return "", err + } + return r.External, nil + } + + // From the Config Connector object + if r.Namespace == "" { + r.Namespace = otherNamespace + } + key := types.NamespacedName{Name: r.Name, Namespace: r.Namespace} + u := &unstructured.Unstructured{} + u.SetGroupVersionKind(AlloyDBInstanceGVK) + if err := reader.Get(ctx, key, u); err != nil { + if apierrors.IsNotFound(err) { + return "", k8s.NewReferenceNotFoundError(u.GroupVersionKind(), key) + } + return "", fmt.Errorf("reading referenced %s %s: %w", AlloyDBInstanceGVK, key, err) + } + // Get external from status.externalRef. This is the most trustworthy place. + actualExternalRef, _, err := unstructured.NestedString(u.Object, "status", "externalRef") + if err != nil { + return "", fmt.Errorf("reading status.externalRef: %w", err) + } + if actualExternalRef == "" { + return "", k8s.NewReferenceNotReadyError(u.GroupVersionKind(), key) + } + r.External = actualExternalRef + return r.External, nil +} diff --git a/apis/alloydb/v1beta1/instance_types.go b/apis/alloydb/v1beta1/instance_types.go new file mode 100644 index 0000000000..78ac8ad533 --- /dev/null +++ b/apis/alloydb/v1beta1/instance_types.go @@ -0,0 +1,195 @@ +// 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 ( + refs "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var AlloyDBInstanceGVK = GroupVersion.WithKind("AlloyDBInstance") + +// AlloyDBInstanceSpec defines the desired state of AlloyDBInstance +// +kcc:proto=google.cloud.alloydb.v1beta.Instance +type AlloyDBInstanceSpec struct { + + // The AlloyDBInstance cluster that this resource belongs to. + // +required + ClusterRef *refs.AlloyDBClusterRef `json:"clusterRef,omitempty"` + + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ResourceID field is immutable" + // Immutable. + // Optional. The instanceId of the resource. If not given, the metadata.name will be used. + ResourceID *string `json:"resourceID,omitempty"` + + // Annotations to allow client tools to store small amount + // of arbitrary data. This is distinct from labels. + Annotations map[string]string `json:"annotations,omitempty"` + + // Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + // + // Note that primary and read instances can have different availability types. + // Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. + // Zone is automatically chosen from the list of zones in the region specified. + // Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more + // can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + AvailabilityType *string `json:"availabilityType,omitempty"` + + // Database flags. Set at instance level. * They are copied + // from primary instance on read instance creation. * Read instances + // can set new or override existing flags that are relevant for reads, + // e.g. for enabling columnar cache on a read instance. Flags set on + // read instance may or may not be present on primary. + DatabaseFlags map[string]string `json:"databaseFlags,omitempty"` + + // User-settable and human-readable display name for the + // Instance. + DisplayName *string `json:"displayName,omitempty"` + + // The Compute Engine zone that the instance should serve + // from, per https://cloud.google.com/compute/docs/regions-zones This + // can ONLY be specified for ZONAL instances. If present for a REGIONAL + // instance, an error will be thrown. If this is absent for a ZONAL + // instance, instance is created in a random zone with available capacity. + GceZone *string `json:"gceZone,omitempty"` + + // We recommend that you use `instanceTypeRef` instead. + // The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY] + InstanceType *string `json:"instanceType,omitempty"` + + // The type of instance. + // Possible values: ["PRIMARY", "READ_POOL", "SECONDARY"] + // + // For PRIMARY and SECONDARY instances, set the value to refer to the name of the associated cluster. + // This is recommended because the instance type of primary and secondary instances is tied to the cluster type of the associated cluster. + // If the secondary cluster is promoted to primary cluster, then the associated secondary instance also becomes primary instance. + // Example: + // instanceTypeRef: + // name: clusterName + // For instances of type READ_POOL, set the value using external keyword. + // Example: + // instanceTypeRef: + // external: READ_POOL + // If the instance type is SECONDARY, the delete instance operation does not delete the secondary instance but abandons it instead. + // Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the cluster forcefully to delete the secondary cluster as well its associated secondary instance. + InstanceTypeRef *refs.AlloyDBClusterTypeRef `json:"instanceTypeRef,omitempty"` + + // Configurations for the machines that host the underlying + // database engine. + MachineConfig *Instance_MachineConfig `json:"machineConfig,omitempty"` + + // Instance level network configuration. + NetworkConfig *Instance_InstanceNetworkConfig `json:"networkConfig,omitempty"` + + // Read pool specific config. If the instance type is READ_POOL, + // this configuration must be provided. + ReadPoolConfig *Instance_ReadPoolConfig `json:"readPoolConfig,omitempty"` +} + +// AlloyDBInstanceStatus defines the config connector machine state of AlloyDBInstance +type AlloyDBInstanceStatus struct { + /* Conditions represent the latest available observations of the + object's current state. */ + Conditions []v1alpha1.Condition `json:"conditions,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. + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + + // A unique specifier for the AlloyDBInstance resource in GCP. + ExternalRef *string `json:"externalRef,omitempty"` + + /* NOTYET + // ObservedState is the state of the resource as most recently observed in GCP. + ObservedState *AlloyDBInstanceObservedState `json:"observedState,omitempty"` + */ + + // Time the Instance was created in UTC. + CreateTime *string `json:"createTime,omitempty"` + + // The IP address for the Instance. This is the connection + // endpoint for an end-user application. + IpAddress *string `json:"ipAddress,omitempty"` + + // The name of the instance resource. + Name *string `json:"name,omitempty"` + + // The outbound public IP addresses for the instance. This is available ONLY when + // networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used + // for outbound connections. + OutboundPublicIpAddresses []string `json:"outboundPublicIpAddresses,omitempty"` + + // The public IP addresses for the Instance. This is available + // ONLY when networkConfig.enablePublicIp is set to true. This is the + // connection endpoint for an end-user application. + PublicIpAddress *string `json:"publicIpAddress,omitempty"` + + // Set to true if the current state of Instance does not + // match the user's intended state, and the service is actively updating + // the resource to reconcile them. This can happen due to user-triggered + // updates or system actions like failover or maintenance. + Reconciling *bool `json:"reconciling,omitempty"` + + // The current state of the alloydb instance. + State *string `json:"state,omitempty"` + + // The system-generated UID of the resource. + Uid *string `json:"uid,omitempty"` + + // Time the Instance was updated in UTC. + UpdateTime *string `json:"updateTime,omitempty"` +} + +/* NOTYET +// AlloyDBInstanceSpec defines the desired state of AlloyDBInstance +// +kcc:proto=google.cloud.alloydb.v1beta.Instance +// AlloyDBInstanceObservedState is the state of the AlloyDBInstance resource as most recently observed in GCP. +type AlloyDBInstanceObservedState struct { +} +*/ + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// TODO(user): make sure the pluralizaiton below is correct +// +kubebuilder:resource:categories=gcp,shortName=gcpalloydbinstance;gcpalloydbinstances +// +kubebuilder:subresource:status +// +kubebuilder:metadata:labels="cnrm.cloud.google.com/tf2crd=true";"cnrm.cloud.google.com/managed-by-kcc=true";"cnrm.cloud.google.com/stability-level=stable";"cnrm.cloud.google.com/system=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'" + +// AlloyDBInstance is the Schema for the AlloyDBInstance API +// +k8s:openapi-gen=true +type AlloyDBInstance struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +required + Spec AlloyDBInstanceSpec `json:"spec,omitempty"` + Status AlloyDBInstanceStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// AlloyDBInstanceList contains a list of AlloyDBInstance +type AlloyDBInstanceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []AlloyDBInstance `json:"items"` +} + +func init() { + SchemeBuilder.Register(&AlloyDBInstance{}, &AlloyDBInstanceList{}) +} diff --git a/apis/alloydb/v1beta1/types.generated.go b/apis/alloydb/v1beta1/types.generated.go new file mode 100644 index 0000000000..2185dbf809 --- /dev/null +++ b/apis/alloydb/v1beta1/types.generated.go @@ -0,0 +1,181 @@ +// 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 + +// +kcc:proto=google.cloud.alloydb.v1beta.GeminiInstanceConfig +type GeminiInstanceConfig struct { + // Output only. Whether the Gemini in Databases add-on is enabled for the + // instance. It will be true only if the add-on has been enabled for the + // billing account corresponding to the instance. Its status is toggled from + // the Admin Control Center (ACC) and cannot be toggled using AlloyDBInstance's APIs. + Entitled *bool `json:"entitled,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.ClientConnectionConfig +type Instance_ClientConnectionConfig struct { + // Optional. Configuration to enforce connectors only (ex: AuthProxy) + // connections to the database. + RequireConnectors *bool `json:"requireConnectors,omitempty"` + + // Optional. SSL configuration option for this instance. + SslConfig *SslConfig `json:"sslConfig,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig +type Instance_InstanceNetworkConfig struct { + // Optional. A list of external network authorized to access this instance. + // This field is only allowed to be set when 'enablePublicIp' is set to true. + AuthorizedExternalNetworks []Instance_InstanceNetworkConfig_AuthorizedNetwork `json:"authorizedExternalNetworks,omitempty"` + + // Optional. Enabling public ip for the instance. If a user wishes + // to disable this, please also clear the list of the authorized + // external networks set on the same instance. + EnablePublicIp *bool `json:"enablePublicIp,omitempty"` + + // Optional. Enabling an outbound public IP address to support a database + // server sending requests out into the internet. + EnableOutboundPublicIp *bool `json:"enableOutboundPublicIp,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig.AuthorizedNetwork +type Instance_InstanceNetworkConfig_AuthorizedNetwork struct { + // CIDR range for one authorzied network of the instance. + CidrRange *string `json:"cidrRange,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.MachineConfig +type Instance_MachineConfig struct { + // The number of CPU's in the VM instance. + CpuCount *int32 `json:"cpuCount,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.Node +type Instance_Node struct { + // The Compute Engine zone of the VM e.g. "us-central1-b". + ZoneID *string `json:"zoneID,omitempty"` + + // The identifier of the VM e.g. "test-read-0601-407e52be-ms3l". + ID *string `json:"id,omitempty"` + + // The private IP address of the VM e.g. "10.57.0.34". + Ip *string `json:"ip,omitempty"` + + // Determined by state of the compute VM and postgres-service health. + // Compute VM state can have values listed in + // https://cloud.google.com/compute/docs/instances/instance-life-cycle and + // postgres-service health can have values: HEALTHY and UNHEALTHY. + State *string `json:"state,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.ObservabilityInstanceConfig +type Instance_ObservabilityInstanceConfig struct { + // Observability feature status for an instance. + // This flag is turned "off" by default. + Enabled *bool `json:"enabled,omitempty"` + + // Preserve comments in query string for an instance. + // This flag is turned "off" by default. + PreserveComments *bool `json:"preserveComments,omitempty"` + + // Track wait events during query execution for an instance. + // This flag is turned "on" by default but tracking is enabled only after + // observability enabled flag is also turned on. + TrackWaitEvents *bool `json:"trackWaitEvents,omitempty"` + + // Output only. Track wait event types during query execution for an + // instance. This flag is turned "on" by default but tracking is enabled + // only after observability enabled flag is also turned on. This is + // read-only flag and only modifiable by producer API. + TrackWaitEventTypes *bool `json:"trackWaitEventTypes,omitempty"` + + // Query string length. The default value is 10k. + MaxQueryStringLength *int32 `json:"maxQueryStringLength,omitempty"` + + // Record application tags for an instance. + // This flag is turned "off" by default. + RecordApplicationTags *bool `json:"recordApplicationTags,omitempty"` + + // Number of query execution plans captured by Insights per minute + // for all queries combined. The default value is 200. + // Any integer between 0 to 200 is considered valid. + QueryPlansPerMinute *int32 `json:"queryPlansPerMinute,omitempty"` + + // Track actively running queries on the instance. + // If not set, this flag is "off" by default. + TrackActiveQueries *bool `json:"trackActiveQueries,omitempty"` + + // Track client address for an instance. + // If not set, default value is "off". + TrackClientAddress *bool `json:"trackClientAddress,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.PscInstanceConfig +type Instance_PscInstanceConfig struct { + // Output only. The service attachment created when Private + // Service Connect (PSC) is enabled for the instance. + // The name of the resource will be in the format of + // `projects//regions//serviceAttachments/` + ServiceAttachmentLink *string `json:"serviceAttachmentLink,omitempty"` + + // Optional. List of consumer projects that are allowed to create + // PSC endpoints to service-attachments to this instance. + AllowedConsumerProjects []string `json:"allowedConsumerProjects,omitempty"` + + // Output only. The DNS name of the instance for PSC connectivity. + // Name convention: ...alloydb-psc.goog + PscDnsName *string `json:"pscDnsName,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.QueryInsightsInstanceConfig +type Instance_QueryInsightsInstanceConfig struct { + // Record application tags for an instance. + // This flag is turned "on" by default. + RecordApplicationTags *bool `json:"recordApplicationTags,omitempty"` + + // Record client address for an instance. Client address is PII information. + // This flag is turned "on" by default. + RecordClientAddress *bool `json:"recordClientAddress,omitempty"` + + // Query string length. The default value is 1024. + // Any integer between 256 and 4500 is considered valid. + QueryStringLength *uint32 `json:"queryStringLength,omitempty"` + + // Number of query execution plans captured by Insights per minute + // for all queries combined. The default value is 5. + // Any integer between 0 and 20 is considered valid. + QueryPlansPerMinute *uint32 `json:"queryPlansPerMinute,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.ReadPoolConfig +type Instance_ReadPoolConfig struct { + // Read capacity, i.e. number of nodes in a read pool instance. + NodeCount *int32 `json:"nodeCount,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.Instance.UpdatePolicy +type Instance_UpdatePolicy struct { + // Mode for updating the instance. + Mode *string `json:"mode,omitempty"` +} + +// +kcc:proto=google.cloud.alloydb.v1beta.SslConfig +type SslConfig struct { + // Optional. SSL mode. Specifies client-server SSL/TLS connection behavior. + SslMode *string `json:"sslMode,omitempty"` + + // Optional. Certificate Authority (CA) source. Only CA_SOURCE_MANAGED is + // supported currently, and is the default value. + CaSource *string `json:"caSource,omitempty"` +} diff --git a/apis/alloydb/v1beta1/zz_generated.deepcopy.go b/apis/alloydb/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..1f5bade33e --- /dev/null +++ b/apis/alloydb/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,630 @@ +//go: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 controller-gen. DO NOT EDIT. + +package v1beta1 + +import ( + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/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 *AlloyDBInstance) DeepCopyInto(out *AlloyDBInstance) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstance. +func (in *AlloyDBInstance) DeepCopy() *AlloyDBInstance { + if in == nil { + return nil + } + out := new(AlloyDBInstance) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AlloyDBInstance) 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 *AlloyDBInstanceList) DeepCopyInto(out *AlloyDBInstanceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]AlloyDBInstance, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstanceList. +func (in *AlloyDBInstanceList) DeepCopy() *AlloyDBInstanceList { + if in == nil { + return nil + } + out := new(AlloyDBInstanceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *AlloyDBInstanceList) 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 *AlloyDBInstanceSpec) DeepCopyInto(out *AlloyDBInstanceSpec) { + *out = *in + if in.ClusterRef != nil { + in, out := &in.ClusterRef, &out.ClusterRef + *out = new(refsv1beta1.AlloyDBClusterRef) + **out = **in + } + if in.ResourceID != nil { + in, out := &in.ResourceID, &out.ResourceID + *out = new(string) + **out = **in + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.AvailabilityType != nil { + in, out := &in.AvailabilityType, &out.AvailabilityType + *out = new(string) + **out = **in + } + if in.DatabaseFlags != nil { + in, out := &in.DatabaseFlags, &out.DatabaseFlags + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.DisplayName != nil { + in, out := &in.DisplayName, &out.DisplayName + *out = new(string) + **out = **in + } + if in.GceZone != nil { + in, out := &in.GceZone, &out.GceZone + *out = new(string) + **out = **in + } + if in.InstanceType != nil { + in, out := &in.InstanceType, &out.InstanceType + *out = new(string) + **out = **in + } + if in.InstanceTypeRef != nil { + in, out := &in.InstanceTypeRef, &out.InstanceTypeRef + *out = new(refsv1beta1.AlloyDBClusterTypeRef) + **out = **in + } + if in.MachineConfig != nil { + in, out := &in.MachineConfig, &out.MachineConfig + *out = new(Instance_MachineConfig) + (*in).DeepCopyInto(*out) + } + if in.NetworkConfig != nil { + in, out := &in.NetworkConfig, &out.NetworkConfig + *out = new(Instance_InstanceNetworkConfig) + (*in).DeepCopyInto(*out) + } + if in.ReadPoolConfig != nil { + in, out := &in.ReadPoolConfig, &out.ReadPoolConfig + *out = new(Instance_ReadPoolConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstanceSpec. +func (in *AlloyDBInstanceSpec) DeepCopy() *AlloyDBInstanceSpec { + if in == nil { + return nil + } + out := new(AlloyDBInstanceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AlloyDBInstanceStatus) DeepCopyInto(out *AlloyDBInstanceStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1alpha1.Condition, len(*in)) + copy(*out, *in) + } + if in.ObservedGeneration != nil { + in, out := &in.ObservedGeneration, &out.ObservedGeneration + *out = new(int64) + **out = **in + } + if in.ExternalRef != nil { + in, out := &in.ExternalRef, &out.ExternalRef + *out = new(string) + **out = **in + } + if in.CreateTime != nil { + in, out := &in.CreateTime, &out.CreateTime + *out = new(string) + **out = **in + } + if in.IpAddress != nil { + in, out := &in.IpAddress, &out.IpAddress + *out = new(string) + **out = **in + } + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.OutboundPublicIpAddresses != nil { + in, out := &in.OutboundPublicIpAddresses, &out.OutboundPublicIpAddresses + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PublicIpAddress != nil { + in, out := &in.PublicIpAddress, &out.PublicIpAddress + *out = new(string) + **out = **in + } + if in.Reconciling != nil { + in, out := &in.Reconciling, &out.Reconciling + *out = new(bool) + **out = **in + } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } + if in.Uid != nil { + in, out := &in.Uid, &out.Uid + *out = new(string) + **out = **in + } + if in.UpdateTime != nil { + in, out := &in.UpdateTime, &out.UpdateTime + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlloyDBInstanceStatus. +func (in *AlloyDBInstanceStatus) DeepCopy() *AlloyDBInstanceStatus { + if in == nil { + return nil + } + out := new(AlloyDBInstanceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GeminiInstanceConfig) DeepCopyInto(out *GeminiInstanceConfig) { + *out = *in + if in.Entitled != nil { + in, out := &in.Entitled, &out.Entitled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeminiInstanceConfig. +func (in *GeminiInstanceConfig) DeepCopy() *GeminiInstanceConfig { + if in == nil { + return nil + } + out := new(GeminiInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceIdentity) DeepCopyInto(out *InstanceIdentity) { + *out = *in + if in.parent != nil { + in, out := &in.parent, &out.parent + *out = new(InstanceParent) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceIdentity. +func (in *InstanceIdentity) DeepCopy() *InstanceIdentity { + if in == nil { + return nil + } + out := new(InstanceIdentity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceParent) DeepCopyInto(out *InstanceParent) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceParent. +func (in *InstanceParent) DeepCopy() *InstanceParent { + if in == nil { + return nil + } + out := new(InstanceParent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InstanceRef) DeepCopyInto(out *InstanceRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceRef. +func (in *InstanceRef) DeepCopy() *InstanceRef { + if in == nil { + return nil + } + out := new(InstanceRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_ClientConnectionConfig) DeepCopyInto(out *Instance_ClientConnectionConfig) { + *out = *in + if in.RequireConnectors != nil { + in, out := &in.RequireConnectors, &out.RequireConnectors + *out = new(bool) + **out = **in + } + if in.SslConfig != nil { + in, out := &in.SslConfig, &out.SslConfig + *out = new(SslConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_ClientConnectionConfig. +func (in *Instance_ClientConnectionConfig) DeepCopy() *Instance_ClientConnectionConfig { + if in == nil { + return nil + } + out := new(Instance_ClientConnectionConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_InstanceNetworkConfig) DeepCopyInto(out *Instance_InstanceNetworkConfig) { + *out = *in + if in.AuthorizedExternalNetworks != nil { + in, out := &in.AuthorizedExternalNetworks, &out.AuthorizedExternalNetworks + *out = make([]Instance_InstanceNetworkConfig_AuthorizedNetwork, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EnablePublicIp != nil { + in, out := &in.EnablePublicIp, &out.EnablePublicIp + *out = new(bool) + **out = **in + } + if in.EnableOutboundPublicIp != nil { + in, out := &in.EnableOutboundPublicIp, &out.EnableOutboundPublicIp + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_InstanceNetworkConfig. +func (in *Instance_InstanceNetworkConfig) DeepCopy() *Instance_InstanceNetworkConfig { + if in == nil { + return nil + } + out := new(Instance_InstanceNetworkConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_InstanceNetworkConfig_AuthorizedNetwork) DeepCopyInto(out *Instance_InstanceNetworkConfig_AuthorizedNetwork) { + *out = *in + if in.CidrRange != nil { + in, out := &in.CidrRange, &out.CidrRange + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_InstanceNetworkConfig_AuthorizedNetwork. +func (in *Instance_InstanceNetworkConfig_AuthorizedNetwork) DeepCopy() *Instance_InstanceNetworkConfig_AuthorizedNetwork { + if in == nil { + return nil + } + out := new(Instance_InstanceNetworkConfig_AuthorizedNetwork) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_MachineConfig) DeepCopyInto(out *Instance_MachineConfig) { + *out = *in + if in.CpuCount != nil { + in, out := &in.CpuCount, &out.CpuCount + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_MachineConfig. +func (in *Instance_MachineConfig) DeepCopy() *Instance_MachineConfig { + if in == nil { + return nil + } + out := new(Instance_MachineConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_Node) DeepCopyInto(out *Instance_Node) { + *out = *in + if in.ZoneID != nil { + in, out := &in.ZoneID, &out.ZoneID + *out = new(string) + **out = **in + } + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Ip != nil { + in, out := &in.Ip, &out.Ip + *out = new(string) + **out = **in + } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_Node. +func (in *Instance_Node) DeepCopy() *Instance_Node { + if in == nil { + return nil + } + out := new(Instance_Node) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_ObservabilityInstanceConfig) DeepCopyInto(out *Instance_ObservabilityInstanceConfig) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.PreserveComments != nil { + in, out := &in.PreserveComments, &out.PreserveComments + *out = new(bool) + **out = **in + } + if in.TrackWaitEvents != nil { + in, out := &in.TrackWaitEvents, &out.TrackWaitEvents + *out = new(bool) + **out = **in + } + if in.TrackWaitEventTypes != nil { + in, out := &in.TrackWaitEventTypes, &out.TrackWaitEventTypes + *out = new(bool) + **out = **in + } + if in.MaxQueryStringLength != nil { + in, out := &in.MaxQueryStringLength, &out.MaxQueryStringLength + *out = new(int32) + **out = **in + } + if in.RecordApplicationTags != nil { + in, out := &in.RecordApplicationTags, &out.RecordApplicationTags + *out = new(bool) + **out = **in + } + if in.QueryPlansPerMinute != nil { + in, out := &in.QueryPlansPerMinute, &out.QueryPlansPerMinute + *out = new(int32) + **out = **in + } + if in.TrackActiveQueries != nil { + in, out := &in.TrackActiveQueries, &out.TrackActiveQueries + *out = new(bool) + **out = **in + } + if in.TrackClientAddress != nil { + in, out := &in.TrackClientAddress, &out.TrackClientAddress + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_ObservabilityInstanceConfig. +func (in *Instance_ObservabilityInstanceConfig) DeepCopy() *Instance_ObservabilityInstanceConfig { + if in == nil { + return nil + } + out := new(Instance_ObservabilityInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_PscInstanceConfig) DeepCopyInto(out *Instance_PscInstanceConfig) { + *out = *in + if in.ServiceAttachmentLink != nil { + in, out := &in.ServiceAttachmentLink, &out.ServiceAttachmentLink + *out = new(string) + **out = **in + } + if in.AllowedConsumerProjects != nil { + in, out := &in.AllowedConsumerProjects, &out.AllowedConsumerProjects + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PscDnsName != nil { + in, out := &in.PscDnsName, &out.PscDnsName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_PscInstanceConfig. +func (in *Instance_PscInstanceConfig) DeepCopy() *Instance_PscInstanceConfig { + if in == nil { + return nil + } + out := new(Instance_PscInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_QueryInsightsInstanceConfig) DeepCopyInto(out *Instance_QueryInsightsInstanceConfig) { + *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 + } + if in.QueryStringLength != nil { + in, out := &in.QueryStringLength, &out.QueryStringLength + *out = new(uint32) + **out = **in + } + if in.QueryPlansPerMinute != nil { + in, out := &in.QueryPlansPerMinute, &out.QueryPlansPerMinute + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_QueryInsightsInstanceConfig. +func (in *Instance_QueryInsightsInstanceConfig) DeepCopy() *Instance_QueryInsightsInstanceConfig { + if in == nil { + return nil + } + out := new(Instance_QueryInsightsInstanceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_ReadPoolConfig) DeepCopyInto(out *Instance_ReadPoolConfig) { + *out = *in + if in.NodeCount != nil { + in, out := &in.NodeCount, &out.NodeCount + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_ReadPoolConfig. +func (in *Instance_ReadPoolConfig) DeepCopy() *Instance_ReadPoolConfig { + if in == nil { + return nil + } + out := new(Instance_ReadPoolConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Instance_UpdatePolicy) DeepCopyInto(out *Instance_UpdatePolicy) { + *out = *in + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance_UpdatePolicy. +func (in *Instance_UpdatePolicy) DeepCopy() *Instance_UpdatePolicy { + if in == nil { + return nil + } + out := new(Instance_UpdatePolicy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SslConfig) DeepCopyInto(out *SslConfig) { + *out = *in + if in.SslMode != nil { + in, out := &in.SslMode, &out.SslMode + *out = new(string) + **out = **in + } + if in.CaSource != nil { + in, out := &in.CaSource, &out.CaSource + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SslConfig. +func (in *SslConfig) DeepCopy() *SslConfig { + if in == nil { + return nil + } + out := new(SslConfig) + in.DeepCopyInto(out) + return out +} diff --git a/apis/refs/v1beta1/alloydbref.go b/apis/refs/v1beta1/alloydbref.go new file mode 100644 index 0000000000..5f58ac7677 --- /dev/null +++ b/apis/refs/v1beta1/alloydbref.go @@ -0,0 +1,283 @@ +// 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 ( + "context" + "fmt" + "strings" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type AlloyDBClusterRef struct { + // If provided must be in the format `projects/[projectId]/locations/[location]/clusters/[clusterId]`. + External string `json:"external,omitempty"` + // The `metadata.name` field of a `AlloyDBCluster` resource. + Name string `json:"name,omitempty"` + // The `metadata.namespace` field of a `AlloyDBCluster` resource. + Namespace string `json:"namespace,omitempty"` +} + +type AlloyDBCluster struct { + projectID string + location string + clusterID string +} + +func ResolveAlloyDBCluster(ctx context.Context, reader client.Reader, src client.Object, ref *AlloyDBClusterRef) (*AlloyDBCluster, error) { + if ref == nil { + return nil, nil + } + + if ref.Name == "" && ref.External == "" { + return nil, fmt.Errorf("must specify either name or external on AlloyDBClusterRef") + } + if ref.Name != "" && ref.External != "" { + return nil, fmt.Errorf("cannot specify both name and external on AlloyDBClusterRef") + } + + // External is provided. + if ref.External != "" { + // External should be in the `projects/[projectId]/locations/[location]/clusters/[clusterId]` format. + tokens := strings.Split(ref.External, "/") + if len(tokens) == 6 && tokens[0] == "projects" && tokens[2] == "locations" && tokens[4] == "clusters" { + return &AlloyDBCluster{ + projectID: tokens[1], + location: tokens[3], + clusterID: tokens[5], + }, nil + } + return nil, fmt.Errorf("format of AlloyDBClusterRef external=%q was not known (use projects/[projectId]/locations/[location]/clusters/[clusterId])", ref.External) + + } + + // Fetch AlloyDBCluster object to construct the external form. + cluster := &unstructured.Unstructured{} + cluster.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "alloydb.cnrm.cloud.google.com", + Version: "v1beta1", + Kind: "AlloyDBCluster", + }) + nn := types.NamespacedName{ + Namespace: ref.Namespace, + Name: ref.Name, + } + if nn.Namespace == "" { + nn.Namespace = src.GetNamespace() + } + if err := reader.Get(ctx, nn, cluster); err != nil { + if apierrors.IsNotFound(err) { + return nil, fmt.Errorf("referenced AlloyDBCluster %v not found", nn) + } + return nil, fmt.Errorf("error reading referenced AlloyDBCluster %v: %w", nn, err) + } + projectID, err := ResolveProjectID(ctx, reader, cluster) + if err != nil { + return nil, err + } + location, err := GetLocation(cluster) + if err != nil { + return nil, err + } + clusterID, err := GetResourceID(cluster) + if err != nil { + return nil, err + } + return &AlloyDBCluster{ + projectID: projectID, + location: location, + clusterID: clusterID, + }, nil +} + +type AlloyDBClusterTypeRef struct { + // The type of instance. Possible values: ["PRIMARY", "READ_POOL", "SECONDARY"] + External string `json:"external,omitempty"` + // The `metadata.name` field of a `AlloyDBCluster` resource. + Name string `json:"name,omitempty"` + // The `metadata.namespace` field of a `AlloyDBCluster` resource. + Namespace string `json:"namespace,omitempty"` +} + +func ResolveAlloyDBClusterType(ctx context.Context, reader client.Reader, src client.Object, ref *AlloyDBClusterTypeRef) (*string, error) { + if ref == nil { + return nil, nil + } + + if ref.Name == "" && ref.External == "" { + return nil, fmt.Errorf("must specify either name or external on AlloyDBClusterRef") + } + if ref.Name != "" && ref.External != "" { + return nil, fmt.Errorf("cannot specify both name and external on AlloyDBClusterRef") + } + + // External is provided. + if ref.External != "" { + return lazyPtr(ref.External), nil + } + + // Fetch AlloyDBCluster object to construct the external form. + cluster := &unstructured.Unstructured{} + cluster.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "alloydb.cnrm.cloud.google.com", + Version: "v1beta1", + Kind: "AlloyDBCluster", + }) + nn := types.NamespacedName{ + Namespace: ref.Namespace, + Name: ref.Name, + } + if nn.Namespace == "" { + nn.Namespace = src.GetNamespace() + } + if err := reader.Get(ctx, nn, cluster); err != nil { + if apierrors.IsNotFound(err) { + return nil, fmt.Errorf("referenced AlloyDBCluster %v not found", nn) + } + return nil, fmt.Errorf("error reading referenced AlloyDBCluster %v: %w", nn, err) + } + clusterType, _, err := unstructured.NestedString(cluster.Object, "spec", "clusterType") + if err != nil { + return nil, fmt.Errorf("reading spec.clusterType from %v %v/%v: %w", cluster.GroupVersionKind().Kind, cluster.GetNamespace(), cluster.GetName(), err) + } + if clusterType == "" { + // clusterType is defaulted to "PRIMARY" when not set. + clusterType = "PRIMARY" + } + return lazyPtr(clusterType), nil +} + +func ResolveAlloyDBClusterName(ctx context.Context, reader client.Reader, obj *unstructured.Unstructured) (string, error) { + clusterRefExternal, _, _ := unstructured.NestedString(obj.Object, "spec", "clusterRef", "external") + if clusterRefExternal != "" { + clusterRef := AlloyDBClusterRef{ + External: clusterRefExternal, + } + + cluster, err := ResolveAlloyDBCluster(ctx, reader, obj, &clusterRef) + if err != nil { + return "", fmt.Errorf("cannot parse clusterRef.external %q in %v %v/%v: %w", clusterRefExternal, obj.GetKind(), obj.GetNamespace(), obj.GetName(), err) + } + return cluster.String(), nil + } + + clusterRefName, _, _ := unstructured.NestedString(obj.Object, "spec", "clusterRef", "name") + if clusterRefName != "" { + clusterRefNamespace, _, _ := unstructured.NestedString(obj.Object, "spec", "clusterRef", "namespace") + + clusterRef := AlloyDBClusterRef{ + Name: clusterRefName, + Namespace: clusterRefNamespace, + } + if clusterRef.Namespace == "" { + clusterRef.Namespace = obj.GetNamespace() + } + + cluster, err := ResolveAlloyDBCluster(ctx, reader, obj, &clusterRef) + if err != nil { + return "", fmt.Errorf("cannot parse clusterRef in %v %v/%v: %w", obj.GetKind(), obj.GetNamespace(), obj.GetName(), err) + } + return cluster.String(), nil + } + + return "", fmt.Errorf("cannot find AlloyDB cluster name for %v %v/%v", obj.GetKind(), obj.GetNamespace(), obj.GetName()) +} + +func (c *AlloyDBCluster) String() string { + return fmt.Sprintf("projects/%s/locations/%s/clusters/%s", c.projectID, c.location, c.clusterID) +} + +type AlloyDBInstanceRef struct { + // If provided must be in the format `projects/[projectId]/locations/[location]/clusters/[clusterId]/instances/[instanceId]`. + External string `json:"external,omitempty"` + // The `metadata.name` field of a `AlloyDBInstance` resource. + Name string `json:"name,omitempty"` + // The `metadata.namespace` field of a `AlloyDBInstance` resource. + Namespace string `json:"namespace,omitempty"` +} + +type AlloyDBInstance struct { + clusterName string + instanceID string +} + +func ResolveAlloyDBInstance(ctx context.Context, reader client.Reader, src client.Object, ref *AlloyDBInstanceRef) (*AlloyDBInstance, error) { + if ref == nil { + return nil, nil + } + + if ref.Name == "" && ref.External == "" { + return nil, fmt.Errorf("must specify either name or external on AlloyDBInstanceRef") + } + if ref.Name != "" && ref.External != "" { + return nil, fmt.Errorf("cannot specify both name and external on AlloyDBInstanceRef") + } + + // External is provided. + if ref.External != "" { + // External should be in the `projects/[projectId]/locations/[location]/clusters/[clusterId]/instances/[instanceId]` format. + tokens := strings.Split(ref.External, "/") + if len(tokens) == 6 && tokens[0] == "projects" && tokens[2] == "locations" && tokens[4] == "clusters" && tokens[6] == "instances" { + return &AlloyDBInstance{ + clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), + instanceID: tokens[7], + }, nil + } + return nil, fmt.Errorf("format of AlloyDBInstanceRef external=%q was not known (use projects/[projectId]/locations/[location]/clusters/[clusterId]/instances/[instanceId])", ref.External) + + } + + // Fetch AlloyDBInstance object to construct the external form. + instance := &unstructured.Unstructured{} + instance.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "alloydb.cnrm.cloud.google.com", + Version: "v1beta1", + Kind: "AlloyDBInstance", + }) + nn := types.NamespacedName{ + Namespace: ref.Namespace, + Name: ref.Name, + } + if nn.Namespace == "" { + nn.Namespace = src.GetNamespace() + } + if err := reader.Get(ctx, nn, instance); err != nil { + if apierrors.IsNotFound(err) { + return nil, fmt.Errorf("referenced AlloyDBInstance %v not found", nn) + } + return nil, fmt.Errorf("error reading referenced AlloyDBInstance %v: %w", nn, err) + } + clusterName, err := ResolveAlloyDBClusterName(ctx, reader, instance) + if err != nil { + return nil, err + } + instanceID, err := GetResourceID(instance) + if err != nil { + return nil, err + } + return &AlloyDBInstance{ + clusterName: clusterName, + instanceID: instanceID, + }, nil +} + +func (i *AlloyDBInstance) String() string { + return fmt.Sprintf("%s/instances/%s", i.clusterName, i.instanceID) +} diff --git a/apis/refs/v1beta1/helper.go b/apis/refs/v1beta1/helper.go index df6733442b..0d0b81b732 100644 --- a/apis/refs/v1beta1/helper.go +++ b/apis/refs/v1beta1/helper.go @@ -41,3 +41,11 @@ func GetLocation(u *unstructured.Unstructured) (string, error) { } return location, nil } + +func lazyPtr[V comparable](v V) *V { + var defaultV V + if v == defaultV { + return nil + } + return &v +} diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml index d5ba9d6474..b32deca361 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml @@ -16,6 +16,7 @@ spec: categories: - gcp kind: AlloyDBInstance + listKind: AlloyDBInstanceList plural: alloydbinstances shortNames: - gcpalloydbinstance @@ -40,28 +41,25 @@ spec: jsonPath: .status.conditions[?(@.type=='Ready')].lastTransitionTime name: Status Age type: date - name: v1beta1 + name: v1alpha1 schema: openAPIV3Schema: + description: AlloyDBInstance is the Schema for the AlloyDBInstance 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: - oneOf: - - required: - - instanceType - - required: - - instanceTypeRef + description: AlloyDBInstanceSpec defines the desired state of AlloyDBInstance properties: annotations: additionalProperties: @@ -71,14 +69,17 @@ spec: type: object availabilityType: description: |- - 'Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + Note that primary and read instances can have different availability types. Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. Zone is automatically chosen from the list of zones in the region specified. Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more - can have regional availability (nodes are present in 2 or more zones in a region).' Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. type: string clusterRef: + description: The AlloyDBInstance cluster that this resource belongs + to. oneOf: - not: required: @@ -95,14 +96,14 @@ spec: - external properties: external: - description: 'Allowed value: The `name` field of an `AlloyDBCluster` - resource.' + description: If provided must be in the format `projects/[projectId]/locations/[location]/clusters/[clusterId]`. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `metadata.name` field of a `AlloyDBCluster` 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 `AlloyDBCluster` + resource. type: string type: object databaseFlags: @@ -126,14 +127,15 @@ spec: instance, instance is created in a random zone with available capacity. type: string instanceType: - description: |- - We recommend that you use `instanceTypeRef` instead. - The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY] + description: 'We recommend that you use `instanceTypeRef` instead. + The type of the instance. Possible values: [PRIMARY, READ_POOL, + SECONDARY]' type: string instanceTypeRef: description: |- The type of instance. Possible values: ["PRIMARY", "READ_POOL", "SECONDARY"] + For PRIMARY and SECONDARY instances, set the value to refer to the name of the associated cluster. This is recommended because the instance type of primary and secondary instances is tied to the cluster type of the associated cluster. If the secondary cluster is promoted to primary cluster, then the associated secondary instance also becomes primary instance. @@ -162,14 +164,15 @@ spec: - external properties: external: - description: 'Allowed value: The `clusterType` field of an `AlloyDBCluster` - resource.' + description: 'The type of instance. Possible values: ["PRIMARY", + "READ_POOL", "SECONDARY"]' type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `metadata.name` field of a `AlloyDBCluster` 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 `AlloyDBCluster` + resource. type: string type: object machineConfig: @@ -178,30 +181,32 @@ spec: properties: cpuCount: description: The number of CPU's in the VM instance. + format: int32 type: integer type: object networkConfig: description: Instance level network configuration. properties: authorizedExternalNetworks: - description: A list of external networks authorized to access - this instance. This field is only allowed to be set when 'enable_public_ip' - is set to true. + description: Optional. A list of external network authorized to + access this instance. This field is only allowed to be set when + 'enablePublicIp' is set to true. items: properties: cidrRange: - description: CIDR range for one authorized network of the + description: CIDR range for one authorzied network of the instance. type: string type: object type: array enableOutboundPublicIp: - description: Enabling outbound public ip for the instance. + description: Optional. Enabling an outbound public IP address + to support a database server sending requests out into the internet. type: boolean enablePublicIp: - description: Enabling public ip for the instance. If a user wishes - to disable this, please also clear the list of the authorized - external networks set on the same instance. + description: Optional. Enabling public ip for the instance. If + a user wishes to disable this, please also clear the list of + the authorized external networks set on the same instance. type: boolean type: object readPoolConfig: @@ -211,21 +216,26 @@ spec: nodeCount: description: Read capacity, i.e. number of nodes in a read pool instance. + format: int32 type: integer type: object resourceID: description: Immutable. Optional. The instanceId of the resource. - Used for creation and acquisition. When unset, the value of `metadata.name` - is used as the default. + If not given, the metadata.name will be used. type: string + x-kubernetes-validations: + - message: ResourceID field is immutable + rule: self == oldSelf required: - clusterRef type: object status: + description: AlloyDBInstanceStatus defines the config connector machine + state of AlloyDBInstance properties: conditions: - description: Conditions represent the latest available observation - of the resource's current state. + description: Conditions represent the latest available observations + of the object's current state. items: properties: lastTransitionTime: @@ -252,6 +262,10 @@ spec: createTime: description: Time the Instance was created in UTC. type: string + externalRef: + description: A unique specifier for the AlloyDBInstance resource in + GCP. + type: string ipAddress: description: The IP address for the Instance. This is the connection endpoint for an end-user application. @@ -265,12 +279,12 @@ 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 outboundPublicIpAddresses: - description: |- - The outbound public IP addresses for the instance. This is available ONLY when - networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used - for outbound connections. + description: The outbound public IP addresses for the instance. This + is available ONLY when networkConfig.enableOutboundPublicIp is set + to true. These IP addresses are used for outbound connections. items: type: string type: array @@ -299,7 +313,7 @@ spec: - spec type: object served: true - storage: false + storage: true subresources: status: {} - additionalPrinterColumns: @@ -318,28 +332,25 @@ spec: jsonPath: .status.conditions[?(@.type=='Ready')].lastTransitionTime name: Status Age type: date - name: v1alpha1 + name: v1beta1 schema: openAPIV3Schema: + description: AlloyDBInstance is the Schema for the AlloyDBInstance 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: - oneOf: - - required: - - instanceType - - required: - - instanceTypeRef + description: AlloyDBInstanceSpec defines the desired state of AlloyDBInstance properties: annotations: additionalProperties: @@ -349,14 +360,17 @@ spec: type: object availabilityType: description: |- - 'Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + Note that primary and read instances can have different availability types. Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. Zone is automatically chosen from the list of zones in the region specified. Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more - can have regional availability (nodes are present in 2 or more zones in a region).' Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. type: string clusterRef: + description: The AlloyDBInstance cluster that this resource belongs + to. oneOf: - not: required: @@ -373,14 +387,14 @@ spec: - external properties: external: - description: 'Allowed value: The `name` field of an `AlloyDBCluster` - resource.' + description: If provided must be in the format `projects/[projectId]/locations/[location]/clusters/[clusterId]`. type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `metadata.name` field of a `AlloyDBCluster` 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 `AlloyDBCluster` + resource. type: string type: object databaseFlags: @@ -404,14 +418,15 @@ spec: instance, instance is created in a random zone with available capacity. type: string instanceType: - description: |- - We recommend that you use `instanceTypeRef` instead. - The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY] + description: 'We recommend that you use `instanceTypeRef` instead. + The type of the instance. Possible values: [PRIMARY, READ_POOL, + SECONDARY]' type: string instanceTypeRef: description: |- The type of instance. Possible values: ["PRIMARY", "READ_POOL", "SECONDARY"] + For PRIMARY and SECONDARY instances, set the value to refer to the name of the associated cluster. This is recommended because the instance type of primary and secondary instances is tied to the cluster type of the associated cluster. If the secondary cluster is promoted to primary cluster, then the associated secondary instance also becomes primary instance. @@ -440,14 +455,15 @@ spec: - external properties: external: - description: 'Allowed value: The `clusterType` field of an `AlloyDBCluster` - resource.' + description: 'The type of instance. Possible values: ["PRIMARY", + "READ_POOL", "SECONDARY"]' type: string name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + description: The `metadata.name` field of a `AlloyDBCluster` 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 `AlloyDBCluster` + resource. type: string type: object machineConfig: @@ -456,30 +472,32 @@ spec: properties: cpuCount: description: The number of CPU's in the VM instance. + format: int32 type: integer type: object networkConfig: description: Instance level network configuration. properties: authorizedExternalNetworks: - description: A list of external networks authorized to access - this instance. This field is only allowed to be set when 'enable_public_ip' - is set to true. + description: Optional. A list of external network authorized to + access this instance. This field is only allowed to be set when + 'enablePublicIp' is set to true. items: properties: cidrRange: - description: CIDR range for one authorized network of the + description: CIDR range for one authorzied network of the instance. type: string type: object type: array enableOutboundPublicIp: - description: Enabling outbound public ip for the instance. + description: Optional. Enabling an outbound public IP address + to support a database server sending requests out into the internet. type: boolean enablePublicIp: - description: Enabling public ip for the instance. If a user wishes - to disable this, please also clear the list of the authorized - external networks set on the same instance. + description: Optional. Enabling public ip for the instance. If + a user wishes to disable this, please also clear the list of + the authorized external networks set on the same instance. type: boolean type: object readPoolConfig: @@ -489,21 +507,26 @@ spec: nodeCount: description: Read capacity, i.e. number of nodes in a read pool instance. + format: int32 type: integer type: object resourceID: description: Immutable. Optional. The instanceId of the resource. - Used for creation and acquisition. When unset, the value of `metadata.name` - is used as the default. + If not given, the metadata.name will be used. type: string + x-kubernetes-validations: + - message: ResourceID field is immutable + rule: self == oldSelf required: - clusterRef type: object status: + description: AlloyDBInstanceStatus defines the config connector machine + state of AlloyDBInstance properties: conditions: - description: Conditions represent the latest available observation - of the resource's current state. + description: Conditions represent the latest available observations + of the object's current state. items: properties: lastTransitionTime: @@ -530,6 +553,10 @@ spec: createTime: description: Time the Instance was created in UTC. type: string + externalRef: + description: A unique specifier for the AlloyDBInstance resource in + GCP. + type: string ipAddress: description: The IP address for the Instance. This is the connection endpoint for an end-user application. @@ -543,12 +570,12 @@ 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 outboundPublicIpAddresses: - description: |- - The outbound public IP addresses for the instance. This is available ONLY when - networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used - for outbound connections. + description: The outbound public IP addresses for the instance. This + is available ONLY when networkConfig.enableOutboundPublicIp is set + to true. These IP addresses are used for outbound connections. items: type: string type: array @@ -577,12 +604,6 @@ spec: - spec type: object served: true - storage: true + storage: false subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/go.mod b/go.mod index b9c8eec6d9..ced7fc68b0 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ toolchain go1.23.2 replace github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp => ./mockgcp require ( + cloud.google.com/go/alloydb v1.14.0 cloud.google.com/go/apikeys v1.1.12 cloud.google.com/go/bigquery v1.65.0 cloud.google.com/go/certificatemanager v1.9.2 diff --git a/go.sum b/go.sum index 9fc6d299cf..8f133a265c 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= +cloud.google.com/go/alloydb v1.14.0 h1:aEmmIHmiHDs46wTr/YqXuumuUGNc5QKYA7317nEFj2Y= +cloud.google.com/go/alloydb v1.14.0/go.mod h1:OTBY1HoL0Z8PsHoMMVhkaUPKyY8oP7hzIAe/Dna6UHk= cloud.google.com/go/apikeys v1.1.12 h1:ZTFWJ1ibGjiIrIhhtdWOm7AGJd+y9R17dVujlgU//6E= cloud.google.com/go/apikeys v1.1.12/go.mod h1:3tqZUj8CmCJm0maQyLufgyO5Ghf3AZQ6hcSkIqsSIm4= cloud.google.com/go/auth v0.11.0 h1:Ic5SZz2lsvbYcWT5dfjNWgw6tTlGi2Wc8hyQSC9BstA= diff --git a/pkg/controller/direct/alloydb/instance_controller.go b/pkg/controller/direct/alloydb/instance_controller.go new file mode 100644 index 0000000000..abb031d971 --- /dev/null +++ b/pkg/controller/direct/alloydb/instance_controller.go @@ -0,0 +1,402 @@ +// 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 alloydb + +import ( + "context" + "fmt" + "reflect" + + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/alloydb/v1beta1" + refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/config" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/directbase" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/registry" + + gcp "cloud.google.com/go/alloydb/apiv1beta" + alloydbpb "cloud.google.com/go/alloydb/apiv1beta/alloydbpb" + "github.com/google/go-cmp/cmp" + "google.golang.org/api/option" + "google.golang.org/protobuf/types/known/fieldmaskpb" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func init() { + registry.RegisterModel(krm.AlloyDBInstanceGVK, NewInstanceModel) +} + +func NewInstanceModel(ctx context.Context, config *config.ControllerConfig) (directbase.Model, error) { + return &instanceModel{config: *config}, nil +} + +var _ directbase.Model = &instanceModel{} + +type instanceModel struct { + config config.ControllerConfig +} + +func (m *instanceModel) client(ctx context.Context) (*gcp.AlloyDBAdminClient, error) { + var opts []option.ClientOption + opts, err := m.config.RESTClientOptions() + if err != nil { + return nil, err + } + gcpClient, err := gcp.NewAlloyDBAdminRESTClient(ctx, opts...) + if err != nil { + return nil, fmt.Errorf("error building AlloyDB client for Instance: %w", err) + } + return gcpClient, err +} + +func (m *instanceModel) AdapterForObject(ctx context.Context, reader client.Reader, u *unstructured.Unstructured) (directbase.Adapter, error) { + obj := &krm.AlloyDBInstance{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &obj); err != nil { + return nil, fmt.Errorf("error converting to %T: %w", obj, err) + } + + id, err := krm.NewInstanceIdentity(ctx, reader, obj) + if err != nil { + return nil, err + } + + if obj.Spec.InstanceType != nil && obj.Spec.InstanceTypeRef != nil { + return nil, fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + + "and 'spec.InstanceType' should be configured: both are configured") + } + if obj.Spec.InstanceType == nil && obj.Spec.InstanceTypeRef == nil { + return nil, fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + + "and 'spec.InstanceType' should be configured: neither is configured") + } + + var instanceType *string + if obj.Spec.InstanceType != nil { + if *instanceType == "" { + return nil, fmt.Errorf("'spec.InstanceType' should be configured with a non-empty string") + } + instanceType = obj.Spec.InstanceType + } + if obj.Spec.InstanceTypeRef != nil { + instanceType, err = refsv1beta1.ResolveAlloyDBClusterType(ctx, reader, obj, obj.Spec.InstanceTypeRef) + if err != nil { + return nil, fmt.Errorf("cannot resolve `spec.InstanceTypeRef`: %w", err) + } + } + obj.Spec.InstanceType = instanceType + + // Get alloydb GCP client + gcpClient, err := m.client(ctx) + if err != nil { + return nil, err + } + return &instanceAdapter{ + id: id, + gcpClient: gcpClient, + desired: obj, + }, nil +} + +func (m *instanceModel) AdapterForURL(ctx context.Context, url string) (directbase.Adapter, error) { + // TODO: Support URLs + return nil, nil +} + +type instanceAdapter struct { + id *krm.InstanceIdentity + gcpClient *gcp.AlloyDBAdminClient + desired *krm.AlloyDBInstance + actual *alloydbpb.Instance +} + +var _ directbase.Adapter = &instanceAdapter{} + +// Find retrieves the GCP resource. +// Return true means the object is found. This triggers Adapter `Update` call. +// Return true means the object is not found. This triggers Adapter `Create` call. +// Return a non-nil error requeues the requests. +func (a *instanceAdapter) Find(ctx context.Context) (bool, error) { + log := klog.FromContext(ctx) + log.V(2).Info("getting instance", "name", a.id) + fmt.Printf("getting instance: %v\n", a.id) + + req := &alloydbpb.GetInstanceRequest{Name: a.id.String()} + instancepb, err := a.gcpClient.GetInstance(ctx, req) + if err != nil { + log.V(2).Info("error getting instance", "name", a.id, "error", err) + fmt.Printf("instance error: %+v\n", err) + if direct.IsNotFound(err) { + return false, nil + } + + return false, fmt.Errorf("getting instance %q: %w", a.id, err) + } + + fmt.Printf("retrieved instance: %+v\n", instancepb) + a.actual = instancepb + return true, nil +} + +// Create creates the resource in GCP based on `spec` and update the Config Connector object `status` based on the GCP response. +func (a *instanceAdapter) Create(ctx context.Context, createOp *directbase.CreateOperation) error { + log := klog.FromContext(ctx) + log.V(2).Info("creating instance", "name", a.id) + fmt.Printf("creating instance: %v\n", a.id) + mapCtx := &direct.MapContext{} + + desired := a.desired.DeepCopy() + resource := AlloyDBInstanceSpec_ToProto(mapCtx, &desired.Spec) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + resource.Labels = make(map[string]string) + for k, v := range a.desired.GetObjectMeta().GetLabels() { + resource.Labels[k] = v + } + resource.Labels["managed-by-cnrm"] = "true" + + var created *alloydbpb.Instance + instanceType := a.desired.Spec.InstanceType + if instanceType != nil && *instanceType == "SECONDARY" { + req := &alloydbpb.CreateSecondaryInstanceRequest{ + Parent: a.id.Parent().String(), + InstanceId: a.id.ID(), + Instance: resource, + } + op, err := a.gcpClient.CreateSecondaryInstance(ctx, req) + if err != nil { + log.V(2).Info("error creating secondary instance", "name", a.id, "error", err) + return fmt.Errorf("creating secondary instance %s: %w", a.id, err) + } + created, err = op.Wait(ctx) + if err != nil { + log.V(2).Info("error waiting secondary instance creation", "name", a.id, "error", err) + return fmt.Errorf("secondary instance %s waiting creation: %w", a.id, err) + } + log.V(2).Info("successfully created secondary instance", "name", a.id) + } else { + req := &alloydbpb.CreateInstanceRequest{ + Parent: a.id.Parent().String(), + InstanceId: a.id.ID(), + Instance: resource, + } + op, err := a.gcpClient.CreateInstance(ctx, req) + if err != nil { + log.V(2).Info("error creating instance", "name", a.id, "error", err) + return fmt.Errorf("creating instance %s: %w", a.id, err) + } + created, err = op.Wait(ctx) + if err != nil { + log.V(2).Info("error waiting instance creation", "name", a.id, "error", err) + return fmt.Errorf("instance %s waiting creation: %w", a.id, err) + } + log.V(2).Info("successfully created instance", "name", a.id) + } + + status := AlloyDBInstanceStatus_FromProto(mapCtx, created) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + status.ExternalRef = a.id.AsExternalRef() + return createOp.UpdateStatus(ctx, status, nil) +} + +// Update updates the resource in GCP based on `spec` and update the Config Connector object `status` based on the GCP response. +func (a *instanceAdapter) Update(ctx context.Context, updateOp *directbase.UpdateOperation) error { + log := klog.FromContext(ctx) + log.V(2).Info("updating instance", "name", a.id) + mapCtx := &direct.MapContext{} + + parsedActual := AlloyDBInstanceSpec_FromProto(mapCtx, a.actual) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + + updatePaths, err := compareInstance(ctx, parsedActual, &a.desired.Spec) + if err != nil { + return err + } + desiredLabels := a.desired.GetObjectMeta().GetLabels() + desiredLabels["managed-by-cnrm"] = "true" + if !reflect.DeepEqual(a.actual.GetLabels(), desiredLabels) { + log.V(2).Info("'metadata.labels' field is updated (-old +new)", cmp.Diff(a.actual.GetLabels(), desiredLabels)) + updatePaths = append(updatePaths, "availability_type") + } + + if len(updatePaths) == 0 { + log.V(2).Info("no field needs update", "name", a.id) + return nil + } + fmt.Printf("maqiuyu... updateMasks: %+v\n", updatePaths) + updateMask := &fieldmaskpb.FieldMask{ + Paths: updatePaths, + } + desiredPb := AlloyDBInstanceSpec_ToProto(mapCtx, &a.desired.DeepCopy().Spec) + desiredPb.Labels = desiredLabels + desiredPb.Name = a.id.String() + req := &alloydbpb.UpdateInstanceRequest{ + UpdateMask: updateMask, + Instance: desiredPb, + } + op, err := a.gcpClient.UpdateInstance(ctx, req) + if err != nil { + log.V(2).Info("error updating instance", "name", a.id, "error", err) + return fmt.Errorf("updating instance %s: %w", a.id, err) + } + updated, err := op.Wait(ctx) + if err != nil { + log.V(2).Info("error waiting instance update", "name", a.id, "error", err) + return fmt.Errorf("instance %s waiting update: %w", a.id, err) + } + log.V(2).Info("successfully updated instance", "name", a.id) + + status := AlloyDBInstanceStatus_FromProto(mapCtx, updated) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + return updateOp.UpdateStatus(ctx, status, nil) +} + +func compareInstance(ctx context.Context, actual, desired *krm.AlloyDBInstanceSpec) (updatePaths []string, err error) { + log := klog.FromContext(ctx) + updatePaths = make([]string, 0) + if !reflect.DeepEqual(actual.Annotations, desired.Annotations) { + log.V(2).Info("'spec.annotations' field is updated (-old +new)", cmp.Diff(actual.Annotations, desired.Annotations)) + updatePaths = append(updatePaths, "annotations") + } + // TODO: Test case with availability type unset. + if desired.AvailabilityType != nil && !reflect.DeepEqual(actual.AvailabilityType, desired.AvailabilityType) { + log.V(2).Info("'spec.availabilityType' field is updated (-old +new)", cmp.Diff(actual.AvailabilityType, desired.AvailabilityType)) + updatePaths = append(updatePaths, "availability_type") + } + // TODO: Test "copied" behavior for read pool + // TODO: Test "overridden" behavior for read pool + // Default value of databaseFlags is unknown for a read instance unless we + // make API calls to get the database flags of the primary instance. + if desired.DatabaseFlags != nil && !reflect.DeepEqual(actual.DatabaseFlags, desired.DatabaseFlags) { + log.V(2).Info("'spec.databaseFlags' field is updated (-old +new)", cmp.Diff(actual.DatabaseFlags, desired.DatabaseFlags)) + updatePaths = append(updatePaths, "database_flags") + } + if desired.DisplayName != nil && !reflect.DeepEqual(actual.DisplayName, desired.DisplayName) { + log.V(2).Info("'spec.displayName' field is updated (-old +new)", cmp.Diff(actual.DisplayName, desired.DisplayName)) + updatePaths = append(updatePaths, "display_name") + } + if desired.GceZone != nil && !reflect.DeepEqual(actual.GceZone, desired.GceZone) { + log.V(2).Info("'spec.gceZone' field is updated (-old +new)", cmp.Diff(actual.GceZone, desired.GceZone)) + updatePaths = append(updatePaths, "gce_zone") + } + if desired.InstanceType != nil && !reflect.DeepEqual(actual.InstanceType, desired.InstanceType) { + log.V(2).Info("'spec.instanceType' field is updated (-old +new)", cmp.Diff(actual.InstanceType, desired.InstanceType)) + return nil, fmt.Errorf("cannot change immutable field %s from %v to %v", "'spec.instanceType'", actual.InstanceType, desired.InstanceType) + } + // TODO: Test machineConfig unset and empty struct + if desired.MachineConfig != nil { + if desired.MachineConfig.CpuCount != nil && !reflect.DeepEqual(actual.MachineConfig.CpuCount, desired.MachineConfig.CpuCount) { + log.V(2).Info("'spec.machineConfig.cpuCount' field is updated (-old +new)", cmp.Diff(actual.MachineConfig.CpuCount, desired.MachineConfig.CpuCount)) + updatePaths = append(updatePaths, "machine_config.cpu_count") + } + } + if desired.NetworkConfig != nil { + if desired.NetworkConfig.EnablePublicIp != nil && !reflect.DeepEqual(actual.NetworkConfig.EnablePublicIp, desired.NetworkConfig.EnablePublicIp) { + log.V(2).Info("'spec.networkConfig.enablePublicIp' field is updated (-old +new)", cmp.Diff(actual.NetworkConfig.EnablePublicIp, desired.NetworkConfig.EnablePublicIp)) + updatePaths = append(updatePaths, "network_config.enable_public_ip") + } + if desired.NetworkConfig.EnableOutboundPublicIp != nil && !reflect.DeepEqual(actual.NetworkConfig.EnableOutboundPublicIp, desired.NetworkConfig.EnableOutboundPublicIp) { + log.V(2).Info("'spec.networkConfig.enableOutboundPublicIp' field is updated (-old +new)", cmp.Diff(actual.NetworkConfig.EnableOutboundPublicIp, desired.NetworkConfig.EnableOutboundPublicIp)) + updatePaths = append(updatePaths, "network_config.enable_outbound_public_ip") + } + if desired.NetworkConfig.AuthorizedExternalNetworks != nil && !reflect.DeepEqual(actual.NetworkConfig.AuthorizedExternalNetworks, desired.NetworkConfig.AuthorizedExternalNetworks) { + log.V(2).Info("'spec.networkConfig.authorizedExternalNetworks' field is updated (-old +new)", cmp.Diff(actual.NetworkConfig.AuthorizedExternalNetworks, desired.NetworkConfig.AuthorizedExternalNetworks)) + updatePaths = append(updatePaths, "network_config.authorized_external_networks") + } + } + if desired.ReadPoolConfig != nil { + if desired.ReadPoolConfig.NodeCount != nil && !reflect.DeepEqual(actual.ReadPoolConfig.NodeCount, desired.ReadPoolConfig.NodeCount) { + log.V(2).Info("'spec.readPoolConfig.nodeCount' field is updated (-old +new)", cmp.Diff(actual.ReadPoolConfig.NodeCount, desired.ReadPoolConfig.NodeCount)) + updatePaths = append(updatePaths, "read_pool_config.node_count") + } + } + return updatePaths, nil +} + +// Export maps the GCP object to a Config Connector resource `spec`. +func (a *instanceAdapter) Export(ctx context.Context) (*unstructured.Unstructured, error) { + if a.actual == nil { + return nil, fmt.Errorf("Find() not called") + } + u := &unstructured.Unstructured{} + + obj := &krm.AlloyDBInstance{} + mapCtx := &direct.MapContext{} + obj.Spec = direct.ValueOf(AlloyDBInstanceSpec_FromProto(mapCtx, a.actual)) + if mapCtx.Err() != nil { + return nil, mapCtx.Err() + } + uObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + + // Split name into tokens and use ID. + u.SetName(a.actual.Name) + u.SetGroupVersionKind(krm.AlloyDBInstanceGVK) + + u.Object = uObj + return u, nil +} + +// Delete the resource from GCP service when the corresponding Config Connector resource is deleted. +func (a *instanceAdapter) Delete(ctx context.Context, deleteOp *directbase.DeleteOperation) (bool, error) { + log := klog.FromContext(ctx) + log.V(2).Info("deleting instance", "name", a.id) + + // Returning true directly if it is to delete a secondary instance. + // Technically the secondary instance is only abandoned but not deleted. + // This is because deletion of secondary instance is not supported. Instead, + // users should delete the secondary cluster which will forcefully delete + // the associated secondary instance. + instanceType := a.desired.Spec.InstanceType + if instanceType != nil && *instanceType == "SECONDARY" { + log.V(2).Info("This operation didn't delete the secondary instance. You need to delete the associated secondary cluster to delete the secondary instance (and the entire secondary cluster).", "name", a.id) + return true, nil + } + + req := &alloydbpb.DeleteInstanceRequest{Name: a.id.String()} + op, err := a.gcpClient.DeleteInstance(ctx, req) + if op != nil { + opMetadata, opErr := op.Metadata() + fmt.Printf("maqiuyu... delete operation: %v\n%v\nMetadata:\n%+v\nErr while getting metadata\n%v\n", op.Name(), op.Done(), opMetadata, opErr) + } else { + fmt.Printf("maqiuyu... delete operation not triggered. Maybe there is an error? %+v\n", err) + } + if err != nil { + log.V(2).Info("error deleting instance", "name", a.id, "error", err) + if direct.IsNotFound(err) { + return false, nil + } + return false, fmt.Errorf("deleting instance %s: %w", a.id, err) + } + + err = op.Wait(ctx) + if err != nil { + log.V(2).Info("error waiting instance delete", "name", a.id, "error", err) + return false, fmt.Errorf("waiting delete instance %s: %w", a.id, err) + } + + log.V(2).Info("successfully deleted instance", "name", a.id) + return true, nil +} diff --git a/pkg/controller/direct/alloydb/instance_mappings.go b/pkg/controller/direct/alloydb/instance_mappings.go new file mode 100644 index 0000000000..c5b40b0e12 --- /dev/null +++ b/pkg/controller/direct/alloydb/instance_mappings.go @@ -0,0 +1,124 @@ +// 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 alloydb + +import ( + "fmt" + + pb "cloud.google.com/go/alloydb/apiv1beta/alloydbpb" + + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/alloydb/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" +) + +func AlloyDBInstanceSpec_FromProto(mapCtx *direct.MapContext, in *pb.Instance) *krm.AlloyDBInstanceSpec { + if in == nil { + return nil + } + out := &krm.AlloyDBInstanceSpec{} + out.Annotations = in.GetAnnotations() + //out.AvailabilityType = direct.LazyPtr(in.GetAvailabilityType().String()) + out.AvailabilityType = direct.Enum_FromProto(mapCtx, in.GetAvailabilityType()) + out.DatabaseFlags = in.GetDatabaseFlags() + out.DisplayName = direct.LazyPtr(in.GetDisplayName()) + out.GceZone = direct.LazyPtr(in.GetGceZone()) + //out.InstanceType = direct.LazyPtr(in.GetInstanceType().String()) + out.InstanceType = direct.Enum_FromProto(mapCtx, in.GetInstanceType()) + // how to handle the labels? + out.MachineConfig = Instance_MachineConfig_FromProto(mapCtx, in.GetMachineConfig()) + out.NetworkConfig = Instance_InstanceNetworkConfig_FromProto(mapCtx, in.GetNetworkConfig()) + out.ReadPoolConfig = Instance_ReadPoolConfig_FromProto(mapCtx, in.GetReadPoolConfig()) + + // MISSING: Uid + // MISSING: CreateTime + // MISSING: UpdateTime + // MISSING: DeleteTime + // MISSING: Labels??? + // MISSING: State + // MISSING: WritableNode + // MISSING: Nodes + // MISSING: QueryInsightsConfig + // MISSING: ObservabilityConfig + // MISSING: IpAddress + // MISSING: PublicIpAddress + // MISSING: Reconciling + // MISSING: Etag + // MISSING: UpdatePolicy + // MISSING: ClientConnectionConfig + // MISSING: SatisfiesPzs + // MISSING: PscInstanceConfig + // MISSING: GeminiConfig + // MISSING: OutboundPublicIpAddresses + fmt.Printf("maqiuyu...AlloyDBInstanceSpec_FromProto: %+v\n", out) + return out +} + +func AlloyDBInstanceSpec_ToProto(mapCtx *direct.MapContext, in *krm.AlloyDBInstanceSpec) *pb.Instance { + if in == nil { + return nil + } + out := &pb.Instance{} + out.Annotations = in.Annotations + out.AvailabilityType = direct.Enum_ToProto[pb.Instance_AvailabilityType](mapCtx, in.AvailabilityType) + out.DatabaseFlags = in.DatabaseFlags + out.DisplayName = direct.ValueOf(in.DisplayName) + out.GceZone = direct.ValueOf(in.GceZone) + out.InstanceType = direct.Enum_ToProto[pb.Instance_InstanceType](mapCtx, in.InstanceType) + // how to handle the labels? + out.MachineConfig = Instance_MachineConfig_ToProto(mapCtx, in.MachineConfig) + out.NetworkConfig = Instance_InstanceNetworkConfig_ToProto(mapCtx, in.NetworkConfig) + out.ReadPoolConfig = Instance_ReadPoolConfig_ToProto(mapCtx, in.ReadPoolConfig) + // MISSING: Uid + // MISSING: CreateTime + // MISSING: UpdateTime + // MISSING: DeleteTime + // MISSING: Labels should be an internal field for to map metadata.labels + // MISSING: State + // MISSING: WritableNode + // MISSING: Nodes + // MISSING: QueryInsightsConfig + // MISSING: ObservabilityConfig + // MISSING: IpAddress + // MISSING: PublicIpAddress + // MISSING: Reconciling + // MISSING: Etag + // MISSING: UpdatePolicy + // MISSING: ClientConnectionConfig + // MISSING: SatisfiesPzs + // MISSING: PscInstanceConfig + // MISSING: GeminiConfig + // MISSING: OutboundPublicIpAddresses + fmt.Printf("maqiuyu...AlloyDBInstanceSpec_ToProto: %+v\n", out) + return out +} + +func AlloyDBInstanceStatus_FromProto(mapCtx *direct.MapContext, in *pb.Instance) *krm.AlloyDBInstanceStatus { + if in == nil { + return nil + } + out := &krm.AlloyDBInstanceStatus{} + out.CreateTime = direct.StringTimestamp_FromProto(mapCtx, in.GetCreateTime()) + out.IpAddress = direct.LazyPtr(in.GetIpAddress()) + out.Name = direct.LazyPtr(in.GetName()) + out.OutboundPublicIpAddresses = in.GetOutboundPublicIpAddresses() + out.PublicIpAddress = direct.LazyPtr(in.GetPublicIpAddress()) + out.Reconciling = direct.LazyPtr(in.Reconciling) + out.State = direct.Enum_FromProto(mapCtx, in.GetState()) + out.Uid = direct.LazyPtr(in.Uid) + out.UpdateTime = direct.StringTimestamp_FromProto(mapCtx, in.GetUpdateTime()) + + fmt.Printf("maqiuyu...AlloyDBInstanceStatus_FromProto: %+v", out) + return out +} diff --git a/pkg/controller/direct/alloydb/mapper.generated.go b/pkg/controller/direct/alloydb/mapper.generated.go new file mode 100644 index 0000000000..1aaa1efb95 --- /dev/null +++ b/pkg/controller/direct/alloydb/mapper.generated.go @@ -0,0 +1,255 @@ +// 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 alloydb + +import ( + pb "cloud.google.com/go/alloydb/apiv1beta/alloydbpb" + + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/alloydb/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" +) + +func GeminiInstanceConfig_FromProto(mapCtx *direct.MapContext, in *pb.GeminiInstanceConfig) *krm.GeminiInstanceConfig { + if in == nil { + return nil + } + out := &krm.GeminiInstanceConfig{} + out.Entitled = direct.LazyPtr(in.GetEntitled()) + return out +} +func GeminiInstanceConfig_ToProto(mapCtx *direct.MapContext, in *krm.GeminiInstanceConfig) *pb.GeminiInstanceConfig { + if in == nil { + return nil + } + out := &pb.GeminiInstanceConfig{} + out.Entitled = direct.ValueOf(in.Entitled) + return out +} +func Instance_ClientConnectionConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_ClientConnectionConfig) *krm.Instance_ClientConnectionConfig { + if in == nil { + return nil + } + out := &krm.Instance_ClientConnectionConfig{} + out.RequireConnectors = direct.LazyPtr(in.GetRequireConnectors()) + out.SslConfig = SslConfig_FromProto(mapCtx, in.GetSslConfig()) + return out +} +func Instance_ClientConnectionConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_ClientConnectionConfig) *pb.Instance_ClientConnectionConfig { + if in == nil { + return nil + } + out := &pb.Instance_ClientConnectionConfig{} + out.RequireConnectors = direct.ValueOf(in.RequireConnectors) + out.SslConfig = SslConfig_ToProto(mapCtx, in.SslConfig) + return out +} +func Instance_InstanceNetworkConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_InstanceNetworkConfig) *krm.Instance_InstanceNetworkConfig { + if in == nil { + return nil + } + out := &krm.Instance_InstanceNetworkConfig{} + out.AuthorizedExternalNetworks = direct.Slice_FromProto(mapCtx, in.AuthorizedExternalNetworks, Instance_InstanceNetworkConfig_AuthorizedNetwork_FromProto) + out.EnablePublicIp = direct.LazyPtr(in.GetEnablePublicIp()) + out.EnableOutboundPublicIp = direct.LazyPtr(in.GetEnableOutboundPublicIp()) + return out +} +func Instance_InstanceNetworkConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_InstanceNetworkConfig) *pb.Instance_InstanceNetworkConfig { + if in == nil { + return nil + } + out := &pb.Instance_InstanceNetworkConfig{} + out.AuthorizedExternalNetworks = direct.Slice_ToProto(mapCtx, in.AuthorizedExternalNetworks, Instance_InstanceNetworkConfig_AuthorizedNetwork_ToProto) + out.EnablePublicIp = direct.ValueOf(in.EnablePublicIp) + out.EnableOutboundPublicIp = direct.ValueOf(in.EnableOutboundPublicIp) + return out +} +func Instance_InstanceNetworkConfig_AuthorizedNetwork_FromProto(mapCtx *direct.MapContext, in *pb.Instance_InstanceNetworkConfig_AuthorizedNetwork) *krm.Instance_InstanceNetworkConfig_AuthorizedNetwork { + if in == nil { + return nil + } + out := &krm.Instance_InstanceNetworkConfig_AuthorizedNetwork{} + out.CidrRange = direct.LazyPtr(in.GetCidrRange()) + return out +} +func Instance_InstanceNetworkConfig_AuthorizedNetwork_ToProto(mapCtx *direct.MapContext, in *krm.Instance_InstanceNetworkConfig_AuthorizedNetwork) *pb.Instance_InstanceNetworkConfig_AuthorizedNetwork { + if in == nil { + return nil + } + out := &pb.Instance_InstanceNetworkConfig_AuthorizedNetwork{} + out.CidrRange = direct.ValueOf(in.CidrRange) + return out +} +func Instance_MachineConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_MachineConfig) *krm.Instance_MachineConfig { + if in == nil { + return nil + } + out := &krm.Instance_MachineConfig{} + out.CpuCount = direct.LazyPtr(in.GetCpuCount()) + return out +} +func Instance_MachineConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_MachineConfig) *pb.Instance_MachineConfig { + if in == nil { + return nil + } + out := &pb.Instance_MachineConfig{} + out.CpuCount = direct.ValueOf(in.CpuCount) + return out +} +func Instance_Node_FromProto(mapCtx *direct.MapContext, in *pb.Instance_Node) *krm.Instance_Node { + if in == nil { + return nil + } + out := &krm.Instance_Node{} + out.ZoneID = direct.LazyPtr(in.GetZoneId()) + out.ID = direct.LazyPtr(in.GetId()) + out.Ip = direct.LazyPtr(in.GetIp()) + out.State = direct.LazyPtr(in.GetState()) + return out +} +func Instance_Node_ToProto(mapCtx *direct.MapContext, in *krm.Instance_Node) *pb.Instance_Node { + if in == nil { + return nil + } + out := &pb.Instance_Node{} + out.ZoneId = direct.ValueOf(in.ZoneID) + out.Id = direct.ValueOf(in.ID) + out.Ip = direct.ValueOf(in.Ip) + out.State = direct.ValueOf(in.State) + return out +} +func Instance_ObservabilityInstanceConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_ObservabilityInstanceConfig) *krm.Instance_ObservabilityInstanceConfig { + if in == nil { + return nil + } + out := &krm.Instance_ObservabilityInstanceConfig{} + out.Enabled = in.Enabled + out.PreserveComments = in.PreserveComments + out.TrackWaitEvents = in.TrackWaitEvents + out.TrackWaitEventTypes = in.TrackWaitEventTypes + out.MaxQueryStringLength = in.MaxQueryStringLength + out.RecordApplicationTags = in.RecordApplicationTags + out.QueryPlansPerMinute = in.QueryPlansPerMinute + out.TrackActiveQueries = in.TrackActiveQueries + out.TrackClientAddress = in.TrackClientAddress + return out +} +func Instance_ObservabilityInstanceConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_ObservabilityInstanceConfig) *pb.Instance_ObservabilityInstanceConfig { + if in == nil { + return nil + } + out := &pb.Instance_ObservabilityInstanceConfig{} + out.Enabled = in.Enabled + out.PreserveComments = in.PreserveComments + out.TrackWaitEvents = in.TrackWaitEvents + out.TrackWaitEventTypes = in.TrackWaitEventTypes + out.MaxQueryStringLength = in.MaxQueryStringLength + out.RecordApplicationTags = in.RecordApplicationTags + out.QueryPlansPerMinute = in.QueryPlansPerMinute + out.TrackActiveQueries = in.TrackActiveQueries + out.TrackClientAddress = in.TrackClientAddress + return out +} +func Instance_PscInstanceConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_PscInstanceConfig) *krm.Instance_PscInstanceConfig { + if in == nil { + return nil + } + out := &krm.Instance_PscInstanceConfig{} + out.ServiceAttachmentLink = direct.LazyPtr(in.GetServiceAttachmentLink()) + out.AllowedConsumerProjects = in.AllowedConsumerProjects + out.PscDnsName = direct.LazyPtr(in.GetPscDnsName()) + return out +} +func Instance_PscInstanceConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_PscInstanceConfig) *pb.Instance_PscInstanceConfig { + if in == nil { + return nil + } + out := &pb.Instance_PscInstanceConfig{} + out.ServiceAttachmentLink = direct.ValueOf(in.ServiceAttachmentLink) + out.AllowedConsumerProjects = in.AllowedConsumerProjects + out.PscDnsName = direct.ValueOf(in.PscDnsName) + return out +} +func Instance_QueryInsightsInstanceConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_QueryInsightsInstanceConfig) *krm.Instance_QueryInsightsInstanceConfig { + if in == nil { + return nil + } + out := &krm.Instance_QueryInsightsInstanceConfig{} + out.RecordApplicationTags = in.RecordApplicationTags + out.RecordClientAddress = in.RecordClientAddress + out.QueryStringLength = direct.LazyPtr(in.GetQueryStringLength()) + out.QueryPlansPerMinute = in.QueryPlansPerMinute + return out +} +func Instance_QueryInsightsInstanceConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_QueryInsightsInstanceConfig) *pb.Instance_QueryInsightsInstanceConfig { + if in == nil { + return nil + } + out := &pb.Instance_QueryInsightsInstanceConfig{} + out.RecordApplicationTags = in.RecordApplicationTags + out.RecordClientAddress = in.RecordClientAddress + out.QueryStringLength = direct.ValueOf(in.QueryStringLength) + out.QueryPlansPerMinute = in.QueryPlansPerMinute + return out +} +func Instance_ReadPoolConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_ReadPoolConfig) *krm.Instance_ReadPoolConfig { + if in == nil { + return nil + } + out := &krm.Instance_ReadPoolConfig{} + out.NodeCount = direct.LazyPtr(in.GetNodeCount()) + return out +} +func Instance_ReadPoolConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_ReadPoolConfig) *pb.Instance_ReadPoolConfig { + if in == nil { + return nil + } + out := &pb.Instance_ReadPoolConfig{} + out.NodeCount = direct.ValueOf(in.NodeCount) + return out +} +func Instance_UpdatePolicy_FromProto(mapCtx *direct.MapContext, in *pb.Instance_UpdatePolicy) *krm.Instance_UpdatePolicy { + if in == nil { + return nil + } + out := &krm.Instance_UpdatePolicy{} + out.Mode = direct.Enum_FromProto(mapCtx, in.GetMode()) + return out +} +func Instance_UpdatePolicy_ToProto(mapCtx *direct.MapContext, in *krm.Instance_UpdatePolicy) *pb.Instance_UpdatePolicy { + if in == nil { + return nil + } + out := &pb.Instance_UpdatePolicy{} + out.Mode = direct.Enum_ToProto[pb.Instance_UpdatePolicy_Mode](mapCtx, in.Mode) + return out +} +func SslConfig_FromProto(mapCtx *direct.MapContext, in *pb.SslConfig) *krm.SslConfig { + if in == nil { + return nil + } + out := &krm.SslConfig{} + out.SslMode = direct.Enum_FromProto(mapCtx, in.GetSslMode()) + out.CaSource = direct.Enum_FromProto(mapCtx, in.GetCaSource()) + return out +} +func SslConfig_ToProto(mapCtx *direct.MapContext, in *krm.SslConfig) *pb.SslConfig { + if in == nil { + return nil + } + out := &pb.SslConfig{} + out.SslMode = direct.Enum_ToProto[pb.SslConfig_SslMode](mapCtx, in.SslMode) + out.CaSource = direct.Enum_ToProto[pb.SslConfig_CaSource](mapCtx, in.CaSource) + return out +} diff --git a/pkg/gvks/supportedgvks/gvks_generated.go b/pkg/gvks/supportedgvks/gvks_generated.go index 50e7d765ac..41c697d4f3 100644 --- a/pkg/gvks/supportedgvks/gvks_generated.go +++ b/pkg/gvks/supportedgvks/gvks_generated.go @@ -157,7 +157,7 @@ var SupportedGVKs = map[schema.GroupVersionKind]GVKMetadata{ }, { Group: "alloydb.cnrm.cloud.google.com", - Version: "v1beta1", + Version: "v1alpha1", Kind: "AlloyDBInstance", }: { Labels: map[string]string{ @@ -169,7 +169,7 @@ var SupportedGVKs = map[schema.GroupVersionKind]GVKMetadata{ }, { Group: "alloydb.cnrm.cloud.google.com", - Version: "v1alpha1", + Version: "v1beta1", Kind: "AlloyDBInstance", }: { Labels: map[string]string{ diff --git a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md index 79e59bcc1b..3770dd32b6 100644 --- a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md +++ b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md @@ -119,12 +119,13 @@ resourceID: string

string

-

{% verbatim %}'Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. +

{% verbatim %}Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + Note that primary and read instances can have different availability types. Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. Zone is automatically chosen from the list of zones in the region specified. Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more -can have regional availability (nodes are present in 2 or more zones in a region).' Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"].{% endverbatim %}

+can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"].{% endverbatim %}

@@ -134,7 +135,7 @@ can have regional availability (nodes are present in 2 or more zones in a region

object

-

{% verbatim %}{% endverbatim %}

+

{% verbatim %}The AlloyDBInstance cluster that this resource belongs to.{% endverbatim %}

@@ -144,7 +145,7 @@ can have regional availability (nodes are present in 2 or more zones in a region

string

-

{% verbatim %}Allowed value: The `name` field of an `AlloyDBCluster` resource.{% endverbatim %}

+

{% verbatim %}If provided must be in the format `projects/[projectId]/locations/[location]/clusters/[clusterId]`.{% endverbatim %}

@@ -154,7 +155,7 @@ can have regional availability (nodes are present in 2 or more zones in a region

string

-

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

+

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

@@ -164,7 +165,7 @@ can have regional availability (nodes are present in 2 or more zones in a region

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 `AlloyDBCluster` resource.{% endverbatim %}

@@ -204,8 +205,7 @@ can have regional availability (nodes are present in 2 or more zones in a region

string

-

{% verbatim %}We recommend that you use `instanceTypeRef` instead. -The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY]{% endverbatim %}

+

{% verbatim %}We recommend that you use `instanceTypeRef` instead. The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY]{% endverbatim %}

@@ -217,6 +217,7 @@ The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY]{% end

object

{% verbatim %}The type of instance. Possible values: ["PRIMARY", "READ_POOL", "SECONDARY"] + For PRIMARY and SECONDARY instances, set the value to refer to the name of the associated cluster. This is recommended because the instance type of primary and secondary instances is tied to the cluster type of the associated cluster. If the secondary cluster is promoted to primary cluster, then the associated secondary instance also becomes primary instance. @@ -238,7 +239,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

string

-

{% verbatim %}Allowed value: The `clusterType` field of an `AlloyDBCluster` resource.{% endverbatim %}

+

{% verbatim %}The type of instance. Possible values: ["PRIMARY", "READ_POOL", "SECONDARY"]{% endverbatim %}

@@ -248,7 +249,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

string

-

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

+

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

@@ -258,7 +259,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

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 `AlloyDBCluster` resource.{% endverbatim %}

@@ -298,7 +299,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

list (object)

-

{% verbatim %}A list of external networks authorized to access this instance. This field is only allowed to be set when 'enable_public_ip' is set to true.{% endverbatim %}

+

{% verbatim %}Optional. A list of external network authorized to access this instance. This field is only allowed to be set when 'enablePublicIp' is set to true.{% endverbatim %}

@@ -318,7 +319,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

string

-

{% verbatim %}CIDR range for one authorized network of the instance.{% endverbatim %}

+

{% verbatim %}CIDR range for one authorzied network of the instance.{% endverbatim %}

@@ -328,7 +329,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

boolean

-

{% verbatim %}Enabling outbound public ip for the instance.{% endverbatim %}

+

{% verbatim %}Optional. Enabling an outbound public IP address to support a database server sending requests out into the internet.{% endverbatim %}

@@ -338,7 +339,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

boolean

-

{% verbatim %}Enabling public ip for the instance. If a user wishes to disable this, please also clear the list of the authorized external networks set on the same instance.{% endverbatim %}

+

{% verbatim %}Optional. Enabling public ip for the instance. If a user wishes to disable this, please also clear the list of the authorized external networks set on the same instance.{% endverbatim %}

@@ -368,7 +369,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

string

-

{% verbatim %}Immutable. Optional. The instanceId of the resource. Used for creation and acquisition. When unset, the value of `metadata.name` is used as the default.{% endverbatim %}

+

{% verbatim %}Immutable. Optional. The instanceId of the resource. If not given, the metadata.name will be used.{% endverbatim %}

@@ -386,6 +387,7 @@ conditions: status: string type: string createTime: string +externalRef: string ipAddress: string name: string observedGeneration: integer @@ -409,7 +411,7 @@ updateTime: 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 object's current state.{% endverbatim %}

@@ -461,6 +463,13 @@ updateTime: string

{% verbatim %}Time the Instance was created in UTC.{% endverbatim %}

+ + externalRef + +

string

+

{% verbatim %}A unique specifier for the AlloyDBInstance resource in GCP.{% endverbatim %}

+ + ipAddress @@ -486,9 +495,7 @@ updateTime: string outboundPublicIpAddresses

list (string)

-

{% verbatim %}The outbound public IP addresses for the instance. This is available ONLY when -networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used -for outbound connections.{% endverbatim %}

+

{% verbatim %}The outbound public IP addresses for the instance. This is available ONLY when networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used for outbound connections.{% endverbatim %}

From f7646b627155993ddba0e037e96b6edba3d64f4b Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Thu, 12 Dec 2024 18:20:59 +0000 Subject: [PATCH 2/8] Clean up --- apis/alloydb/v1alpha1/instance_types.go | 11 ++-- apis/alloydb/v1beta1/instance_types.go | 11 ++-- ...stances.alloydb.cnrm.cloud.google.com.yaml | 22 ++++---- .../direct/alloydb/instance_controller.go | 13 +---- .../direct/alloydb/instance_mappings.go | 50 ------------------- .../resource-docs/alloydb/alloydbinstance.md | 11 ++-- 6 files changed, 26 insertions(+), 92 deletions(-) diff --git a/apis/alloydb/v1alpha1/instance_types.go b/apis/alloydb/v1alpha1/instance_types.go index 5210a86ba3..41a70666fc 100644 --- a/apis/alloydb/v1alpha1/instance_types.go +++ b/apis/alloydb/v1alpha1/instance_types.go @@ -39,13 +39,12 @@ type AlloyDBInstanceSpec struct { // of arbitrary data. This is distinct from labels. Annotations map[string]string `json:"annotations,omitempty"` - // Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + // Availability type of an Instance. If empty, defaults to REGIONAL for primary instances. // - // Note that primary and read instances can have different availability types. - // Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. - // Zone is automatically chosen from the list of zones in the region specified. - // Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more - // can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + // For read pools, availabilityType is always UNSPECIFIED. Instances in the + // read pools are evenly distributed across available zones within the region + // (i.e. read pools with more than one node will have a node in at least two zones). + // Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. AvailabilityType *string `json:"availabilityType,omitempty"` // Database flags. Set at instance level. * They are copied diff --git a/apis/alloydb/v1beta1/instance_types.go b/apis/alloydb/v1beta1/instance_types.go index 78ac8ad533..2fe8fe57ce 100644 --- a/apis/alloydb/v1beta1/instance_types.go +++ b/apis/alloydb/v1beta1/instance_types.go @@ -39,13 +39,12 @@ type AlloyDBInstanceSpec struct { // of arbitrary data. This is distinct from labels. Annotations map[string]string `json:"annotations,omitempty"` - // Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + // Availability type of an Instance. If empty, defaults to REGIONAL for primary instances. // - // Note that primary and read instances can have different availability types. - // Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. - // Zone is automatically chosen from the list of zones in the region specified. - // Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more - // can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + // For read pools, availabilityType is always UNSPECIFIED. Instances in the + // read pools are evenly distributed across available zones within the region + // (i.e. read pools with more than one node will have a node in at least two zones). + // Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. AvailabilityType *string `json:"availabilityType,omitempty"` // Database flags. Set at instance level. * They are copied diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml index b32deca361..72edcbdce0 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml @@ -69,13 +69,12 @@ spec: type: object availabilityType: description: |- - Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + Availability type of an Instance. If empty, defaults to REGIONAL for primary instances. - Note that primary and read instances can have different availability types. - Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. - Zone is automatically chosen from the list of zones in the region specified. - Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more - can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + For read pools, availabilityType is always UNSPECIFIED. Instances in the + read pools are evenly distributed across available zones within the region + (i.e. read pools with more than one node will have a node in at least two zones). + Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. type: string clusterRef: description: The AlloyDBInstance cluster that this resource belongs @@ -360,13 +359,12 @@ spec: type: object availabilityType: description: |- - Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. + Availability type of an Instance. If empty, defaults to REGIONAL for primary instances. - Note that primary and read instances can have different availability types. - Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. - Zone is automatically chosen from the list of zones in the region specified. - Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more - can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. + For read pools, availabilityType is always UNSPECIFIED. Instances in the + read pools are evenly distributed across available zones within the region + (i.e. read pools with more than one node will have a node in at least two zones). + Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"]. type: string clusterRef: description: The AlloyDBInstance cluster that this resource belongs diff --git a/pkg/controller/direct/alloydb/instance_controller.go b/pkg/controller/direct/alloydb/instance_controller.go index abb031d971..61597895e8 100644 --- a/pkg/controller/direct/alloydb/instance_controller.go +++ b/pkg/controller/direct/alloydb/instance_controller.go @@ -132,13 +132,11 @@ var _ directbase.Adapter = &instanceAdapter{} func (a *instanceAdapter) Find(ctx context.Context) (bool, error) { log := klog.FromContext(ctx) log.V(2).Info("getting instance", "name", a.id) - fmt.Printf("getting instance: %v\n", a.id) req := &alloydbpb.GetInstanceRequest{Name: a.id.String()} instancepb, err := a.gcpClient.GetInstance(ctx, req) if err != nil { log.V(2).Info("error getting instance", "name", a.id, "error", err) - fmt.Printf("instance error: %+v\n", err) if direct.IsNotFound(err) { return false, nil } @@ -146,7 +144,6 @@ func (a *instanceAdapter) Find(ctx context.Context) (bool, error) { return false, fmt.Errorf("getting instance %q: %w", a.id, err) } - fmt.Printf("retrieved instance: %+v\n", instancepb) a.actual = instancepb return true, nil } @@ -155,7 +152,6 @@ func (a *instanceAdapter) Find(ctx context.Context) (bool, error) { func (a *instanceAdapter) Create(ctx context.Context, createOp *directbase.CreateOperation) error { log := klog.FromContext(ctx) log.V(2).Info("creating instance", "name", a.id) - fmt.Printf("creating instance: %v\n", a.id) mapCtx := &direct.MapContext{} desired := a.desired.DeepCopy() @@ -234,14 +230,13 @@ func (a *instanceAdapter) Update(ctx context.Context, updateOp *directbase.Updat desiredLabels["managed-by-cnrm"] = "true" if !reflect.DeepEqual(a.actual.GetLabels(), desiredLabels) { log.V(2).Info("'metadata.labels' field is updated (-old +new)", cmp.Diff(a.actual.GetLabels(), desiredLabels)) - updatePaths = append(updatePaths, "availability_type") + updatePaths = append(updatePaths, "labels") } if len(updatePaths) == 0 { log.V(2).Info("no field needs update", "name", a.id) return nil } - fmt.Printf("maqiuyu... updateMasks: %+v\n", updatePaths) updateMask := &fieldmaskpb.FieldMask{ Paths: updatePaths, } @@ -377,12 +372,6 @@ func (a *instanceAdapter) Delete(ctx context.Context, deleteOp *directbase.Delet req := &alloydbpb.DeleteInstanceRequest{Name: a.id.String()} op, err := a.gcpClient.DeleteInstance(ctx, req) - if op != nil { - opMetadata, opErr := op.Metadata() - fmt.Printf("maqiuyu... delete operation: %v\n%v\nMetadata:\n%+v\nErr while getting metadata\n%v\n", op.Name(), op.Done(), opMetadata, opErr) - } else { - fmt.Printf("maqiuyu... delete operation not triggered. Maybe there is an error? %+v\n", err) - } if err != nil { log.V(2).Info("error deleting instance", "name", a.id, "error", err) if direct.IsNotFound(err) { diff --git a/pkg/controller/direct/alloydb/instance_mappings.go b/pkg/controller/direct/alloydb/instance_mappings.go index c5b40b0e12..fe2087c053 100644 --- a/pkg/controller/direct/alloydb/instance_mappings.go +++ b/pkg/controller/direct/alloydb/instance_mappings.go @@ -15,8 +15,6 @@ package alloydb import ( - "fmt" - pb "cloud.google.com/go/alloydb/apiv1beta/alloydbpb" krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/alloydb/v1beta1" @@ -29,39 +27,14 @@ func AlloyDBInstanceSpec_FromProto(mapCtx *direct.MapContext, in *pb.Instance) * } out := &krm.AlloyDBInstanceSpec{} out.Annotations = in.GetAnnotations() - //out.AvailabilityType = direct.LazyPtr(in.GetAvailabilityType().String()) out.AvailabilityType = direct.Enum_FromProto(mapCtx, in.GetAvailabilityType()) out.DatabaseFlags = in.GetDatabaseFlags() out.DisplayName = direct.LazyPtr(in.GetDisplayName()) out.GceZone = direct.LazyPtr(in.GetGceZone()) - //out.InstanceType = direct.LazyPtr(in.GetInstanceType().String()) out.InstanceType = direct.Enum_FromProto(mapCtx, in.GetInstanceType()) - // how to handle the labels? out.MachineConfig = Instance_MachineConfig_FromProto(mapCtx, in.GetMachineConfig()) out.NetworkConfig = Instance_InstanceNetworkConfig_FromProto(mapCtx, in.GetNetworkConfig()) out.ReadPoolConfig = Instance_ReadPoolConfig_FromProto(mapCtx, in.GetReadPoolConfig()) - - // MISSING: Uid - // MISSING: CreateTime - // MISSING: UpdateTime - // MISSING: DeleteTime - // MISSING: Labels??? - // MISSING: State - // MISSING: WritableNode - // MISSING: Nodes - // MISSING: QueryInsightsConfig - // MISSING: ObservabilityConfig - // MISSING: IpAddress - // MISSING: PublicIpAddress - // MISSING: Reconciling - // MISSING: Etag - // MISSING: UpdatePolicy - // MISSING: ClientConnectionConfig - // MISSING: SatisfiesPzs - // MISSING: PscInstanceConfig - // MISSING: GeminiConfig - // MISSING: OutboundPublicIpAddresses - fmt.Printf("maqiuyu...AlloyDBInstanceSpec_FromProto: %+v\n", out) return out } @@ -76,31 +49,9 @@ func AlloyDBInstanceSpec_ToProto(mapCtx *direct.MapContext, in *krm.AlloyDBInsta out.DisplayName = direct.ValueOf(in.DisplayName) out.GceZone = direct.ValueOf(in.GceZone) out.InstanceType = direct.Enum_ToProto[pb.Instance_InstanceType](mapCtx, in.InstanceType) - // how to handle the labels? out.MachineConfig = Instance_MachineConfig_ToProto(mapCtx, in.MachineConfig) out.NetworkConfig = Instance_InstanceNetworkConfig_ToProto(mapCtx, in.NetworkConfig) out.ReadPoolConfig = Instance_ReadPoolConfig_ToProto(mapCtx, in.ReadPoolConfig) - // MISSING: Uid - // MISSING: CreateTime - // MISSING: UpdateTime - // MISSING: DeleteTime - // MISSING: Labels should be an internal field for to map metadata.labels - // MISSING: State - // MISSING: WritableNode - // MISSING: Nodes - // MISSING: QueryInsightsConfig - // MISSING: ObservabilityConfig - // MISSING: IpAddress - // MISSING: PublicIpAddress - // MISSING: Reconciling - // MISSING: Etag - // MISSING: UpdatePolicy - // MISSING: ClientConnectionConfig - // MISSING: SatisfiesPzs - // MISSING: PscInstanceConfig - // MISSING: GeminiConfig - // MISSING: OutboundPublicIpAddresses - fmt.Printf("maqiuyu...AlloyDBInstanceSpec_ToProto: %+v\n", out) return out } @@ -119,6 +70,5 @@ func AlloyDBInstanceStatus_FromProto(mapCtx *direct.MapContext, in *pb.Instance) out.Uid = direct.LazyPtr(in.Uid) out.UpdateTime = direct.StringTimestamp_FromProto(mapCtx, in.GetUpdateTime()) - fmt.Printf("maqiuyu...AlloyDBInstanceStatus_FromProto: %+v", out) return out } diff --git a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md index 3770dd32b6..f2bb9bac9d 100644 --- a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md +++ b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md @@ -119,13 +119,12 @@ resourceID: string

string

-

{% verbatim %}Availability type of an Instance. Defaults to REGIONAL for both primary and read instances. +

{% verbatim %}Availability type of an Instance. If empty, defaults to REGIONAL for primary instances. -Note that primary and read instances can have different availability types. -Only READ_POOL instance supports ZONAL type. Users can't specify the zone for READ_POOL instance. -Zone is automatically chosen from the list of zones in the region specified. -Read pool of size 1 can only have zonal availability. Read pools with node count of 2 or more -can have regional availability (nodes are present in 2 or more zones in a region). Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"].{% endverbatim %}

+For read pools, availabilityType is always UNSPECIFIED. Instances in the +read pools are evenly distributed across available zones within the region +(i.e. read pools with more than one node will have a node in at least two zones). +Possible values: ["AVAILABILITY_TYPE_UNSPECIFIED", "ZONAL", "REGIONAL"].{% endverbatim %}

From 1fcfd24e49c273972e963678b70690be6436db5f Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Tue, 17 Dec 2024 03:33:10 +0000 Subject: [PATCH 3/8] Fix updates in mockalloydb --- mockgcp/mockalloydb/instance.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mockgcp/mockalloydb/instance.go b/mockgcp/mockalloydb/instance.go index a79654d8e0..990c5e3780 100644 --- a/mockgcp/mockalloydb/instance.go +++ b/mockgcp/mockalloydb/instance.go @@ -17,6 +17,7 @@ package mockalloydb import ( "context" "fmt" + "strings" "google.golang.org/genproto/googleapis/longrunning" "google.golang.org/grpc/codes" @@ -188,7 +189,8 @@ func (s *AlloyDBAdminV1) UpdateInstance(ctx context.Context, req *pb.UpdateInsta // TODO: Some sort of helper for fieldmask? for _, path := range paths { - switch path { + topLevelField := strings.Split(path, ".")[0] + switch topLevelField { case "labels": obj.Labels = req.Instance.GetLabels() case "annotations": From 239edf0312a108c5272be19cc48f62e288074005 Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Fri, 13 Dec 2024 03:56:47 +0000 Subject: [PATCH 4/8] Update testdata to use direct controller instead --- ...ed_object_basicalloydbinstance.golden.yaml | 8 +- .../basicalloydbinstance/_http.log | 72 +++++--- .../basicalloydbinstance/create.yaml | 2 + .../basicalloydbinstance/update.yaml | 2 + ..._basicsecondaryalloydbinstance.golden.yaml | 8 +- .../basicsecondaryalloydbinstance/_http.log | 171 ++++++------------ .../basicsecondaryalloydbinstance/create.yaml | 2 + .../dependencies.yaml | 2 + .../basicsecondaryalloydbinstance/update.yaml | 2 + ...ted_object_fullalloydbinstance.golden.yaml | 3 +- .../fullalloydbinstance/_http.log | 69 ++++--- .../fullalloydbinstance/create.yaml | 2 + .../fullalloydbinstance/update.yaml | 2 + ...ted_object_readalloydbinstance.golden.yaml | 3 +- .../readalloydbinstance/_http.log | 171 +++++++----------- .../readalloydbinstance/create.yaml | 2 + .../readalloydbinstance/dependencies.yaml | 2 + .../readalloydbinstance/update.yaml | 2 + ...ed_object_zonalalloydbinstance.golden.yaml | 8 +- .../zonalalloydbinstance/_http.log | 42 +++-- .../zonalalloydbinstance/create.yaml | 2 + 21 files changed, 265 insertions(+), 312 deletions(-) diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml index 65a23831fd..2be4d71488 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml @@ -2,12 +2,12 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: annotations: + alpha.cnrm.cloud.google.com/reconciler: direct cnrm.cloud.google.com/management-conflict-prevention-policy: none - 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: alloydbinstance-${uniqueId} @@ -22,7 +22,6 @@ spec: name: alloydbcluster-${uniqueId} machineConfig: cpuCount: 2 - resourceID: alloydbinstance-${uniqueId} status: conditions: - lastTransitionTime: "1970-01-01T00:00:00Z" @@ -31,9 +30,10 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" + externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} - observedGeneration: 3 + observedGeneration: 2 state: READY uid: "12345678" updateTime: "1970-01-01T00:00:00Z" diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_http.log index b9512c4b94..e93ba4ee4c 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_http.log @@ -765,9 +765,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} 404 Not Found Cache-Control: private @@ -790,13 +791,14 @@ X-Xss-Protection: 0 --- -POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances?alt=json&instanceId=alloydbinstance-${uniqueId} +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbinstance-${uniqueId} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId} { - "availabilityType": "REGIONAL", - "instanceType": "PRIMARY", + "availabilityType": 2, + "instanceType": 1, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -832,9 +834,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -913,9 +916,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} 200 OK Cache-Control: private @@ -929,15 +933,15 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", "geminiConfig": {}, - "instanceType": "PRIMARY", + "instanceType": 1, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -970,7 +974,7 @@ X-Xss-Protection: 0 "recordClientAddress": false }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -980,22 +984,26 @@ X-Xss-Protection: 0 --- -PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json&updateMask=databaseFlags +PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint&updateMask=databaseFlags Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: instance.name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} { - "availabilityType": "REGIONAL", + "availabilityType": 2, "databaseFlags": { "enable_google_adaptive_autovacuum": "off" }, + "instanceType": 1, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" }, "machineConfig": { "cpuCount": 2 - } + }, + "name": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}", + "reconciling": false } 200 OK @@ -1024,9 +1032,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -1108,9 +1117,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} 200 OK Cache-Control: private @@ -1124,10 +1134,10 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", @@ -1135,7 +1145,7 @@ X-Xss-Protection: 0 "enable_google_adaptive_autovacuum": "off" }, "geminiConfig": {}, - "instanceType": "PRIMARY", + "instanceType": 1, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1168,7 +1178,7 @@ X-Xss-Protection: 0 "recordClientAddress": false }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -1178,9 +1188,10 @@ X-Xss-Protection: 0 --- -DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json +DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} 200 OK Cache-Control: private @@ -1208,9 +1219,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Foperations%2F${operationID} 200 OK Cache-Control: private diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/create.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/create.yaml index 58ac921991..1cf1fb431b 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/create.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/create.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/update.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/update.yaml index b10deea72c..86c1db0d97 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/update.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/update.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml index a10071e611..76483d572d 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml @@ -2,12 +2,12 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: annotations: + alpha.cnrm.cloud.google.com/reconciler: direct cnrm.cloud.google.com/management-conflict-prevention-policy: none - 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: alloydbinstance-2-${uniqueId} @@ -22,7 +22,6 @@ spec: name: alloydbcluster-2-${uniqueId} machineConfig: cpuCount: 2 - resourceID: alloydbinstance-2-${uniqueId} status: conditions: - lastTransitionTime: "1970-01-01T00:00:00Z" @@ -31,9 +30,10 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" + externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId} - observedGeneration: 3 + observedGeneration: 2 state: READY uid: "12345678" updateTime: "1970-01-01T00:00:00Z" diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_http.log index 8d4ee52c5e..72c0ce0b95 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_http.log @@ -765,9 +765,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-1-${uniqueId}%2Finstances%2Falloydbinstance-1-${uniqueId} 404 Not Found Cache-Control: private @@ -790,13 +791,14 @@ X-Xss-Protection: 0 --- -POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances?alt=json&instanceId=alloydbinstance-1-${uniqueId} +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbinstance-1-${uniqueId} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-1-${uniqueId} { - "availabilityType": "REGIONAL", - "instanceType": "PRIMARY", + "availabilityType": 2, + "instanceType": 1, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -832,9 +834,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -913,73 +916,6 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${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 - -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 - -{ - "availabilityType": "REGIONAL", - "clientConnectionConfig": { - "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" - } - }, - "createTime": "2024-04-01T12:34:56.123456Z", - "geminiConfig": {}, - "instanceType": "PRIMARY", - "ipAddress": "10.1.2.3", - "labels": { - "cnrm-test": "true", - "managed-by-cnrm": "true" - }, - "machineConfig": { - "cpuCount": 2 - }, - "name": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${uniqueId}", - "nodes": [ - { - "zoneId": "europe-west1-c" - } - ], - "observabilityConfig": { - "enabled": false, - "maxQueryStringLength": 10240, - "preserveComments": false, - "queryPlansPerMinute": 20, - "recordApplicationTags": false, - "trackActiveQueries": false, - "trackClientAddress": false, - "trackWaitEventTypes": true, - "trackWaitEvents": true - }, - "queryInsightsConfig": { - "queryPlansPerMinute": 5, - "queryStringLength": 1024, - "recordApplicationTags": false, - "recordClientAddress": false - }, - "reconciling": false, - "state": "READY", - "uid": "111111111111111111111", - "updateTime": "2024-04-01T12:34:56.123456Z", - "writableNode": { - "zoneId": "europe-west1-b" - } -} - ---- - GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${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 @@ -1237,9 +1173,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west2%2Fclusters%2Falloydbcluster-2-${uniqueId}%2Finstances%2Falloydbinstance-2-${uniqueId} 404 Not Found Cache-Control: private @@ -1262,13 +1199,14 @@ X-Xss-Protection: 0 --- -POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances:createsecondary?alt=json&instanceId=alloydbinstance-2-${uniqueId} +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances:createsecondary?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbinstance-2-${uniqueId} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-west2%2Fclusters%2Falloydbcluster-2-${uniqueId} { - "availabilityType": "REGIONAL", - "instanceType": "SECONDARY", + "availabilityType": 2, + "instanceType": 3, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -1304,9 +1242,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west2%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -1385,9 +1324,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west2%2Fclusters%2Falloydbcluster-2-${uniqueId}%2Finstances%2Falloydbinstance-2-${uniqueId} 200 OK Cache-Control: private @@ -1401,15 +1341,15 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", "geminiConfig": {}, - "instanceType": "SECONDARY", + "instanceType": 3, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1442,7 +1382,7 @@ X-Xss-Protection: 0 "recordClientAddress": true }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -1452,22 +1392,26 @@ X-Xss-Protection: 0 --- -PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?alt=json&updateMask=databaseFlags +PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?%24alt=json%3Benum-encoding%3Dint&updateMask=databaseFlags Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: instance.name=projects%2F${projectId}%2Flocations%2Feurope-west2%2Fclusters%2Falloydbcluster-2-${uniqueId}%2Finstances%2Falloydbinstance-2-${uniqueId} { - "availabilityType": "REGIONAL", + "availabilityType": 2, "databaseFlags": { "enable_google_adaptive_autovacuum": "off" }, + "instanceType": 3, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" }, "machineConfig": { "cpuCount": 2 - } + }, + "name": "projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}", + "reconciling": false } 200 OK @@ -1496,9 +1440,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west2%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -1580,9 +1525,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west2%2Fclusters%2Falloydbcluster-2-${uniqueId}%2Finstances%2Falloydbinstance-2-${uniqueId} 200 OK Cache-Control: private @@ -1596,10 +1542,10 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", @@ -1607,7 +1553,7 @@ X-Xss-Protection: 0 "enable_google_adaptive_autovacuum": "off" }, "geminiConfig": {}, - "instanceType": "SECONDARY", + "instanceType": 3, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1640,7 +1586,7 @@ X-Xss-Protection: 0 "recordClientAddress": true }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -1801,9 +1747,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-1-${uniqueId}%2Finstances%2Falloydbinstance-1-${uniqueId} 200 OK Cache-Control: private @@ -1817,15 +1764,15 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", "geminiConfig": {}, - "instanceType": "PRIMARY", + "instanceType": 1, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1858,7 +1805,7 @@ X-Xss-Protection: 0 "recordClientAddress": false }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -1868,9 +1815,10 @@ X-Xss-Protection: 0 --- -DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${uniqueId}?alt=json +DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-1-${uniqueId}/instances/alloydbinstance-1-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-1-${uniqueId}%2Finstances%2Falloydbinstance-1-${uniqueId} 200 OK Cache-Control: private @@ -1898,9 +1846,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Foperations%2F${operationID} 200 OK Cache-Control: private diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/create.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/create.yaml index 990e2d6ccc..1a262980f2 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/create.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/create.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-2-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/dependencies.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/dependencies.yaml index 443264d684..fd380fbf78 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/dependencies.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/dependencies.yaml @@ -60,6 +60,8 @@ spec: apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-1-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/update.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/update.yaml index 8770370057..04fa87f64c 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/update.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/update.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-2-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml index 4c5f65c319..9f324e9ede 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml @@ -2,8 +2,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: annotations: + alpha.cnrm.cloud.google.com/reconciler: direct cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/state-into-spec: absent finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender @@ -35,6 +35,7 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" + externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId} observedGeneration: 2 diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_http.log index 6283f9e279..f3c04a6cb7 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_http.log @@ -763,9 +763,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} 404 Not Found Cache-Control: private @@ -788,15 +789,16 @@ X-Xss-Protection: 0 --- -POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances?alt=json&instanceId=alloydbinstance${uniqueId} +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbinstance${uniqueId} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-north1%2Fclusters%2Falloydbcluster${uniqueId} { "databaseFlags": { "password.enforce_complexity": "on" }, - "instanceType": "PRIMARY", + "instanceType": 1, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -844,9 +846,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -945,9 +948,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} 200 OK Cache-Control: private @@ -961,10 +965,10 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", @@ -972,7 +976,7 @@ X-Xss-Protection: 0 "password.enforce_complexity": "on" }, "geminiConfig": {}, - "instanceType": "PRIMARY", + "instanceType": 1, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1022,7 +1026,7 @@ X-Xss-Protection: 0 "recordClientAddress": false }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -1032,16 +1036,17 @@ X-Xss-Protection: 0 --- -PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json&updateMask=databaseFlags%2CmachineConfig%2CnetworkConfig +PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint&updateMask=databaseFlags%2CmachineConfig.cpuCount%2CnetworkConfig.enablePublicIp%2CnetworkConfig.enableOutboundPublicIp%2CnetworkConfig.authorizedExternalNetworks Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: instance.name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} { - "availabilityType": "REGIONAL", "databaseFlags": { "enable_google_adaptive_autovacuum": "off", "password.enforce_complexity": "on" }, + "instanceType": 1, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -1049,7 +1054,9 @@ User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 t "machineConfig": { "cpuCount": 4 }, - "networkConfig": {} + "name": "projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}", + "networkConfig": {}, + "reconciling": false } 200 OK @@ -1078,9 +1085,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -1169,9 +1177,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} 200 OK Cache-Control: private @@ -1185,10 +1194,10 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", @@ -1197,7 +1206,7 @@ X-Xss-Protection: 0 "password.enforce_complexity": "on" }, "geminiConfig": {}, - "instanceType": "PRIMARY", + "instanceType": 1, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1236,7 +1245,7 @@ X-Xss-Protection: 0 "recordClientAddress": false }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -1246,9 +1255,10 @@ X-Xss-Protection: 0 --- -DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} 200 OK Cache-Control: private @@ -1276,9 +1286,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-north1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-north1%2Foperations%2F${operationID} 200 OK Cache-Control: private diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/create.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/create.yaml index eb81f02bb2..72126db5f7 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/create.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/create.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/update.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/update.yaml index d03d6b7633..5dc20ba559 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/update.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/update.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml index f6fb733209..66b3dd5bc2 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml @@ -2,8 +2,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: annotations: + alpha.cnrm.cloud.google.com/reconciler: direct cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/state-into-spec: absent finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender @@ -30,6 +30,7 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" + externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId} observedGeneration: 2 diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_http.log index 274b115aa7..8950ae6347 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_http.log @@ -805,9 +805,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} 404 Not Found Cache-Control: private @@ -830,12 +831,13 @@ X-Xss-Protection: 0 --- -POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances?alt=json&instanceId=alloydbinstance${uniqueId} +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbinstance${uniqueId} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId} { - "instanceType": "PRIMARY", + "instanceType": 1, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -871,9 +873,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -952,76 +955,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: 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 - -{ - "availabilityType": "REGIONAL", - "clientConnectionConfig": { - "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" - } - }, - "createTime": "2024-04-01T12:34:56.123456Z", - "geminiConfig": {}, - "instanceType": "PRIMARY", - "ipAddress": "10.1.2.3", - "labels": { - "cnrm-test": "true", - "managed-by-cnrm": "true" - }, - "machineConfig": { - "cpuCount": 2 - }, - "name": "projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}", - "nodes": [ - { - "zoneId": "europe-southwest1-c" - } - ], - "observabilityConfig": { - "enabled": false, - "maxQueryStringLength": 10240, - "preserveComments": false, - "queryPlansPerMinute": 20, - "recordApplicationTags": false, - "trackActiveQueries": false, - "trackClientAddress": false, - "trackWaitEventTypes": true, - "trackWaitEvents": true - }, - "queryInsightsConfig": { - "queryPlansPerMinute": 5, - "queryStringLength": 1024, - "recordApplicationTags": false, - "recordClientAddress": false - }, - "reconciling": false, - "state": "READY", - "uid": "111111111111111111111", - "updateTime": "2024-04-01T12:34:56.123456Z", - "writableNode": { - "zoneId": "europe-southwest1-b" - } -} - ---- - -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${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 +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbreadinstance${uniqueId} 404 Not Found Cache-Control: private @@ -1044,12 +981,13 @@ X-Xss-Protection: 0 --- -POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances?alt=json&instanceId=alloydbreadinstance${uniqueId} +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbreadinstance${uniqueId} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId} { - "instanceType": "READ_POOL", + "instanceType": 2, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -1088,9 +1026,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -1163,9 +1102,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbreadinstance${uniqueId} 200 OK Cache-Control: private @@ -1181,12 +1121,12 @@ X-Xss-Protection: 0 { "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", "geminiConfig": {}, - "instanceType": "READ_POOL", + "instanceType": 2, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1217,18 +1157,20 @@ X-Xss-Protection: 0 "nodeCount": 1 }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z" } --- -PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?alt=json&updateMask=readPoolConfig +PATCH https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint&updateMask=readPoolConfig.nodeCount Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: instance.name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbreadinstance${uniqueId} { + "instanceType": 2, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -1236,9 +1178,11 @@ User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 t "machineConfig": { "cpuCount": 2 }, + "name": "projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}", "readPoolConfig": { "nodeCount": 3 - } + }, + "reconciling": false } 200 OK @@ -1267,9 +1211,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -1342,9 +1287,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbreadinstance${uniqueId} 200 OK Cache-Control: private @@ -1360,12 +1306,12 @@ X-Xss-Protection: 0 { "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", "geminiConfig": {}, - "instanceType": "READ_POOL", + "instanceType": 2, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1396,16 +1342,17 @@ X-Xss-Protection: 0 "nodeCount": 3 }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z" } --- -DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?alt=json +DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbreadinstance${uniqueId} 200 OK Cache-Control: private @@ -1433,9 +1380,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -1467,9 +1415,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} 200 OK Cache-Control: private @@ -1483,15 +1432,15 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "REGIONAL", + "availabilityType": 2, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", "geminiConfig": {}, - "instanceType": "PRIMARY", + "instanceType": 1, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -1524,7 +1473,7 @@ X-Xss-Protection: 0 "recordClientAddress": false }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -1534,9 +1483,10 @@ X-Xss-Protection: 0 --- -DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?alt=json +DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Fclusters%2Falloydbcluster${uniqueId}%2Finstances%2Falloydbinstance${uniqueId} 200 OK Cache-Control: private @@ -1564,9 +1514,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-southwest1/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-southwest1%2Foperations%2F${operationID} 200 OK Cache-Control: private diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/create.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/create.yaml index 5a2d0b84c9..19f42508ad 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/create.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/create.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbreadinstance-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/dependencies.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/dependencies.yaml index f2fb81f7cb..f1497fe34b 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/dependencies.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/dependencies.yaml @@ -70,6 +70,8 @@ spec: apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/update.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/update.yaml index 4b1d5e48d2..0e8c60e320 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/update.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/update.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbreadinstance-${uniqueId} spec: clusterRef: diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml index 07bcb87c5a..7e77bd8fe7 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml @@ -2,12 +2,12 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: annotations: + alpha.cnrm.cloud.google.com/reconciler: direct cnrm.cloud.google.com/management-conflict-prevention-policy: none - cnrm.cloud.google.com/state-into-spec: absent finalizers: - cnrm.cloud.google.com/finalizer - cnrm.cloud.google.com/deletion-defender - generation: 2 + generation: 1 labels: cnrm-test: "true" name: alloydbinstance-${uniqueId} @@ -20,7 +20,6 @@ spec: name: alloydbcluster-${uniqueId} machineConfig: cpuCount: 2 - resourceID: alloydbinstance-${uniqueId} status: conditions: - lastTransitionTime: "1970-01-01T00:00:00Z" @@ -29,9 +28,10 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" + externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} - observedGeneration: 2 + observedGeneration: 1 state: READY uid: "12345678" updateTime: "1970-01-01T00:00:00Z" diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_http.log b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_http.log index 8e1e853d39..306587c0c2 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_http.log +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_http.log @@ -765,9 +765,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-central2%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} 404 Not Found Cache-Control: private @@ -790,13 +791,14 @@ X-Xss-Protection: 0 --- -POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances?alt=json&instanceId=alloydbinstance-${uniqueId} +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbinstance-${uniqueId} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-central2%2Fclusters%2Falloydbcluster-${uniqueId} { - "availabilityType": "ZONAL", - "instanceType": "PRIMARY", + "availabilityType": 1, + "instanceType": 1, "labels": { "cnrm-test": "true", "managed-by-cnrm": "true" @@ -832,9 +834,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-central2%2Foperations%2F${operationID} 200 OK Cache-Control: private @@ -908,9 +911,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-central2%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} 200 OK Cache-Control: private @@ -924,15 +928,15 @@ X-Frame-Options: SAMEORIGIN X-Xss-Protection: 0 { - "availabilityType": "ZONAL", + "availabilityType": 1, "clientConnectionConfig": { "sslConfig": { - "sslMode": "ENCRYPTED_ONLY" + "sslMode": 5 } }, "createTime": "2024-04-01T12:34:56.123456Z", "geminiConfig": {}, - "instanceType": "PRIMARY", + "instanceType": 1, "ipAddress": "10.1.2.3", "labels": { "cnrm-test": "true", @@ -960,7 +964,7 @@ X-Xss-Protection: 0 "recordClientAddress": false }, "reconciling": false, - "state": "READY", + "state": 1, "uid": "111111111111111111111", "updateTime": "2024-04-01T12:34:56.123456Z", "writableNode": { @@ -970,9 +974,10 @@ X-Xss-Protection: 0 --- -DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?alt=json +DELETE https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-central2%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} 200 OK Cache-Control: private @@ -1000,9 +1005,10 @@ X-Xss-Protection: 0 --- -GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/operations/${operationID}?alt=json +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-central2/operations/${operationID} Content-Type: application/json -User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-central2%2Foperations%2F${operationID} 200 OK Cache-Control: private diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/create.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/create.yaml index 0289df586d..a2d7a6d379 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/create.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/create.yaml @@ -15,6 +15,8 @@ apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 kind: AlloyDBInstance metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" name: alloydbinstance-${uniqueId} spec: clusterRef: From 0b6b188c9fea70b5834de87d2413e00dc9545c4c Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Tue, 17 Dec 2024 02:35:04 +0000 Subject: [PATCH 5/8] Capitalize acronyms in AlloyDB instance types --- apis/alloydb/v1alpha1/instance_types.go | 8 +-- apis/alloydb/v1alpha1/types.generated.go | 18 +++--- .../alloydb/v1alpha1/zz_generated.deepcopy.go | 58 +++++++++---------- apis/alloydb/v1beta1/instance_types.go | 8 +-- apis/alloydb/v1beta1/types.generated.go | 18 +++--- apis/alloydb/v1beta1/zz_generated.deepcopy.go | 58 +++++++++---------- .../direct/alloydb/instance_controller.go | 18 +++--- .../direct/alloydb/instance_mappings.go | 10 ++-- .../direct/alloydb/mapper.generated.go | 38 ++++++------ 9 files changed, 117 insertions(+), 117 deletions(-) diff --git a/apis/alloydb/v1alpha1/instance_types.go b/apis/alloydb/v1alpha1/instance_types.go index 41a70666fc..90987a7671 100644 --- a/apis/alloydb/v1alpha1/instance_types.go +++ b/apis/alloydb/v1alpha1/instance_types.go @@ -63,7 +63,7 @@ type AlloyDBInstanceSpec struct { // can ONLY be specified for ZONAL instances. If present for a REGIONAL // instance, an error will be thrown. If this is absent for a ZONAL // instance, instance is created in a random zone with available capacity. - GceZone *string `json:"gceZone,omitempty"` + GCEZone *string `json:"gceZone,omitempty"` // We recommend that you use `instanceTypeRef` instead. // The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY] @@ -120,7 +120,7 @@ type AlloyDBInstanceStatus struct { // The IP address for the Instance. This is the connection // endpoint for an end-user application. - IpAddress *string `json:"ipAddress,omitempty"` + IPAddress *string `json:"ipAddress,omitempty"` // The name of the instance resource. Name *string `json:"name,omitempty"` @@ -128,12 +128,12 @@ type AlloyDBInstanceStatus struct { // The outbound public IP addresses for the instance. This is available ONLY when // networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used // for outbound connections. - OutboundPublicIpAddresses []string `json:"outboundPublicIpAddresses,omitempty"` + OutboundPublicIPAddresses []string `json:"outboundPublicIpAddresses,omitempty"` // The public IP addresses for the Instance. This is available // ONLY when networkConfig.enablePublicIp is set to true. This is the // connection endpoint for an end-user application. - PublicIpAddress *string `json:"publicIpAddress,omitempty"` + PublicIPAddress *string `json:"publicIpAddress,omitempty"` // Set to true if the current state of Instance does not // match the user's intended state, and the service is actively updating diff --git a/apis/alloydb/v1alpha1/types.generated.go b/apis/alloydb/v1alpha1/types.generated.go index fac1677e73..d3427afab3 100644 --- a/apis/alloydb/v1alpha1/types.generated.go +++ b/apis/alloydb/v1alpha1/types.generated.go @@ -30,7 +30,7 @@ type Instance_ClientConnectionConfig struct { RequireConnectors *bool `json:"requireConnectors,omitempty"` // Optional. SSL configuration option for this instance. - SslConfig *SslConfig `json:"sslConfig,omitempty"` + SSLConfig *SSLConfig `json:"sslConfig,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig @@ -42,11 +42,11 @@ type Instance_InstanceNetworkConfig struct { // Optional. Enabling public ip for the instance. If a user wishes // to disable this, please also clear the list of the authorized // external networks set on the same instance. - EnablePublicIp *bool `json:"enablePublicIp,omitempty"` + EnablePublicIP *bool `json:"enablePublicIp,omitempty"` // Optional. Enabling an outbound public IP address to support a database // server sending requests out into the internet. - EnableOutboundPublicIp *bool `json:"enableOutboundPublicIp,omitempty"` + EnableOutboundPublicIP *bool `json:"enableOutboundPublicIp,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig.AuthorizedNetwork @@ -58,7 +58,7 @@ type Instance_InstanceNetworkConfig_AuthorizedNetwork struct { // +kcc:proto=google.cloud.alloydb.v1beta.Instance.MachineConfig type Instance_MachineConfig struct { // The number of CPU's in the VM instance. - CpuCount *int32 `json:"cpuCount,omitempty"` + CPUCount *int32 `json:"cpuCount,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.Node @@ -70,7 +70,7 @@ type Instance_Node struct { ID *string `json:"id,omitempty"` // The private IP address of the VM e.g. "10.57.0.34". - Ip *string `json:"ip,omitempty"` + IP *string `json:"ip,omitempty"` // Determined by state of the compute VM and postgres-service health. // Compute VM state can have values listed in @@ -135,7 +135,7 @@ type Instance_PscInstanceConfig struct { // Output only. The DNS name of the instance for PSC connectivity. // Name convention: ...alloydb-psc.goog - PscDnsName *string `json:"pscDnsName,omitempty"` + PSCDNSName *string `json:"pscDnsName,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.QueryInsightsInstanceConfig @@ -171,11 +171,11 @@ type Instance_UpdatePolicy struct { } // +kcc:proto=google.cloud.alloydb.v1beta.SslConfig -type SslConfig struct { +type SSLConfig struct { // Optional. SSL mode. Specifies client-server SSL/TLS connection behavior. - SslMode *string `json:"sslMode,omitempty"` + SSLMode *string `json:"sslMode,omitempty"` // Optional. Certificate Authority (CA) source. Only CA_SOURCE_MANAGED is // supported currently, and is the default value. - CaSource *string `json:"caSource,omitempty"` + CASource *string `json:"caSource,omitempty"` } diff --git a/apis/alloydb/v1alpha1/zz_generated.deepcopy.go b/apis/alloydb/v1alpha1/zz_generated.deepcopy.go index c9fc8953f9..389d7d1c89 100644 --- a/apis/alloydb/v1alpha1/zz_generated.deepcopy.go +++ b/apis/alloydb/v1alpha1/zz_generated.deepcopy.go @@ -120,8 +120,8 @@ func (in *AlloyDBInstanceSpec) DeepCopyInto(out *AlloyDBInstanceSpec) { *out = new(string) **out = **in } - if in.GceZone != nil { - in, out := &in.GceZone, &out.GceZone + if in.GCEZone != nil { + in, out := &in.GCEZone, &out.GCEZone *out = new(string) **out = **in } @@ -185,8 +185,8 @@ func (in *AlloyDBInstanceStatus) DeepCopyInto(out *AlloyDBInstanceStatus) { *out = new(string) **out = **in } - if in.IpAddress != nil { - in, out := &in.IpAddress, &out.IpAddress + if in.IPAddress != nil { + in, out := &in.IPAddress, &out.IPAddress *out = new(string) **out = **in } @@ -195,13 +195,13 @@ func (in *AlloyDBInstanceStatus) DeepCopyInto(out *AlloyDBInstanceStatus) { *out = new(string) **out = **in } - if in.OutboundPublicIpAddresses != nil { - in, out := &in.OutboundPublicIpAddresses, &out.OutboundPublicIpAddresses + if in.OutboundPublicIPAddresses != nil { + in, out := &in.OutboundPublicIPAddresses, &out.OutboundPublicIPAddresses *out = make([]string, len(*in)) copy(*out, *in) } - if in.PublicIpAddress != nil { - in, out := &in.PublicIpAddress, &out.PublicIpAddress + if in.PublicIPAddress != nil { + in, out := &in.PublicIPAddress, &out.PublicIPAddress *out = new(string) **out = **in } @@ -315,9 +315,9 @@ func (in *Instance_ClientConnectionConfig) DeepCopyInto(out *Instance_ClientConn *out = new(bool) **out = **in } - if in.SslConfig != nil { - in, out := &in.SslConfig, &out.SslConfig - *out = new(SslConfig) + if in.SSLConfig != nil { + in, out := &in.SSLConfig, &out.SSLConfig + *out = new(SSLConfig) (*in).DeepCopyInto(*out) } } @@ -342,13 +342,13 @@ func (in *Instance_InstanceNetworkConfig) DeepCopyInto(out *Instance_InstanceNet (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.EnablePublicIp != nil { - in, out := &in.EnablePublicIp, &out.EnablePublicIp + if in.EnablePublicIP != nil { + in, out := &in.EnablePublicIP, &out.EnablePublicIP *out = new(bool) **out = **in } - if in.EnableOutboundPublicIp != nil { - in, out := &in.EnableOutboundPublicIp, &out.EnableOutboundPublicIp + if in.EnableOutboundPublicIP != nil { + in, out := &in.EnableOutboundPublicIP, &out.EnableOutboundPublicIP *out = new(bool) **out = **in } @@ -387,8 +387,8 @@ func (in *Instance_InstanceNetworkConfig_AuthorizedNetwork) DeepCopy() *Instance // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Instance_MachineConfig) DeepCopyInto(out *Instance_MachineConfig) { *out = *in - if in.CpuCount != nil { - in, out := &in.CpuCount, &out.CpuCount + if in.CPUCount != nil { + in, out := &in.CPUCount, &out.CPUCount *out = new(int32) **out = **in } @@ -417,8 +417,8 @@ func (in *Instance_Node) DeepCopyInto(out *Instance_Node) { *out = new(string) **out = **in } - if in.Ip != nil { - in, out := &in.Ip, &out.Ip + if in.IP != nil { + in, out := &in.IP, &out.IP *out = new(string) **out = **in } @@ -512,8 +512,8 @@ func (in *Instance_PscInstanceConfig) DeepCopyInto(out *Instance_PscInstanceConf *out = make([]string, len(*in)) copy(*out, *in) } - if in.PscDnsName != nil { - in, out := &in.PscDnsName, &out.PscDnsName + if in.PSCDNSName != nil { + in, out := &in.PSCDNSName, &out.PSCDNSName *out = new(string) **out = **in } @@ -605,26 +605,26 @@ func (in *Instance_UpdatePolicy) DeepCopy() *Instance_UpdatePolicy { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SslConfig) DeepCopyInto(out *SslConfig) { +func (in *SSLConfig) DeepCopyInto(out *SSLConfig) { *out = *in - if in.SslMode != nil { - in, out := &in.SslMode, &out.SslMode + if in.SSLMode != nil { + in, out := &in.SSLMode, &out.SSLMode *out = new(string) **out = **in } - if in.CaSource != nil { - in, out := &in.CaSource, &out.CaSource + if in.CASource != nil { + in, out := &in.CASource, &out.CASource *out = new(string) **out = **in } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SslConfig. -func (in *SslConfig) DeepCopy() *SslConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSLConfig. +func (in *SSLConfig) DeepCopy() *SSLConfig { if in == nil { return nil } - out := new(SslConfig) + out := new(SSLConfig) in.DeepCopyInto(out) return out } diff --git a/apis/alloydb/v1beta1/instance_types.go b/apis/alloydb/v1beta1/instance_types.go index 2fe8fe57ce..769952ecde 100644 --- a/apis/alloydb/v1beta1/instance_types.go +++ b/apis/alloydb/v1beta1/instance_types.go @@ -63,7 +63,7 @@ type AlloyDBInstanceSpec struct { // can ONLY be specified for ZONAL instances. If present for a REGIONAL // instance, an error will be thrown. If this is absent for a ZONAL // instance, instance is created in a random zone with available capacity. - GceZone *string `json:"gceZone,omitempty"` + GCEZone *string `json:"gceZone,omitempty"` // We recommend that you use `instanceTypeRef` instead. // The type of the instance. Possible values: [PRIMARY, READ_POOL, SECONDARY] @@ -120,7 +120,7 @@ type AlloyDBInstanceStatus struct { // The IP address for the Instance. This is the connection // endpoint for an end-user application. - IpAddress *string `json:"ipAddress,omitempty"` + IPAddress *string `json:"ipAddress,omitempty"` // The name of the instance resource. Name *string `json:"name,omitempty"` @@ -128,12 +128,12 @@ type AlloyDBInstanceStatus struct { // The outbound public IP addresses for the instance. This is available ONLY when // networkConfig.enableOutboundPublicIp is set to true. These IP addresses are used // for outbound connections. - OutboundPublicIpAddresses []string `json:"outboundPublicIpAddresses,omitempty"` + OutboundPublicIPAddresses []string `json:"outboundPublicIpAddresses,omitempty"` // The public IP addresses for the Instance. This is available // ONLY when networkConfig.enablePublicIp is set to true. This is the // connection endpoint for an end-user application. - PublicIpAddress *string `json:"publicIpAddress,omitempty"` + PublicIPAddress *string `json:"publicIpAddress,omitempty"` // Set to true if the current state of Instance does not // match the user's intended state, and the service is actively updating diff --git a/apis/alloydb/v1beta1/types.generated.go b/apis/alloydb/v1beta1/types.generated.go index 2185dbf809..9dc6eb2646 100644 --- a/apis/alloydb/v1beta1/types.generated.go +++ b/apis/alloydb/v1beta1/types.generated.go @@ -30,7 +30,7 @@ type Instance_ClientConnectionConfig struct { RequireConnectors *bool `json:"requireConnectors,omitempty"` // Optional. SSL configuration option for this instance. - SslConfig *SslConfig `json:"sslConfig,omitempty"` + SSLConfig *SSLConfig `json:"sslConfig,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig @@ -42,11 +42,11 @@ type Instance_InstanceNetworkConfig struct { // Optional. Enabling public ip for the instance. If a user wishes // to disable this, please also clear the list of the authorized // external networks set on the same instance. - EnablePublicIp *bool `json:"enablePublicIp,omitempty"` + EnablePublicIP *bool `json:"enablePublicIp,omitempty"` // Optional. Enabling an outbound public IP address to support a database // server sending requests out into the internet. - EnableOutboundPublicIp *bool `json:"enableOutboundPublicIp,omitempty"` + EnableOutboundPublicIP *bool `json:"enableOutboundPublicIp,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.InstanceNetworkConfig.AuthorizedNetwork @@ -58,7 +58,7 @@ type Instance_InstanceNetworkConfig_AuthorizedNetwork struct { // +kcc:proto=google.cloud.alloydb.v1beta.Instance.MachineConfig type Instance_MachineConfig struct { // The number of CPU's in the VM instance. - CpuCount *int32 `json:"cpuCount,omitempty"` + CPUCount *int32 `json:"cpuCount,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.Node @@ -70,7 +70,7 @@ type Instance_Node struct { ID *string `json:"id,omitempty"` // The private IP address of the VM e.g. "10.57.0.34". - Ip *string `json:"ip,omitempty"` + IP *string `json:"ip,omitempty"` // Determined by state of the compute VM and postgres-service health. // Compute VM state can have values listed in @@ -135,7 +135,7 @@ type Instance_PscInstanceConfig struct { // Output only. The DNS name of the instance for PSC connectivity. // Name convention: ...alloydb-psc.goog - PscDnsName *string `json:"pscDnsName,omitempty"` + PSCDNSName *string `json:"pscDnsName,omitempty"` } // +kcc:proto=google.cloud.alloydb.v1beta.Instance.QueryInsightsInstanceConfig @@ -171,11 +171,11 @@ type Instance_UpdatePolicy struct { } // +kcc:proto=google.cloud.alloydb.v1beta.SslConfig -type SslConfig struct { +type SSLConfig struct { // Optional. SSL mode. Specifies client-server SSL/TLS connection behavior. - SslMode *string `json:"sslMode,omitempty"` + SSLMode *string `json:"sslMode,omitempty"` // Optional. Certificate Authority (CA) source. Only CA_SOURCE_MANAGED is // supported currently, and is the default value. - CaSource *string `json:"caSource,omitempty"` + CASource *string `json:"caSource,omitempty"` } diff --git a/apis/alloydb/v1beta1/zz_generated.deepcopy.go b/apis/alloydb/v1beta1/zz_generated.deepcopy.go index 1f5bade33e..f6636fbd17 100644 --- a/apis/alloydb/v1beta1/zz_generated.deepcopy.go +++ b/apis/alloydb/v1beta1/zz_generated.deepcopy.go @@ -120,8 +120,8 @@ func (in *AlloyDBInstanceSpec) DeepCopyInto(out *AlloyDBInstanceSpec) { *out = new(string) **out = **in } - if in.GceZone != nil { - in, out := &in.GceZone, &out.GceZone + if in.GCEZone != nil { + in, out := &in.GCEZone, &out.GCEZone *out = new(string) **out = **in } @@ -185,8 +185,8 @@ func (in *AlloyDBInstanceStatus) DeepCopyInto(out *AlloyDBInstanceStatus) { *out = new(string) **out = **in } - if in.IpAddress != nil { - in, out := &in.IpAddress, &out.IpAddress + if in.IPAddress != nil { + in, out := &in.IPAddress, &out.IPAddress *out = new(string) **out = **in } @@ -195,13 +195,13 @@ func (in *AlloyDBInstanceStatus) DeepCopyInto(out *AlloyDBInstanceStatus) { *out = new(string) **out = **in } - if in.OutboundPublicIpAddresses != nil { - in, out := &in.OutboundPublicIpAddresses, &out.OutboundPublicIpAddresses + if in.OutboundPublicIPAddresses != nil { + in, out := &in.OutboundPublicIPAddresses, &out.OutboundPublicIPAddresses *out = make([]string, len(*in)) copy(*out, *in) } - if in.PublicIpAddress != nil { - in, out := &in.PublicIpAddress, &out.PublicIpAddress + if in.PublicIPAddress != nil { + in, out := &in.PublicIPAddress, &out.PublicIPAddress *out = new(string) **out = **in } @@ -315,9 +315,9 @@ func (in *Instance_ClientConnectionConfig) DeepCopyInto(out *Instance_ClientConn *out = new(bool) **out = **in } - if in.SslConfig != nil { - in, out := &in.SslConfig, &out.SslConfig - *out = new(SslConfig) + if in.SSLConfig != nil { + in, out := &in.SSLConfig, &out.SSLConfig + *out = new(SSLConfig) (*in).DeepCopyInto(*out) } } @@ -342,13 +342,13 @@ func (in *Instance_InstanceNetworkConfig) DeepCopyInto(out *Instance_InstanceNet (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.EnablePublicIp != nil { - in, out := &in.EnablePublicIp, &out.EnablePublicIp + if in.EnablePublicIP != nil { + in, out := &in.EnablePublicIP, &out.EnablePublicIP *out = new(bool) **out = **in } - if in.EnableOutboundPublicIp != nil { - in, out := &in.EnableOutboundPublicIp, &out.EnableOutboundPublicIp + if in.EnableOutboundPublicIP != nil { + in, out := &in.EnableOutboundPublicIP, &out.EnableOutboundPublicIP *out = new(bool) **out = **in } @@ -387,8 +387,8 @@ func (in *Instance_InstanceNetworkConfig_AuthorizedNetwork) DeepCopy() *Instance // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Instance_MachineConfig) DeepCopyInto(out *Instance_MachineConfig) { *out = *in - if in.CpuCount != nil { - in, out := &in.CpuCount, &out.CpuCount + if in.CPUCount != nil { + in, out := &in.CPUCount, &out.CPUCount *out = new(int32) **out = **in } @@ -417,8 +417,8 @@ func (in *Instance_Node) DeepCopyInto(out *Instance_Node) { *out = new(string) **out = **in } - if in.Ip != nil { - in, out := &in.Ip, &out.Ip + if in.IP != nil { + in, out := &in.IP, &out.IP *out = new(string) **out = **in } @@ -512,8 +512,8 @@ func (in *Instance_PscInstanceConfig) DeepCopyInto(out *Instance_PscInstanceConf *out = make([]string, len(*in)) copy(*out, *in) } - if in.PscDnsName != nil { - in, out := &in.PscDnsName, &out.PscDnsName + if in.PSCDNSName != nil { + in, out := &in.PSCDNSName, &out.PSCDNSName *out = new(string) **out = **in } @@ -605,26 +605,26 @@ func (in *Instance_UpdatePolicy) DeepCopy() *Instance_UpdatePolicy { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SslConfig) DeepCopyInto(out *SslConfig) { +func (in *SSLConfig) DeepCopyInto(out *SSLConfig) { *out = *in - if in.SslMode != nil { - in, out := &in.SslMode, &out.SslMode + if in.SSLMode != nil { + in, out := &in.SSLMode, &out.SSLMode *out = new(string) **out = **in } - if in.CaSource != nil { - in, out := &in.CaSource, &out.CaSource + if in.CASource != nil { + in, out := &in.CASource, &out.CASource *out = new(string) **out = **in } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SslConfig. -func (in *SslConfig) DeepCopy() *SslConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SSLConfig. +func (in *SSLConfig) DeepCopy() *SSLConfig { if in == nil { return nil } - out := new(SslConfig) + out := new(SSLConfig) in.DeepCopyInto(out) return out } diff --git a/pkg/controller/direct/alloydb/instance_controller.go b/pkg/controller/direct/alloydb/instance_controller.go index 61597895e8..8ed840cb8e 100644 --- a/pkg/controller/direct/alloydb/instance_controller.go +++ b/pkg/controller/direct/alloydb/instance_controller.go @@ -127,7 +127,7 @@ var _ directbase.Adapter = &instanceAdapter{} // Find retrieves the GCP resource. // Return true means the object is found. This triggers Adapter `Update` call. -// Return true means the object is not found. This triggers Adapter `Create` call. +// Return false means the object is not found. This triggers Adapter `Create` call. // Return a non-nil error requeues the requests. func (a *instanceAdapter) Find(ctx context.Context) (bool, error) { log := klog.FromContext(ctx) @@ -290,8 +290,8 @@ func compareInstance(ctx context.Context, actual, desired *krm.AlloyDBInstanceSp log.V(2).Info("'spec.displayName' field is updated (-old +new)", cmp.Diff(actual.DisplayName, desired.DisplayName)) updatePaths = append(updatePaths, "display_name") } - if desired.GceZone != nil && !reflect.DeepEqual(actual.GceZone, desired.GceZone) { - log.V(2).Info("'spec.gceZone' field is updated (-old +new)", cmp.Diff(actual.GceZone, desired.GceZone)) + if desired.GCEZone != nil && !reflect.DeepEqual(actual.GCEZone, desired.GCEZone) { + log.V(2).Info("'spec.gceZone' field is updated (-old +new)", cmp.Diff(actual.GCEZone, desired.GCEZone)) updatePaths = append(updatePaths, "gce_zone") } if desired.InstanceType != nil && !reflect.DeepEqual(actual.InstanceType, desired.InstanceType) { @@ -300,18 +300,18 @@ func compareInstance(ctx context.Context, actual, desired *krm.AlloyDBInstanceSp } // TODO: Test machineConfig unset and empty struct if desired.MachineConfig != nil { - if desired.MachineConfig.CpuCount != nil && !reflect.DeepEqual(actual.MachineConfig.CpuCount, desired.MachineConfig.CpuCount) { - log.V(2).Info("'spec.machineConfig.cpuCount' field is updated (-old +new)", cmp.Diff(actual.MachineConfig.CpuCount, desired.MachineConfig.CpuCount)) + if desired.MachineConfig.CPUCount != nil && !reflect.DeepEqual(actual.MachineConfig.CPUCount, desired.MachineConfig.CPUCount) { + log.V(2).Info("'spec.machineConfig.cpuCount' field is updated (-old +new)", cmp.Diff(actual.MachineConfig.CPUCount, desired.MachineConfig.CPUCount)) updatePaths = append(updatePaths, "machine_config.cpu_count") } } if desired.NetworkConfig != nil { - if desired.NetworkConfig.EnablePublicIp != nil && !reflect.DeepEqual(actual.NetworkConfig.EnablePublicIp, desired.NetworkConfig.EnablePublicIp) { - log.V(2).Info("'spec.networkConfig.enablePublicIp' field is updated (-old +new)", cmp.Diff(actual.NetworkConfig.EnablePublicIp, desired.NetworkConfig.EnablePublicIp)) + if desired.NetworkConfig.EnablePublicIP != nil && !reflect.DeepEqual(actual.NetworkConfig.EnablePublicIP, desired.NetworkConfig.EnablePublicIP) { + log.V(2).Info("'spec.networkConfig.enablePublicIp' field is updated (-old +new)", cmp.Diff(actual.NetworkConfig.EnablePublicIP, desired.NetworkConfig.EnablePublicIP)) updatePaths = append(updatePaths, "network_config.enable_public_ip") } - if desired.NetworkConfig.EnableOutboundPublicIp != nil && !reflect.DeepEqual(actual.NetworkConfig.EnableOutboundPublicIp, desired.NetworkConfig.EnableOutboundPublicIp) { - log.V(2).Info("'spec.networkConfig.enableOutboundPublicIp' field is updated (-old +new)", cmp.Diff(actual.NetworkConfig.EnableOutboundPublicIp, desired.NetworkConfig.EnableOutboundPublicIp)) + if desired.NetworkConfig.EnableOutboundPublicIP != nil && !reflect.DeepEqual(actual.NetworkConfig.EnableOutboundPublicIP, desired.NetworkConfig.EnableOutboundPublicIP) { + log.V(2).Info("'spec.networkConfig.enableOutboundPublicIp' field is updated (-old +new)", cmp.Diff(actual.NetworkConfig.EnableOutboundPublicIP, desired.NetworkConfig.EnableOutboundPublicIP)) updatePaths = append(updatePaths, "network_config.enable_outbound_public_ip") } if desired.NetworkConfig.AuthorizedExternalNetworks != nil && !reflect.DeepEqual(actual.NetworkConfig.AuthorizedExternalNetworks, desired.NetworkConfig.AuthorizedExternalNetworks) { diff --git a/pkg/controller/direct/alloydb/instance_mappings.go b/pkg/controller/direct/alloydb/instance_mappings.go index fe2087c053..511af83b63 100644 --- a/pkg/controller/direct/alloydb/instance_mappings.go +++ b/pkg/controller/direct/alloydb/instance_mappings.go @@ -30,7 +30,7 @@ func AlloyDBInstanceSpec_FromProto(mapCtx *direct.MapContext, in *pb.Instance) * out.AvailabilityType = direct.Enum_FromProto(mapCtx, in.GetAvailabilityType()) out.DatabaseFlags = in.GetDatabaseFlags() out.DisplayName = direct.LazyPtr(in.GetDisplayName()) - out.GceZone = direct.LazyPtr(in.GetGceZone()) + out.GCEZone = direct.LazyPtr(in.GetGceZone()) out.InstanceType = direct.Enum_FromProto(mapCtx, in.GetInstanceType()) out.MachineConfig = Instance_MachineConfig_FromProto(mapCtx, in.GetMachineConfig()) out.NetworkConfig = Instance_InstanceNetworkConfig_FromProto(mapCtx, in.GetNetworkConfig()) @@ -47,7 +47,7 @@ func AlloyDBInstanceSpec_ToProto(mapCtx *direct.MapContext, in *krm.AlloyDBInsta out.AvailabilityType = direct.Enum_ToProto[pb.Instance_AvailabilityType](mapCtx, in.AvailabilityType) out.DatabaseFlags = in.DatabaseFlags out.DisplayName = direct.ValueOf(in.DisplayName) - out.GceZone = direct.ValueOf(in.GceZone) + out.GceZone = direct.ValueOf(in.GCEZone) out.InstanceType = direct.Enum_ToProto[pb.Instance_InstanceType](mapCtx, in.InstanceType) out.MachineConfig = Instance_MachineConfig_ToProto(mapCtx, in.MachineConfig) out.NetworkConfig = Instance_InstanceNetworkConfig_ToProto(mapCtx, in.NetworkConfig) @@ -61,10 +61,10 @@ func AlloyDBInstanceStatus_FromProto(mapCtx *direct.MapContext, in *pb.Instance) } out := &krm.AlloyDBInstanceStatus{} out.CreateTime = direct.StringTimestamp_FromProto(mapCtx, in.GetCreateTime()) - out.IpAddress = direct.LazyPtr(in.GetIpAddress()) + out.IPAddress = direct.LazyPtr(in.GetIpAddress()) out.Name = direct.LazyPtr(in.GetName()) - out.OutboundPublicIpAddresses = in.GetOutboundPublicIpAddresses() - out.PublicIpAddress = direct.LazyPtr(in.GetPublicIpAddress()) + out.OutboundPublicIPAddresses = in.GetOutboundPublicIpAddresses() + out.PublicIPAddress = direct.LazyPtr(in.GetPublicIpAddress()) out.Reconciling = direct.LazyPtr(in.Reconciling) out.State = direct.Enum_FromProto(mapCtx, in.GetState()) out.Uid = direct.LazyPtr(in.Uid) diff --git a/pkg/controller/direct/alloydb/mapper.generated.go b/pkg/controller/direct/alloydb/mapper.generated.go index 1aaa1efb95..9e6b614763 100644 --- a/pkg/controller/direct/alloydb/mapper.generated.go +++ b/pkg/controller/direct/alloydb/mapper.generated.go @@ -43,7 +43,7 @@ func Instance_ClientConnectionConfig_FromProto(mapCtx *direct.MapContext, in *pb } out := &krm.Instance_ClientConnectionConfig{} out.RequireConnectors = direct.LazyPtr(in.GetRequireConnectors()) - out.SslConfig = SslConfig_FromProto(mapCtx, in.GetSslConfig()) + out.SSLConfig = SslConfig_FromProto(mapCtx, in.GetSslConfig()) return out } func Instance_ClientConnectionConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_ClientConnectionConfig) *pb.Instance_ClientConnectionConfig { @@ -52,7 +52,7 @@ func Instance_ClientConnectionConfig_ToProto(mapCtx *direct.MapContext, in *krm. } out := &pb.Instance_ClientConnectionConfig{} out.RequireConnectors = direct.ValueOf(in.RequireConnectors) - out.SslConfig = SslConfig_ToProto(mapCtx, in.SslConfig) + out.SslConfig = SslConfig_ToProto(mapCtx, in.SSLConfig) return out } func Instance_InstanceNetworkConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_InstanceNetworkConfig) *krm.Instance_InstanceNetworkConfig { @@ -61,8 +61,8 @@ func Instance_InstanceNetworkConfig_FromProto(mapCtx *direct.MapContext, in *pb. } out := &krm.Instance_InstanceNetworkConfig{} out.AuthorizedExternalNetworks = direct.Slice_FromProto(mapCtx, in.AuthorizedExternalNetworks, Instance_InstanceNetworkConfig_AuthorizedNetwork_FromProto) - out.EnablePublicIp = direct.LazyPtr(in.GetEnablePublicIp()) - out.EnableOutboundPublicIp = direct.LazyPtr(in.GetEnableOutboundPublicIp()) + out.EnablePublicIP = direct.LazyPtr(in.GetEnablePublicIp()) + out.EnableOutboundPublicIP = direct.LazyPtr(in.GetEnableOutboundPublicIp()) return out } func Instance_InstanceNetworkConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_InstanceNetworkConfig) *pb.Instance_InstanceNetworkConfig { @@ -71,8 +71,8 @@ func Instance_InstanceNetworkConfig_ToProto(mapCtx *direct.MapContext, in *krm.I } out := &pb.Instance_InstanceNetworkConfig{} out.AuthorizedExternalNetworks = direct.Slice_ToProto(mapCtx, in.AuthorizedExternalNetworks, Instance_InstanceNetworkConfig_AuthorizedNetwork_ToProto) - out.EnablePublicIp = direct.ValueOf(in.EnablePublicIp) - out.EnableOutboundPublicIp = direct.ValueOf(in.EnableOutboundPublicIp) + out.EnablePublicIp = direct.ValueOf(in.EnablePublicIP) + out.EnableOutboundPublicIp = direct.ValueOf(in.EnableOutboundPublicIP) return out } func Instance_InstanceNetworkConfig_AuthorizedNetwork_FromProto(mapCtx *direct.MapContext, in *pb.Instance_InstanceNetworkConfig_AuthorizedNetwork) *krm.Instance_InstanceNetworkConfig_AuthorizedNetwork { @@ -96,7 +96,7 @@ func Instance_MachineConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance return nil } out := &krm.Instance_MachineConfig{} - out.CpuCount = direct.LazyPtr(in.GetCpuCount()) + out.CPUCount = direct.LazyPtr(in.GetCpuCount()) return out } func Instance_MachineConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_MachineConfig) *pb.Instance_MachineConfig { @@ -104,7 +104,7 @@ func Instance_MachineConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_ return nil } out := &pb.Instance_MachineConfig{} - out.CpuCount = direct.ValueOf(in.CpuCount) + out.CpuCount = direct.ValueOf(in.CPUCount) return out } func Instance_Node_FromProto(mapCtx *direct.MapContext, in *pb.Instance_Node) *krm.Instance_Node { @@ -114,7 +114,7 @@ func Instance_Node_FromProto(mapCtx *direct.MapContext, in *pb.Instance_Node) *k out := &krm.Instance_Node{} out.ZoneID = direct.LazyPtr(in.GetZoneId()) out.ID = direct.LazyPtr(in.GetId()) - out.Ip = direct.LazyPtr(in.GetIp()) + out.IP = direct.LazyPtr(in.GetIp()) out.State = direct.LazyPtr(in.GetState()) return out } @@ -125,7 +125,7 @@ func Instance_Node_ToProto(mapCtx *direct.MapContext, in *krm.Instance_Node) *pb out := &pb.Instance_Node{} out.ZoneId = direct.ValueOf(in.ZoneID) out.Id = direct.ValueOf(in.ID) - out.Ip = direct.ValueOf(in.Ip) + out.Ip = direct.ValueOf(in.IP) out.State = direct.ValueOf(in.State) return out } @@ -168,7 +168,7 @@ func Instance_PscInstanceConfig_FromProto(mapCtx *direct.MapContext, in *pb.Inst out := &krm.Instance_PscInstanceConfig{} out.ServiceAttachmentLink = direct.LazyPtr(in.GetServiceAttachmentLink()) out.AllowedConsumerProjects = in.AllowedConsumerProjects - out.PscDnsName = direct.LazyPtr(in.GetPscDnsName()) + out.PSCDNSName = direct.LazyPtr(in.GetPscDnsName()) return out } func Instance_PscInstanceConfig_ToProto(mapCtx *direct.MapContext, in *krm.Instance_PscInstanceConfig) *pb.Instance_PscInstanceConfig { @@ -178,7 +178,7 @@ func Instance_PscInstanceConfig_ToProto(mapCtx *direct.MapContext, in *krm.Insta out := &pb.Instance_PscInstanceConfig{} out.ServiceAttachmentLink = direct.ValueOf(in.ServiceAttachmentLink) out.AllowedConsumerProjects = in.AllowedConsumerProjects - out.PscDnsName = direct.ValueOf(in.PscDnsName) + out.PscDnsName = direct.ValueOf(in.PSCDNSName) return out } func Instance_QueryInsightsInstanceConfig_FromProto(mapCtx *direct.MapContext, in *pb.Instance_QueryInsightsInstanceConfig) *krm.Instance_QueryInsightsInstanceConfig { @@ -235,21 +235,21 @@ func Instance_UpdatePolicy_ToProto(mapCtx *direct.MapContext, in *krm.Instance_U out.Mode = direct.Enum_ToProto[pb.Instance_UpdatePolicy_Mode](mapCtx, in.Mode) return out } -func SslConfig_FromProto(mapCtx *direct.MapContext, in *pb.SslConfig) *krm.SslConfig { +func SslConfig_FromProto(mapCtx *direct.MapContext, in *pb.SslConfig) *krm.SSLConfig { if in == nil { return nil } - out := &krm.SslConfig{} - out.SslMode = direct.Enum_FromProto(mapCtx, in.GetSslMode()) - out.CaSource = direct.Enum_FromProto(mapCtx, in.GetCaSource()) + out := &krm.SSLConfig{} + out.SSLMode = direct.Enum_FromProto(mapCtx, in.GetSslMode()) + out.CASource = direct.Enum_FromProto(mapCtx, in.GetCaSource()) return out } -func SslConfig_ToProto(mapCtx *direct.MapContext, in *krm.SslConfig) *pb.SslConfig { +func SslConfig_ToProto(mapCtx *direct.MapContext, in *krm.SSLConfig) *pb.SslConfig { if in == nil { return nil } out := &pb.SslConfig{} - out.SslMode = direct.Enum_ToProto[pb.SslConfig_SslMode](mapCtx, in.SslMode) - out.CaSource = direct.Enum_ToProto[pb.SslConfig_CaSource](mapCtx, in.CaSource) + out.SslMode = direct.Enum_ToProto[pb.SslConfig_SslMode](mapCtx, in.SSLMode) + out.CaSource = direct.Enum_ToProto[pb.SslConfig_CaSource](mapCtx, in.CASource) return out } From 59e4167952260e0abf828436d6e4248f5c0f9be1 Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Thu, 19 Dec 2024 02:46:51 +0000 Subject: [PATCH 6/8] Address comments --- apis/alloydb/v1alpha1/instance_identity.go | 21 --------- apis/alloydb/v1alpha1/instance_reference.go | 21 +++++++++ apis/alloydb/v1alpha1/instance_types.go | 1 - apis/alloydb/v1beta1/instance_identity.go | 21 --------- apis/alloydb/v1beta1/instance_reference.go | 21 +++++++++ apis/alloydb/v1beta1/instance_types.go | 1 - ...stances.alloydb.cnrm.cloud.google.com.yaml | 6 --- .../direct/alloydb/instance_controller.go | 45 ++++++++++++------- 8 files changed, 72 insertions(+), 65 deletions(-) diff --git a/apis/alloydb/v1alpha1/instance_identity.go b/apis/alloydb/v1alpha1/instance_identity.go index 16542ff1ec..b0613fc4b3 100644 --- a/apis/alloydb/v1alpha1/instance_identity.go +++ b/apis/alloydb/v1alpha1/instance_identity.go @@ -17,7 +17,6 @@ package v1alpha1 import ( "context" "fmt" - "strings" "github.com/GoogleCloudPlatform/k8s-config-connector/apis/common" refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" @@ -101,23 +100,3 @@ func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDB id: resourceID, }, nil } - -func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { - if !strings.HasPrefix(externalRef, serviceDomain) { - return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) - } - path := strings.TrimPrefix(externalRef, serviceDomain+"/") - return ParseInstanceExternal(path) -} - -func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { - tokens := strings.Split(external, "/") - if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { - return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) - } - parent = &InstanceParent{ - clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), - } - resourceID = tokens[7] - return parent, resourceID, nil -} diff --git a/apis/alloydb/v1alpha1/instance_reference.go b/apis/alloydb/v1alpha1/instance_reference.go index e2b6055c6b..b07f519c40 100644 --- a/apis/alloydb/v1alpha1/instance_reference.go +++ b/apis/alloydb/v1alpha1/instance_reference.go @@ -17,6 +17,7 @@ package v1alpha1 import ( "context" "fmt" + "strings" refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s" @@ -81,3 +82,23 @@ func (r *InstanceRef) NormalizedExternal(ctx context.Context, reader client.Read r.External = actualExternalRef return r.External, nil } + +func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { + if !strings.HasPrefix(externalRef, serviceDomain) { + return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) + } + path := strings.TrimPrefix(externalRef, serviceDomain+"/") + return ParseInstanceExternal(path) +} + +func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { + tokens := strings.Split(external, "/") + if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { + return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) + } + parent = &InstanceParent{ + clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), + } + resourceID = tokens[7] + return parent, resourceID, nil +} diff --git a/apis/alloydb/v1alpha1/instance_types.go b/apis/alloydb/v1alpha1/instance_types.go index 90987a7671..8f4c5c5daf 100644 --- a/apis/alloydb/v1alpha1/instance_types.go +++ b/apis/alloydb/v1alpha1/instance_types.go @@ -30,7 +30,6 @@ type AlloyDBInstanceSpec struct { // +required ClusterRef *refs.AlloyDBClusterRef `json:"clusterRef,omitempty"` - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ResourceID field is immutable" // Immutable. // Optional. The instanceId of the resource. If not given, the metadata.name will be used. ResourceID *string `json:"resourceID,omitempty"` diff --git a/apis/alloydb/v1beta1/instance_identity.go b/apis/alloydb/v1beta1/instance_identity.go index 9ee7c11a1a..20bae0d996 100644 --- a/apis/alloydb/v1beta1/instance_identity.go +++ b/apis/alloydb/v1beta1/instance_identity.go @@ -17,7 +17,6 @@ package v1beta1 import ( "context" "fmt" - "strings" "github.com/GoogleCloudPlatform/k8s-config-connector/apis/common" refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" @@ -101,23 +100,3 @@ func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDB id: resourceID, }, nil } - -func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { - if !strings.HasPrefix(externalRef, serviceDomain) { - return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) - } - path := strings.TrimPrefix(externalRef, serviceDomain+"/") - return ParseInstanceExternal(path) -} - -func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { - tokens := strings.Split(external, "/") - if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { - return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) - } - parent = &InstanceParent{ - clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), - } - resourceID = tokens[7] - return parent, resourceID, nil -} diff --git a/apis/alloydb/v1beta1/instance_reference.go b/apis/alloydb/v1beta1/instance_reference.go index 0518e62537..af24e27d1f 100644 --- a/apis/alloydb/v1beta1/instance_reference.go +++ b/apis/alloydb/v1beta1/instance_reference.go @@ -17,6 +17,7 @@ package v1beta1 import ( "context" "fmt" + "strings" refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/k8s" @@ -81,3 +82,23 @@ func (r *InstanceRef) NormalizedExternal(ctx context.Context, reader client.Read r.External = actualExternalRef return r.External, nil } + +func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { + if !strings.HasPrefix(externalRef, serviceDomain) { + return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) + } + path := strings.TrimPrefix(externalRef, serviceDomain+"/") + return ParseInstanceExternal(path) +} + +func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { + tokens := strings.Split(external, "/") + if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { + return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) + } + parent = &InstanceParent{ + clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), + } + resourceID = tokens[7] + return parent, resourceID, nil +} diff --git a/apis/alloydb/v1beta1/instance_types.go b/apis/alloydb/v1beta1/instance_types.go index 769952ecde..9d20b47bd9 100644 --- a/apis/alloydb/v1beta1/instance_types.go +++ b/apis/alloydb/v1beta1/instance_types.go @@ -30,7 +30,6 @@ type AlloyDBInstanceSpec struct { // +required ClusterRef *refs.AlloyDBClusterRef `json:"clusterRef,omitempty"` - // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ResourceID field is immutable" // Immutable. // Optional. The instanceId of the resource. If not given, the metadata.name will be used. ResourceID *string `json:"resourceID,omitempty"` diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml index 72edcbdce0..bf78746d31 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml @@ -222,9 +222,6 @@ spec: description: Immutable. Optional. The instanceId of the resource. If not given, the metadata.name will be used. type: string - x-kubernetes-validations: - - message: ResourceID field is immutable - rule: self == oldSelf required: - clusterRef type: object @@ -512,9 +509,6 @@ spec: description: Immutable. Optional. The instanceId of the resource. If not given, the metadata.name will be used. type: string - x-kubernetes-validations: - - message: ResourceID field is immutable - rule: self == oldSelf required: - clusterRef type: object diff --git a/pkg/controller/direct/alloydb/instance_controller.go b/pkg/controller/direct/alloydb/instance_controller.go index 8ed840cb8e..5717cfcb79 100644 --- a/pkg/controller/direct/alloydb/instance_controller.go +++ b/pkg/controller/direct/alloydb/instance_controller.go @@ -64,40 +64,44 @@ func (m *instanceModel) client(ctx context.Context) (*gcp.AlloyDBAdminClient, er return gcpClient, err } -func (m *instanceModel) AdapterForObject(ctx context.Context, reader client.Reader, u *unstructured.Unstructured) (directbase.Adapter, error) { - obj := &krm.AlloyDBInstance{} - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &obj); err != nil { - return nil, fmt.Errorf("error converting to %T: %w", obj, err) - } - - id, err := krm.NewInstanceIdentity(ctx, reader, obj) - if err != nil { - return nil, err - } - +func validateRequiredFields(ctx context.Context, reader client.Reader, obj *krm.AlloyDBInstance) error { if obj.Spec.InstanceType != nil && obj.Spec.InstanceTypeRef != nil { - return nil, fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + + return fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + "and 'spec.InstanceType' should be configured: both are configured") } if obj.Spec.InstanceType == nil && obj.Spec.InstanceTypeRef == nil { - return nil, fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + + return fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + "and 'spec.InstanceType' should be configured: neither is configured") } var instanceType *string if obj.Spec.InstanceType != nil { if *instanceType == "" { - return nil, fmt.Errorf("'spec.InstanceType' should be configured with a non-empty string") + return fmt.Errorf("'spec.InstanceType' should be configured with a non-empty string") } instanceType = obj.Spec.InstanceType } if obj.Spec.InstanceTypeRef != nil { + var err error instanceType, err = refsv1beta1.ResolveAlloyDBClusterType(ctx, reader, obj, obj.Spec.InstanceTypeRef) if err != nil { - return nil, fmt.Errorf("cannot resolve `spec.InstanceTypeRef`: %w", err) + return fmt.Errorf("cannot resolve `spec.InstanceTypeRef`: %w", err) } } obj.Spec.InstanceType = instanceType + return nil +} + +func (m *instanceModel) AdapterForObject(ctx context.Context, reader client.Reader, u *unstructured.Unstructured) (directbase.Adapter, error) { + obj := &krm.AlloyDBInstance{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &obj); err != nil { + return nil, fmt.Errorf("error converting to %T: %w", obj, err) + } + + id, err := krm.NewInstanceIdentity(ctx, reader, obj) + if err != nil { + return nil, err + } // Get alloydb GCP client gcpClient, err := m.client(ctx) @@ -107,6 +111,7 @@ func (m *instanceModel) AdapterForObject(ctx context.Context, reader client.Read return &instanceAdapter{ id: id, gcpClient: gcpClient, + reader: reader, desired: obj, }, nil } @@ -119,6 +124,7 @@ func (m *instanceModel) AdapterForURL(ctx context.Context, url string) (directba type instanceAdapter struct { id *krm.InstanceIdentity gcpClient *gcp.AlloyDBAdminClient + reader client.Reader desired *krm.AlloyDBInstance actual *alloydbpb.Instance } @@ -154,6 +160,10 @@ func (a *instanceAdapter) Create(ctx context.Context, createOp *directbase.Creat log.V(2).Info("creating instance", "name", a.id) mapCtx := &direct.MapContext{} + if err := validateRequiredFields(ctx, a.reader, a.desired); err != nil { + return err + } + desired := a.desired.DeepCopy() resource := AlloyDBInstanceSpec_ToProto(mapCtx, &desired.Spec) if mapCtx.Err() != nil { @@ -217,11 +227,16 @@ func (a *instanceAdapter) Update(ctx context.Context, updateOp *directbase.Updat log.V(2).Info("updating instance", "name", a.id) mapCtx := &direct.MapContext{} + if err := validateRequiredFields(ctx, a.reader, a.desired); err != nil { + return err + } + parsedActual := AlloyDBInstanceSpec_FromProto(mapCtx, a.actual) if mapCtx.Err() != nil { return mapCtx.Err() } + // TODO: Change to CompareProtoMessage once we support all the files in the instance pb. updatePaths, err := compareInstance(ctx, parsedActual, &a.desired.Spec) if err != nil { return err From 7c7cc3909a23bbbc5750da350c61d2cd0f72c2d4 Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Thu, 19 Dec 2024 03:43:28 +0000 Subject: [PATCH 7/8] Support no change test to verify the diffing behavior in Update() --- .../direct/alloydb/instance_controller.go | 3 + .../basic_primary_no_change/_http00.log | 154 +++++++++ .../basic_primary_no_change/_http01.log | 322 ++++++++++++++++++ .../basic_primary_no_change/_http02.log | 240 +++++++++++++ .../basic_primary_no_change/_http03.log | 171 ++++++++++ .../basic_primary_no_change/_http04.log | 135 ++++++++ .../basic_primary_no_change/_http05.log | 60 ++++ .../basic_primary_no_change/_object00.yaml | 25 ++ .../basic_primary_no_change/_object01.yaml | 52 +++ .../basic_primary_no_change/_object02.yaml | 34 ++ .../basic_primary_no_change/_object03.yaml | 28 ++ .../basic_primary_no_change/_object04.yaml | 33 ++ .../basic_primary_no_change/_object05.yaml | 34 ++ .../basic_primary_no_change/script.yaml | 91 +++++ 14 files changed, 1382 insertions(+) create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http00.log create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http01.log create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http02.log create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http03.log create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http04.log create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http05.log create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object00.yaml create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object01.yaml create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object02.yaml create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object03.yaml create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object04.yaml create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object05.yaml create mode 100644 tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/script.yaml diff --git a/pkg/controller/direct/alloydb/instance_controller.go b/pkg/controller/direct/alloydb/instance_controller.go index 5717cfcb79..e2447ae3de 100644 --- a/pkg/controller/direct/alloydb/instance_controller.go +++ b/pkg/controller/direct/alloydb/instance_controller.go @@ -242,6 +242,9 @@ func (a *instanceAdapter) Update(ctx context.Context, updateOp *directbase.Updat return err } desiredLabels := a.desired.GetObjectMeta().GetLabels() + if desiredLabels == nil { + desiredLabels = make(map[string]string) + } desiredLabels["managed-by-cnrm"] = "true" if !reflect.DeepEqual(a.actual.GetLabels(), desiredLabels) { log.V(2).Info("'metadata.labels' field is updated (-old +new)", cmp.Diff(a.actual.GetLabels(), desiredLabels)) diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http00.log b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http00.log new file mode 100644 index 0000000000..0628a15b6d --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http00.log @@ -0,0 +1,154 @@ +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?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 + +404 Not Found +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 + +{ + "error": { + "code": 404, + "errors": [ + { + "domain": "global", + "message": "The resource 'projects/${projectId}/global/networks/computenetwork-${uniqueId}' was not found", + "reason": "notFound" + } + ], + "message": "The resource 'projects/${projectId}/global/networks/computenetwork-${uniqueId}' was not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks?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 + +{ + "autoCreateSubnetworks": false, + "name": "computenetwork-${uniqueId}", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL" +} + +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 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "insert", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "1734579095060432657", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/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", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "insert", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "1734579095060432657", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?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 + +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 + +{ + "autoCreateSubnetworks": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#network", + "name": "computenetwork-${uniqueId}", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/1734579095060432657" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?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 + +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 + +{ + "autoCreateSubnetworks": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#network", + "name": "computenetwork-${uniqueId}", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/1734579095060432657" +} \ No newline at end of file diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http01.log b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http01.log new file mode 100644 index 0000000000..ad58baea5a --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http01.log @@ -0,0 +1,322 @@ +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${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 + +404 Not Found +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 + +{ + "error": { + "code": 404, + "message": "Resource 'projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}' was not found", + "status": "NOT_FOUND" + } +} + +--- + +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters?alt=json&clusterId=alloydbcluster-${uniqueId} +Content-Type: application/json +User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager + +{ + "clusterType": "PRIMARY", + "initialUser": { + "password": "alloydb-pg" + }, + "labels": { + "managed-by-cnrm": "true" + }, + "networkConfig": { + "network": "projects/${projectId}/global/networks/computenetwork-${uniqueId}" + } +} + +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 + +{ + "metadata": { + "@type": "type.googleapis.com/google.cloud.alloydb.v1beta.OperationMetadata", + "apiVersion": "v1beta", + "createTime": "2024-04-01T12:34:56.123456Z", + "target": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}", + "verb": "create" + }, + "name": "projects/${projectId}/locations/europe-west1/operations/${operationID}" +} + +--- + +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID}?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 + +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 + +{ + "done": true, + "metadata": { + "@type": "type.googleapis.com/google.cloud.alloydb.v1beta.OperationMetadata", + "apiVersion": "v1beta", + "createTime": "2024-04-01T12:34:56.123456Z", + "endTime": "2024-04-01T12:34:56.123456Z", + "target": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}", + "verb": "create" + }, + "name": "projects/${projectId}/locations/europe-west1/operations/${operationID}", + "response": { + "@type": "type.googleapis.com/google.cloud.alloydb.v1beta.Cluster", + "automatedBackupPolicy": { + "backupWindow": "3600s", + "enabled": false, + "location": "europe-west1", + "timeBasedRetention": { + "retentionPeriod": "1209600s" + }, + "weeklySchedule": { + "daysOfWeek": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ], + "startTimes": [ + { + "hours": 23 + } + ] + } + }, + "clusterType": "PRIMARY", + "continuousBackupConfig": { + "enabled": true, + "recoveryWindowDays": 14 + }, + "continuousBackupInfo": { + "enabledTime": "2024-12-19T03:31:35.520038851Z", + "encryptionInfo": { + "encryptionType": "GOOGLE_DEFAULT_ENCRYPTION" + }, + "schedule": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ] + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseVersion": "POSTGRES_15", + "encryptionInfo": { + "encryptionType": "GOOGLE_DEFAULT_ENCRYPTION" + }, + "geminiConfig": {}, + "labels": { + "managed-by-cnrm": "true" + }, + "name": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}", + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}", + "networkConfig": { + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}" + }, + "state": "READY", + "subscriptionType": "STANDARD", + "uid": "111111111111111111111", + "updateTime": "2024-04-01T12:34:56.123456Z" + } +} + +--- + +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${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 + +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 + +{ + "automatedBackupPolicy": { + "backupWindow": "3600s", + "enabled": false, + "location": "europe-west1", + "timeBasedRetention": { + "retentionPeriod": "1209600s" + }, + "weeklySchedule": { + "daysOfWeek": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ], + "startTimes": [ + { + "hours": 23 + } + ] + } + }, + "clusterType": "PRIMARY", + "continuousBackupConfig": { + "enabled": true, + "recoveryWindowDays": 14 + }, + "continuousBackupInfo": { + "enabledTime": "2024-12-19T03:31:35.520038851Z", + "encryptionInfo": { + "encryptionType": "GOOGLE_DEFAULT_ENCRYPTION" + }, + "schedule": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ] + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseVersion": "POSTGRES_15", + "encryptionInfo": { + "encryptionType": "GOOGLE_DEFAULT_ENCRYPTION" + }, + "geminiConfig": {}, + "labels": { + "managed-by-cnrm": "true" + }, + "name": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}", + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}", + "networkConfig": { + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}" + }, + "state": "READY", + "subscriptionType": "STANDARD", + "uid": "111111111111111111111", + "updateTime": "2024-04-01T12:34:56.123456Z" +} + +--- + +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${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 + +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 + +{ + "automatedBackupPolicy": { + "backupWindow": "3600s", + "enabled": false, + "location": "europe-west1", + "timeBasedRetention": { + "retentionPeriod": "1209600s" + }, + "weeklySchedule": { + "daysOfWeek": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ], + "startTimes": [ + { + "hours": 23 + } + ] + } + }, + "clusterType": "PRIMARY", + "continuousBackupConfig": { + "enabled": true, + "recoveryWindowDays": 14 + }, + "continuousBackupInfo": { + "enabledTime": "2024-12-19T03:31:35.520038851Z", + "encryptionInfo": { + "encryptionType": "GOOGLE_DEFAULT_ENCRYPTION" + }, + "schedule": [ + "MONDAY", + "TUESDAY", + "WEDNESDAY", + "THURSDAY", + "FRIDAY", + "SATURDAY", + "SUNDAY" + ] + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "databaseVersion": "POSTGRES_15", + "encryptionInfo": { + "encryptionType": "GOOGLE_DEFAULT_ENCRYPTION" + }, + "geminiConfig": {}, + "labels": { + "managed-by-cnrm": "true" + }, + "name": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}", + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}", + "networkConfig": { + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}" + }, + "state": "READY", + "subscriptionType": "STANDARD", + "uid": "111111111111111111111", + "updateTime": "2024-04-01T12:34:56.123456Z" +} \ No newline at end of file diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http02.log b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http02.log new file mode 100644 index 0000000000..2c7175fb5d --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http02.log @@ -0,0 +1,240 @@ +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${addressID}?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 + +404 Not Found +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 + +{ + "error": { + "code": 404, + "errors": [ + { + "domain": "global", + "message": "The resource 'projects/${projectId}/global/addresses/computeaddress-${uniqueId}' was not found", + "reason": "notFound" + } + ], + "message": "The resource 'projects/${projectId}/global/addresses/computeaddress-${uniqueId}' was not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses?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 + +{ + "addressType": "INTERNAL", + "labels": { + "managed-by-cnrm": "true" + }, + "name": "computeaddress-${uniqueId}", + "network": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "prefixLength": 16, + "purpose": "VPC_PEERING" +} + +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 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "insert", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "1734579096533117230", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/computeaddress-${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/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", + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "operationType": "insert", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "1734579096533117230", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/computeaddress-${uniqueId}", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${addressID}?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 + +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 + +{ + "address": "8.8.8.8", + "addressType": "INTERNAL", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#address", + "labelFingerprint": "mH6+UXFFMQ+75UV0AxzLuQ==", + "labels": { + "managed-by-cnrm": "true" + }, + "name": "computeaddress-${uniqueId}", + "network": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "prefixLength": 16, + "purpose": "VPC_PEERING", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/computeaddress-${uniqueId}" +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${addressID}/setLabels?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 + +{ + "labelFingerprint": "mH6+UXFFMQ+75UV0AxzLuQ==", + "labels": { + "managed-by-cnrm": "true" + } +} + +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 + +{ + "id": "000000000000000000000", + "insertTime": "2024-04-01T12:34:56.123456Z", + "kind": "compute#operation", + "name": "${operationID}", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${addressID}?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 + +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 + +{ + "address": "8.8.8.8", + "addressType": "INTERNAL", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#address", + "labelFingerprint": "mH6+UXFFMQ+75UV0AxzLuQ==", + "labels": { + "managed-by-cnrm": "true" + }, + "name": "computeaddress-${uniqueId}", + "network": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "prefixLength": 16, + "purpose": "VPC_PEERING", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/computeaddress-${uniqueId}" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/addresses/${addressID}?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 + +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 + +{ + "address": "8.8.8.8", + "addressType": "INTERNAL", + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "id": "000000000000000000000", + "kind": "compute#address", + "labelFingerprint": "mH6+UXFFMQ+75UV0AxzLuQ==", + "labels": { + "managed-by-cnrm": "true" + }, + "name": "computeaddress-${uniqueId}", + "network": "projects/${projectId}/global/networks/computenetwork-${uniqueId}", + "prefixLength": 16, + "purpose": "VPC_PEERING", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/computeaddress-${uniqueId}" +} \ No newline at end of file diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http03.log b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http03.log new file mode 100644 index 0000000000..4c170c75a4 --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http03.log @@ -0,0 +1,171 @@ +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 + +{} + +--- + +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}" +} + +--- + +PATCH https://servicenetworking.googleapis.com/v1/services/servicenetworking.googleapis.com/connections/-?alt=json&force=true&prettyPrint=false&updateMask=reservedPeeringRanges +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 + +{ + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}", + "reservedPeeringRanges": [ + "computeaddress-${uniqueId}" + ] +} + +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 + +{ + "name": "operations/${operationID}" +} + +--- + +GET https://servicenetworking.googleapis.com/v1/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 + +{ + "done": true, + "name": "operations/${operationID}", + "response": { + "@type": "type.googleapis.com/google.cloud.servicenetworking.v1.Connection", + "network": "projects/${projectNumber}/global/networks/computenetwork-${uniqueId}", + "peering": "servicenetworking-googleapis-com", + "reservedPeeringRanges": [ + "computeaddress-${uniqueId}" + ], + "service": "services/servicenetworking.googleapis.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 + +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" + } + ] +} \ No newline at end of file diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http04.log b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http04.log new file mode 100644 index 0000000000..cea435b38a --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http04.log @@ -0,0 +1,135 @@ +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} + +404 Not Found +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 + +{ + "error": { + "code": 404, + "message": "Resource 'projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}' was not found", + "status": "NOT_FOUND" + } +} + +--- + +POST https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances?%24alt=json%3Benum-encoding%3Dint&instanceId=alloydbinstance-${uniqueId} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: parent=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId} + +{ + "instanceType": 1, + "labels": { + "managed-by-cnrm": "true" + } +} + +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 + +{ + "metadata": { + "@type": "type.googleapis.com/google.cloud.alloydb.v1beta.OperationMetadata", + "apiVersion": "v1beta", + "createTime": "2024-04-01T12:34:56.123456Z", + "target": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}", + "verb": "create" + }, + "name": "projects/${projectId}/locations/europe-west1/operations/${operationID}" +} + +--- + +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/operations/${operationID} +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Foperations%2F${operationID} + +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 + +{ + "done": true, + "metadata": { + "@type": "type.googleapis.com/google.cloud.alloydb.v1beta.OperationMetadata", + "apiVersion": "v1beta", + "createTime": "2024-04-01T12:34:56.123456Z", + "endTime": "2024-04-01T12:34:56.123456Z", + "target": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}", + "verb": "create" + }, + "name": "projects/${projectId}/locations/europe-west1/operations/${operationID}", + "response": { + "@type": "type.googleapis.com/google.cloud.alloydb.v1beta.Instance", + "availabilityType": "REGIONAL", + "clientConnectionConfig": { + "sslConfig": { + "sslMode": "ENCRYPTED_ONLY" + } + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "geminiConfig": {}, + "instanceType": "PRIMARY", + "ipAddress": "10.1.2.3", + "labels": { + "managed-by-cnrm": "true" + }, + "name": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}", + "nodes": [ + { + "zoneId": "europe-west1-c" + } + ], + "observabilityConfig": { + "enabled": false, + "maxQueryStringLength": 10240, + "preserveComments": false, + "queryPlansPerMinute": 20, + "recordApplicationTags": false, + "trackActiveQueries": false, + "trackClientAddress": false, + "trackWaitEventTypes": true, + "trackWaitEvents": true + }, + "queryInsightsConfig": { + "queryPlansPerMinute": 5, + "queryStringLength": 1024, + "recordApplicationTags": false, + "recordClientAddress": false + }, + "state": "READY", + "uid": "12345678", + "updateTime": "2024-04-01T12:34:56.123456Z", + "writableNode": { + "zoneId": "europe-west1-b" + } + } +} \ No newline at end of file diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http05.log b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http05.log new file mode 100644 index 0000000000..d529d7a600 --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_http05.log @@ -0,0 +1,60 @@ +GET https://alloydb.googleapis.com/v1beta/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}?%24alt=json%3Benum-encoding%3Dint +Content-Type: application/json +User-Agent: kcc/controller-manager +x-goog-request-params: name=projects%2F${projectId}%2Flocations%2Feurope-west1%2Fclusters%2Falloydbcluster-${uniqueId}%2Finstances%2Falloydbinstance-${uniqueId} + +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 + +{ + "availabilityType": 2, + "clientConnectionConfig": { + "sslConfig": { + "sslMode": 5 + } + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "geminiConfig": {}, + "instanceType": 1, + "ipAddress": "10.1.2.3", + "labels": { + "managed-by-cnrm": "true" + }, + "name": "projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId}", + "nodes": [ + { + "zoneId": "europe-west1-c" + } + ], + "observabilityConfig": { + "enabled": false, + "maxQueryStringLength": 10240, + "preserveComments": false, + "queryPlansPerMinute": 20, + "recordApplicationTags": false, + "trackActiveQueries": false, + "trackClientAddress": false, + "trackWaitEventTypes": true, + "trackWaitEvents": true + }, + "queryInsightsConfig": { + "queryPlansPerMinute": 5, + "queryStringLength": 1024, + "recordApplicationTags": false, + "recordClientAddress": false + }, + "state": 1, + "uid": "12345678", + "updateTime": "2024-04-01T12:34:56.123456Z", + "writableNode": { + "zoneId": "europe-west1-b" + } +} \ No newline at end of file diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object00.yaml b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object00.yaml new file mode 100644 index 0000000000..ba69a2257c --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object00.yaml @@ -0,0 +1,25 @@ +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeNetwork +metadata: + annotations: + cnrm.cloud.google.com/management-conflict-prevention-policy: none + 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: 2 + name: computenetwork-${uniqueId} + namespace: ${projectId} +spec: + autoCreateSubnetworks: false + resourceID: computenetwork-${uniqueId} +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + observedGeneration: 2 + selfLink: https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId} diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object01.yaml b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object01.yaml new file mode 100644 index 0000000000..3d6aa745f2 --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object01.yaml @@ -0,0 +1,52 @@ +apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 +kind: AlloyDBCluster +metadata: + annotations: + cnrm.cloud.google.com/management-conflict-prevention-policy: none + 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: 2 + name: alloydbcluster-${uniqueId} + namespace: ${projectId} +spec: + initialUser: + password: + value: alloydb-pg + location: europe-west1 + networkConfig: + networkRef: + name: computenetwork-${uniqueId} + projectRef: + external: ${projectId} + resourceID: alloydbcluster-${uniqueId} +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + continuousBackupInfo: + - enabledTime: "1970-01-01T00:00:00Z" + encryptionInfo: + - encryptionType: GOOGLE_DEFAULT_ENCRYPTION + schedule: + - MONDAY + - TUESDAY + - WEDNESDAY + - THURSDAY + - FRIDAY + - SATURDAY + - SUNDAY + databaseVersion: POSTGRES_15 + encryptionInfo: + - encryptionType: GOOGLE_DEFAULT_ENCRYPTION + name: projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId} + observedGeneration: 2 + observedState: + clusterType: PRIMARY + uid: "12345678" diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object02.yaml b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object02.yaml new file mode 100644 index 0000000000..858afd4f1b --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object02.yaml @@ -0,0 +1,34 @@ +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeAddress +metadata: + annotations: + cnrm.cloud.google.com/management-conflict-prevention-policy: none + 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: 2 + name: computeaddress-${uniqueId} + namespace: ${projectId} +spec: + addressType: INTERNAL + location: global + networkRef: + name: computenetwork-${uniqueId} + prefixLength: 16 + purpose: VPC_PEERING + resourceID: computeaddress-${uniqueId} +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + creationTimestamp: "1970-01-01T00:00:00Z" + labelFingerprint: abcdef0123A= + observedGeneration: 2 + observedState: + address: 8.8.8.8 + selfLink: https://www.googleapis.com/compute/v1/projects/${projectId}/global/addresses/computeaddress-${uniqueId} diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object03.yaml b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object03.yaml new file mode 100644 index 0000000000..302eaffe7a --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object03.yaml @@ -0,0 +1,28 @@ +apiVersion: servicenetworking.cnrm.cloud.google.com/v1beta1 +kind: ServiceNetworkingConnection +metadata: + annotations: + cnrm.cloud.google.com/management-conflict-prevention-policy: none + 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: 1 + name: servicenetworkingconnection-${uniqueId} + namespace: ${projectId} +spec: + networkRef: + name: computenetwork-${uniqueId} + reservedPeeringRanges: + - name: computeaddress-${uniqueId} + service: servicenetworking.googleapis.com +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + observedGeneration: 1 + peering: servicenetworking-googleapis-com diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object04.yaml b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object04.yaml new file mode 100644 index 0000000000..afad75cbec --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object04.yaml @@ -0,0 +1,33 @@ +apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 +kind: AlloyDBInstance +metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: direct + cnrm.cloud.google.com/management-conflict-prevention-policy: none + cnrm.cloud.google.com/project-id: ${projectId} + finalizers: + - cnrm.cloud.google.com/finalizer + - cnrm.cloud.google.com/deletion-defender + generation: 1 + name: alloydbinstance-${uniqueId} + namespace: ${projectId} +spec: + clusterRef: + name: alloydbcluster-${uniqueId} + instanceTypeRef: + name: alloydbcluster-${uniqueId} +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + createTime: "1970-01-01T00:00:00Z" + externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} + ipAddress: 10.1.2.3 + name: projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} + observedGeneration: 1 + state: READY + uid: "12345678" + updateTime: "1970-01-01T00:00:00Z" diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object05.yaml b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object05.yaml new file mode 100644 index 0000000000..5e2bad0691 --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/_object05.yaml @@ -0,0 +1,34 @@ +apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 +kind: AlloyDBInstance +metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: direct + cnrm.cloud.google.com/management-conflict-prevention-policy: none + cnrm.cloud.google.com/project-id: ${projectId} + finalizers: + - cnrm.cloud.google.com/finalizer + - cnrm.cloud.google.com/deletion-defender + generation: 2 + name: alloydbinstance-${uniqueId} + namespace: ${projectId} +spec: + clusterRef: + name: alloydbcluster-${uniqueId} + instanceTypeRef: + name: alloydbcluster-${uniqueId} + resourceID: alloydbinstance-${uniqueId} +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + createTime: "1970-01-01T00:00:00Z" + externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} + ipAddress: 10.1.2.3 + name: projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} + observedGeneration: 2 + state: READY + uid: "12345678" + updateTime: "1970-01-01T00:00:00Z" diff --git a/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/script.yaml b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/script.yaml new file mode 100644 index 0000000000..9fbe973dc2 --- /dev/null +++ b/tests/e2e/testdata/scenarios/alloydbinstance/basic_primary_no_change/script.yaml @@ -0,0 +1,91 @@ +# 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. + +# 00 +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeNetwork +metadata: + name: computenetwork-${uniqueId} +spec: + autoCreateSubnetworks: false +--- +# 01 +apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 +kind: AlloyDBCluster +metadata: + name: alloydbcluster-${uniqueId} +spec: + initialUser: + password: + value: alloydb-pg + location: europe-west1 + networkConfig: + networkRef: + name: computenetwork-${uniqueId} + projectRef: + external: ${projectId} +--- +# 02 +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeAddress +metadata: + name: computeaddress-${uniqueId} +spec: + location: global + addressType: INTERNAL + networkRef: + name: computenetwork-${uniqueId} + prefixLength: 16 + purpose: VPC_PEERING +--- +# 03 +apiVersion: servicenetworking.cnrm.cloud.google.com/v1beta1 +kind: ServiceNetworkingConnection +metadata: + name: servicenetworkingconnection-${uniqueId} +spec: + networkRef: + name: computenetwork-${uniqueId} + reservedPeeringRanges: + - name: computeaddress-${uniqueId} + service: servicenetworking.googleapis.com +--- +# 04 +apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 +kind: AlloyDBInstance +metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" + name: alloydbinstance-${uniqueId} +spec: + clusterRef: + name: alloydbcluster-${uniqueId} + instanceTypeRef: + name: alloydbcluster-${uniqueId} +--- +# 05: Trigger the reconciliation with no change because this step just sets +# `spec.resourceID`. +# _http05.log should not contain a PATCH request. +apiVersion: alloydb.cnrm.cloud.google.com/v1beta1 +kind: AlloyDBInstance +metadata: + annotations: + alpha.cnrm.cloud.google.com/reconciler: "direct" + name: alloydbinstance-${uniqueId} +spec: + clusterRef: + name: alloydbcluster-${uniqueId} + instanceTypeRef: + name: alloydbcluster-${uniqueId} + resourceID: alloydbinstance-${uniqueId} From e33dba7bff0b6d7bbbcda342b808a6d1cb70cbc7 Mon Sep 17 00:00:00 2001 From: Joyce Ma Date: Thu, 19 Dec 2024 08:51:56 +0000 Subject: [PATCH 8/8] Address further comments --- apis/alloydb/v1alpha1/instance_identity.go | 27 ++-- apis/alloydb/v1alpha1/instance_reference.go | 12 +- apis/alloydb/v1alpha1/instance_types.go | 2 - apis/alloydb/v1beta1/instance_identity.go | 27 ++-- apis/alloydb/v1beta1/instance_reference.go | 12 +- apis/alloydb/v1beta1/instance_types.go | 2 - apis/common/utils.go | 8 + apis/refs/v1beta1/alloydbref.go | 141 ++---------------- apis/refs/v1beta1/helper.go | 8 - ...stances.alloydb.cnrm.cloud.google.com.yaml | 8 +- .../direct/alloydb/instance_controller.go | 44 ++++-- ...ed_object_basicalloydbinstance.golden.yaml | 2 +- ..._basicsecondaryalloydbinstance.golden.yaml | 2 +- ...ted_object_fullalloydbinstance.golden.yaml | 2 +- ...ted_object_readalloydbinstance.golden.yaml | 2 +- ...ed_object_zonalalloydbinstance.golden.yaml | 2 +- .../resource-docs/alloydb/alloydbinstance.md | 2 +- 17 files changed, 95 insertions(+), 208 deletions(-) diff --git a/apis/alloydb/v1alpha1/instance_identity.go b/apis/alloydb/v1alpha1/instance_identity.go index b0613fc4b3..44dfb55475 100644 --- a/apis/alloydb/v1alpha1/instance_identity.go +++ b/apis/alloydb/v1alpha1/instance_identity.go @@ -24,10 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -const serviceDomain = "//alloydb.googleapis.com" - -// InstanceIdentity defines the resource reference to AlloyDBInstance, which "External" field -// holds the GCP identifier for the KRM object. +// InstanceIdentity defines the resource reference to AlloyDBInstance. type InstanceIdentity struct { parent *InstanceParent id string @@ -45,18 +42,14 @@ func (i *InstanceIdentity) Parent() *InstanceParent { return i.parent } -// AsExternalRef builds a externalRef from a PrivilegedAccessManagerEntitlement. -func (i *InstanceIdentity) AsExternalRef() *string { - er := serviceDomain + "/" + i.String() - return &er -} - type InstanceParent struct { - clusterName string + projectID string + location string + clusterID string } func (p *InstanceParent) String() string { - return p.clusterName + return "projects/" + p.projectID + "/locations/" + p.location + "/clusters/" + p.clusterID } // New builds a InstanceIdentity from the Config Connector Instance object. @@ -81,12 +74,12 @@ func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDB externalRef := common.ValueOf(obj.Status.ExternalRef) if externalRef != "" { // Validate desired with actual - actualParent, actualResourceID, err := ParseInstanceExternalRef(externalRef) + actualParent, actualResourceID, err := ParseInstanceExternal(externalRef) if err != nil { return nil, err } - if actualParent.clusterName != clusterRef.String() { - return nil, fmt.Errorf("spec.clusterRef changed, expect %s, got %s", actualParent.clusterName, clusterRef) + if actualParent.String() != clusterRef.String() { + return nil, fmt.Errorf("spec.clusterRef changed, expect %s, got %s", actualParent.String(), clusterRef) } if actualResourceID != resourceID { return nil, fmt.Errorf("cannot reset `metadata.name` or `spec.resourceID` to %s, since it has already assigned to %s", @@ -95,7 +88,9 @@ func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDB } return &InstanceIdentity{ parent: &InstanceParent{ - clusterName: clusterRef.String(), + projectID: clusterRef.ProjectID, + location: clusterRef.Location, + clusterID: clusterRef.ClusterID, }, id: resourceID, }, nil diff --git a/apis/alloydb/v1alpha1/instance_reference.go b/apis/alloydb/v1alpha1/instance_reference.go index b07f519c40..291dc1dfb5 100644 --- a/apis/alloydb/v1alpha1/instance_reference.go +++ b/apis/alloydb/v1alpha1/instance_reference.go @@ -83,21 +83,15 @@ func (r *InstanceRef) NormalizedExternal(ctx context.Context, reader client.Read return r.External, nil } -func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { - if !strings.HasPrefix(externalRef, serviceDomain) { - return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) - } - path := strings.TrimPrefix(externalRef, serviceDomain+"/") - return ParseInstanceExternal(path) -} - func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { tokens := strings.Split(external, "/") if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) } parent = &InstanceParent{ - clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), + projectID: tokens[1], + location: tokens[3], + clusterID: tokens[5], } resourceID = tokens[7] return parent, resourceID, nil diff --git a/apis/alloydb/v1alpha1/instance_types.go b/apis/alloydb/v1alpha1/instance_types.go index 8f4c5c5daf..b49b436f2e 100644 --- a/apis/alloydb/v1alpha1/instance_types.go +++ b/apis/alloydb/v1alpha1/instance_types.go @@ -30,7 +30,6 @@ type AlloyDBInstanceSpec struct { // +required ClusterRef *refs.AlloyDBClusterRef `json:"clusterRef,omitempty"` - // Immutable. // Optional. The instanceId of the resource. If not given, the metadata.name will be used. ResourceID *string `json:"resourceID,omitempty"` @@ -160,7 +159,6 @@ type AlloyDBInstanceObservedState struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// TODO(user): make sure the pluralizaiton below is correct // +kubebuilder:resource:categories=gcp,shortName=gcpalloydbinstance;gcpalloydbinstances // +kubebuilder:subresource:status // +kubebuilder:metadata:labels="cnrm.cloud.google.com/tf2crd=true";"cnrm.cloud.google.com/managed-by-kcc=true";"cnrm.cloud.google.com/stability-level=stable";"cnrm.cloud.google.com/system=true" diff --git a/apis/alloydb/v1beta1/instance_identity.go b/apis/alloydb/v1beta1/instance_identity.go index 20bae0d996..b5ee7221a7 100644 --- a/apis/alloydb/v1beta1/instance_identity.go +++ b/apis/alloydb/v1beta1/instance_identity.go @@ -24,10 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -const serviceDomain = "//alloydb.googleapis.com" - -// InstanceIdentity defines the resource reference to AlloyDBInstance, which "External" field -// holds the GCP identifier for the KRM object. +// InstanceIdentity defines the resource reference to AlloyDBInstance. type InstanceIdentity struct { parent *InstanceParent id string @@ -45,18 +42,14 @@ func (i *InstanceIdentity) Parent() *InstanceParent { return i.parent } -// AsExternalRef builds a externalRef from a PrivilegedAccessManagerEntitlement. -func (i *InstanceIdentity) AsExternalRef() *string { - er := serviceDomain + "/" + i.String() - return &er -} - type InstanceParent struct { - clusterName string + projectID string + location string + clusterID string } func (p *InstanceParent) String() string { - return p.clusterName + return "projects/" + p.projectID + "/locations/" + p.location + "/clusters/" + p.clusterID } // New builds a InstanceIdentity from the Config Connector Instance object. @@ -81,12 +74,12 @@ func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDB externalRef := common.ValueOf(obj.Status.ExternalRef) if externalRef != "" { // Validate desired with actual - actualParent, actualResourceID, err := ParseInstanceExternalRef(externalRef) + actualParent, actualResourceID, err := ParseInstanceExternal(externalRef) if err != nil { return nil, err } - if actualParent.clusterName != clusterRef.String() { - return nil, fmt.Errorf("spec.clusterRef changed, expect %s, got %s", actualParent.clusterName, clusterRef) + if actualParent.String() != clusterRef.String() { + return nil, fmt.Errorf("spec.clusterRef changed, expect %s, got %s", actualParent.String(), clusterRef) } if actualResourceID != resourceID { return nil, fmt.Errorf("cannot reset `metadata.name` or `spec.resourceID` to %s, since it has already assigned to %s", @@ -95,7 +88,9 @@ func NewInstanceIdentity(ctx context.Context, reader client.Reader, obj *AlloyDB } return &InstanceIdentity{ parent: &InstanceParent{ - clusterName: clusterRef.String(), + projectID: clusterRef.ProjectID, + location: clusterRef.Location, + clusterID: clusterRef.ClusterID, }, id: resourceID, }, nil diff --git a/apis/alloydb/v1beta1/instance_reference.go b/apis/alloydb/v1beta1/instance_reference.go index af24e27d1f..19c032120c 100644 --- a/apis/alloydb/v1beta1/instance_reference.go +++ b/apis/alloydb/v1beta1/instance_reference.go @@ -83,21 +83,15 @@ func (r *InstanceRef) NormalizedExternal(ctx context.Context, reader client.Read return r.External, nil } -func ParseInstanceExternalRef(externalRef string) (parent *InstanceParent, resourceID string, err error) { - if !strings.HasPrefix(externalRef, serviceDomain) { - return nil, "", fmt.Errorf("externalRef should have prefix %s, got %s", serviceDomain, externalRef) - } - path := strings.TrimPrefix(externalRef, serviceDomain+"/") - return ParseInstanceExternal(path) -} - func ParseInstanceExternal(external string) (parent *InstanceParent, resourceID string, err error) { tokens := strings.Split(external, "/") if len(tokens) != 8 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" || tokens[6] != "instances" { return nil, "", fmt.Errorf("format of AlloyDBInstance external=%q was not known (use projects//locations//clusters//instances/)", external) } parent = &InstanceParent{ - clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), + projectID: tokens[1], + location: tokens[3], + clusterID: tokens[5], } resourceID = tokens[7] return parent, resourceID, nil diff --git a/apis/alloydb/v1beta1/instance_types.go b/apis/alloydb/v1beta1/instance_types.go index 9d20b47bd9..3694a50ab7 100644 --- a/apis/alloydb/v1beta1/instance_types.go +++ b/apis/alloydb/v1beta1/instance_types.go @@ -30,7 +30,6 @@ type AlloyDBInstanceSpec struct { // +required ClusterRef *refs.AlloyDBClusterRef `json:"clusterRef,omitempty"` - // Immutable. // Optional. The instanceId of the resource. If not given, the metadata.name will be used. ResourceID *string `json:"resourceID,omitempty"` @@ -160,7 +159,6 @@ type AlloyDBInstanceObservedState struct { // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// TODO(user): make sure the pluralizaiton below is correct // +kubebuilder:resource:categories=gcp,shortName=gcpalloydbinstance;gcpalloydbinstances // +kubebuilder:subresource:status // +kubebuilder:metadata:labels="cnrm.cloud.google.com/tf2crd=true";"cnrm.cloud.google.com/managed-by-kcc=true";"cnrm.cloud.google.com/stability-level=stable";"cnrm.cloud.google.com/system=true" diff --git a/apis/common/utils.go b/apis/common/utils.go index 13e60763d0..295c13eb58 100644 --- a/apis/common/utils.go +++ b/apis/common/utils.go @@ -21,3 +21,11 @@ func ValueOf[T any](t *T) T { } return *t } + +func LazyPtr[V comparable](v V) *V { + var defaultV V + if v == defaultV { + return nil + } + return &v +} diff --git a/apis/refs/v1beta1/alloydbref.go b/apis/refs/v1beta1/alloydbref.go index 5f58ac7677..6afa4bd169 100644 --- a/apis/refs/v1beta1/alloydbref.go +++ b/apis/refs/v1beta1/alloydbref.go @@ -19,6 +19,8 @@ import ( "fmt" "strings" + "github.com/GoogleCloudPlatform/k8s-config-connector/apis/common" + apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -36,11 +38,12 @@ type AlloyDBClusterRef struct { } type AlloyDBCluster struct { - projectID string - location string - clusterID string + ProjectID string + Location string + ClusterID string } +// TODO: Remove after AlloyDBCluster is migrated to direct controller. func ResolveAlloyDBCluster(ctx context.Context, reader client.Reader, src client.Object, ref *AlloyDBClusterRef) (*AlloyDBCluster, error) { if ref == nil { return nil, nil @@ -59,9 +62,9 @@ func ResolveAlloyDBCluster(ctx context.Context, reader client.Reader, src client tokens := strings.Split(ref.External, "/") if len(tokens) == 6 && tokens[0] == "projects" && tokens[2] == "locations" && tokens[4] == "clusters" { return &AlloyDBCluster{ - projectID: tokens[1], - location: tokens[3], - clusterID: tokens[5], + ProjectID: tokens[1], + Location: tokens[3], + ClusterID: tokens[5], }, nil } return nil, fmt.Errorf("format of AlloyDBClusterRef external=%q was not known (use projects/[projectId]/locations/[location]/clusters/[clusterId])", ref.External) @@ -101,9 +104,9 @@ func ResolveAlloyDBCluster(ctx context.Context, reader client.Reader, src client return nil, err } return &AlloyDBCluster{ - projectID: projectID, - location: location, - clusterID: clusterID, + ProjectID: projectID, + Location: location, + ClusterID: clusterID, }, nil } @@ -130,7 +133,7 @@ func ResolveAlloyDBClusterType(ctx context.Context, reader client.Reader, src cl // External is provided. if ref.External != "" { - return lazyPtr(ref.External), nil + return common.LazyPtr(ref.External), nil } // Fetch AlloyDBCluster object to construct the external form. @@ -161,123 +164,9 @@ func ResolveAlloyDBClusterType(ctx context.Context, reader client.Reader, src cl // clusterType is defaulted to "PRIMARY" when not set. clusterType = "PRIMARY" } - return lazyPtr(clusterType), nil -} - -func ResolveAlloyDBClusterName(ctx context.Context, reader client.Reader, obj *unstructured.Unstructured) (string, error) { - clusterRefExternal, _, _ := unstructured.NestedString(obj.Object, "spec", "clusterRef", "external") - if clusterRefExternal != "" { - clusterRef := AlloyDBClusterRef{ - External: clusterRefExternal, - } - - cluster, err := ResolveAlloyDBCluster(ctx, reader, obj, &clusterRef) - if err != nil { - return "", fmt.Errorf("cannot parse clusterRef.external %q in %v %v/%v: %w", clusterRefExternal, obj.GetKind(), obj.GetNamespace(), obj.GetName(), err) - } - return cluster.String(), nil - } - - clusterRefName, _, _ := unstructured.NestedString(obj.Object, "spec", "clusterRef", "name") - if clusterRefName != "" { - clusterRefNamespace, _, _ := unstructured.NestedString(obj.Object, "spec", "clusterRef", "namespace") - - clusterRef := AlloyDBClusterRef{ - Name: clusterRefName, - Namespace: clusterRefNamespace, - } - if clusterRef.Namespace == "" { - clusterRef.Namespace = obj.GetNamespace() - } - - cluster, err := ResolveAlloyDBCluster(ctx, reader, obj, &clusterRef) - if err != nil { - return "", fmt.Errorf("cannot parse clusterRef in %v %v/%v: %w", obj.GetKind(), obj.GetNamespace(), obj.GetName(), err) - } - return cluster.String(), nil - } - - return "", fmt.Errorf("cannot find AlloyDB cluster name for %v %v/%v", obj.GetKind(), obj.GetNamespace(), obj.GetName()) + return common.LazyPtr(clusterType), nil } func (c *AlloyDBCluster) String() string { - return fmt.Sprintf("projects/%s/locations/%s/clusters/%s", c.projectID, c.location, c.clusterID) -} - -type AlloyDBInstanceRef struct { - // If provided must be in the format `projects/[projectId]/locations/[location]/clusters/[clusterId]/instances/[instanceId]`. - External string `json:"external,omitempty"` - // The `metadata.name` field of a `AlloyDBInstance` resource. - Name string `json:"name,omitempty"` - // The `metadata.namespace` field of a `AlloyDBInstance` resource. - Namespace string `json:"namespace,omitempty"` -} - -type AlloyDBInstance struct { - clusterName string - instanceID string -} - -func ResolveAlloyDBInstance(ctx context.Context, reader client.Reader, src client.Object, ref *AlloyDBInstanceRef) (*AlloyDBInstance, error) { - if ref == nil { - return nil, nil - } - - if ref.Name == "" && ref.External == "" { - return nil, fmt.Errorf("must specify either name or external on AlloyDBInstanceRef") - } - if ref.Name != "" && ref.External != "" { - return nil, fmt.Errorf("cannot specify both name and external on AlloyDBInstanceRef") - } - - // External is provided. - if ref.External != "" { - // External should be in the `projects/[projectId]/locations/[location]/clusters/[clusterId]/instances/[instanceId]` format. - tokens := strings.Split(ref.External, "/") - if len(tokens) == 6 && tokens[0] == "projects" && tokens[2] == "locations" && tokens[4] == "clusters" && tokens[6] == "instances" { - return &AlloyDBInstance{ - clusterName: fmt.Sprintf("%s/%s/%s/%s/%s/%s", tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]), - instanceID: tokens[7], - }, nil - } - return nil, fmt.Errorf("format of AlloyDBInstanceRef external=%q was not known (use projects/[projectId]/locations/[location]/clusters/[clusterId]/instances/[instanceId])", ref.External) - - } - - // Fetch AlloyDBInstance object to construct the external form. - instance := &unstructured.Unstructured{} - instance.SetGroupVersionKind(schema.GroupVersionKind{ - Group: "alloydb.cnrm.cloud.google.com", - Version: "v1beta1", - Kind: "AlloyDBInstance", - }) - nn := types.NamespacedName{ - Namespace: ref.Namespace, - Name: ref.Name, - } - if nn.Namespace == "" { - nn.Namespace = src.GetNamespace() - } - if err := reader.Get(ctx, nn, instance); err != nil { - if apierrors.IsNotFound(err) { - return nil, fmt.Errorf("referenced AlloyDBInstance %v not found", nn) - } - return nil, fmt.Errorf("error reading referenced AlloyDBInstance %v: %w", nn, err) - } - clusterName, err := ResolveAlloyDBClusterName(ctx, reader, instance) - if err != nil { - return nil, err - } - instanceID, err := GetResourceID(instance) - if err != nil { - return nil, err - } - return &AlloyDBInstance{ - clusterName: clusterName, - instanceID: instanceID, - }, nil -} - -func (i *AlloyDBInstance) String() string { - return fmt.Sprintf("%s/instances/%s", i.clusterName, i.instanceID) + return fmt.Sprintf("projects/%s/locations/%s/clusters/%s", c.ProjectID, c.Location, c.ClusterID) } diff --git a/apis/refs/v1beta1/helper.go b/apis/refs/v1beta1/helper.go index 0d0b81b732..df6733442b 100644 --- a/apis/refs/v1beta1/helper.go +++ b/apis/refs/v1beta1/helper.go @@ -41,11 +41,3 @@ func GetLocation(u *unstructured.Unstructured) (string, error) { } return location, nil } - -func lazyPtr[V comparable](v V) *V { - var defaultV V - if v == defaultV { - return nil - } - return &v -} diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml index bf78746d31..75c95e1f6b 100644 --- a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_alloydbinstances.alloydb.cnrm.cloud.google.com.yaml @@ -219,8 +219,8 @@ spec: type: integer type: object resourceID: - description: Immutable. Optional. The instanceId of the resource. - If not given, the metadata.name will be used. + description: Optional. The instanceId of the resource. If not given, + the metadata.name will be used. type: string required: - clusterRef @@ -506,8 +506,8 @@ spec: type: integer type: object resourceID: - description: Immutable. Optional. The instanceId of the resource. - If not given, the metadata.name will be used. + description: Optional. The instanceId of the resource. If not given, + the metadata.name will be used. type: string required: - clusterRef diff --git a/pkg/controller/direct/alloydb/instance_controller.go b/pkg/controller/direct/alloydb/instance_controller.go index e2447ae3de..fc7d60d409 100644 --- a/pkg/controller/direct/alloydb/instance_controller.go +++ b/pkg/controller/direct/alloydb/instance_controller.go @@ -64,11 +64,7 @@ func (m *instanceModel) client(ctx context.Context) (*gcp.AlloyDBAdminClient, er return gcpClient, err } -func validateRequiredFields(ctx context.Context, reader client.Reader, obj *krm.AlloyDBInstance) error { - if obj.Spec.InstanceType != nil && obj.Spec.InstanceTypeRef != nil { - return fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + - "and 'spec.InstanceType' should be configured: both are configured") - } +func resolveInstanceType(ctx context.Context, reader client.Reader, obj *krm.AlloyDBInstance, isDeletion bool) error { if obj.Spec.InstanceType == nil && obj.Spec.InstanceTypeRef == nil { return fmt.Errorf("one and only one of 'spec.InstanceTypeRef' " + "and 'spec.InstanceType' should be configured: neither is configured") @@ -76,16 +72,26 @@ func validateRequiredFields(ctx context.Context, reader client.Reader, obj *krm. var instanceType *string if obj.Spec.InstanceType != nil { + instanceType = obj.Spec.InstanceType if *instanceType == "" { return fmt.Errorf("'spec.InstanceType' should be configured with a non-empty string") } - instanceType = obj.Spec.InstanceType } if obj.Spec.InstanceTypeRef != nil { + plainTextInstanceType := instanceType var err error instanceType, err = refsv1beta1.ResolveAlloyDBClusterType(ctx, reader, obj, obj.Spec.InstanceTypeRef) if err != nil { - return fmt.Errorf("cannot resolve `spec.InstanceTypeRef`: %w", err) + if !isDeletion { + // TODO: Read instance type from observed state because it's necessary during deletion. + return fmt.Errorf("cannot resolve `spec.InstanceTypeRef`: %w", err) + } + } + if plainTextInstanceType != nil && *plainTextInstanceType != *instanceType { + return fmt.Errorf("'spec.InstanceTypeRef' and 'spec.InstanceType' "+ + "resolve into different values: spec.InstanceTypeRef resolves to "+ + "instanceType %q, spec.InstanceType is %q: they must be the same", + *instanceType, *plainTextInstanceType) } } obj.Spec.InstanceType = instanceType @@ -160,7 +166,7 @@ func (a *instanceAdapter) Create(ctx context.Context, createOp *directbase.Creat log.V(2).Info("creating instance", "name", a.id) mapCtx := &direct.MapContext{} - if err := validateRequiredFields(ctx, a.reader, a.desired); err != nil { + if err := resolveInstanceType(ctx, a.reader, a.desired, false); err != nil { return err } @@ -217,7 +223,7 @@ func (a *instanceAdapter) Create(ctx context.Context, createOp *directbase.Creat if mapCtx.Err() != nil { return mapCtx.Err() } - status.ExternalRef = a.id.AsExternalRef() + status.ExternalRef = direct.LazyPtr(a.id.String()) return createOp.UpdateStatus(ctx, status, nil) } @@ -227,7 +233,7 @@ func (a *instanceAdapter) Update(ctx context.Context, updateOp *directbase.Updat log.V(2).Info("updating instance", "name", a.id) mapCtx := &direct.MapContext{} - if err := validateRequiredFields(ctx, a.reader, a.desired); err != nil { + if err := resolveInstanceType(ctx, a.reader, a.desired, false); err != nil { return err } @@ -253,6 +259,14 @@ func (a *instanceAdapter) Update(ctx context.Context, updateOp *directbase.Updat if len(updatePaths) == 0 { log.V(2).Info("no field needs update", "name", a.id) + if *a.desired.Status.ExternalRef == "" { + // If it is the first reconciliation after switching to direct controller, + // then update Status to fill out the ExternalRef even if there is + // no update. + status := a.desired.Status + status.ExternalRef = direct.LazyPtr(a.id.String()) + return updateOp.UpdateStatus(ctx, status, nil) + } return nil } updateMask := &fieldmaskpb.FieldMask{ @@ -278,6 +292,11 @@ func (a *instanceAdapter) Update(ctx context.Context, updateOp *directbase.Updat log.V(2).Info("successfully updated instance", "name", a.id) status := AlloyDBInstanceStatus_FromProto(mapCtx, updated) + if *a.desired.Status.ExternalRef == "" { + // If it is the first reconciliation after switching to direct controller, + // then fill out the ExternalRef. + status.ExternalRef = direct.LazyPtr(a.id.String()) + } if mapCtx.Err() != nil { return mapCtx.Err() } @@ -377,6 +396,11 @@ func (a *instanceAdapter) Delete(ctx context.Context, deleteOp *directbase.Delet log := klog.FromContext(ctx) log.V(2).Info("deleting instance", "name", a.id) + // instanceType must be resolved before calling DELETE. + if err := resolveInstanceType(ctx, a.reader, a.desired, true); err != nil { + return false, err + } + // Returning true directly if it is to delete a secondary instance. // Technically the secondary instance is only abandoned but not deleted. // This is because deletion of secondary instance is not supported. Instead, diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml index 2be4d71488..c705fe9f55 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicalloydbinstance/_generated_object_basicalloydbinstance.golden.yaml @@ -30,7 +30,7 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" - externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} + externalRef: projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-west1/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} observedGeneration: 2 diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml index 76483d572d..4e77bf6d4f 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/basicsecondaryalloydbinstance/_generated_object_basicsecondaryalloydbinstance.golden.yaml @@ -30,7 +30,7 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" - externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId} + externalRef: projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-west2/clusters/alloydbcluster-2-${uniqueId}/instances/alloydbinstance-2-${uniqueId} observedGeneration: 2 diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml index 9f324e9ede..509ee51e29 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/fullalloydbinstance/_generated_object_fullalloydbinstance.golden.yaml @@ -35,7 +35,7 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" - externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId} + externalRef: projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-north1/clusters/alloydbcluster${uniqueId}/instances/alloydbinstance${uniqueId} observedGeneration: 2 diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml index 66b3dd5bc2..7dfa2a97ae 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/readalloydbinstance/_generated_object_readalloydbinstance.golden.yaml @@ -30,7 +30,7 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" - externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId} + externalRef: projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-southwest1/clusters/alloydbcluster${uniqueId}/instances/alloydbreadinstance${uniqueId} observedGeneration: 2 diff --git a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml index 7e77bd8fe7..68d9d461e1 100644 --- a/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml +++ b/pkg/test/resourcefixture/testdata/basic/alloydb/v1beta1/alloydbinstance/zonalalloydbinstance/_generated_object_zonalalloydbinstance.golden.yaml @@ -28,7 +28,7 @@ status: status: "True" type: Ready createTime: "1970-01-01T00:00:00Z" - externalRef: //alloydb.googleapis.com/projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} + externalRef: projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} ipAddress: 10.1.2.3 name: projects/${projectId}/locations/europe-central2/clusters/alloydbcluster-${uniqueId}/instances/alloydbinstance-${uniqueId} observedGeneration: 1 diff --git a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md index f2bb9bac9d..4c46f1d94f 100644 --- a/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md +++ b/scripts/generate-google3-docs/resource-reference/generated/resource-docs/alloydb/alloydbinstance.md @@ -368,7 +368,7 @@ Use deletionPolicy = "FORCE" in the associated secondary cluster and delete the

string

-

{% verbatim %}Immutable. Optional. The instanceId of the resource. If not given, the metadata.name will be used.{% endverbatim %}

+

{% verbatim %}Optional. The instanceId of the resource. If not given, the metadata.name will be used.{% endverbatim %}