Skip to content

Commit

Permalink
add parsing to support required field
Browse files Browse the repository at this point in the history
Add projects to test parsing CRD

Add test for project validations

rebase master
  • Loading branch information
Liujingfang1 committed Jun 1, 2018
1 parent 800df6f commit 58bab20
Show file tree
Hide file tree
Showing 25 changed files with 1,161 additions and 13 deletions.
26 changes: 19 additions & 7 deletions cmd/internal/codegen/parse/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ func (b *APIs) parseArrayValidation(t *types.Type, found sets.String, comments [
type objectTemplateArgs struct {
v1beta1.JSONSchemaProps
Fields map[string]string
Required []string
}

var objectTemplate = template.Must(template.New("object-template").Parse(
Expand All @@ -329,6 +330,11 @@ var objectTemplate = template.Must(template.New("object-template").Parse(
"{{ $k }}": {{ $v }},
{{ end -}}
},
{{if .Required}}Required: []string{
{{ range $k, $v := .Required -}}
"{{ $v }}",
{{ end -}}
},{{ end -}}
}`))

// parseObjectValidation returns a JSONSchemaProps object and its serialization in
Expand All @@ -340,19 +346,20 @@ func (b *APIs) parseObjectValidation(t *types.Type, found sets.String, comments
}

if strings.HasPrefix(t.Name.String(), "k8s.io/api") {
if err := objectTemplate.Execute(buff, objectTemplateArgs{props, nil}); err != nil {
if err := objectTemplate.Execute(buff, objectTemplateArgs{props, nil, nil}); err != nil {
log.Fatalf("%v", err)
}
} else {
m, result := b.getMembers(t, found)
m, result, required := b.getMembers(t, found)
props.Properties = m
props.Required = required

// Only add field validation for non-inlined fields
for _, l := range comments {
getValidation(l, &props)
}

if err := objectTemplate.Execute(buff, objectTemplateArgs{props, result}); err != nil {
if err := objectTemplate.Execute(buff, objectTemplateArgs{props, result, required}); err != nil {
log.Fatalf("%v", err)
}
}
Expand Down Expand Up @@ -475,15 +482,16 @@ func getValidation(comment string, props *v1beta1.JSONSchemaProps) {

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

// Don't allow recursion until we support it through refs
// TODO: Support recursion
if found.Has(t.Name.String()) {
fmt.Printf("Breaking recursion for type %s", t.Name.String())
return members, result
return members, result, required
}
found.Insert(t.Name.String())

Expand All @@ -506,22 +514,26 @@ func (b *APIs) getMembers(t *types.Type, found sets.String) (map[string]v1beta1.

// Inline "inline" structs
if strat == "inline" {
m, r := b.getMembers(member.Type, found)
m, r, re:= b.getMembers(member.Type, found)
for n, v := range m {
members[n] = v
}
for n, v := range r {
result[n] = v
}
required = append(required, re...)
} else {
m, r := b.typeToJSONSchemaProps(member.Type, found, member.CommentLines)
members[name] = m
result[name] = r
if !strings.HasSuffix(strat, "omitempty") {
required = append(required, name)
}
}
}

defer found.Delete(t.Name.String())
return members, result
return members, result, required
}

// getCategoriesTag returns the value of the +kubebuilder:categories tags
Expand Down
12 changes: 6 additions & 6 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -517,18 +517,18 @@ function test_crd_validation {
sed -i -e '/type HouseSpec struct/ a \
// +kubebuilder:validation:Maximum=100\
// +kubebuilder:validation:ExclusiveMinimum=true\
Power float32 \`json:"power"\`\
Bricks int32 \`json:"bricks"\`\
Power float32 \`json:"power,omitempty"\`\
Bricks int32 \`json:"bricks,omitempty"\`\
// +kubebuilder:validation:MaxLength=15\
// +kubebuilder:validation:MinLength=1\
Name string \`json:"name"\`\
Name string \`json:"name,omitempty"\`\
// +kubebuilder:validation:MaxItems=500\
// +kubebuilder:validation:MinItems=1\
// +kubebuilder:validation:UniqueItems=false\
Knights []string \`json:"knights"\`\
Winner bool \`json:"winner"\`\
Knights []string \`json:"knights,omitempty"\`\
Winner bool \`json:"winner,omitempty"\`\
// +kubebuilder:validation:Enum=Lion,Wolf,Dragon\
Alias string \`json:"alias"\`\
Alias string \`json:"alias,omitempty"\`\
// +kubebuilder:validation:Enum=1,2,3\
Rank int \`json:"rank"\`\
Comment []byte \`json:"comment,omitempty"\`\
Expand Down
2 changes: 2 additions & 0 deletions test/data/resource/expected/crd-expected.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ spec:
type: integer
winner:
type: boolean
required:
- rank
type: object
status:
type: object
Expand Down
1 change: 1 addition & 0 deletions test/projects/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Sample project is a project that created by kubebuilder and moved into `samples`

## Current Sample Projects
- memcached-api-apiserver
- validations

## Test Sample Project
Run following command to test a sample project such as memcached-api-apiserver
Expand Down
2 changes: 2 additions & 0 deletions test/projects/memcached-api-server/test/hack/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ spec:
maximum: 100
minimum: 5
type: integer
required:
- size
type: object
status:
properties:
Expand Down
Loading

0 comments on commit 58bab20

Please sign in to comment.