Skip to content

Commit 2ce1b89

Browse files
committed
Ignore unknown k8s:validation comments tags
1 parent 67ed584 commit 2ce1b89

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

pkg/generators/markers.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ import (
2020
"encoding/json"
2121
"errors"
2222
"fmt"
23+
"reflect"
2324
"regexp"
2425
"strconv"
2526
"strings"
27+
"sync"
2628

2729
"k8s.io/gengo/v2/types"
2830
openapi "k8s.io/kube-openapi/pkg/common"
@@ -61,6 +63,30 @@ func (c *CELTag) Validate() error {
6163
return nil
6264
}
6365

66+
func isKnownTagCommentKey(key string) bool {
67+
split := func(r rune) bool { return r == ':' || r == '[' }
68+
commentTags := strings.FieldsFunc(key, split)
69+
if len(commentTags) == 0 {
70+
return false
71+
}
72+
_, ok := tagKeys()[commentTags[0]]
73+
return ok
74+
}
75+
76+
var tagKeys = sync.OnceValue(func() map[string]struct{} {
77+
result := map[string]struct{}{}
78+
t := reflect.TypeOf(commentTags{})
79+
for i := 0; i < t.NumField(); i++ {
80+
field := t.Field(i)
81+
if jsonTag := field.Tag.Get("json"); jsonTag != "" {
82+
if key, _, _ := strings.Cut(jsonTag, ","); key != "" {
83+
result[key] = struct{}{}
84+
}
85+
}
86+
}
87+
return result
88+
})
89+
6490
// commentTags represents the parsed comment tags for a given type. These types are then used to generate schema validations.
6591
// These only include the newer prefixed tags. The older tags are still supported,
6692
// but are not included in this struct. Comment Tags are transformed into a
@@ -385,12 +411,11 @@ func memberWithJSONName(t *types.Type, key string) *types.Member {
385411
return nil
386412
}
387413

388-
// Parses the given comments into a CommentTags type. Validates the parsed comment tags, and returns the result.
414+
// ParseCommentTags parses the given comments into a CommentTags type. Validates the parsed comment tags, and returns the result.
389415
// Accepts an optional type to validate against, and a prefix to filter out markers not related to validation.
390416
// Accepts a prefix to filter out markers not related to validation.
391417
// Returns any errors encountered while parsing or validating the comment tags.
392418
func ParseCommentTags(t *types.Type, comments []string, prefix string) (*spec.Schema, error) {
393-
394419
markers, err := parseMarkers(comments, prefix)
395420
if err != nil {
396421
return nil, fmt.Errorf("failed to parse marker comments: %w", err)
@@ -610,6 +635,8 @@ func parseMarkers(markerComments []string, prefix string) (map[string]any, error
610635

611636
if len(key) == 0 {
612637
return nil, fmt.Errorf("cannot have empty key for marker comment")
638+
} else if !isKnownTagCommentKey(key) {
639+
continue
613640
} else if _, ok := parseSymbolReference(value, ""); ok {
614641
// Skip ref markers
615642
continue

pkg/generators/markers_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"testing"
2020

2121
"github.com/stretchr/testify/require"
22+
2223
"k8s.io/gengo/v2/types"
2324
"k8s.io/kube-openapi/pkg/generators"
2425
"k8s.io/kube-openapi/pkg/validation/spec"
@@ -960,6 +961,23 @@ func TestCommentTags_Validate(t *testing.T) {
960961
},
961962
errorMessage: `failed to validate property "name": pattern can only be used on string types`,
962963
},
964+
{
965+
name: "ignore unknown field with unparsable value",
966+
comments: []string{
967+
`+k8s:validation:xyz=a=b`, // a=b is not a valid value
968+
},
969+
t: &types.Type{
970+
Kind: types.Struct,
971+
Name: types.Name{Name: "struct"},
972+
Members: []types.Member{
973+
{
974+
Name: "name",
975+
Type: types.String,
976+
Tags: `json:"name"`,
977+
},
978+
},
979+
},
980+
},
963981
}
964982

965983
for _, tc := range testCases {

pkg/generators/openapi_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/google/go-cmp/cmp"
2828
"golang.org/x/tools/go/packages"
2929
"golang.org/x/tools/go/packages/packagestest"
30+
3031
"k8s.io/gengo/v2/generator"
3132
"k8s.io/gengo/v2/namer"
3233
"k8s.io/gengo/v2/parser"
@@ -2386,7 +2387,7 @@ func TestMarkerComments(t *testing.T) {
23862387
// +k8s:validation:pattern="^foo$[0-9]+"
23872388
StringValue string
23882389
2389-
// +k8s:validation:maxitems=10
2390+
// +k8s:validation:maxItems=10
23902391
// +k8s:validation:minItems=1
23912392
// +k8s:validation:uniqueItems
23922393
ArrayValue []string

0 commit comments

Comments
 (0)