Skip to content

Commit 3d9b565

Browse files
committed
FirestoreDocument: CRD/Mapper/Fuzzer
1 parent ab2da86 commit 3d9b565

File tree

7 files changed

+382
-4
lines changed

7 files changed

+382
-4
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2025 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 v1alpha1
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2025 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 v1alpha1
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2025 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 v1alpha1
16+
17+
import (
18+
"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/k8s/v1alpha1"
19+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
var FirestoreDocumentGVK = GroupVersion.WithKind("FirestoreDocument")
24+
25+
// FirestoreDocumentSpec defines the desired state of FirestoreDocument
26+
// +kcc:spec:proto=google.firestore.v1.Document
27+
type FirestoreDocumentSpec struct {
28+
// The FirestoreDocument name. If not given, the metadata.name will be used.
29+
ResourceID *string `json:"resourceID,omitempty"`
30+
31+
// // The resource name of the document, for example
32+
// // `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
33+
// // +kcc:proto:field=google.firestore.v1.Document.name
34+
// Name *string `json:"name,omitempty"`
35+
36+
// Fields holds the field values; values follow JSON typing conventions.
37+
Fields map[string]apiextensionsv1.JSON `json:"fields,omitempty"`
38+
}
39+
40+
// FirestoreDocumentStatus defines the config connector machine state of FirestoreDocument
41+
type FirestoreDocumentStatus struct {
42+
/* Conditions represent the latest available observations of the
43+
object's current state. */
44+
Conditions []v1alpha1.Condition `json:"conditions,omitempty"`
45+
46+
// 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.
47+
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
48+
49+
// A unique specifier for the FirestoreDocument resource in GCP.
50+
ExternalRef *string `json:"externalRef,omitempty"`
51+
52+
// ObservedState is the state of the resource as most recently observed in GCP.
53+
ObservedState *FirestoreDocumentObservedState `json:"observedState,omitempty"`
54+
}
55+
56+
// FirestoreDocumentObservedState is the state of the FirestoreDocument resource as most recently observed in GCP.
57+
// +kcc:observedstate:proto=google.firestore.v1.Document
58+
type FirestoreDocumentObservedState struct {
59+
// Output only. The time at which the document was created.
60+
//
61+
// This value increases monotonically when a document is deleted then
62+
// recreated. It can also be compared to values from other documents and
63+
// the `read_time` of a query.
64+
// +kcc:proto:field=google.firestore.v1.Document.create_time
65+
CreateTime *string `json:"createTime,omitempty"`
66+
67+
// Output only. The time at which the document was last changed.
68+
//
69+
// This value is initially set to the `create_time` then increases
70+
// monotonically with each change to the document. It can also be
71+
// compared to values from other documents and the `read_time` of a query.
72+
// +kcc:proto:field=google.firestore.v1.Document.update_time
73+
UpdateTime *string `json:"updateTime,omitempty"`
74+
}
75+
76+
// +genclient
77+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
78+
// +kubebuilder:resource:categories=gcp,shortName=gcpfirestoredocument;gcpfirestoredocuments
79+
// +kubebuilder:subresource:status
80+
// +kubebuilder:metadata:labels="cnrm.cloud.google.com/managed-by-kcc=true";"cnrm.cloud.google.com/system=true"
81+
// +kubebuilder:printcolumn:name="Age",JSONPath=".metadata.creationTimestamp",type="date"
82+
// +kubebuilder:printcolumn:name="Ready",JSONPath=".status.conditions[?(@.type=='Ready')].status",type="string",description="When 'True', the most recent reconcile of the resource succeeded"
83+
// +kubebuilder:printcolumn:name="Status",JSONPath=".status.conditions[?(@.type=='Ready')].reason",type="string",description="The reason for the value in 'Ready'"
84+
// +kubebuilder:printcolumn:name="Status Age",JSONPath=".status.conditions[?(@.type=='Ready')].lastTransitionTime",type="date",description="The last transition time for the value in 'Status'"
85+
86+
// FirestoreDocument is the Schema for the FirestoreDocument API
87+
// +k8s:openapi-gen=true
88+
type FirestoreDocument struct {
89+
metav1.TypeMeta `json:",inline"`
90+
metav1.ObjectMeta `json:"metadata,omitempty"`
91+
92+
// +required
93+
Spec FirestoreDocumentSpec `json:"spec,omitempty"`
94+
Status FirestoreDocumentStatus `json:"status,omitempty"`
95+
}
96+
97+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
98+
// FirestoreDocumentList contains a list of FirestoreDocument
99+
type FirestoreDocumentList struct {
100+
metav1.TypeMeta `json:",inline"`
101+
metav1.ListMeta `json:"metadata,omitempty"`
102+
Items []FirestoreDocument `json:"items"`
103+
}
104+
105+
func init() {
106+
SchemeBuilder.Register(&FirestoreDocument{}, &FirestoreDocumentList{})
107+
}

apis/firestore/v1alpha1/generate.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
1716
set -o errexit
1817
set -o nounset
1918
set -o pipefail
@@ -24,16 +23,17 @@ cd ${REPO_ROOT}/dev/tools/controllerbuilder
2423
go run . generate-types \
2524
--service google.firestore.admin.v1 \
2625
--api-version firestore.cnrm.cloud.google.com/v1alpha1 \
26+
--resource FirestoreDocument:google.firestore.v1.Document \
2727
--resource FirestoreField:Field \
2828
--resource FirestoreBackupSchedule:BackupSchedule
2929

3030
go run . generate-mapper \
3131
--multiversion \
3232
--service google.firestore.admin.v1 \
33+
--service google.firestore.v1 \
3334
--api-version firestore.cnrm.cloud.google.com/v1alpha1
3435

35-
3636
cd ${REPO_ROOT}
3737
dev/tasks/generate-crds
3838

39-
go run -mod=readonly golang.org/x/tools/cmd/goimports@latest -w pkg/controller/direct/firestore/
39+
go run -mod=readonly golang.org/x/tools/cmd/goimports@latest -w pkg/controller/direct/firestore/

dev/tools/controllerbuilder/generate-proto.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ protoc --include_imports --include_source_info \
8181
${THIRD_PARTY}/googleapis/google/cloud/*/*/*/*.proto \
8282
${THIRD_PARTY}/googleapis/google/cloud/*/*/*/*/*.proto \
8383
${THIRD_PARTY}/googleapis/google/dataflow/*/*.proto \
84-
${THIRD_PARTY}/googleapis/google/firestore/admin/v1/*.proto \
84+
${THIRD_PARTY}/googleapis/google/firestore/*/*.proto \
85+
${THIRD_PARTY}/googleapis/google/firestore/*/*/*.proto \
8586
${THIRD_PARTY}/googleapis/google/iam/v1/*.proto \
8687
${THIRD_PARTY}/googleapis/google/logging/v2/*.proto \
8788
${THIRD_PARTY}/googleapis/google/monitoring/v3/*.proto \
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright 2025 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+
// +tool:fuzz-gen
16+
// proto.message: google.firestore.v1.Document
17+
// api.group: firestore.cnrm.cloud.google.com
18+
19+
package firestore
20+
21+
import (
22+
pb "cloud.google.com/go/firestore/apiv1/firestorepb"
23+
"github.com/GoogleCloudPlatform/k8s-config-connector/pkg/fuzztesting"
24+
structpb "google.golang.org/protobuf/types/known/structpb"
25+
)
26+
27+
func init() {
28+
fuzztesting.RegisterKRMFuzzer(firestoreDocumentFuzzer())
29+
}
30+
31+
func firestoreDocumentFuzzer() fuzztesting.KRMFuzzer {
32+
f := fuzztesting.NewKRMTypedFuzzer(&pb.Document{},
33+
FirestoreDocumentSpec_v1alpha1_FromProto, FirestoreDocumentSpec_v1alpha1_ToProto,
34+
FirestoreDocumentObservedState_v1alpha1_FromProto, FirestoreDocumentObservedState_v1alpha1_ToProto,
35+
)
36+
f.FilterSpec = func(in *pb.Document) {
37+
for _, field := range in.GetFields() {
38+
removeUnsupportedFieldValues(field)
39+
}
40+
}
41+
42+
f.IdentityField(".name")
43+
44+
f.SpecField(".fields")
45+
46+
f.StatusField(".create_time")
47+
f.StatusField(".update_time")
48+
49+
return f
50+
}
51+
52+
// removeUnsupportedFieldValues removes field values that do not easily
53+
// round-trip to JSON, replacing them with null values.
54+
// These values are not currently supported in KCC FirestoreDocument resources.
55+
func removeUnsupportedFieldValues(v *pb.Value) {
56+
if v == nil {
57+
return
58+
}
59+
switch value := v.ValueType.(type) {
60+
case *pb.Value_MapValue:
61+
for _, fv := range value.MapValue.Fields {
62+
removeUnsupportedFieldValues(fv)
63+
}
64+
case *pb.Value_ArrayValue:
65+
for _, av := range value.ArrayValue.Values {
66+
removeUnsupportedFieldValues(av)
67+
}
68+
69+
// These types do not easily round-trip to JSON, so we omit them for now.
70+
case *pb.Value_BytesValue, *pb.Value_TimestampValue, *pb.Value_ReferenceValue, *pb.Value_GeoPointValue:
71+
v.ValueType = &pb.Value_NullValue{NullValue: structpb.NullValue_NULL_VALUE}
72+
}
73+
}

0 commit comments

Comments
 (0)