Skip to content

Commit 7a9e2af

Browse files
authored
testutils: Enforce CRD structural schema (#12833)
Signed-off-by: timflannagan <[email protected]>
1 parent e74aaa4 commit 7a9e2af

File tree

5 files changed

+22
-8
lines changed

5 files changed

+22
-8
lines changed

internal/kgateway/agentgatewaysyncer/testdata/inputs/backend/multipool-priority-levels.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,18 @@ spec:
5454
- name: gemini
5555
gemini:
5656
model: "gemini-1.5-flash"
57+
apiVersion: "v1"
5758
authToken:
5859
kind: "SecretRef"
5960
secretRef:
6061
name: gemini-fallback-secret
6162
- name: vertexai
6263
vertexai:
6364
model: "gemini-pro"
65+
apiVersion: "v1"
66+
location: "us-central1"
67+
projectId: "vertex-fallback-project"
68+
publisher: "GOOGLE"
6469
authToken:
6570
kind: "Passthrough"
6671
# Priority 2 - Tertiary fallback provider

internal/kgateway/agentgatewaysyncer/testdata/inputs/backend/multipool-secret-auth.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ spec:
4545
- name: gemini
4646
gemini:
4747
model: "gemini-1.5-pro"
48+
apiVersion: "v1"
4849
authToken:
4950
kind: "SecretRef"
5051
secretRef:

internal/kgateway/agentgatewaysyncer/testdata/outputs/backend/multipool-priority-levels.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Backends:
1515
- name: vertexai
1616
vertex:
1717
model: gemini-pro
18+
projectId: vertex-fallback-project
19+
region: us-central1
1820
- providers:
1921
- bedrock:
2022
model: anthropic.claude-3-haiku-20240307-v1:0

test/testutils/crd.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ func GetStructuralSchemas(
6767
func ApplyDefaults(
6868
objYAML []byte,
6969
structuralSchema *apiserverschema.Structural,
70-
) ([]byte, error) {
70+
) (*unstructured.Unstructured, []byte, error) {
7171
// Convert YAML to map without losing any fields (using the Go type with omitempty will drop zero-value fields)
7272
raw := make(map[string]interface{})
7373
err := yaml.Unmarshal(objYAML, &raw)
7474
if err != nil {
75-
return nil, err
75+
return nil, nil, err
7676
}
7777
u := &unstructured.Unstructured{
7878
Object: raw,
@@ -86,17 +86,17 @@ func ApplyDefaults(
8686
}
8787
unknownFields := structuralpruning.PruneWithOptions(u.Object, structuralSchema, true, pruneOpts)
8888
if len(unknownFields) > 0 {
89-
return nil, fmt.Errorf("got unknown fields: %v", unknownFields)
89+
return nil, nil, fmt.Errorf("got unknown fields: %v", unknownFields)
9090
}
9191
structuraldefaulting.PruneNonNullableNullsWithoutDefaults(u.Object, structuralSchema)
9292

9393
// Apply defaults
9494
structuraldefaulting.Default(u.UnstructuredContent(), structuralSchema)
9595
objYAML, err = yaml.Marshal(u.Object)
9696
if err != nil {
97-
return nil, err
97+
return nil, nil, err
9898
}
99-
return objYAML, nil
99+
return u, objYAML, nil
100100
}
101101

102102
func parseCRDs(path string) ([]*apiextensions.CustomResourceDefinition, error) {

test/testutils/file_loader.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/ghodss/yaml"
1515
apiserverschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
16+
apiextensionsvalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation"
1617
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1718
"k8s.io/apimachinery/pkg/runtime"
1819
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -136,12 +137,17 @@ func parseFile(
136137
}
137138

138139
if structuralSchema, ok := gvkToStructuralSchema[gvk]; ok {
139-
objYamlWithDefaults, err := ApplyDefaults(objYaml, structuralSchema)
140+
unstructuredObj, objYamlWithDefaults, err := ApplyDefaults(objYaml, structuralSchema)
140141
if err != nil {
141142
return nil, fmt.Errorf("failed to apply defaults for %s: %w", gvk, err)
142143
}
143-
err = yaml.Unmarshal(objYamlWithDefaults, obj)
144-
if err != nil {
144+
validator := apiextensionsvalidation.NewSchemaValidatorFromOpenAPI(structuralSchema.ToKubeOpenAPI())
145+
validationErrs := apiextensionsvalidation.ValidateCustomResource(nil, unstructuredObj.UnstructuredContent(), validator)
146+
if len(validationErrs) > 0 {
147+
agg := validationErrs.ToAggregate()
148+
return nil, fmt.Errorf("failed to validate %s: %w", gvk, agg)
149+
}
150+
if err := yaml.Unmarshal(objYamlWithDefaults, obj); err != nil {
145151
return nil, fmt.Errorf("failed to unmarshal object with defaults for %s: %w", gvk, err)
146152
}
147153
}

0 commit comments

Comments
 (0)