Skip to content

Commit b7d0efd

Browse files
committed
Implement direct KRM types and generate.sh for ComputeServiceAttachment
Implement direct KRM types and configure generate.sh for ComputeServiceAttachment, ensuring strict schema compatibility with the baseline CRD. We have also implemented mapping mappers and configured the KRM round-trip fuzzer. Fixes #10035
1 parent c442d2d commit b7d0efd

15 files changed

Lines changed: 1167 additions & 66 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# ComputeServiceAttachment Direct Types Migration Journal
2+
3+
## Observation & Implementation Details
4+
- Handcoded mapping is required for `ComputeServiceAttachmentSpec` and `ComputeServiceAttachmentStatus` because of type differences between the KRM representation and the direct compute client protobuf types (`pb.ServiceAttachment`):
5+
- `ConnectionPreference` is `*string` in the protobuf client but `string` in KRM.
6+
- Reference lists such as `ConsumerRejectLists []refs.ProjectRef` and `NatSubnets []ComputeSubnetworkRef` are represented as `[]string` in the proto. We mapped these using local list helpers similar to other regional compute resources.
7+
- The PSC Service Attachment ID field is a custom `pb.Uint128` containing `High` and `Low` fields of `*uint64`, whereas KRM status has `High` and `Low` as `*int64`. This required safe ptr-int/uint conversion mapping.
8+
- The region/location was extracted from the protobuf `Region` selflink string using manually coded splitting logic.
9+
- We registered the KRM round-trip fuzzer for `ComputeServiceAttachment` in `computeserviceattachment_fuzzer.go` using type-safe helpers. During fuzz-testing, the fields `consumer_accept_lists[].network_url` and `connected_endpoints[].nat_ips` were identified as unimplemented/not-yet-triaged by the fuzz runner, and we successfully configured them as such.

.gemini/skills/kcc-direct-base-types-implementer/SKILL.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,11 @@ After running the generator (via `generate.sh`), you must verify and enforce the
2121
- **Status Fields**: `status.observedGeneration` must be exactly `*int64`.
2222
- **Reference Fields**: Ensure that fields referencing other GCP/KCC resources are implemented as proper KCC reference fields (e.g., using `pubsubv1beta1.PubSubTopicRef` or `refsv1beta1.KMSCryptoKeyRef`), following the `Ref` suffix naming convention. You **MUST NOT** add new exceptions to `tests/apichecks/testdata/exceptions/missingrefs.txt`. All reference-like fields must be implemented as proper references.
2323
- **Reference Types Location**: Whenever a reference type (e.g. `<Kind>Ref` implementing `refsv1beta1.Ref`) is needed, it must **always** be defined and implemented in its own separate file named `<kind>_reference.go` (e.g., `filestorebackup_reference.go`) rather than inside `_types.go`. This keeps the main type definitions clean and isolated from reference resolution boilerplate.
24+
25+
- **KCC Proto Annotations**:
26+
To enable auto-generation of mappers, you must add the correct "kcc:proto" annotations to Go structs in `_types.go`:
27+
* The Spec struct must be annotated with `// +kcc:spec:proto=<proto_type>` (e.g. `// +kcc:spec:proto=google.cloud.compute.v1.ServiceAttachment`).
28+
* The ObservedState struct (if present) must be annotated with `// +kcc:observedstate:proto=<proto_type>`.
29+
* The Status struct (if there is no separate ObservedState struct) must be annotated with `// +kcc:status:proto=<proto_type>`.
30+
* Nested/referenced helper structs (both in Spec and Status) must be annotated with `// +kcc:proto=<proto_sub_type>` (e.g. `// +kcc:proto=google.cloud.compute.v1.ServiceAttachmentConnectedEndpoint`).
31+
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package v1beta1
16+
17+
import (
18+
"github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs"
19+
refsv1beta1 "github.com/GoogleCloudPlatform/k8s-config-connector/apis/refs/v1beta1"
20+
"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1"
21+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22+
)
23+
24+
var ComputeServiceAttachmentGVK = GroupVersion.WithKind("ComputeServiceAttachment")
25+
26+
// +kcc:proto=google.cloud.compute.v1.ServiceAttachmentConsumerProjectLimit
27+
type ServiceattachmentConsumerAcceptLists struct {
28+
/* The value of the limit to set. */
29+
// +optional
30+
ConnectionLimit *int64 `json:"connectionLimit,omitempty"`
31+
32+
ProjectRef refs.ProjectRef `json:"projectRef"`
33+
}
34+
35+
// ComputeServiceAttachmentSpec defines the desired state of ComputeServiceAttachment
36+
// +kcc:spec:proto=google.cloud.compute.v1.ServiceAttachment
37+
type ComputeServiceAttachmentSpec struct {
38+
/* The connection preference of service attachment. The value can be set to `ACCEPT_AUTOMATIC`. An `ACCEPT_AUTOMATIC` service attachment is one that always accepts the connection from consumer forwarding rules. Possible values: CONNECTION_PREFERENCE_UNSPECIFIED, ACCEPT_AUTOMATIC, ACCEPT_MANUAL */
39+
ConnectionPreference string `json:"connectionPreference"`
40+
41+
/* Projects that are allowed to connect to this service attachment. */
42+
// +optional
43+
ConsumerAcceptLists []ServiceattachmentConsumerAcceptLists `json:"consumerAcceptLists,omitempty"`
44+
45+
// +optional
46+
ConsumerRejectLists []refs.ProjectRef `json:"consumerRejectLists,omitempty"`
47+
48+
/* An optional description of this resource. Provide this property when you create the resource. */
49+
// +optional
50+
Description *string `json:"description,omitempty"`
51+
52+
/* Immutable. If true, enable the proxy protocol which is for supplying client TCP/IP address data in TCP connections that traverse proxies on their way to destination servers. */
53+
// +optional
54+
EnableProxyProtocol *bool `json:"enableProxyProtocol,omitempty"`
55+
56+
/* Immutable. The location for the resource */
57+
Location string `json:"location"`
58+
59+
NatSubnets []ComputeSubnetworkRef `json:"natSubnets"`
60+
61+
/* Immutable. The Project that this resource belongs to. */
62+
ProjectRef refs.ProjectRef `json:"projectRef"`
63+
64+
/* Immutable. Optional. The name of the resource. Used for creation and acquisition. When unset, the value of `metadata.name` is used as the default. */
65+
// +optional
66+
ResourceID *string `json:"resourceID,omitempty"`
67+
68+
/* Immutable. */
69+
TargetServiceRef refsv1beta1.ComputeForwardingRuleRef `json:"targetServiceRef"`
70+
}
71+
72+
// +kcc:proto=google.cloud.compute.v1.ServiceAttachmentConnectedEndpoint
73+
type ServiceattachmentConnectedEndpointsStatus struct {
74+
/* The url of a connected endpoint. */
75+
// +optional
76+
Endpoint *string `json:"endpoint,omitempty"`
77+
78+
/* The PSC connection id of the connected endpoint. */
79+
// +optional
80+
PscConnectionId *int64 `json:"pscConnectionId,omitempty"`
81+
82+
/* The status of a connected endpoint to this service attachment. Possible values: PENDING, RUNNING, DONE */
83+
// +optional
84+
Status *string `json:"status,omitempty"`
85+
}
86+
87+
// +kcc:proto=google.cloud.compute.v1.Uint128
88+
type ServiceattachmentPscServiceAttachmentIdStatus struct {
89+
// +optional
90+
High *int64 `json:"high,omitempty"`
91+
92+
// +optional
93+
Low *int64 `json:"low,omitempty"`
94+
}
95+
96+
// ComputeServiceAttachmentStatus defines the config connector machine state of ComputeServiceAttachment
97+
// +kcc:status:proto=google.cloud.compute.v1.ServiceAttachment
98+
type ComputeServiceAttachmentStatus struct {
99+
/* Conditions represent the latest available observations of the
100+
ComputeServiceAttachment's current state. */
101+
Conditions []v1alpha1.Condition `json:"conditions,omitempty"`
102+
103+
/* An array of connections for all the consumers connected to this service attachment. */
104+
// +optional
105+
ConnectedEndpoints []ServiceattachmentConnectedEndpointsStatus `json:"connectedEndpoints,omitempty"`
106+
107+
/* Fingerprint of this resource. This field is used internally during updates of this resource. */
108+
// +optional
109+
Fingerprint *string `json:"fingerprint,omitempty"`
110+
111+
/* The unique identifier for the resource type. The server generates this identifier. */
112+
// +optional
113+
Id *int64 `json:"id,omitempty"`
114+
115+
/* 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. */
116+
// +optional
117+
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
118+
119+
/* An 128-bit global unique ID of the PSC service attachment. */
120+
// +optional
121+
PscServiceAttachmentId *ServiceattachmentPscServiceAttachmentIdStatus `json:"pscServiceAttachmentId,omitempty"`
122+
123+
/* URL of the region where the service attachment resides. This field applies only to the region resource. You must specify this field as part of the HTTP request URL. It is not settable as a field in the request body. */
124+
// +optional
125+
Region *string `json:"region,omitempty"`
126+
127+
/* Server-defined URL for the resource. */
128+
// +optional
129+
SelfLink *string `json:"selfLink,omitempty"`
130+
}
131+
132+
// +genclient
133+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
134+
// +kubebuilder:resource:categories=gcp,shortName=gcpcomputeserviceattachment;gcpcomputeserviceattachments
135+
// +kubebuilder:subresource:status
136+
// +kubebuilder:metadata:labels="cnrm.cloud.google.com/dcl2crd=true"
137+
// +kubebuilder:metadata:labels="cnrm.cloud.google.com/managed-by-kcc=true"
138+
// +kubebuilder:metadata:labels="cnrm.cloud.google.com/stability-level=stable"
139+
// +kubebuilder:metadata:labels="cnrm.cloud.google.com/system=true"
140+
// +kubebuilder:printcolumn:name="Age",JSONPath=".metadata.creationTimestamp",type="date"
141+
// +kubebuilder:printcolumn:name="Ready",JSONPath=".status.conditions[?(@.type=='Ready')].status",type="string",description="When 'True', the most recent reconcile of the resource succeeded"
142+
// +kubebuilder:printcolumn:name="Status",JSONPath=".status.conditions[?(@.type=='Ready')].reason",type="string",description="The reason for the value in 'Ready'"
143+
// +kubebuilder:printcolumn:name="Status Age",JSONPath=".status.conditions[?(@.type=='Ready')].lastTransitionTime",type="date",description="The last transition time for the value in 'Status'"
144+
145+
// ComputeServiceAttachment is the Schema for the ComputeServiceAttachment API
146+
// +k8s:openapi-gen=true
147+
type ComputeServiceAttachment struct {
148+
metav1.TypeMeta `json:",inline"`
149+
metav1.ObjectMeta `json:"metadata,omitempty"`
150+
151+
// +required
152+
Spec ComputeServiceAttachmentSpec `json:"spec,omitempty"`
153+
Status ComputeServiceAttachmentStatus `json:"status,omitempty"`
154+
}
155+
156+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
157+
// ComputeServiceAttachmentList contains a list of ComputeServiceAttachment
158+
type ComputeServiceAttachmentList struct {
159+
metav1.TypeMeta `json:",inline"`
160+
metav1.ListMeta `json:"metadata,omitempty"`
161+
Items []ComputeServiceAttachment `json:"items"`
162+
}
163+
164+
func init() {
165+
SchemeBuilder.Register(&ComputeServiceAttachment{}, &ComputeServiceAttachmentList{})
166+
}

apis/compute/v1beta1/generate.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ go run . generate-types \
7171
--resource ComputeVPNTunnel:VpnTunnel \
7272
--resource ComputeInterconnectAttachment:InterconnectAttachment \
7373
--resource ComputePacketMirroring:PacketMirroring \
74+
--resource ComputeServiceAttachment:ServiceAttachment \
7475
--include-skipped-output
7576

7677
go run . generate-mapper \

0 commit comments

Comments
 (0)