Skip to content

Commit

Permalink
BUILD/MINOR: kubebuilder: add validation markers for Pattern, Minimum…
Browse files Browse the repository at this point in the history
…, Maximum, Format to the generator
  • Loading branch information
hdurand0710 committed Dec 14, 2023
1 parent 485b290 commit 941d3cc
Show file tree
Hide file tree
Showing 64 changed files with 386 additions and 30 deletions.
74 changes: 71 additions & 3 deletions cmd/kubebuilder_marker_generator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
_ "embed"
"fmt"
"go/token"
"log"
"os"
Expand All @@ -11,6 +12,10 @@ import (
"github.com/sirkon/dst/decorator"
)

const (
kubebuilderValidationMarker = "// +kubebuilder:validation:"
)

func main() {
// tool to add `json:",inline"` for embedded structs

Expand Down Expand Up @@ -40,20 +45,42 @@ func generate(fileName string) error { //nolint:gocognit,unparam
if structType, ok := typeSpec.Type.(*dst.StructType); ok {
for _, field := range structType.Fields.List {
comments := field.Decorations().Start.All()
// Remove // +kubebuilder:validation
comments = cleanup(comments, kubebuilderValidationMarker)
field.Decorations().Start.Replace(comments...)
// Then do the job
for _, comment := range comments {
if strings.HasPrefix(comment, "// Enum: [") {
field.Decorations().Before = dst.NewLine
newComment := `// +kubebuilder:validation:Enum=`
newComment := kubebuilderValidationMarker + `Enum=`
comment = strings.TrimPrefix(comment, "// Enum: [")
comment = strings.TrimSuffix(comment, "]")
// We must keep empty strings:
// For example in Globals HttpclientSslVerify: // Enum: [ none required]
// from swagger: enum: ["", "none", "required"]
for _, enum := range strings.Split(comment, " ") {
enum = strings.TrimSpace(enum)
if enum == "" {
newComment += `""`
}
newComment += enum
newComment += ";"
}
field.Decorations().Start.Append(newComment)
log.Printf("Adding comment for: %s: %+v %s\n", fileName, field.Type, newComment)
log.Printf("Adding comment for: %s: %s %s\n", fileName, field.Names[0].Name, newComment)
}
if strings.HasPrefix(comment, "// Pattern: ") {
addSimpleMarker(field, fileName, comment, "Pattern", "string")
}
if strings.HasPrefix(comment, "// Maximum: ") {
addSimpleMarker(field, fileName, comment, "Maximum", "raw")
}
if strings.HasPrefix(comment, "// Minimum: ") {
addSimpleMarker(field, fileName, comment, "Minimum", "raw")
}
if strings.HasPrefix(comment, "// Format: ") {
addSimpleMarker(field, fileName, comment, "Format", "raw")
}

}
// if len(field.Names) > 0 {
// log.Printf("Comments before the field %s: %v\n", field.Names[0].Name, comments)
Expand All @@ -79,3 +106,44 @@ func generate(fileName string) error { //nolint:gocognit,unparam

return nil
}

// addSimpleMarker adds a simple kubebuilder marker to the given field.
//
// Parameters:
// - field: the field to add the marker to.
// - fileName: the name of the file.
// - markerValue: the marker value.
// - validationType: the type of validation (for example, "Pattern", "Maximum", "Minimum").
// - validationContentType: the content type of the validation:
// "string" to add “ around the comment
// "raw" to add the comment as is
func addSimpleMarker(field *dst.Field, fileName, markerValue, validationType, validationContentType string) {
field.Decorations().Before = dst.NewLine
markerValue = strings.TrimPrefix(markerValue, "// "+validationType+": ")
var marker string
switch validationContentType {
case "string":
marker = fmt.Sprintf("%s%s=`%v`", kubebuilderValidationMarker, validationType, markerValue)
case "raw":
marker = fmt.Sprintf("%s%s=%v", kubebuilderValidationMarker, validationType, markerValue)
default:
log.Printf("Unknown validation content type: %s", validationContentType)
}
field.Decorations().Start.Append(marker)
log.Printf("Adding comment for: %s: %+v %s\n", fileName, field.Names[0].Name, marker)
}

// cleanup removes all strings from a slice of strings that have a specific prefix.
//
// comments is the slice of strings containing the comments to clean up.
// prefixToRemove is the prefix of the comments to remove.
// It returns a new slice of strings without the comments that have the specified prefix.
func cleanup(comments []string, prefixToRemove string) []string {
var res []string
for _, comment := range comments {
if !strings.HasPrefix(comment, prefixToRemove) {
res = append(res, comment)
}
}
return res
}
3 changes: 2 additions & 1 deletion models/acl.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions models/aws_region.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions models/backend.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions models/backend_switching_rule.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions models/balance.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions models/bind.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions models/bind_params.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions models/cache.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions models/cluster_settings.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions models/config_stick_table.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion models/consul.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 941d3cc

Please sign in to comment.