Skip to content

Commit 4987c4d

Browse files
authored
Merge pull request #101 from pmorie/comment-fixes
Comment fixes for code generation
2 parents 5c2f3d8 + c98652c commit 4987c4d

File tree

5 files changed

+106
-82
lines changed

5 files changed

+106
-82
lines changed

cmd/internal/codegen/parse/controllers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ type controllerTags struct {
3232
resource string
3333
}
3434

35+
// parseControllers populates the list of controllers to generate code from the
36+
// list of annotated types.
3537
func (b *APIs) parseControllers() {
3638
for _, c := range b.context.Order {
3739
if IsController(c) {

cmd/internal/codegen/parse/index.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ import (
2929
// parseIndex indexes all types with the comment "// +resource=RESOURCE" by GroupVersionKind and
3030
// GroupKindVersion
3131
func (b *APIs) parseIndex() {
32-
// Index resource by group version kind
32+
// Index resource by group, version, kind
3333
b.ByGroupVersionKind = map[string]map[string]map[string]*codegen.APIResource{}
3434

3535
// Index resources by group, kind, version
3636
b.ByGroupKindVersion = map[string]map[string]map[string]*codegen.APIResource{}
3737

38-
// Index subresources
38+
// Index subresources by group, version, kind
3939
b.SubByGroupVersionKind = map[string]map[string]map[string]*types.Type{}
4040

4141
for _, c := range b.context.Order {
42-
// The type is a subresource, add it to the
42+
// The type is a subresource, add it to the subresource index
4343
if IsAPISubresource(c) {
4444
group := GetGroup(c)
4545
version := GetVersion(c, group)

cmd/internal/codegen/parse/rbac.go

Lines changed: 73 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ import (
2222
"strings"
2323

2424
rbacv1 "k8s.io/api/rbac/v1"
25+
"k8s.io/apimachinery/pkg/apis/meta/v1"
2526
"k8s.io/gengo/types"
26-
"k8s.io/apimachinery/pkg/apis/meta/v1"
2727
)
2828

29+
// parseRBAC populates the RBAC rules for each annotated type.
2930
func (b *APIs) parseRBAC() {
3031
for _, c := range b.context.Order {
3132
if IsRBAC(c) {
@@ -37,85 +38,86 @@ func (b *APIs) parseRBAC() {
3738
}
3839

3940
func (b *APIs) getRBACTag(c *types.Type) []string {
40-
comments := Comments(c.CommentLines)
41-
resource := comments.getTags("rbac", ":")
42-
resource = append(resource, comments.getTags("kubebuilder:rbac", ":")...)
43-
if len(resource) == 0 {
44-
panic(fmt.Errorf("Must specify +kubebuilder:rbac comment for type %v", c.Name))
45-
}
46-
return resource
41+
comments := Comments(c.CommentLines)
42+
resource := comments.getTags("rbac", ":")
43+
resource = append(resource, comments.getTags("kubebuilder:rbac", ":")...)
44+
if len(resource) == 0 {
45+
panic(fmt.Errorf("Must specify +kubebuilder:rbac comment for type %v", c.Name))
46+
}
47+
return resource
4748
}
4849

4950
func parseRBACTag(tag string) rbacv1.PolicyRule {
50-
result := rbacv1.PolicyRule{}
51-
for _, elem := range strings.Split(tag, ",") {
52-
kv := strings.Split(elem, "=")
53-
if len(kv) != 2 {
54-
log.Fatalf("// +kubebuilder:rbac: tags must be key value pairs. Expected "+
55-
"keys [groups=<group1;group2>,resources=<resource1;resource2>,verbs=<verb1;verb2>] "+
56-
"Got string: [%s]", tag)
57-
}
58-
value := kv[1]
59-
values := []string{}
60-
if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") {
61-
value = value[1 : len(value)-1]
62-
}
63-
values = strings.Split(value, ";")
64-
switch kv[0] {
65-
case "groups":
66-
result.APIGroups = values
67-
case "resources":
68-
result.Resources = values
69-
case "verbs":
70-
result.Verbs = values
71-
case "urls":
72-
result.NonResourceURLs = values
73-
}
74-
}
75-
return result
51+
result := rbacv1.PolicyRule{}
52+
for _, elem := range strings.Split(tag, ",") {
53+
kv := strings.Split(elem, "=")
54+
if len(kv) != 2 {
55+
log.Fatalf("// +kubebuilder:rbac: tags must be key value pairs. Expected "+
56+
"keys [groups=<group1;group2>,resources=<resource1;resource2>,verbs=<verb1;verb2>] "+
57+
"Got string: [%s]", tag)
58+
}
59+
value := kv[1]
60+
values := []string{}
61+
if strings.HasPrefix(value, "\"") && strings.HasSuffix(value, "\"") {
62+
value = value[1 : len(value)-1]
63+
}
64+
values = strings.Split(value, ";")
65+
switch kv[0] {
66+
case "groups":
67+
result.APIGroups = values
68+
case "resources":
69+
result.Resources = values
70+
case "verbs":
71+
result.Verbs = values
72+
case "urls":
73+
result.NonResourceURLs = values
74+
}
75+
}
76+
return result
7677
}
7778

79+
// parseInfomers populates the informers to generate on each annotated type.
7880
func (b *APIs) parseInformers() {
79-
for _, c := range b.context.Order {
80-
if IsInformer(c) {
81-
for _, tag := range b.getInformerTag(c) {
82-
if b.Informers == nil {
83-
b.Informers = map[v1.GroupVersionKind]bool{}
84-
}
85-
b.Informers[parseInformerTag(tag)] = true
86-
}
87-
}
88-
}
81+
for _, c := range b.context.Order {
82+
if IsInformer(c) {
83+
for _, tag := range b.getInformerTag(c) {
84+
if b.Informers == nil {
85+
b.Informers = map[v1.GroupVersionKind]bool{}
86+
}
87+
b.Informers[parseInformerTag(tag)] = true
88+
}
89+
}
90+
}
8991
}
9092

9193
func (b *APIs) getInformerTag(c *types.Type) []string {
92-
comments := Comments(c.CommentLines)
93-
resource := comments.getTags("informers", ":")
94-
resource = append(resource, comments.getTags("kubebuilder:informers", ":")...)
95-
if len(resource) == 0 {
96-
panic(fmt.Errorf("Must specify +kubebuilder:informers comment for type %v", c.Name))
97-
}
98-
return resource
94+
comments := Comments(c.CommentLines)
95+
resource := comments.getTags("informers", ":")
96+
resource = append(resource, comments.getTags("kubebuilder:informers", ":")...)
97+
if len(resource) == 0 {
98+
panic(fmt.Errorf("Must specify +kubebuilder:informers comment for type %v", c.Name))
99+
}
100+
return resource
99101
}
100102

101103
func parseInformerTag(tag string) v1.GroupVersionKind {
102-
result := v1.GroupVersionKind{}
103-
for _, elem := range strings.Split(tag, ",") {
104-
kv := strings.Split(elem, "=")
105-
if len(kv) != 2 {
106-
log.Fatalf("// +kubebuilder:informers: tags must be key value pairs. Expected "+
107-
"keys [group=core,version=v1,kind=Pod] "+
108-
"Got string: [%s]", tag)
109-
}
110-
value := kv[1]
111-
switch kv[0] {
112-
case "group":
113-
result.Group = value
114-
case "version":
115-
result.Version = value
116-
case "kind":
117-
result.Kind = value
118-
}
119-
}
120-
return result
121-
}
104+
result := v1.GroupVersionKind{}
105+
for _, elem := range strings.Split(tag, ",") {
106+
kv := strings.Split(elem, "=")
107+
if len(kv) != 2 {
108+
log.Fatalf("// +kubebuilder:informers: tags must be key value pairs. Expected "+
109+
"keys [group=core,version=v1,kind=Pod] "+
110+
"Got string: [%s]", tag)
111+
}
112+
value := kv[1]
113+
switch kv[0] {
114+
case "group":
115+
result.Group = value
116+
case "version":
117+
result.Version = value
118+
case "kind":
119+
result.Kind = value
120+
}
121+
}
122+
return result
123+
}

cmd/internal/codegen/parse/util.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
// IsAPIResource returns true if t has a +resource/+kubebuilder:resource comment tag
3030
func IsAPIResource(t *types.Type) bool {
3131
for _, c := range t.CommentLines {
32-
if strings.Contains(c, "+resource") || strings.Contains(c, "+kubebuilder:resource"){
32+
if strings.Contains(c, "+resource") || strings.Contains(c, "+kubebuilder:resource") {
3333
return true
3434
}
3535
}
@@ -57,6 +57,7 @@ func IsNonNamespaced(t *types.Type) bool {
5757
return false
5858
}
5959

60+
// IsController returns true if t has a +controller or +kubebuilder:controller tag
6061
func IsController(t *types.Type) bool {
6162
for _, c := range t.CommentLines {
6263
if strings.Contains(c, "+controller") || strings.Contains(c, "+kubebuilder:controller") {
@@ -66,6 +67,7 @@ func IsController(t *types.Type) bool {
6667
return false
6768
}
6869

70+
// IsRBAC returns true if t has a +rbac or +kubebuilder:rbac tag
6971
func IsRBAC(t *types.Type) bool {
7072
for _, c := range t.CommentLines {
7173
if strings.Contains(c, "+rbac") || strings.Contains(c, "+kubebuilder:rbac") {
@@ -75,16 +77,16 @@ func IsRBAC(t *types.Type) bool {
7577
return false
7678
}
7779

80+
// IsInformer returns true if t has a +informers or +kubebuilder:informers tag
7881
func IsInformer(t *types.Type) bool {
79-
for _, c := range t.CommentLines {
80-
if strings.Contains(c, "+informers") || strings.Contains(c, "+kubebuilder:informers") {
81-
return true
82-
}
83-
}
84-
return false
82+
for _, c := range t.CommentLines {
83+
if strings.Contains(c, "+informers") || strings.Contains(c, "+kubebuilder:informers") {
84+
return true
85+
}
86+
}
87+
return false
8588
}
8689

87-
8890
// IsAPISubresource returns true if t has a +subresource-request comment tag
8991
func IsAPISubresource(t *types.Type) bool {
9092
for _, c := range t.CommentLines {
@@ -162,6 +164,7 @@ func (c Comments) getTag(name, sep string) string {
162164
return ""
163165
}
164166

167+
// hasTag returns true if the Comments has a tag with the given name
165168
func (c Comments) hasTag(name string) bool {
166169
for _, c := range c {
167170
prefix := fmt.Sprintf("+%s", name)

cmd/internal/codegen/parse/validation.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import (
3232
"text/template"
3333
)
3434

35+
// parseJSONSchemaProps populates the CRD field of each Group.Version.Resource,
36+
// creating validations using the annotations on type fields.
3537
func (b *APIs) parseJSONSchemaProps() {
3638
for _, group := range b.APIs.Groups {
3739
for _, version := range group.Versions {
@@ -94,6 +96,8 @@ func (b *APIs) getMeta() string {
9496
}`
9597
}
9698

99+
// typeToJSONSchemaProps returns a JSONSchemaProps object and its serialization
100+
// in Go that describe the JSONSchema validations for the given type.
97101
func (b *APIs) typeToJSONSchemaProps(t *types.Type, found sets.String, comments []string) (v1beta1.JSONSchemaProps, string) {
98102
// Special cases
99103
time := types.Name{Name: "Time", Package: "k8s.io/apimachinery/pkg/apis/meta/v1"}
@@ -165,6 +169,9 @@ var primitiveTemplate = template.Must(template.New("map-template").Parse(
165169
{{ end -}}
166170
}`))
167171

172+
// parsePrimitiveValidation returns a JSONSchemaProps object and its
173+
// serialization in Go that describe the validations for the given primitive
174+
// type.
168175
func (b *APIs) parsePrimitiveValidation(t *types.Type, found sets.String, comments []string) (v1beta1.JSONSchemaProps, string) {
169176
props := v1beta1.JSONSchemaProps{Type: string(t.Name.Name)}
170177

@@ -211,6 +218,8 @@ var mapTemplate = template.Must(template.New("map-template").Parse(
211218
},
212219
}`))
213220

221+
// parseMapValidation returns a JSONSchemaProps object and its serialization in
222+
// Go that describe the validations for the given map type.
214223
func (b *APIs) parseMapValidation(t *types.Type, found sets.String, comments []string) (v1beta1.JSONSchemaProps, string) {
215224
additionalProps, _ := b.typeToJSONSchemaProps(t.Elem, found, comments)
216225
props := v1beta1.JSONSchemaProps{
@@ -235,6 +244,8 @@ var arrayTemplate = template.Must(template.New("array-template").Parse(
235244
},
236245
}`))
237246

247+
// parseArrayValidation returns a JSONSchemaProps object and its serialization in
248+
// Go that describe the validations for the given array type.
238249
func (b *APIs) parseArrayValidation(t *types.Type, found sets.String, comments []string) (v1beta1.JSONSchemaProps, string) {
239250
items, result := b.typeToJSONSchemaProps(t.Elem, found, comments)
240251
props := v1beta1.JSONSchemaProps{
@@ -264,6 +275,8 @@ var objectTemplate = template.Must(template.New("object-template").Parse(
264275
},
265276
}`))
266277

278+
// parseObjectValidation returns a JSONSchemaProps object and its serialization in
279+
// Go that describe the validations for the given object type.
267280
func (b *APIs) parseObjectValidation(t *types.Type, found sets.String, comments []string) (v1beta1.JSONSchemaProps, string) {
268281
buff := &bytes.Buffer{}
269282
props := v1beta1.JSONSchemaProps{
@@ -290,6 +303,8 @@ func (b *APIs) parseObjectValidation(t *types.Type, found sets.String, comments
290303
return props, buff.String()
291304
}
292305

306+
// getValidation parses the validation tags from the comment and sets the
307+
// validation rules on the given JSONSchemaProps.
293308
func getValidation(comment string, props *v1beta1.JSONSchemaProps) {
294309
comment = strings.TrimLeft(comment, " ")
295310
if !strings.HasPrefix(comment, "+kubebuilder:validation:") {
@@ -392,6 +407,8 @@ func getValidation(comment string, props *v1beta1.JSONSchemaProps) {
392407
}
393408
}
394409

410+
// getMembers builds maps by field name of the JSONSchemaProps and their Go
411+
// serializations.
395412
func (b *APIs) getMembers(t *types.Type, found sets.String) (map[string]v1beta1.JSONSchemaProps, map[string]string) {
396413
members := map[string]v1beta1.JSONSchemaProps{}
397414
result := map[string]string{}

0 commit comments

Comments
 (0)