Skip to content

Commit

Permalink
Add +optional/+required markers at package and struct level for CRD v…
Browse files Browse the repository at this point in the history
…alidation

Using +kubebuilder:validation:Optional/Required at the package level sets the default value for fields in that package to that value, while using the opposite marker on fields in that package sets them as an exception
  • Loading branch information
damemi committed May 17, 2019
1 parent 89f6323 commit 9244fa3
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 2 deletions.
2 changes: 2 additions & 0 deletions pkg/crd/markers/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ func init() {
AllDefinitions = append(AllDefinitions,
markers.Must(markers.MakeDefinition("groupName", markers.DescribesPackage, "")),
markers.Must(markers.MakeDefinition("versionName", markers.DescribesPackage, "")),
markers.Must(markers.MakeDefinition("kubebuilder:validation:Optional", markers.DescribesPackage, struct{}{})),
markers.Must(markers.MakeDefinition("kubebuilder:validation:Required", markers.DescribesPackage, struct{}{})),
)
}
4 changes: 4 additions & 0 deletions pkg/crd/markers/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.
Enum(nil),
Format(""),
Type(""),
Required(struct{}{}),
Optional(struct{}{}),
)

func init() {
Expand Down Expand Up @@ -86,6 +88,8 @@ type UniqueItems bool
type Enum []interface{}
type Format string
type Type string
type Required struct{}
type Optional struct{}

func (m Maximum) ApplyToSchema(schema *v1beta1.JSONSchemaProps) error {
if schema.Type != "integer" {
Expand Down
1 change: 1 addition & 0 deletions pkg/crd/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ func (p *Parser) indexTypes(pkg *loader.Package) {
Name: info.Name,
}

info.PackageMarkers = pkgMarkers
p.Types[ident] = info
}); err != nil {
pkg.AddError(err)
Expand Down
21 changes: 19 additions & 2 deletions pkg/crd/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,26 @@ func structToSchema(ctx *schemaContext, structType *ast.StructType) *v1beta1.JSO
fieldName := jsonOpts[0]
inline = inline || fieldName == "" // anonymous fields are inline fields in YAML/JSON

if !inline && !omitEmpty {
props.Required = append(props.Required, fieldName)
// if no default required mode is set, default to required
defaultMode := "required"
if ctx.info.PackageMarkers.Get("kubebuilder:validation:Optional") != nil {
defaultMode = "optional"
}
// if this package isn't set to optional default...
if defaultMode == "required" {
// ...everything that's not inline, omitempty, or explicitly optional is required
if !inline && !omitEmpty && field.Markers.Get("kubebuilder:validation:Optional") == nil {
props.Required = append(props.Required, fieldName)
}
}
// if this package isn't set to required default...
if defaultMode == "optional" {
// ...everything that isn't explicitly required is optional
if field.Markers.Get("kubebuilder:validation:Required") != nil {
props.Required = append(props.Required, fieldName)
}
}


propSchema := typeToSchema(ctx.ForInfo(&markers.TypeInfo{}), field.RawField.Type)
propSchema.Description = field.Doc
Expand Down
2 changes: 2 additions & 0 deletions pkg/markers/zip.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ type TypeInfo struct {

// Markers are all registered markers associated with the type.
Markers MarkerValues
// PackageMarkers are the registered markers for the package of the type
PackageMarkers MarkerValues

// Fields are all the fields associated with the type, if it's a struct.
// (if not, Fields will be nil).
Expand Down

0 comments on commit 9244fa3

Please sign in to comment.