From b25acb6a43dde96762883332315017dae53ea89a Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Tue, 21 Jan 2025 22:15:07 +0000 Subject: [PATCH 1/7] chore: generate types for ManagedKafkaCluster --- .../managedkafka/v1alpha1/cluster_identity.go | 117 ++++++++++++ .../v1alpha1/cluster_reference.go | 83 ++++++++ apis/managedkafka/v1alpha1/cluster_types.go | 85 +++++++++ apis/managedkafka/v1alpha1/doc.go | 16 ++ .../v1alpha1/groupversion_info.go | 33 ++++ apis/managedkafka/v1alpha1/types.generated.go | 180 ++++++++++++++++++ dev/tools/controllerbuilder/generate.sh | 10 +- 7 files changed, 519 insertions(+), 5 deletions(-) create mode 100644 apis/managedkafka/v1alpha1/cluster_identity.go create mode 100644 apis/managedkafka/v1alpha1/cluster_reference.go create mode 100644 apis/managedkafka/v1alpha1/cluster_types.go create mode 100644 apis/managedkafka/v1alpha1/doc.go create mode 100644 apis/managedkafka/v1alpha1/groupversion_info.go create mode 100644 apis/managedkafka/v1alpha1/types.generated.go diff --git a/apis/managedkafka/v1alpha1/cluster_identity.go b/apis/managedkafka/v1alpha1/cluster_identity.go new file mode 100644 index 0000000000..8906caf8cd --- /dev/null +++ b/apis/managedkafka/v1alpha1/cluster_identity.go @@ -0,0 +1,117 @@ +// 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" +) + +// ClusterIdentity defines the resource reference to ManagedKafkaCluster, which "External" field +// holds the GCP identifier for the KRM object. +type ClusterIdentity struct { + parent *ClusterParent + id string +} + +func (i *ClusterIdentity) String() string { + return i.parent.String() + "/clusters/" + i.id +} + +func (i *ClusterIdentity) ID() string { + return i.id +} + +func (i *ClusterIdentity) Parent() *ClusterParent { + return i.parent +} + +type ClusterParent struct { + ProjectID string + Location string +} + +func (p *ClusterParent) String() string { + return "projects/" + p.ProjectID + "/locations/" + p.Location +} + +// New builds a ClusterIdentity from the Config Connector Cluster object. +func NewClusterIdentity(ctx context.Context, reader client.Reader, obj *ManagedKafkaCluster) (*ClusterIdentity, error) { + + // Get Parent + projectRef, err := refsv1beta1.ResolveProject(ctx, reader, obj.GetNamespace(), obj.Spec.ProjectRef) + if err != nil { + return nil, err + } + projectID := projectRef.ProjectID + if projectID == "" { + return nil, fmt.Errorf("cannot resolve project") + } + location := obj.Spec.Location + + // 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 External + externalRef := common.ValueOf(obj.Status.ExternalRef) + if externalRef != "" { + // Validate desired with actual + actualParent, actualResourceID, err := ParseClusterExternal(externalRef) + if err != nil { + return nil, err + } + if actualParent.ProjectID != projectID { + return nil, fmt.Errorf("spec.projectRef changed, expect %s, got %s", actualParent.ProjectID, projectID) + } + if actualParent.Location != location { + return nil, fmt.Errorf("spec.location changed, expect %s, got %s", actualParent.Location, location) + } + 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 &ClusterIdentity{ + parent: &ClusterParent{ + ProjectID: projectID, + Location: location, + }, + id: resourceID, + }, nil +} + +func ParseClusterExternal(external string) (parent *ClusterParent, resourceID string, err error) { + tokens := strings.Split(external, "/") + if len(tokens) != 6 || tokens[0] != "projects" || tokens[2] != "locations" || tokens[4] != "clusters" { + return nil, "", fmt.Errorf("format of ManagedKafkaCluster external=%q was not known (use projects/{{projectID}}/locations/{{location}}/clusters/{{clusterID}})", external) + } + parent = &ClusterParent{ + ProjectID: tokens[1], + Location: tokens[3], + } + resourceID = tokens[5] + return parent, resourceID, nil +} diff --git a/apis/managedkafka/v1alpha1/cluster_reference.go b/apis/managedkafka/v1alpha1/cluster_reference.go new file mode 100644 index 0000000000..b68a33676c --- /dev/null +++ b/apis/managedkafka/v1alpha1/cluster_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 = &ClusterRef{} + +// ClusterRef defines the resource reference to ManagedKafkaCluster, which "External" field +// holds the GCP identifier for the KRM object. +type ClusterRef struct { + // A reference to an externally managed ManagedKafkaCluster resource. + // Should be in the format "projects/{{projectID}}/locations/{{location}}/clusters/{{clusterID}}". + External string `json:"external,omitempty"` + + // The name of a ManagedKafkaCluster resource. + Name string `json:"name,omitempty"` + + // The namespace of a ManagedKafkaCluster resource. + Namespace string `json:"namespace,omitempty"` +} + +// NormalizedExternal provision the "External" value for other resource that depends on ManagedKafkaCluster. +// If the "External" is given in the other resource's spec.ManagedKafkaClusterRef, the given value will be used. +// Otherwise, the "Name" and "Namespace" will be used to query the actual ManagedKafkaCluster object from the cluster. +func (r *ClusterRef) 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", ManagedKafkaClusterGVK.Kind) + } + // From given External + if r.External != "" { + if _, _, err := ParseClusterExternal(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(ManagedKafkaClusterGVK) + 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", ManagedKafkaClusterGVK, 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/managedkafka/v1alpha1/cluster_types.go b/apis/managedkafka/v1alpha1/cluster_types.go new file mode 100644 index 0000000000..f73d8c938c --- /dev/null +++ b/apis/managedkafka/v1alpha1/cluster_types.go @@ -0,0 +1,85 @@ +// 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 ( + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ManagedKafkaClusterGVK = GroupVersion.WithKind("ManagedKafkaCluster") + +// ManagedKafkaClusterSpec defines the desired state of ManagedKafkaCluster +// +kcc:proto=google.cloud.managedkafka.v1.Cluster +type ManagedKafkaClusterSpec struct { + // The ManagedKafkaCluster name. If not given, the metadata.name will be used. + ResourceID *string `json:"resourceID,omitempty"` +} + +// ManagedKafkaClusterStatus defines the config connector machine state of ManagedKafkaCluster +type ManagedKafkaClusterStatus 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 ManagedKafkaCluster resource in GCP. + ExternalRef *string `json:"externalRef,omitempty"` + + // ObservedState is the state of the resource as most recently observed in GCP. + ObservedState *ManagedKafkaClusterObservedState `json:"observedState,omitempty"` +} + +// ManagedKafkaClusterSpec defines the desired state of ManagedKafkaCluster +// +kcc:proto=google.cloud.managedkafka.v1.Cluster +// ManagedKafkaClusterObservedState is the state of the ManagedKafkaCluster resource as most recently observed in GCP. +type ManagedKafkaClusterObservedState 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=gcpmanagedkafkacluster;gcpmanagedkafkaclusters +// +kubebuilder:subresource:status +// +kubebuilder:metadata:labels="cnrm.cloud.google.com/managed-by-kcc=true";"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'" + +// ManagedKafkaCluster is the Schema for the ManagedKafkaCluster API +// +k8s:openapi-gen=true +type ManagedKafkaCluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // +required + Spec ManagedKafkaClusterSpec `json:"spec,omitempty"` + Status ManagedKafkaClusterStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// ManagedKafkaClusterList contains a list of ManagedKafkaCluster +type ManagedKafkaClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ManagedKafkaCluster `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ManagedKafkaCluster{}, &ManagedKafkaClusterList{}) +} diff --git a/apis/managedkafka/v1alpha1/doc.go b/apis/managedkafka/v1alpha1/doc.go new file mode 100644 index 0000000000..afadd01abf --- /dev/null +++ b/apis/managedkafka/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.managedkafka.v1 +package v1alpha1 diff --git a/apis/managedkafka/v1alpha1/groupversion_info.go b/apis/managedkafka/v1alpha1/groupversion_info.go new file mode 100644 index 0000000000..1ab510ee82 --- /dev/null +++ b/apis/managedkafka/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=managedkafka.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: "managedkafka.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/managedkafka/v1alpha1/types.generated.go b/apis/managedkafka/v1alpha1/types.generated.go new file mode 100644 index 0000000000..55c863dba4 --- /dev/null +++ b/apis/managedkafka/v1alpha1/types.generated.go @@ -0,0 +1,180 @@ +// Copyright 2025 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.managedkafka.v1.AccessConfig +type AccessConfig struct { + // Required. Virtual Private Cloud (VPC) networks that must be granted direct + // access to the Kafka cluster. Minimum of 1 network is required. Maximum 10 + // networks can be specified. + // +kcc:proto:field=google.cloud.managedkafka.v1.AccessConfig.network_configs + NetworkConfigs []NetworkConfig `json:"networkConfigs,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.CapacityConfig +type CapacityConfig struct { + // Required. The number of vCPUs to provision for the cluster. Minimum: 3. + // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.vcpu_count + VcpuCount *int64 `json:"vcpuCount,omitempty"` + + // Required. The memory to provision for the cluster in bytes. + // The CPU:memory ratio (vCPU:GiB) must be between 1:1 and 1:8. + // Minimum: 3221225472 (3 GiB). + // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.memory_bytes + MemoryBytes *int64 `json:"memoryBytes,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.Cluster +type Cluster struct { + // Required. Configuration properties for a Kafka cluster deployed to Google + // Cloud Platform. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.gcp_config + GcpConfig *GcpConfig `json:"gcpConfig,omitempty"` + + // Identifier. The name of the cluster. Structured like: + // projects/{project_number}/locations/{location}/clusters/{cluster_id} + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.name + Name *string `json:"name,omitempty"` + + // Output only. The time when the cluster was created. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.create_time + CreateTime *string `json:"createTime,omitempty"` + + // Output only. The time when the cluster was last updated. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.update_time + UpdateTime *string `json:"updateTime,omitempty"` + + // Optional. Labels as key value pairs. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.labels + Labels map[string]string `json:"labels,omitempty"` + + // Required. Capacity configuration for the Kafka cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.capacity_config + CapacityConfig *CapacityConfig `json:"capacityConfig,omitempty"` + + // Optional. Rebalance configuration for the Kafka cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.rebalance_config + RebalanceConfig *RebalanceConfig `json:"rebalanceConfig,omitempty"` + + // Output only. The current state of the cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.state + State *string `json:"state,omitempty"` + + // Output only. Reserved for future use. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.satisfies_pzi + SatisfiesPzi *bool `json:"satisfiesPzi,omitempty"` + + // Output only. Reserved for future use. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.satisfies_pzs + SatisfiesPzs *bool `json:"satisfiesPzs,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.GcpConfig +type GcpConfig struct { + // Required. Access configuration for the Kafka cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.access_config + AccessConfig *AccessConfig `json:"accessConfig,omitempty"` + + // Optional. Immutable. The Cloud KMS Key name to use for encryption. The key + // must be located in the same region as the cluster and cannot be changed. + // Structured like: + // projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}. + // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.kms_key + KMSKey *string `json:"kmsKey,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.NetworkConfig +type NetworkConfig struct { + // Required. Name of the VPC subnet in which to create Private Service Connect + // (PSC) endpoints for the Kafka brokers and bootstrap address. Structured + // like: projects/{project}/regions/{region}/subnetworks/{subnet_id} + // + // The subnet must be located in the same region as the Kafka cluster. The + // project may differ. Multiple subnets from the same parent network must not + // be specified. + // + // The CIDR range of the subnet must be within the IPv4 address ranges for + // private networks, as specified in RFC 1918. + // +kcc:proto:field=google.cloud.managedkafka.v1.NetworkConfig.subnet + Subnet *string `json:"subnet,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.RebalanceConfig +type RebalanceConfig struct { + // Optional. The rebalance behavior for the cluster. + // When not specified, defaults to `NO_REBALANCE`. + // +kcc:proto:field=google.cloud.managedkafka.v1.RebalanceConfig.mode + Mode *string `json:"mode,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.AccessConfig +type AccessConfig struct { + // Required. Virtual Private Cloud (VPC) networks that must be granted direct + // access to the Kafka cluster. Minimum of 1 network is required. Maximum 10 + // networks can be specified. + // +kcc:proto:field=google.cloud.managedkafka.v1.AccessConfig.network_configs + NetworkConfigs []NetworkConfig `json:"networkConfigs,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.CapacityConfig +type CapacityConfig struct { + // Required. The number of vCPUs to provision for the cluster. Minimum: 3. + // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.vcpu_count + VcpuCount *int64 `json:"vcpuCount,omitempty"` + + // Required. The memory to provision for the cluster in bytes. + // The CPU:memory ratio (vCPU:GiB) must be between 1:1 and 1:8. + // Minimum: 3221225472 (3 GiB). + // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.memory_bytes + MemoryBytes *int64 `json:"memoryBytes,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.GcpConfig +type GcpConfig struct { + // Required. Access configuration for the Kafka cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.access_config + AccessConfig *AccessConfig `json:"accessConfig,omitempty"` + + // Optional. Immutable. The Cloud KMS Key name to use for encryption. The key + // must be located in the same region as the cluster and cannot be changed. + // Structured like: + // projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}. + // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.kms_key + KMSKey *string `json:"kmsKey,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.NetworkConfig +type NetworkConfig struct { + // Required. Name of the VPC subnet in which to create Private Service Connect + // (PSC) endpoints for the Kafka brokers and bootstrap address. Structured + // like: projects/{project}/regions/{region}/subnetworks/{subnet_id} + // + // The subnet must be located in the same region as the Kafka cluster. The + // project may differ. Multiple subnets from the same parent network must not + // be specified. + // + // The CIDR range of the subnet must be within the IPv4 address ranges for + // private networks, as specified in RFC 1918. + // +kcc:proto:field=google.cloud.managedkafka.v1.NetworkConfig.subnet + Subnet *string `json:"subnet,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.RebalanceConfig +type RebalanceConfig struct { + // Optional. The rebalance behavior for the cluster. + // When not specified, defaults to `NO_REBALANCE`. + // +kcc:proto:field=google.cloud.managedkafka.v1.RebalanceConfig.mode + Mode *string `json:"mode,omitempty"` +} diff --git a/dev/tools/controllerbuilder/generate.sh b/dev/tools/controllerbuilder/generate.sh index 629e741b61..fb6137620a 100755 --- a/dev/tools/controllerbuilder/generate.sh +++ b/dev/tools/controllerbuilder/generate.sh @@ -188,11 +188,11 @@ go run . generate-mapper \ --service google.cloud.iap.v1 \ --api-version iap.cnrm.cloud.google.com/v1alpha1 -# $ go run . generate-controller \ -# --service google.cloud.iap.v1 \ -# --api-version iap.cnrm.cloud.google.com/v1alpha1 \ -# --kind IAPSettings \ -# --proto-resource IapSettings +# ManagedKafka +go run . generate-types \ + --service google.cloud.managedkafka.v1 \ + --api-version managedkafka.cnrm.cloud.google.com/v1alpha1 \ + --resource ManagedKafkaCluster:Cluster # Fix up formatting ${REPO_ROOT}/dev/tasks/fix-gofmt From 893b12c9ae7a80e375eba280e056aa369dbce141 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Tue, 21 Jan 2025 22:49:36 +0000 Subject: [PATCH 2/7] feat: manual edits to ManagedKafkaCluster types --- .../managedkafka/v1alpha1/cluster_identity.go | 1 - apis/managedkafka/v1alpha1/cluster_types.go | 107 ++++++++++++ apis/managedkafka/v1alpha1/types.generated.go | 157 ------------------ 3 files changed, 107 insertions(+), 158 deletions(-) diff --git a/apis/managedkafka/v1alpha1/cluster_identity.go b/apis/managedkafka/v1alpha1/cluster_identity.go index 8906caf8cd..c9a5f81c37 100644 --- a/apis/managedkafka/v1alpha1/cluster_identity.go +++ b/apis/managedkafka/v1alpha1/cluster_identity.go @@ -54,7 +54,6 @@ func (p *ClusterParent) String() string { // New builds a ClusterIdentity from the Config Connector Cluster object. func NewClusterIdentity(ctx context.Context, reader client.Reader, obj *ManagedKafkaCluster) (*ClusterIdentity, error) { - // Get Parent projectRef, err := refsv1beta1.ResolveProject(ctx, reader, obj.GetNamespace(), obj.Spec.ProjectRef) if err != nil { diff --git a/apis/managedkafka/v1alpha1/cluster_types.go b/apis/managedkafka/v1alpha1/cluster_types.go index f73d8c938c..f754ac1838 100644 --- a/apis/managedkafka/v1alpha1/cluster_types.go +++ b/apis/managedkafka/v1alpha1/cluster_types.go @@ -15,17 +15,98 @@ package v1alpha1 import ( + refs "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + commonv1alpha1 "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/common/v1alpha1" "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ManagedKafkaClusterGVK = GroupVersion.WithKind("ManagedKafkaCluster") +// +kcc:proto=google.cloud.managedkafka.v1.AccessConfig +type AccessConfig struct { + // Required. Virtual Private Cloud (VPC) networks that must be granted direct + // access to the Kafka cluster. Minimum of 1 network is required. Maximum 10 + // networks can be specified. + // +kcc:proto:field=google.cloud.managedkafka.v1.AccessConfig.network_configs + // +required + NetworkConfigs []NetworkConfig `json:"networkConfigs,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.CapacityConfig +type CapacityConfig struct { + // Required. The number of vCPUs to provision for the cluster. Minimum: 3. + // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.vcpu_count + // +required + VcpuCount *int64 `json:"vcpuCount,omitempty"` + + // Required. The memory to provision for the cluster in bytes. + // The CPU:memory ratio (vCPU:GiB) must be between 1:1 and 1:8. + // Minimum: 3221225472 (3 GiB). + // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.memory_bytes + // +required + MemoryBytes *int64 `json:"memoryBytes,omitempty"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.NetworkConfig +type NetworkConfig struct { + // Required. Reference to the VPC subnet in which to create Private Service Connect + // (PSC) endpoints for the Kafka brokers and bootstrap address. + // + // The subnet must be located in the same region as the Kafka cluster. The + // project may differ. Multiple subnets from the same parent network must not + // be specified. + // + // The CIDR range of the subnet must be within the IPv4 address ranges for + // private networks, as specified in RFC 1918. + // +kcc:proto:field=google.cloud.managedkafka.v1.NetworkConfig.subnet + // +required + SubnetworkRef *refs.ComputeSubnetworkRef `json:"subnetworkRef"` +} + +// +kcc:proto=google.cloud.managedkafka.v1.GcpConfig +type GcpConfig struct { + // Required. Access configuration for the Kafka cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.access_config + // +required + AccessConfig *AccessConfig `json:"accessConfig,omitempty"` + + // Optional. Immutable. The Cloud KMS Key name to use for encryption. The key + // must be located in the same region as the cluster and cannot be changed. + // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.kms_key + KmsKeyRef *refs.KMSCryptoKeyRef `json:"kmsKeyRef,omitempty"` +} + // ManagedKafkaClusterSpec defines the desired state of ManagedKafkaCluster // +kcc:proto=google.cloud.managedkafka.v1.Cluster type ManagedKafkaClusterSpec struct { + commonv1alpha1.CommonSpec `json:",inline"` + + // +required + Location string `json:"location"` + // The ManagedKafkaCluster name. If not given, the metadata.name will be used. ResourceID *string `json:"resourceID,omitempty"` + + // Required. Configuration properties for a Kafka cluster deployed to Google + // Cloud Platform. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.gcp_config + // +required + GcpConfig *GcpConfig `json:"gcpConfig,omitempty"` + + // Optional. Labels as key value pairs. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.labels + Labels map[string]string `json:"labels,omitempty"` + + // Required. Capacity configuration for the Kafka cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.capacity_config + // +required + CapacityConfig *CapacityConfig `json:"capacityConfig,omitempty"` + + // Optional. Rebalance configuration for the Kafka cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.rebalance_config + RebalanceConfig *RebalanceConfig `json:"rebalanceConfig,omitempty"` } // ManagedKafkaClusterStatus defines the config connector machine state of ManagedKafkaCluster @@ -48,6 +129,32 @@ type ManagedKafkaClusterStatus struct { // +kcc:proto=google.cloud.managedkafka.v1.Cluster // ManagedKafkaClusterObservedState is the state of the ManagedKafkaCluster resource as most recently observed in GCP. type ManagedKafkaClusterObservedState struct { + // Identifier. The name of the cluster. Structured like: + // projects/{project_number}/locations/{location}/clusters/{cluster_id} + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.name + Name *string `json:"name,omitempty"` + + // Output only. The time when the cluster was created. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.create_time + CreateTime *string `json:"createTime,omitempty"` + + // Output only. The time when the cluster was last updated. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.update_time + UpdateTime *string `json:"updateTime,omitempty"` + + // Output only. The current state of the cluster. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.state + State *string `json:"state,omitempty"` + + // NOTYET + // Output only. Reserved for future use. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.satisfies_pzi + // SatisfiesPzi *bool `json:"satisfiesPzi,omitempty"` + + // NOTYET + // Output only. Reserved for future use. + // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.satisfies_pzs + // SatisfiesPzs *bool `json:"satisfiesPzs,omitempty"` } // +genclient diff --git a/apis/managedkafka/v1alpha1/types.generated.go b/apis/managedkafka/v1alpha1/types.generated.go index 55c863dba4..aedc5bd93a 100644 --- a/apis/managedkafka/v1alpha1/types.generated.go +++ b/apis/managedkafka/v1alpha1/types.generated.go @@ -14,163 +14,6 @@ package v1alpha1 -// +kcc:proto=google.cloud.managedkafka.v1.AccessConfig -type AccessConfig struct { - // Required. Virtual Private Cloud (VPC) networks that must be granted direct - // access to the Kafka cluster. Minimum of 1 network is required. Maximum 10 - // networks can be specified. - // +kcc:proto:field=google.cloud.managedkafka.v1.AccessConfig.network_configs - NetworkConfigs []NetworkConfig `json:"networkConfigs,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.CapacityConfig -type CapacityConfig struct { - // Required. The number of vCPUs to provision for the cluster. Minimum: 3. - // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.vcpu_count - VcpuCount *int64 `json:"vcpuCount,omitempty"` - - // Required. The memory to provision for the cluster in bytes. - // The CPU:memory ratio (vCPU:GiB) must be between 1:1 and 1:8. - // Minimum: 3221225472 (3 GiB). - // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.memory_bytes - MemoryBytes *int64 `json:"memoryBytes,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.Cluster -type Cluster struct { - // Required. Configuration properties for a Kafka cluster deployed to Google - // Cloud Platform. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.gcp_config - GcpConfig *GcpConfig `json:"gcpConfig,omitempty"` - - // Identifier. The name of the cluster. Structured like: - // projects/{project_number}/locations/{location}/clusters/{cluster_id} - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.name - Name *string `json:"name,omitempty"` - - // Output only. The time when the cluster was created. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.create_time - CreateTime *string `json:"createTime,omitempty"` - - // Output only. The time when the cluster was last updated. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.update_time - UpdateTime *string `json:"updateTime,omitempty"` - - // Optional. Labels as key value pairs. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.labels - Labels map[string]string `json:"labels,omitempty"` - - // Required. Capacity configuration for the Kafka cluster. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.capacity_config - CapacityConfig *CapacityConfig `json:"capacityConfig,omitempty"` - - // Optional. Rebalance configuration for the Kafka cluster. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.rebalance_config - RebalanceConfig *RebalanceConfig `json:"rebalanceConfig,omitempty"` - - // Output only. The current state of the cluster. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.state - State *string `json:"state,omitempty"` - - // Output only. Reserved for future use. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.satisfies_pzi - SatisfiesPzi *bool `json:"satisfiesPzi,omitempty"` - - // Output only. Reserved for future use. - // +kcc:proto:field=google.cloud.managedkafka.v1.Cluster.satisfies_pzs - SatisfiesPzs *bool `json:"satisfiesPzs,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.GcpConfig -type GcpConfig struct { - // Required. Access configuration for the Kafka cluster. - // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.access_config - AccessConfig *AccessConfig `json:"accessConfig,omitempty"` - - // Optional. Immutable. The Cloud KMS Key name to use for encryption. The key - // must be located in the same region as the cluster and cannot be changed. - // Structured like: - // projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}. - // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.kms_key - KMSKey *string `json:"kmsKey,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.NetworkConfig -type NetworkConfig struct { - // Required. Name of the VPC subnet in which to create Private Service Connect - // (PSC) endpoints for the Kafka brokers and bootstrap address. Structured - // like: projects/{project}/regions/{region}/subnetworks/{subnet_id} - // - // The subnet must be located in the same region as the Kafka cluster. The - // project may differ. Multiple subnets from the same parent network must not - // be specified. - // - // The CIDR range of the subnet must be within the IPv4 address ranges for - // private networks, as specified in RFC 1918. - // +kcc:proto:field=google.cloud.managedkafka.v1.NetworkConfig.subnet - Subnet *string `json:"subnet,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.RebalanceConfig -type RebalanceConfig struct { - // Optional. The rebalance behavior for the cluster. - // When not specified, defaults to `NO_REBALANCE`. - // +kcc:proto:field=google.cloud.managedkafka.v1.RebalanceConfig.mode - Mode *string `json:"mode,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.AccessConfig -type AccessConfig struct { - // Required. Virtual Private Cloud (VPC) networks that must be granted direct - // access to the Kafka cluster. Minimum of 1 network is required. Maximum 10 - // networks can be specified. - // +kcc:proto:field=google.cloud.managedkafka.v1.AccessConfig.network_configs - NetworkConfigs []NetworkConfig `json:"networkConfigs,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.CapacityConfig -type CapacityConfig struct { - // Required. The number of vCPUs to provision for the cluster. Minimum: 3. - // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.vcpu_count - VcpuCount *int64 `json:"vcpuCount,omitempty"` - - // Required. The memory to provision for the cluster in bytes. - // The CPU:memory ratio (vCPU:GiB) must be between 1:1 and 1:8. - // Minimum: 3221225472 (3 GiB). - // +kcc:proto:field=google.cloud.managedkafka.v1.CapacityConfig.memory_bytes - MemoryBytes *int64 `json:"memoryBytes,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.GcpConfig -type GcpConfig struct { - // Required. Access configuration for the Kafka cluster. - // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.access_config - AccessConfig *AccessConfig `json:"accessConfig,omitempty"` - - // Optional. Immutable. The Cloud KMS Key name to use for encryption. The key - // must be located in the same region as the cluster and cannot be changed. - // Structured like: - // projects/{project}/locations/{location}/keyRings/{key_ring}/cryptoKeys/{crypto_key}. - // +kcc:proto:field=google.cloud.managedkafka.v1.GcpConfig.kms_key - KMSKey *string `json:"kmsKey,omitempty"` -} - -// +kcc:proto=google.cloud.managedkafka.v1.NetworkConfig -type NetworkConfig struct { - // Required. Name of the VPC subnet in which to create Private Service Connect - // (PSC) endpoints for the Kafka brokers and bootstrap address. Structured - // like: projects/{project}/regions/{region}/subnetworks/{subnet_id} - // - // The subnet must be located in the same region as the Kafka cluster. The - // project may differ. Multiple subnets from the same parent network must not - // be specified. - // - // The CIDR range of the subnet must be within the IPv4 address ranges for - // private networks, as specified in RFC 1918. - // +kcc:proto:field=google.cloud.managedkafka.v1.NetworkConfig.subnet - Subnet *string `json:"subnet,omitempty"` -} - // +kcc:proto=google.cloud.managedkafka.v1.RebalanceConfig type RebalanceConfig struct { // Optional. The rebalance behavior for the cluster. From d2ca36e9e26cac0066e95c7250eaefe843c34e2d Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Tue, 21 Jan 2025 22:51:00 +0000 Subject: [PATCH 3/7] chore: generate CRD for ManagedKafkaCluster --- .../v1alpha1/zz_generated.deepcopy.go | 359 ++++++++++++++++++ ...rs.managedkafka.cnrm.cloud.google.com.yaml | 299 +++++++++++++++ 2 files changed, 658 insertions(+) create mode 100644 apis/managedkafka/v1alpha1/zz_generated.deepcopy.go create mode 100644 config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_managedkafkaclusters.managedkafka.cnrm.cloud.google.com.yaml diff --git a/apis/managedkafka/v1alpha1/zz_generated.deepcopy.go b/apis/managedkafka/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 0000000000..6172b91a69 --- /dev/null +++ b/apis/managedkafka/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,359 @@ +//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 *AccessConfig) DeepCopyInto(out *AccessConfig) { + *out = *in + if in.NetworkConfigs != nil { + in, out := &in.NetworkConfigs, &out.NetworkConfigs + *out = make([]NetworkConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessConfig. +func (in *AccessConfig) DeepCopy() *AccessConfig { + if in == nil { + return nil + } + out := new(AccessConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CapacityConfig) DeepCopyInto(out *CapacityConfig) { + *out = *in + if in.VcpuCount != nil { + in, out := &in.VcpuCount, &out.VcpuCount + *out = new(int64) + **out = **in + } + if in.MemoryBytes != nil { + in, out := &in.MemoryBytes, &out.MemoryBytes + *out = new(int64) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CapacityConfig. +func (in *CapacityConfig) DeepCopy() *CapacityConfig { + if in == nil { + return nil + } + out := new(CapacityConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterIdentity) DeepCopyInto(out *ClusterIdentity) { + *out = *in + if in.parent != nil { + in, out := &in.parent, &out.parent + *out = new(ClusterParent) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterIdentity. +func (in *ClusterIdentity) DeepCopy() *ClusterIdentity { + if in == nil { + return nil + } + out := new(ClusterIdentity) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterParent) DeepCopyInto(out *ClusterParent) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterParent. +func (in *ClusterParent) DeepCopy() *ClusterParent { + if in == nil { + return nil + } + out := new(ClusterParent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterRef) DeepCopyInto(out *ClusterRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRef. +func (in *ClusterRef) DeepCopy() *ClusterRef { + if in == nil { + return nil + } + out := new(ClusterRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GcpConfig) DeepCopyInto(out *GcpConfig) { + *out = *in + if in.AccessConfig != nil { + in, out := &in.AccessConfig, &out.AccessConfig + *out = new(AccessConfig) + (*in).DeepCopyInto(*out) + } + if in.KmsKeyRef != nil { + in, out := &in.KmsKeyRef, &out.KmsKeyRef + *out = new(v1beta1.KMSCryptoKeyRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GcpConfig. +func (in *GcpConfig) DeepCopy() *GcpConfig { + if in == nil { + return nil + } + out := new(GcpConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedKafkaCluster) DeepCopyInto(out *ManagedKafkaCluster) { + *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 ManagedKafkaCluster. +func (in *ManagedKafkaCluster) DeepCopy() *ManagedKafkaCluster { + if in == nil { + return nil + } + out := new(ManagedKafkaCluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ManagedKafkaCluster) 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 *ManagedKafkaClusterList) DeepCopyInto(out *ManagedKafkaClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ManagedKafkaCluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedKafkaClusterList. +func (in *ManagedKafkaClusterList) DeepCopy() *ManagedKafkaClusterList { + if in == nil { + return nil + } + out := new(ManagedKafkaClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ManagedKafkaClusterList) 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 *ManagedKafkaClusterObservedState) DeepCopyInto(out *ManagedKafkaClusterObservedState) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.CreateTime != nil { + in, out := &in.CreateTime, &out.CreateTime + *out = new(string) + **out = **in + } + if in.UpdateTime != nil { + in, out := &in.UpdateTime, &out.UpdateTime + *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 ManagedKafkaClusterObservedState. +func (in *ManagedKafkaClusterObservedState) DeepCopy() *ManagedKafkaClusterObservedState { + if in == nil { + return nil + } + out := new(ManagedKafkaClusterObservedState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedKafkaClusterSpec) DeepCopyInto(out *ManagedKafkaClusterSpec) { + *out = *in + in.CommonSpec.DeepCopyInto(&out.CommonSpec) + if in.ResourceID != nil { + in, out := &in.ResourceID, &out.ResourceID + *out = new(string) + **out = **in + } + if in.GcpConfig != nil { + in, out := &in.GcpConfig, &out.GcpConfig + *out = new(GcpConfig) + (*in).DeepCopyInto(*out) + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CapacityConfig != nil { + in, out := &in.CapacityConfig, &out.CapacityConfig + *out = new(CapacityConfig) + (*in).DeepCopyInto(*out) + } + if in.RebalanceConfig != nil { + in, out := &in.RebalanceConfig, &out.RebalanceConfig + *out = new(RebalanceConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedKafkaClusterSpec. +func (in *ManagedKafkaClusterSpec) DeepCopy() *ManagedKafkaClusterSpec { + if in == nil { + return nil + } + out := new(ManagedKafkaClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagedKafkaClusterStatus) DeepCopyInto(out *ManagedKafkaClusterStatus) { + *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.ObservedState != nil { + in, out := &in.ObservedState, &out.ObservedState + *out = new(ManagedKafkaClusterObservedState) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagedKafkaClusterStatus. +func (in *ManagedKafkaClusterStatus) DeepCopy() *ManagedKafkaClusterStatus { + if in == nil { + return nil + } + out := new(ManagedKafkaClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkConfig) DeepCopyInto(out *NetworkConfig) { + *out = *in + if in.SubnetworkRef != nil { + in, out := &in.SubnetworkRef, &out.SubnetworkRef + *out = new(v1beta1.ComputeSubnetworkRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkConfig. +func (in *NetworkConfig) DeepCopy() *NetworkConfig { + if in == nil { + return nil + } + out := new(NetworkConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RebalanceConfig) DeepCopyInto(out *RebalanceConfig) { + *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 RebalanceConfig. +func (in *RebalanceConfig) DeepCopy() *RebalanceConfig { + if in == nil { + return nil + } + out := new(RebalanceConfig) + in.DeepCopyInto(out) + return out +} diff --git a/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_managedkafkaclusters.managedkafka.cnrm.cloud.google.com.yaml b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_managedkafkaclusters.managedkafka.cnrm.cloud.google.com.yaml new file mode 100644 index 0000000000..7e10db0b56 --- /dev/null +++ b/config/crds/resources/apiextensions.k8s.io_v1_customresourcedefinition_managedkafkaclusters.managedkafka.cnrm.cloud.google.com.yaml @@ -0,0 +1,299 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cnrm.cloud.google.com/version: 0.0.0-dev + creationTimestamp: null + labels: + cnrm.cloud.google.com/managed-by-kcc: "true" + cnrm.cloud.google.com/system: "true" + name: managedkafkaclusters.managedkafka.cnrm.cloud.google.com +spec: + group: managedkafka.cnrm.cloud.google.com + names: + categories: + - gcp + kind: ManagedKafkaCluster + listKind: ManagedKafkaClusterList + plural: managedkafkaclusters + shortNames: + - gcpmanagedkafkacluster + - gcpmanagedkafkaclusters + singular: managedkafkacluster + preserveUnknownFields: false + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: When 'True', the most recent reconcile of the resource succeeded + jsonPath: .status.conditions[?(@.type=='Ready')].status + name: Ready + type: string + - description: The reason for the value in 'Ready' + jsonPath: .status.conditions[?(@.type=='Ready')].reason + name: Status + type: string + - description: The last transition time for the value in 'Status' + jsonPath: .status.conditions[?(@.type=='Ready')].lastTransitionTime + name: Status Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ManagedKafkaCluster is the Schema for the ManagedKafkaCluster + API + properties: + apiVersion: + 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/sig-architecture/api-conventions.md#resources' + type: string + kind: + 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/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ManagedKafkaClusterSpec defines the desired state of ManagedKafkaCluster + properties: + capacityConfig: + description: Required. Capacity configuration for the Kafka cluster. + properties: + memoryBytes: + description: 'Required. The memory to provision for the cluster + in bytes. The CPU:memory ratio (vCPU:GiB) must be between 1:1 + and 1:8. Minimum: 3221225472 (3 GiB).' + format: int64 + type: integer + vcpuCount: + description: 'Required. The number of vCPUs to provision for the + cluster. Minimum: 3.' + format: int64 + type: integer + required: + - memoryBytes + - vcpuCount + type: object + gcpConfig: + description: Required. Configuration properties for a Kafka cluster + deployed to Google Cloud Platform. + properties: + accessConfig: + description: Required. Access configuration for the Kafka cluster. + properties: + networkConfigs: + description: Required. Virtual Private Cloud (VPC) networks + that must be granted direct access to the Kafka cluster. + Minimum of 1 network is required. Maximum 10 networks can + be specified. + items: + properties: + subnetworkRef: + description: |- + Required. Reference to the VPC subnet in which to create Private Service Connect + (PSC) endpoints for the Kafka brokers and bootstrap address. + + The subnet must be located in the same region as the Kafka cluster. The + project may differ. Multiple subnets from the same parent network must not + be specified. + + The CIDR range of the subnet must be within the IPv4 address ranges for + private networks, as specified in RFC 1918. + oneOf: + - not: + required: + - external + required: + - name + - not: + anyOf: + - required: + - name + - required: + - namespace + required: + - external + properties: + external: + description: The ComputeSubnetwork selflink of form + "projects/{{project}}/regions/{{region}}/subnetworks/{{name}}", + when not managed by Config Connector. + type: string + name: + description: The `name` field of a `ComputeSubnetwork` + resource. + type: string + namespace: + description: The `namespace` field of a `ComputeSubnetwork` + resource. + type: string + type: object + required: + - subnetworkRef + type: object + type: array + required: + - networkConfigs + type: object + kmsKeyRef: + description: Optional. Immutable. The Cloud KMS Key name to use + for encryption. The key must be located in the same region as + the cluster and cannot be changed. + oneOf: + - not: + required: + - external + required: + - name + - not: + anyOf: + - required: + - name + - required: + - namespace + required: + - external + properties: + external: + description: A reference to an externally managed KMSCryptoKey. + Should be in the format `projects/[kms_project_id]/locations/[region]/keyRings/[key_ring_id]/cryptoKeys/[key]`. + type: string + name: + description: The `name` of a `KMSCryptoKey` resource. + type: string + namespace: + description: The `namespace` of a `KMSCryptoKey` resource. + type: string + type: object + required: + - accessConfig + type: object + labels: + additionalProperties: + type: string + description: Optional. Labels as key value pairs. + type: object + location: + type: string + projectRef: + description: The Project that this resource belongs to. + oneOf: + - not: + required: + - external + required: + - name + - not: + anyOf: + - required: + - name + - required: + - namespace + required: + - external + properties: + external: + description: The `projectID` field of a project, when not managed + by Config Connector. + type: string + kind: + description: The kind of the Project resource; optional but must + be `Project` if provided. + type: string + name: + description: The `name` field of a `Project` resource. + type: string + namespace: + description: The `namespace` field of a `Project` resource. + type: string + type: object + rebalanceConfig: + description: Optional. Rebalance configuration for the Kafka cluster. + properties: + mode: + description: Optional. The rebalance behavior for the cluster. + When not specified, defaults to `NO_REBALANCE`. + type: string + type: object + resourceID: + description: The GCP resource identifier. If not given, the metadata.name + will be used. + type: string + required: + - capacityConfig + - gcpConfig + - location + - projectRef + type: object + status: + description: ManagedKafkaClusterStatus defines the config connector machine + state of ManagedKafkaCluster + properties: + conditions: + description: Conditions represent the latest available observations + of the object's current state. + items: + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. Can be True, + False, Unknown. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + externalRef: + description: A unique specifier for the ManagedKafkaCluster resource + in GCP. + type: string + observedGeneration: + description: 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. + format: int64 + type: integer + observedState: + description: ObservedState is the state of the resource as most recently + observed in GCP. + properties: + createTime: + description: Output only. The time when the cluster was created. + type: string + name: + description: 'Identifier. The name of the cluster. Structured + like: projects/{project_number}/locations/{location}/clusters/{cluster_id}' + type: string + state: + description: Output only. The current state of the cluster. + type: string + updateTime: + description: Output only. The time when the cluster was last updated. + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} From b8194f5c2e7699523cc7086d2c72de8a0af60f55 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Tue, 21 Jan 2025 23:37:34 +0000 Subject: [PATCH 4/7] feat: add mapping functions for ManagedKafkaCluster --- dev/tools/controllerbuilder/generate.sh | 4 + go.mod | 13 +- go.sum | 26 ++-- .../direct/managedkafka/cluster_mappings.go | 65 ++++++++++ .../direct/managedkafka/mapper.generated.go | 118 ++++++++++++++++++ 5 files changed, 208 insertions(+), 18 deletions(-) create mode 100644 pkg/controller/direct/managedkafka/cluster_mappings.go create mode 100644 pkg/controller/direct/managedkafka/mapper.generated.go diff --git a/dev/tools/controllerbuilder/generate.sh b/dev/tools/controllerbuilder/generate.sh index fb6137620a..e926057c36 100755 --- a/dev/tools/controllerbuilder/generate.sh +++ b/dev/tools/controllerbuilder/generate.sh @@ -194,5 +194,9 @@ go run . generate-types \ --api-version managedkafka.cnrm.cloud.google.com/v1alpha1 \ --resource ManagedKafkaCluster:Cluster +go run . generate-mapper \ + --service google.cloud.managedkafka.v1 \ + --api-version managedkafka.cnrm.cloud.google.com/v1alpha1 + # Fix up formatting ${REPO_ROOT}/dev/tasks/fix-gofmt diff --git a/go.mod b/go.mod index 8788079f8f..986d14c478 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( cloud.google.com/go/iam v1.2.2 cloud.google.com/go/iap v1.10.2 cloud.google.com/go/kms v1.20.1 + cloud.google.com/go/managedkafka v0.4.0 cloud.google.com/go/monitoring v1.21.2 cloud.google.com/go/privilegedaccessmanager v0.2.1 cloud.google.com/go/profiler v0.4.1 @@ -68,11 +69,11 @@ require ( golang.org/x/oauth2 v0.25.0 golang.org/x/sync v0.10.0 golang.org/x/time v0.9.0 - google.golang.org/api v0.210.0 + google.golang.org/api v0.214.0 google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 - google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f - google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 - google.golang.org/grpc v1.67.1 + google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 + google.golang.org/grpc v1.67.3 google.golang.org/protobuf v1.35.2 gopkg.in/dnaeon/go-vcr.v3 v3.2.0 gopkg.in/yaml.v2 v2.4.0 @@ -93,10 +94,10 @@ require ( bitbucket.org/creachadair/stringset v0.0.8 // indirect cel.dev/expr v0.16.0 // indirect cloud.google.com/go v0.116.0 // indirect - cloud.google.com/go/auth v0.11.0 // indirect + cloud.google.com/go/auth v0.13.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.6 // indirect cloud.google.com/go/bigtable v1.33.0 // indirect - cloud.google.com/go/compute/metadata v0.5.2 // indirect + cloud.google.com/go/compute/metadata v0.6.0 // indirect cloud.google.com/go/longrunning v0.6.2 // indirect dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect diff --git a/go.sum b/go.sum index 9050b3e3f1..1e82d7ad6a 100644 --- a/go.sum +++ b/go.sum @@ -26,8 +26,8 @@ cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= 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= -cloud.google.com/go/auth v0.11.0/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI= +cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs= +cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q= cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU= cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -46,8 +46,8 @@ cloud.google.com/go/cloudbuild v1.19.0 h1:Uo0bL251yvyWsNtO3Og9m5Z4S48cgGf3IUX7xz cloud.google.com/go/cloudbuild v1.19.0/go.mod h1:ZGRqbNMrVGhknIIjwASa6MqoRTOpXIVMSI+Ew5DMPuY= cloud.google.com/go/compute v1.29.0 h1:Lph6d8oPi38NHkOr6S55Nus/Pbbcp37m/J0ohgKAefs= cloud.google.com/go/compute v1.29.0/go.mod h1:HFlsDurE5DpQZClAGf/cYh+gxssMhBxBovZDYkEn/Og= -cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= -cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= +cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= +cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/dataflow v0.10.2 h1:o9P5/zR2mOYJmCnfp9/7RprKFZCwmSu3TvemQSmCaFM= cloud.google.com/go/dataflow v0.10.2/go.mod h1:+HIb4HJxDCZYuCqDGnBHZEglh5I0edi/mLgVbxDf0Ag= cloud.google.com/go/dataform v0.10.2 h1:t16DoejuOHoxJR88qrpdmFFlCXA9+x5PKrqI9qiDYz0= @@ -69,6 +69,8 @@ cloud.google.com/go/kms v1.20.1 h1:og29Wv59uf2FVaZlesaiDAqHFzHaoUyHI3HYp9VUHVg= cloud.google.com/go/kms v1.20.1/go.mod h1:LywpNiVCvzYNJWS9JUcGJSVTNSwPwi0vBAotzDqn2nc= cloud.google.com/go/longrunning v0.6.2 h1:xjDfh1pQcWPEvnfjZmwjKQEcHnpz6lHjfy7Fo0MK+hc= cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= +cloud.google.com/go/managedkafka v0.4.0 h1:/snDok/h6TZKw0ubmfj/LYIwSn16mWBoBI2OEl7ldIA= +cloud.google.com/go/managedkafka v0.4.0/go.mod h1:AUCV9FeT5IbuIf4ctH6TsnovE/KuIPE6Mp/YowkTyx0= cloud.google.com/go/monitoring v1.21.2 h1:FChwVtClH19E7pJ+e0xUhJPGksctZNVOk2UhMmblmdU= cloud.google.com/go/monitoring v1.21.2/go.mod h1:hS3pXvaG8KgWTSz+dAdyzPrGUYmi2Q+WFX8g2hqVEZU= cloud.google.com/go/privilegedaccessmanager v0.2.1 h1:8a9N5vXTVaEUsTOVxpY7bI354vjS9jVOY8FjwMRfWTI= @@ -1380,8 +1382,8 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.210.0 h1:HMNffZ57OoZCRYSbdWVRoqOa8V8NIHLL0CzdBPLztWk= -google.golang.org/api v0.210.0/go.mod h1:B9XDZGnx2NtyjzVkOVTGrFSAVZgPcbedzKg/gTLwqBs= +google.golang.org/api v0.214.0 h1:h2Gkq07OYi6kusGOaT/9rnNljuXmqPnaig7WGPmKbwA= +google.golang.org/api v0.214.0/go.mod h1:bYPpLG8AyeMWwDU6NXoB00xC0DFkikVvd5MfwoxjLqE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1437,10 +1439,10 @@ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxH google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk= google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f h1:M65LEviCfuZTfrfzwwEoxVtgvfkFkBUbFnRbxCXuXhU= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f/go.mod h1:Yo94eF2nj7igQt+TiJ49KxjIH8ndLYPZMIRSiRcEbg0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1462,8 +1464,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= -google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8= +google.golang.org/grpc v1.67.3/go.mod h1:YGaHCc6Oap+FzBJTZLBzkGSYt/cvGPFTPxkn7QfSU8s= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/pkg/controller/direct/managedkafka/cluster_mappings.go b/pkg/controller/direct/managedkafka/cluster_mappings.go new file mode 100644 index 0000000000..16e2d41514 --- /dev/null +++ b/pkg/controller/direct/managedkafka/cluster_mappings.go @@ -0,0 +1,65 @@ +// Copyright 2025 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 managedkafka + +import ( + pb "cloud.google.com/go/managedkafka/apiv1/managedkafkapb" + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/managedkafka/v1alpha1" + refs "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" +) + +func GcpConfig_FromProto(mapCtx *direct.MapContext, in *pb.GcpConfig) *krm.GcpConfig { + if in == nil { + return nil + } + out := &krm.GcpConfig{} + out.AccessConfig = AccessConfig_FromProto(mapCtx, in.GetAccessConfig()) + if in.GetKmsKey() != "" { + out.KmsKeyRef = &refs.KMSCryptoKeyRef{External: in.GetKmsKey()} + } + return out +} +func GcpConfig_ToProto(mapCtx *direct.MapContext, in *krm.GcpConfig) *pb.GcpConfig { + if in == nil { + return nil + } + out := &pb.GcpConfig{} + out.AccessConfig = AccessConfig_ToProto(mapCtx, in.AccessConfig) + if in.KmsKeyRef != nil { + out.KmsKey = in.KmsKeyRef.External + } + return out +} +func NetworkConfig_FromProto(mapCtx *direct.MapContext, in *pb.NetworkConfig) *krm.NetworkConfig { + if in == nil { + return nil + } + out := &krm.NetworkConfig{} + if in.GetSubnet() != "" { + out.SubnetworkRef = &refs.ComputeSubnetworkRef{External: in.GetSubnet()} + } + return out +} +func NetworkConfig_ToProto(mapCtx *direct.MapContext, in *krm.NetworkConfig) *pb.NetworkConfig { + if in == nil { + return nil + } + out := &pb.NetworkConfig{} + if in.SubnetworkRef != nil { + out.Subnet = in.SubnetworkRef.External + } + return out +} diff --git a/pkg/controller/direct/managedkafka/mapper.generated.go b/pkg/controller/direct/managedkafka/mapper.generated.go new file mode 100644 index 0000000000..b84f7e9f7c --- /dev/null +++ b/pkg/controller/direct/managedkafka/mapper.generated.go @@ -0,0 +1,118 @@ +// Copyright 2025 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 managedkafka + +import ( + pb "cloud.google.com/go/managedkafka/apiv1/managedkafkapb" + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/managedkafka/v1alpha1" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct" +) + +func AccessConfig_FromProto(mapCtx *direct.MapContext, in *pb.AccessConfig) *krm.AccessConfig { + if in == nil { + return nil + } + out := &krm.AccessConfig{} + out.NetworkConfigs = direct.Slice_FromProto(mapCtx, in.NetworkConfigs, NetworkConfig_FromProto) + return out +} +func AccessConfig_ToProto(mapCtx *direct.MapContext, in *krm.AccessConfig) *pb.AccessConfig { + if in == nil { + return nil + } + out := &pb.AccessConfig{} + out.NetworkConfigs = direct.Slice_ToProto(mapCtx, in.NetworkConfigs, NetworkConfig_ToProto) + return out +} +func CapacityConfig_FromProto(mapCtx *direct.MapContext, in *pb.CapacityConfig) *krm.CapacityConfig { + if in == nil { + return nil + } + out := &krm.CapacityConfig{} + out.VcpuCount = direct.LazyPtr(in.GetVcpuCount()) + out.MemoryBytes = direct.LazyPtr(in.GetMemoryBytes()) + return out +} +func CapacityConfig_ToProto(mapCtx *direct.MapContext, in *krm.CapacityConfig) *pb.CapacityConfig { + if in == nil { + return nil + } + out := &pb.CapacityConfig{} + out.VcpuCount = direct.ValueOf(in.VcpuCount) + out.MemoryBytes = direct.ValueOf(in.MemoryBytes) + return out +} +func ManagedKafkaClusterObservedState_FromProto(mapCtx *direct.MapContext, in *pb.Cluster) *krm.ManagedKafkaClusterObservedState { + if in == nil { + return nil + } + out := &krm.ManagedKafkaClusterObservedState{} + out.Name = direct.LazyPtr(in.GetName()) + out.CreateTime = direct.StringTimestamp_FromProto(mapCtx, in.GetCreateTime()) + out.UpdateTime = direct.StringTimestamp_FromProto(mapCtx, in.GetUpdateTime()) + out.State = direct.Enum_FromProto(mapCtx, in.GetState()) + return out +} +func ManagedKafkaClusterObservedState_ToProto(mapCtx *direct.MapContext, in *krm.ManagedKafkaClusterObservedState) *pb.Cluster { + if in == nil { + return nil + } + out := &pb.Cluster{} + out.Name = direct.ValueOf(in.Name) + out.CreateTime = direct.StringTimestamp_ToProto(mapCtx, in.CreateTime) + out.UpdateTime = direct.StringTimestamp_ToProto(mapCtx, in.UpdateTime) + out.State = direct.Enum_ToProto[pb.Cluster_State](mapCtx, in.State) + return out +} +func ManagedKafkaClusterSpec_FromProto(mapCtx *direct.MapContext, in *pb.Cluster) *krm.ManagedKafkaClusterSpec { + if in == nil { + return nil + } + out := &krm.ManagedKafkaClusterSpec{} + out.GcpConfig = GcpConfig_FromProto(mapCtx, in.GetGcpConfig()) + out.Labels = in.Labels + out.CapacityConfig = CapacityConfig_FromProto(mapCtx, in.GetCapacityConfig()) + out.RebalanceConfig = RebalanceConfig_FromProto(mapCtx, in.GetRebalanceConfig()) + return out +} +func ManagedKafkaClusterSpec_ToProto(mapCtx *direct.MapContext, in *krm.ManagedKafkaClusterSpec) *pb.Cluster { + if in == nil { + return nil + } + out := &pb.Cluster{} + if oneof := GcpConfig_ToProto(mapCtx, in.GcpConfig); oneof != nil { + out.PlatformConfig = &pb.Cluster_GcpConfig{GcpConfig: oneof} + } + out.Labels = in.Labels + out.CapacityConfig = CapacityConfig_ToProto(mapCtx, in.CapacityConfig) + out.RebalanceConfig = RebalanceConfig_ToProto(mapCtx, in.RebalanceConfig) + return out +} +func RebalanceConfig_FromProto(mapCtx *direct.MapContext, in *pb.RebalanceConfig) *krm.RebalanceConfig { + if in == nil { + return nil + } + out := &krm.RebalanceConfig{} + out.Mode = direct.Enum_FromProto(mapCtx, in.GetMode()) + return out +} +func RebalanceConfig_ToProto(mapCtx *direct.MapContext, in *krm.RebalanceConfig) *pb.RebalanceConfig { + if in == nil { + return nil + } + out := &pb.RebalanceConfig{} + out.Mode = direct.Enum_ToProto[pb.RebalanceConfig_Mode](mapCtx, in.Mode) + return out +} From 71d052e96c7d45545ab530ffde41b73bdd66cec8 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Mon, 27 Jan 2025 03:22:39 +0000 Subject: [PATCH 5/7] feat: implement direct controller for ManagedKafkaCluster --- .../direct/managedkafka/cluster_controller.go | 298 ++++++++++++++++++ pkg/controller/direct/register/register.go | 1 + 2 files changed, 299 insertions(+) create mode 100644 pkg/controller/direct/managedkafka/cluster_controller.go diff --git a/pkg/controller/direct/managedkafka/cluster_controller.go b/pkg/controller/direct/managedkafka/cluster_controller.go new file mode 100644 index 0000000000..70eb70c09f --- /dev/null +++ b/pkg/controller/direct/managedkafka/cluster_controller.go @@ -0,0 +1,298 @@ +// 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 managedkafka + +import ( + "context" + "fmt" + + krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/managedkafka/v1alpha1" + refs "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/common" + "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/managedkafka/apiv1" + pb "cloud.google.com/go/managedkafka/apiv1/managedkafkapb" + "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/apimachinery/pkg/util/sets" + "k8s.io/klog/v2" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func init() { + registry.RegisterModel(krm.ManagedKafkaClusterGVK, NewClusterModel) +} + +func NewClusterModel(ctx context.Context, config *config.ControllerConfig) (directbase.Model, error) { + return &modelCluster{config: *config}, nil +} + +var _ directbase.Model = &modelCluster{} + +type modelCluster struct { + config config.ControllerConfig +} + +func (m *modelCluster) client(ctx context.Context) (*gcp.Client, error) { + var opts []option.ClientOption + opts, err := m.config.RESTClientOptions() + if err != nil { + return nil, err + } + gcpClient, err := gcp.NewRESTClient(ctx, opts...) + if err != nil { + return nil, fmt.Errorf("building Cluster client: %w", err) + } + return gcpClient, err +} + +func (m *modelCluster) AdapterForObject(ctx context.Context, reader client.Reader, u *unstructured.Unstructured) (directbase.Adapter, error) { + obj := &krm.ManagedKafkaCluster{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &obj); err != nil { + return nil, fmt.Errorf("error converting to %T: %w", obj, err) + } + + id, err := krm.NewClusterIdentity(ctx, reader, obj) + if err != nil { + return nil, err + } + + // Get managedkafka GCP client + gcpClient, err := m.client(ctx) + if err != nil { + return nil, err + } + return &ClusterAdapter{ + id: id, + gcpClient: gcpClient, + desired: obj, + reader: reader, + }, nil +} + +func (m *modelCluster) AdapterForURL(ctx context.Context, url string) (directbase.Adapter, error) { + // TODO: Support URLs + return nil, nil +} + +type ClusterAdapter struct { + id *krm.ClusterIdentity + gcpClient *gcp.Client + desired *krm.ManagedKafkaCluster + actual *pb.Cluster + reader client.Reader +} + +var _ directbase.Adapter = &ClusterAdapter{} + +// Find retrieves the GCP resource. +// Return true means the object is found. This triggers Adapter `Update` call. +// Return false means the object is not found. This triggers Adapter `Create` call. +// Return a non-nil error requeues the requests. +func (a *ClusterAdapter) Find(ctx context.Context) (bool, error) { + log := klog.FromContext(ctx) + log.V(2).Info("getting Cluster", "name", a.id) + + req := &pb.GetClusterRequest{Name: a.id.String()} + clusterpb, err := a.gcpClient.GetCluster(ctx, req) + if err != nil { + if direct.IsNotFound(err) { + return false, nil + } + return false, fmt.Errorf("getting Cluster %q: %w", a.id, err) + } + + a.actual = clusterpb + 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 *ClusterAdapter) Create(ctx context.Context, createOp *directbase.CreateOperation) error { + log := klog.FromContext(ctx) + log.V(2).Info("creating Cluster", "name", a.id) + + if err := a.normalizeReference(ctx); err != nil { + return err + } + + mapCtx := &direct.MapContext{} + desired := a.desired.DeepCopy() + resource := ManagedKafkaClusterSpec_ToProto(mapCtx, &desired.Spec) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + + // TODO(contributor): Complete the gcp "CREATE" or "INSERT" request. + req := &pb.CreateClusterRequest{ + Parent: a.id.Parent().String(), + ClusterId: a.id.ID(), // Note: this is not the fully qualified name for this resource, it is just the resource ID + Cluster: resource, + } + op, err := a.gcpClient.CreateCluster(ctx, req) + if err != nil { + return fmt.Errorf("creating Cluster %s: %w", a.id, err) + } + created, err := op.Wait(ctx) + if err != nil { + return fmt.Errorf("waiting for creation of Cluster %s: %w", a.id, err) + } + log.V(2).Info("successfully created Cluster", "name", a.id) + + status := &krm.ManagedKafkaClusterStatus{} + status.ObservedState = ManagedKafkaClusterObservedState_FromProto(mapCtx, created) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + status.ExternalRef = &created.Name // populate externalRef + 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 *ClusterAdapter) Update(ctx context.Context, updateOp *directbase.UpdateOperation) error { + log := klog.FromContext(ctx) + log.V(2).Info("updating Cluster", "name", a.id) + + if err := a.normalizeReference(ctx); err != nil { + return err + } + + mapCtx := &direct.MapContext{} + desiredPb := ManagedKafkaClusterSpec_ToProto(mapCtx, &a.desired.DeepCopy().Spec) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + + paths, err := common.CompareProtoMessage(desiredPb, a.actual, common.BasicDiff) + if err != nil { + return err + } + + if len(paths) == 0 { + log.V(2).Info("no field needs update", "name", a.id.String()) + status := &krm.ManagedKafkaClusterStatus{} + status.ObservedState = ManagedKafkaClusterObservedState_FromProto(mapCtx, a.actual) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + return updateOp.UpdateStatus(ctx, status, nil) + } + updateMask := &fieldmaskpb.FieldMask{ + Paths: sets.List(paths)} + + desiredPb.Name = a.id.String() // populate the name field so that the GCP API can identify the resource + req := &pb.UpdateClusterRequest{ + UpdateMask: updateMask, + Cluster: desiredPb, + } + op, err := a.gcpClient.UpdateCluster(ctx, req) + if err != nil { + return fmt.Errorf("updating Cluster %s: %w", a.id.String(), err) + } + updated, err := op.Wait(ctx) + if err != nil { + return fmt.Errorf("waiting update for Cluster %s: %w", a.id.String(), err) + } + log.V(2).Info("successfully updated Cluster", "name", a.id.String()) + + status := &krm.ManagedKafkaClusterStatus{} + status.ExternalRef = &updated.Name // populate externalRef + status.ObservedState = ManagedKafkaClusterObservedState_FromProto(mapCtx, updated) + if mapCtx.Err() != nil { + return mapCtx.Err() + } + return updateOp.UpdateStatus(ctx, status, nil) +} + +// Export maps the GCP object to a Config Connector resource `spec`. +func (a *ClusterAdapter) Export(ctx context.Context) (*unstructured.Unstructured, error) { + if a.actual == nil { + return nil, fmt.Errorf("Find() not called") + } + u := &unstructured.Unstructured{} + + obj := &krm.ManagedKafkaCluster{} + mapCtx := &direct.MapContext{} + obj.Spec = direct.ValueOf(ManagedKafkaClusterSpec_FromProto(mapCtx, a.actual)) + if mapCtx.Err() != nil { + return nil, mapCtx.Err() + } + obj.Spec.ProjectRef = &refs.ProjectRef{External: a.id.Parent().ProjectID} + obj.Spec.Location = a.id.Parent().Location + uObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + if err != nil { + return nil, err + } + + u.SetName(a.actual.Name) + u.SetGroupVersionKind(krm.ManagedKafkaClusterGVK) + + u.Object = uObj + return u, nil +} + +// Delete the resource from GCP service when the corresponding Config Connector resource is deleted. +func (a *ClusterAdapter) Delete(ctx context.Context, deleteOp *directbase.DeleteOperation) (bool, error) { + log := klog.FromContext(ctx) + log.V(2).Info("deleting Cluster", "name", a.id) + + req := &pb.DeleteClusterRequest{Name: a.id.String()} + op, err := a.gcpClient.DeleteCluster(ctx, req) + if err != nil { + return false, fmt.Errorf("deleting Cluster %s: %w", a.id, err) + } + log.V(2).Info("successfully deleted Cluster", "name", a.id) + + err = op.Wait(ctx) + if err != nil { + return false, fmt.Errorf("waiting delete Cluster %s: %w", a.id, err) + } + return true, nil +} + +func (a *ClusterAdapter) normalizeReference(ctx context.Context) error { + obj := a.desired + + // Normalize the subnetworkRef in the accessConfig.networkConfigs + if obj.Spec.GcpConfig != nil && obj.Spec.GcpConfig.AccessConfig != nil && obj.Spec.GcpConfig.AccessConfig.NetworkConfigs != nil { + for i := range obj.Spec.GcpConfig.AccessConfig.NetworkConfigs { + networkConfig := &obj.Spec.GcpConfig.AccessConfig.NetworkConfigs[i] + if networkConfig.SubnetworkRef != nil { + subnet, err := refs.ResolveComputeSubnetwork(ctx, a.reader, obj, networkConfig.SubnetworkRef) + if err != nil { + return err + } + networkConfig.SubnetworkRef = subnet + } + } + } + + // Normalize the kmsKeyRef in the gcpConfig + if obj.Spec.GcpConfig != nil && obj.Spec.GcpConfig.KmsKeyRef != nil { + kmsKey, err := refs.ResolveKMSCryptoKeyRef(ctx, a.reader, obj, obj.Spec.GcpConfig.KmsKeyRef) + if err != nil { + return err + } + obj.Spec.GcpConfig.KmsKeyRef = kmsKey + } + + return nil +} diff --git a/pkg/controller/direct/register/register.go b/pkg/controller/direct/register/register.go index 78cd411129..9dce92703d 100644 --- a/pkg/controller/direct/register/register.go +++ b/pkg/controller/direct/register/register.go @@ -36,6 +36,7 @@ import ( _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/kms/autokeyconfig" _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/kms/keyhandle" _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/logging" + _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/managedkafka" _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/monitoring" _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/networkconnectivity" _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/privateca" From 95446393d4a95ebcd8c7b2ff543b59678969fbe0 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Mon, 27 Jan 2025 03:23:12 +0000 Subject: [PATCH 6/7] test: add a basic test for ManagedKafkaCluster --- ...ted_object_managedkafkacluster.golden.yaml | 41 + .../v1alpha1/managedkafkacluster/_http.log | 1466 +++++++++++++++++ .../v1alpha1/managedkafkacluster/create.yaml | 32 + .../managedkafkacluster/dependencies.yaml | 47 + .../v1alpha1/managedkafkacluster/update.yaml | 34 + 5 files changed, 1620 insertions(+) create mode 100644 pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_generated_object_managedkafkacluster.golden.yaml create mode 100644 pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_http.log create mode 100644 pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/create.yaml create mode 100644 pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/dependencies.yaml create mode 100644 pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/update.yaml diff --git a/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_generated_object_managedkafkacluster.golden.yaml b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_generated_object_managedkafkacluster.golden.yaml new file mode 100644 index 0000000000..f6703147a7 --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_generated_object_managedkafkacluster.golden.yaml @@ -0,0 +1,41 @@ +apiVersion: managedkafka.cnrm.cloud.google.com/v1alpha1 +kind: ManagedKafkaCluster +metadata: + finalizers: + - cnrm.cloud.google.com/finalizer + - cnrm.cloud.google.com/deletion-defender + generation: 2 + labels: + cnrm-test: "true" + name: managedkafkacluster-${uniqueId} + namespace: ${uniqueId} +spec: + capacityConfig: + memoryBytes: 4294967296 + vcpuCount: 4 + gcpConfig: + accessConfig: + networkConfigs: + - subnetworkRef: + name: computesubnetwork-${uniqueId}-1 + - subnetworkRef: + name: computesubnetwork-${uniqueId}-2 + location: us-central1 + projectRef: + external: ${projectId} + rebalanceConfig: + mode: AUTO_REBALANCE_ON_SCALE_UP +status: + conditions: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: The resource is up to date + reason: UpToDate + status: "True" + type: Ready + externalRef: projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId} + observedGeneration: 2 + observedState: + createTime: "1970-01-01T00:00:00Z" + name: projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId} + state: ACTIVE + updateTime: "1970-01-01T00:00:00Z" diff --git a/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_http.log b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_http.log new file mode 100644 index 0000000000..e82dbf8c5c --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/_http.log @@ -0,0 +1,1466 @@ +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +404 Not Found +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}-1' was not found", + "reason": "notFound" + } + ], + "message": "The resource 'projects/${projectId}/global/networks/computenetwork-${uniqueId}-1' was not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +{ + "autoCreateSubnetworks": false, + "name": "computenetwork-${uniqueId}-1", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL" +} + +200 OK +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": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "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 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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}-1", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "routingConfig": { + "bgpBestPathSelectionMode": "LEGACY", + "routingMode": "REGIONAL" + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +404 Not Found +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}-2' was not found", + "reason": "notFound" + } + ], + "message": "The resource 'projects/${projectId}/global/networks/computenetwork-${uniqueId}-2' was not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +{ + "autoCreateSubnetworks": false, + "name": "computenetwork-${uniqueId}-2", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL" +} + +200 OK +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": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "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 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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}-2", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "routingConfig": { + "bgpBestPathSelectionMode": "LEGACY", + "routingMode": "REGIONAL" + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +404 Not Found +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}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1' was not found", + "reason": "notFound" + } + ], + "message": "The resource 'projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1' was not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +{ + "ipCidrRange": "10.0.0.0/24", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-1", + "network": "projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "region": "projects/${projectId}/global/regions/us-central1" +} + +200 OK +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, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: google-api-go-client/0.5 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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 + +{ + "allowSubnetCidrRoutesOverlap": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "enableFlowLogs": false, + "fingerprint": "abcdef0123A=", + "gatewayAddress": "10.0.0.1", + "id": "000000000000000000000", + "ipCidrRange": "10.0.0.0/24", + "kind": "compute#subnetwork", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-1", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "privateIpGoogleAccess": false, + "privateIpv6GoogleAccess": "DISABLE_GOOGLE_ACCESS", + "purpose": "PRIVATE", + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1", + "stackType": "IPV4_ONLY" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +404 Not Found +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}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2' was not found", + "reason": "notFound" + } + ], + "message": "The resource 'projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2' was not found" + } +} + +--- + +POST https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +{ + "ipCidrRange": "10.0.1.0/24", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-2", + "network": "projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "region": "projects/${projectId}/global/regions/us-central1" +} + +200 OK +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, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: google-api-go-client/0.5 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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 + +{ + "allowSubnetCidrRoutesOverlap": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "enableFlowLogs": false, + "fingerprint": "abcdef0123A=", + "gatewayAddress": "10.0.1.1", + "id": "000000000000000000000", + "ipCidrRange": "10.0.1.0/24", + "kind": "compute#subnetwork", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-2", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "privateIpGoogleAccess": false, + "privateIpv6GoogleAccess": "DISABLE_GOOGLE_ACCESS", + "purpose": "PRIVATE", + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2", + "stackType": "IPV4_ONLY" +} + +--- + +GET https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}?%24alt=json%3Benum-encoding%3Dint +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: name=projects%2F${projectId}%2Flocations%2Fus-central1%2Fclusters%2Fmanagedkafkacluster-${uniqueId} + +404 Not Found +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/us-central1/clusters/managedkafkacluster-${uniqueId}' was not found", + "status": "NOT_FOUND" + } +} + +--- + +POST https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/clusters?%24alt=json%3Benum-encoding%3Dint&clusterId=managedkafkacluster-${uniqueId} +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: parent=projects%2F${projectId}%2Flocations%2Fus-central1 + +{ + "capacityConfig": { + "memoryBytes": "3221225472", + "vcpuCount": "3" + }, + "gcpConfig": { + "accessConfig": { + "networkConfigs": [ + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1" + } + ] + } + }, + "rebalanceConfig": { + "mode": 1 + } +} + +200 OK +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": false, + "metadata": { + "@type": "type.googleapis.com/google.cloud.managedkafka.v1.OperationMetadata", + "apiVersion": "v1", + "createTime": "2024-04-01T12:34:56.123456Z", + "requestedCancellation": false, + "target": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "verb": "create" + }, + "name": "projects/${projectId}/locations/us-central1/operations/${operationID}" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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}-1", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "routingConfig": { + "bgpBestPathSelectionMode": "LEGACY", + "routingMode": "REGIONAL" + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "subnetworks": [ + "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1" + ] +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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}-2", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "routingConfig": { + "bgpBestPathSelectionMode": "LEGACY", + "routingMode": "REGIONAL" + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}", + "subnetworks": [ + "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2" + ] +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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 + +{ + "allowSubnetCidrRoutesOverlap": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "enableFlowLogs": false, + "fingerprint": "abcdef0123A=", + "gatewayAddress": "10.0.1.1", + "id": "000000000000000000000", + "ipCidrRange": "10.0.1.0/24", + "kind": "compute#subnetwork", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-2", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "privateIpGoogleAccess": false, + "privateIpv6GoogleAccess": "DISABLE_GOOGLE_ACCESS", + "purpose": "PRIVATE", + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2", + "stackType": "IPV4_ONLY" +} + +--- + +GET https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/operations/${operationID} +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: name=projects%2F${projectId}%2Flocations%2Fus-central1%2Foperations%2F${operationID} + +200 OK +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.managedkafka.v1.OperationMetadata", + "apiVersion": "v1", + "createTime": "2024-04-01T12:34:56.123456Z", + "endTime": "2024-04-01T12:34:56.123456Z", + "requestedCancellation": false, + "target": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "verb": "create" + }, + "name": "projects/${projectId}/locations/us-central1/operations/${operationID}", + "response": { + "@type": "type.googleapis.com/google.cloud.managedkafka.v1.Cluster", + "capacityConfig": { + "memoryBytes": "3221225472", + "vcpuCount": "3" + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "gcpConfig": { + "accessConfig": { + "networkConfigs": [ + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1" + } + ] + } + }, + "name": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "rebalanceConfig": { + "mode": "NO_REBALANCE" + }, + "satisfiesPzi": false, + "satisfiesPzs": false, + "state": "ACTIVE", + "updateTime": "2024-04-01T12:34:56.123456Z" + } +} + +--- + +GET https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}?%24alt=json%3Benum-encoding%3Dint +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: name=projects%2F${projectId}%2Flocations%2Fus-central1%2Fclusters%2Fmanagedkafkacluster-${uniqueId} + +200 OK +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 + +{ + "capacityConfig": { + "memoryBytes": "3221225472", + "vcpuCount": "3" + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "gcpConfig": { + "accessConfig": { + "networkConfigs": [ + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1" + } + ] + } + }, + "name": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "rebalanceConfig": { + "mode": 1 + }, + "satisfiesPzi": false, + "satisfiesPzs": false, + "state": 2, + "updateTime": "2024-04-01T12:34:56.123456Z" +} + +--- + +PATCH https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}?%24alt=json%3Benum-encoding%3Dint&updateMask=capacityConfig.memoryBytes%2CcapacityConfig.vcpuCount%2CgcpConfig.accessConfig.networkConfigs%2Cname%2CrebalanceConfig.mode +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: cluster.name=projects%2F${projectId}%2Flocations%2Fus-central1%2Fclusters%2Fmanagedkafkacluster-${uniqueId} + +{ + "capacityConfig": { + "memoryBytes": "4294967296", + "vcpuCount": "4" + }, + "gcpConfig": { + "accessConfig": { + "networkConfigs": [ + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1" + }, + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2" + } + ] + } + }, + "name": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "rebalanceConfig": { + "mode": 2 + } +} + +200 OK +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": false, + "metadata": { + "@type": "type.googleapis.com/google.cloud.managedkafka.v1.OperationMetadata", + "apiVersion": "v1", + "createTime": "2024-04-01T12:34:56.123456Z", + "requestedCancellation": false, + "target": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "verb": "update" + }, + "name": "projects/${projectId}/locations/us-central1/operations/${operationID}" +} + +--- + +GET https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/operations/${operationID} +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: name=projects%2F${projectId}%2Flocations%2Fus-central1%2Foperations%2F${operationID} + +200 OK +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.managedkafka.v1.OperationMetadata", + "apiVersion": "v1", + "createTime": "2024-04-01T12:34:56.123456Z", + "endTime": "2024-04-01T12:34:56.123456Z", + "requestedCancellation": false, + "target": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "verb": "update" + }, + "name": "projects/${projectId}/locations/us-central1/operations/${operationID}", + "response": { + "@type": "type.googleapis.com/google.cloud.managedkafka.v1.Cluster", + "capacityConfig": { + "memoryBytes": "4294967296", + "vcpuCount": "4" + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "gcpConfig": { + "accessConfig": { + "networkConfigs": [ + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1" + }, + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2" + } + ] + } + }, + "name": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "rebalanceConfig": { + "mode": "AUTO_REBALANCE_ON_SCALE_UP" + }, + "satisfiesPzi": false, + "satisfiesPzs": false, + "state": "ACTIVE", + "updateTime": "2024-04-01T12:34:56.123456Z" + } +} + +--- + +GET https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}?%24alt=json%3Benum-encoding%3Dint +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: name=projects%2F${projectId}%2Flocations%2Fus-central1%2Fclusters%2Fmanagedkafkacluster-${uniqueId} + +200 OK +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 + +{ + "capacityConfig": { + "memoryBytes": "4294967296", + "vcpuCount": "4" + }, + "createTime": "2024-04-01T12:34:56.123456Z", + "gcpConfig": { + "accessConfig": { + "networkConfigs": [ + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1" + }, + { + "subnet": "projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2" + } + ] + } + }, + "name": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "rebalanceConfig": { + "mode": 2 + }, + "satisfiesPzi": false, + "satisfiesPzs": false, + "state": 2, + "updateTime": "2024-04-01T12:34:56.123456Z" +} + +--- + +DELETE https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}?%24alt=json%3Benum-encoding%3Dint +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: name=projects%2F${projectId}%2Flocations%2Fus-central1%2Fclusters%2Fmanagedkafkacluster-${uniqueId} + +200 OK +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": false, + "metadata": { + "@type": "type.googleapis.com/google.cloud.managedkafka.v1.OperationMetadata", + "apiVersion": "v1", + "createTime": "2024-04-01T12:34:56.123456Z", + "requestedCancellation": false, + "target": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "verb": "delete" + }, + "name": "projects/${projectId}/locations/us-central1/operations/${operationID}" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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 + +{ + "allowSubnetCidrRoutesOverlap": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "enableFlowLogs": false, + "fingerprint": "abcdef0123A=", + "gatewayAddress": "10.0.0.1", + "id": "000000000000000000000", + "ipCidrRange": "10.0.0.0/24", + "kind": "compute#subnetwork", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-1", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "privateIpGoogleAccess": false, + "privateIpv6GoogleAccess": "DISABLE_GOOGLE_ACCESS", + "purpose": "PRIVATE", + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1", + "stackType": "IPV4_ONLY" +} + +--- + +GET https://managedkafka.googleapis.com/v1/projects/${projectId}/locations/us-central1/operations/${operationID} +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} +X-Goog-Request-Params: name=projects%2F${projectId}%2Flocations%2Fus-central1%2Foperations%2F${operationID} + +200 OK +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.managedkafka.v1.OperationMetadata", + "apiVersion": "v1", + "createTime": "2024-04-01T12:34:56.123456Z", + "endTime": "2024-04-01T12:34:56.123456Z", + "requestedCancellation": false, + "target": "projects/${projectId}/locations/us-central1/clusters/managedkafkacluster-${uniqueId}", + "verb": "delete" + }, + "name": "projects/${projectId}/locations/us-central1/operations/${operationID}", + "response": { + "@type": "type.googleapis.com/google.protobuf.Empty" + } +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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 + +{ + "allowSubnetCidrRoutesOverlap": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "enableFlowLogs": false, + "fingerprint": "abcdef0123A=", + "gatewayAddress": "10.0.1.1", + "id": "000000000000000000000", + "ipCidrRange": "10.0.1.0/24", + "kind": "compute#subnetwork", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-2", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "privateIpGoogleAccess": false, + "privateIpv6GoogleAccess": "DISABLE_GOOGLE_ACCESS", + "purpose": "PRIVATE", + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2", + "stackType": "IPV4_ONLY" +} + +--- + +DELETE https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 0, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: google-api-go-client/0.5 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 100, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-2", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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 + +{ + "allowSubnetCidrRoutesOverlap": false, + "creationTimestamp": "2024-04-01T12:34:56.123456Z", + "enableFlowLogs": false, + "fingerprint": "abcdef0123A=", + "gatewayAddress": "10.0.0.1", + "id": "000000000000000000000", + "ipCidrRange": "10.0.0.0/24", + "kind": "compute#subnetwork", + "logConfig": { + "enable": false + }, + "name": "computesubnetwork-${uniqueId}-1", + "network": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "privateIpGoogleAccess": false, + "privateIpv6GoogleAccess": "DISABLE_GOOGLE_ACCESS", + "purpose": "PRIVATE", + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1", + "stackType": "IPV4_ONLY" +} + +--- + +DELETE https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/${subnetworkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 0, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}?alt=json&prettyPrint=false +User-Agent: google-api-go-client/0.5 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 100, + "region": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1", + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${subnetworkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/regions/us-central1/subnetworks/computesubnetwork-${uniqueId}-1", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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}-2", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "routingConfig": { + "bgpBestPathSelectionMode": "LEGACY", + "routingMode": "REGIONAL" + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}" +} + +--- + +DELETE https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "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 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-2", + "user": "user@example.com" +} + +--- + +GET https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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}-1", + "networkFirewallPolicyEnforcementOrder": "AFTER_CLASSIC_FIREWALL", + "routingConfig": { + "bgpBestPathSelectionMode": "LEGACY", + "routingMode": "REGIONAL" + }, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}" +} + +--- + +DELETE https://compute.googleapis.com/compute/v1/projects/${projectId}/global/networks/${networkID}?alt=json +Content-Type: application/json +User-Agent: kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 0, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "RUNNING", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "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 kcc/${kccVersion} (+https://github.com/GoogleCloudPlatform/k8s-config-connector) kcc/controller-manager/${kccVersion} + +200 OK +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": "delete", + "progress": 100, + "selfLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/operations/${operationID}", + "startTime": "2024-04-01T12:34:56.123456Z", + "status": "DONE", + "targetId": "${networkID}", + "targetLink": "https://www.googleapis.com/compute/v1/projects/${projectId}/global/networks/computenetwork-${uniqueId}-1", + "user": "user@example.com" +} \ No newline at end of file diff --git a/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/create.yaml b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/create.yaml new file mode 100644 index 0000000000..7a890ef576 --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/create.yaml @@ -0,0 +1,32 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: managedkafka.cnrm.cloud.google.com/v1alpha1 +kind: ManagedKafkaCluster +metadata: + name: managedkafkacluster-${uniqueId} +spec: + projectRef: + external: ${projectId} + location: us-central1 + capacityConfig: + vcpuCount: 3 + memoryBytes: 3221225472 # 3GB + gcpConfig: + accessConfig: + networkConfigs: + - subnetworkRef: + name: computesubnetwork-${uniqueId}-1 + rebalanceConfig: + mode: NO_REBALANCE diff --git a/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/dependencies.yaml b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/dependencies.yaml new file mode 100644 index 0000000000..cf56c4c07a --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/dependencies.yaml @@ -0,0 +1,47 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeNetwork +metadata: + name: computenetwork-${uniqueId}-1 +spec: + autoCreateSubnetworks: false +--- +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeNetwork +metadata: + name: computenetwork-${uniqueId}-2 +spec: + autoCreateSubnetworks: false +--- +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeSubnetwork +metadata: + name: computesubnetwork-${uniqueId}-1 +spec: + region: us-central1 + networkRef: + name: computenetwork-${uniqueId}-1 + ipCidrRange: 10.0.0.0/24 +--- +apiVersion: compute.cnrm.cloud.google.com/v1beta1 +kind: ComputeSubnetwork +metadata: + name: computesubnetwork-${uniqueId}-2 +spec: + region: us-central1 + networkRef: + name: computenetwork-${uniqueId}-2 + ipCidrRange: 10.0.1.0/24 diff --git a/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/update.yaml b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/update.yaml new file mode 100644 index 0000000000..3cc236ef22 --- /dev/null +++ b/pkg/test/resourcefixture/testdata/basic/managedkafka/v1alpha1/managedkafkacluster/update.yaml @@ -0,0 +1,34 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: managedkafka.cnrm.cloud.google.com/v1alpha1 +kind: ManagedKafkaCluster +metadata: + name: managedkafkacluster-${uniqueId} +spec: + projectRef: + external: ${projectId} + location: us-central1 + capacityConfig: + vcpuCount: 4 # 3 -> 4 + memoryBytes: 4294967296 # 3GB -> 4GB + gcpConfig: + accessConfig: + networkConfigs: + - subnetworkRef: + name: computesubnetwork-${uniqueId}-1 + - subnetworkRef: + name: computesubnetwork-${uniqueId}-2 # 1 subnetwork -> 2 subnetworks + rebalanceConfig: + mode: AUTO_REBALANCE_ON_SCALE_UP # NO_REBALANCE -> AUTO_REBALANCE_ON_SCALE_UP From 723b06d2445cdb4a1b821cd706851d6fe1cd00c0 Mon Sep 17 00:00:00 2001 From: Jingyi Hu Date: Tue, 28 Jan 2025 03:44:13 +0000 Subject: [PATCH 7/7] chore: make ready-pr --- .../components/clusterroles/cnrm_admin.yaml | 12 ++++++++++++ .../components/clusterroles/cnrm_viewer.yaml | 8 ++++++++ pkg/gvks/supportedgvks/gvks_generated.go | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/config/installbundle/components/clusterroles/cnrm_admin.yaml b/config/installbundle/components/clusterroles/cnrm_admin.yaml index a515fc7ddd..b91eebfe49 100644 --- a/config/installbundle/components/clusterroles/cnrm_admin.yaml +++ b/config/installbundle/components/clusterroles/cnrm_admin.yaml @@ -775,6 +775,18 @@ rules: - update - patch - delete +- apiGroups: + - managedkafka.cnrm.cloud.google.com + resources: + - '*' + verbs: + - get + - list + - watch + - create + - update + - patch + - delete - apiGroups: - memcache.cnrm.cloud.google.com resources: diff --git a/config/installbundle/components/clusterroles/cnrm_viewer.yaml b/config/installbundle/components/clusterroles/cnrm_viewer.yaml index e34e7d98eb..d31542680d 100644 --- a/config/installbundle/components/clusterroles/cnrm_viewer.yaml +++ b/config/installbundle/components/clusterroles/cnrm_viewer.yaml @@ -518,6 +518,14 @@ rules: - get - list - watch +- apiGroups: + - managedkafka.cnrm.cloud.google.com + resources: + - '*' + verbs: + - get + - list + - watch - apiGroups: - memcache.cnrm.cloud.google.com resources: diff --git a/pkg/gvks/supportedgvks/gvks_generated.go b/pkg/gvks/supportedgvks/gvks_generated.go index 2fb353ee2f..90eefca943 100644 --- a/pkg/gvks/supportedgvks/gvks_generated.go +++ b/pkg/gvks/supportedgvks/gvks_generated.go @@ -3297,6 +3297,16 @@ var SupportedGVKs = map[schema.GroupVersionKind]GVKMetadata{ "cnrm.cloud.google.com/system": "true", }, }, + { + Group: "managedkafka.cnrm.cloud.google.com", + Version: "v1alpha1", + Kind: "ManagedKafkaCluster", + }: { + Labels: map[string]string{ + "cnrm.cloud.google.com/managed-by-kcc": "true", + "cnrm.cloud.google.com/system": "true", + }, + }, { Group: "memcache.cnrm.cloud.google.com", Version: "v1beta1",