Skip to content

Commit f64be28

Browse files
committed
feat: ignore errors in matchers and add format byte
Signed-off-by: Gergely Brautigam <[email protected]>
1 parent b4573d3 commit f64be28

9 files changed

+41
-22
lines changed

crd-testing-README.md

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ tests:
2323
- matchSnapshot:
2424
# this will generate one snapshot / CRD version and match all of them to the right version of the CRD
2525
path: sample-tests/__snapshots__
26+
ignoreErrors:
27+
- "ignore this match"
2628
- matchSnapshot:
2729
path: sample-tests/__snapshots__
2830
# generates a yaml file

pkg/generate.go

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package pkg
22

33
import (
4+
"encoding/base64"
45
"fmt"
56
"io"
67
"os"
@@ -240,6 +241,10 @@ func outputValueType(v v1beta1.JSONSchemaProps, skipRandom bool) string {
240241
return "2024-10-11T12:48:44Z"
241242
}
242243

244+
if v.Format == "byte" {
245+
return base64.StdEncoding.EncodeToString([]byte("string"))
246+
}
247+
243248
return st
244249
case "integer":
245250
if v.Minimum != nil {

pkg/matches/matchsnapshot/matcher.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ import (
1717
const MatcherName = "matchSnapshot"
1818

1919
type Config struct {
20-
Path string `yaml:"path"`
21-
Minimal bool `yaml:"minimal"`
20+
Path string `yaml:"path"`
21+
IgnoreErrors []string `yaml:"ignoreErrors,omitempty"`
22+
Minimal bool `yaml:"minimal"`
2223
}
24+
2325
type Matcher struct {
2426
Updater Updater
2527
}
@@ -92,7 +94,7 @@ func (m *Matcher) Match(ctx context.Context, crdLocation string, payload []byte)
9294
return fmt.Errorf("failed to read snapshot template: %w", err)
9395
}
9496

95-
if err := matches.Validate(content, snapshotContent); err != nil {
97+
if err := matches.Validate(content, snapshotContent, c.IgnoreErrors); err != nil {
9698
validationErrors = errors.Join(validationErrors, err)
9799
}
98100
}

pkg/matches/matchsnapshot/update.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func (u *Update) Update(sourceTemplateLocation string, targetSnapshotLocation st
5050
return fmt.Errorf("failed to open file %s: %w", filepath.Join(targetSnapshotLocation, name), err)
5151
}
5252

53-
parser := pkg.NewParser(schemaType.Group, schemaType.Kind, false, minimal, false)
53+
parser := pkg.NewParser(schemaType.Group, schemaType.Kind, false, minimal, true)
5454
if err := parser.ParseProperties(version.Name, file, version.Schema.Properties, pkg.RootRequiredFields); err != nil {
5555
_ = file.Close()
5656

pkg/matches/matchstring/matcher.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"os"
77

8-
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
98
"k8s.io/apimachinery/pkg/util/yaml"
109

1110
"github.com/Skarlso/crd-to-sample-yaml/pkg/matches"
@@ -14,8 +13,12 @@ import (
1413

1514
type Matcher struct{}
1615

16+
type Config struct {
17+
IgnoreErrors []string `yaml:"ignoreErrors,omitempty"`
18+
}
19+
1720
func (m *Matcher) Match(_ context.Context, crdLocation string, payload []byte) error {
18-
c := &apiextensionsv1.JSON{}
21+
c := &Config{}
1922
if err := yaml.Unmarshal(payload, &c); err != nil {
2023
return err
2124
}
@@ -25,7 +28,7 @@ func (m *Matcher) Match(_ context.Context, crdLocation string, payload []byte) e
2528
return fmt.Errorf("error reading file %s: %w", crdLocation, err)
2629
}
2730

28-
return matches.Validate(crdContent, payload)
31+
return matches.Validate(crdContent, payload, c.IgnoreErrors)
2932
}
3033

3134
func init() {

pkg/matches/validate.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
const maxBufferSize = 2048
1616

1717
// Validate takes a source CRD and a sample file and validates its contents against the CRD definition.
18-
func Validate(sourceCRD []byte, sampleFile []byte) error {
18+
func Validate(sourceCRD []byte, sampleFile []byte, ignoreErrors []string) error {
1919
reader := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(sampleFile), maxBufferSize)
2020
obj := &unstructured.Unstructured{}
2121
err := reader.Decode(obj)
@@ -29,7 +29,7 @@ func Validate(sourceCRD []byte, sampleFile []byte) error {
2929
}
3030

3131
if crd.Spec.Validation != nil && len(crd.Spec.Versions) == 0 {
32-
return ValidateCRDValidation(crd, sampleFile)
32+
return ValidateCRDValidation(crd, sampleFile, ignoreErrors)
3333
}
3434

3535
availableVersions := make([]string, 0, len(crd.Spec.Versions))
@@ -41,7 +41,7 @@ func Validate(sourceCRD []byte, sampleFile []byte) error {
4141
// Make sure we are only testing versions that equal to the CRD's version.
4242
// This is important in case there are multiple versions in the CRD.
4343
if obj.GroupVersionKind().Version == v.Name {
44-
if err := validate(v.Schema.OpenAPIV3Schema, obj, crd.Spec.Names.Kind, v.Name); err != nil {
44+
if err := validate(v.Schema.OpenAPIV3Schema, obj, crd.Spec.Names.Kind, v.Name, ignoreErrors); err != nil {
4545
return fmt.Errorf("failed to validate kind %s and version %s: %w", crd.Spec.Names.Kind, v.Name, err)
4646
}
4747

@@ -56,26 +56,33 @@ func Validate(sourceCRD []byte, sampleFile []byte) error {
5656
)
5757
}
5858

59-
func ValidateCRDValidation(crd *apiextensions.CustomResourceDefinition, sampleFile []byte) error {
59+
func ValidateCRDValidation(crd *apiextensions.CustomResourceDefinition, sampleFile []byte, ignoreErrors []string) error {
6060
reader := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(sampleFile), maxBufferSize)
6161
obj := &unstructured.Unstructured{}
6262
err := reader.Decode(obj)
6363
if err != nil {
6464
return fmt.Errorf("failed to decode sample file: %w", err)
6565
}
6666

67-
return validate(crd.Spec.Validation.OpenAPIV3Schema, obj, crd.Spec.Names.Kind, crd.Name)
67+
return validate(crd.Spec.Validation.OpenAPIV3Schema, obj, crd.Spec.Names.Kind, crd.Name, ignoreErrors)
6868
}
6969

70-
func validate(props *apiextensions.JSONSchemaProps, obj *unstructured.Unstructured, kind, name string) error {
70+
func validate(props *apiextensions.JSONSchemaProps, obj *unstructured.Unstructured, kind, name string, ignoreErrors []string) error {
7171
eval, _, err := validation.NewSchemaValidator(props)
7272
if err != nil {
7373
return fmt.Errorf("invalid schema: %w", err)
7474
}
7575

7676
var resultErrors error
7777
result := eval.Validate(obj)
78+
loop:
7879
for _, e := range result.Errors {
80+
for _, ignore := range ignoreErrors {
81+
if strings.Contains(e.Error(), ignore) {
82+
continue loop
83+
}
84+
}
85+
7986
resultErrors = errors.Join(resultErrors, e)
8087
}
8188

sample-tests/__snapshots__/bootstrap_crd-v1alpha1.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ status:
4848
- lastTransitionTime: 2024-10-11T12:48:44Z
4949
message: string
5050
observedGeneration: 0
51-
reason: w # ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
52-
status: "True"
53-
type: 2.ik2p.6.i/Q # ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
51+
reason: string
52+
status: "True" # "True", "False", "Unknown"
53+
type: string
5454
lastAppliedCRDNames: {}
5555
lastAppliedRevision: string
5656
lastAttemptedRevision: string

sample-tests/__snapshots__/infrastructure.cluster.x-k8s.io_awsclusters-v1beta1.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ spec:
1616
additionalSecurityGroups: [] # minItems 0 of type string
1717
crossZoneLoadBalancing: true
1818
healthCheckProtocol: string
19-
name: OyI7Q3Hn4r # ^[A-Za-z0-9]([A-Za-z0-9]{0,31}|[-A-Za-z0-9]{0,30}[A-Za-z0-9])$
19+
name: string
2020
scheme: "internet-facing"
2121
subnets: [] # minItems 0 of type string
2222
identityRef:
23-
kind: "AWSClusterControllerIdentity"
23+
kind: "AWSClusterControllerIdentity" # "AWSClusterControllerIdentity", "AWSClusterRoleIdentity", "AWSClusterStaticIdentity"
2424
name: string
2525
imageLookupBaseOS: string
2626
imageLookupFormat: string
@@ -57,7 +57,7 @@ spec:
5757
region: string
5858
s3Bucket:
5959
controlPlaneIAMInstanceProfile: string
60-
name: pls.vm9y # ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
60+
name: string
6161
nodesIAMInstanceProfiles: [] # minItems 0 of type string
6262
sshKeyName: string
6363
status:

sample-tests/__snapshots__/infrastructure.cluster.x-k8s.io_awsclusters-v1beta2.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ spec:
1616
additionalSecurityGroups: [] # minItems 0 of type string
1717
crossZoneLoadBalancing: true
1818
healthCheckProtocol: string
19-
name: IxmzTD4eEFJ # ^[A-Za-z0-9]([A-Za-z0-9]{0,31}|[-A-Za-z0-9]{0,30}[A-Za-z0-9])$
19+
name: string
2020
scheme: "internet-facing"
2121
subnets: [] # minItems 0 of type string
2222
identityRef:
23-
kind: "AWSClusterControllerIdentity"
23+
kind: "AWSClusterControllerIdentity" # "AWSClusterControllerIdentity", "AWSClusterRoleIdentity", "AWSClusterStaticIdentity"
2424
name: string
2525
imageLookupBaseOS: string
2626
imageLookupFormat: string
@@ -57,7 +57,7 @@ spec:
5757
region: string
5858
s3Bucket:
5959
controlPlaneIAMInstanceProfile: string
60-
name: x7-n6fza # ^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$
60+
name: string
6161
nodesIAMInstanceProfiles: [] # minItems 0 of type string
6262
sshKeyName: string
6363
status:

0 commit comments

Comments
 (0)