Skip to content

Commit

Permalink
refactor: expose kubeconform config
Browse files Browse the repository at this point in the history
  • Loading branch information
aabouzaid committed Apr 11, 2023
1 parent 8c19e7e commit 7029e22
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 81 deletions.
24 changes: 10 additions & 14 deletions cmd/kubeconform/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,19 @@ func processResults(cancel context.CancelFunc, o output.Output, validationResult
return result
}

func Validate(cfg config.Config, out string) int {
func Validate(cfg config.Config, out string) error {

if out != "" {
o := cfg.Stream.Error
errCode := 1
if cfg.Help {
o = cfg.Stream.Output
errCode = 0
fmt.Fprintln(cfg.Stream.Output, out)
return nil
}
fmt.Fprintln(o, out)
return errCode
return fmt.Errorf("config out is not empty")
}

if cfg.Version {
fmt.Fprintln(cfg.Stream.Output, out)
return 0
return nil
}

cpuProfileFile := os.Getenv("KUBECONFORM_CPUPROFILE_FILE")
Expand Down Expand Up @@ -87,8 +85,7 @@ func Validate(cfg config.Config, out string) int {

o, err := output.New(cfg.Stream.Output, cfg.OutputFormat, cfg.Summary, useStdin, cfg.Verbose)
if err != nil {
fmt.Fprintln(cfg.Stream.Error, err)
return 1
return fmt.Errorf("failed to get output: %s", err.Error())
}
v, err := validator.New(cfg.SchemaLocations, validator.Opts{
Cache: cfg.Cache,
Expand All @@ -101,8 +98,7 @@ func Validate(cfg config.Config, out string) int {
IgnoreMissingSchemas: cfg.IgnoreMissingSchemas,
})
if err != nil {
fmt.Fprintln(cfg.Stream.Error, err)
return 1
return fmt.Errorf("failed to validate: %s", err.Error())
}

validationResults := make(chan validator.Result)
Expand Down Expand Up @@ -162,8 +158,8 @@ func Validate(cfg config.Config, out string) int {
o.Flush()

if !success {
return 1
return fmt.Errorf("failed to process results")
}

return 0
return nil
}
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@ func main() {
fmt.Fprintf(os.Stderr, "failed parsing command line: %s\n", err.Error())
os.Exit(1)
}
os.Exit(kubeconform.Validate(cfg, out))

if err = kubeconform.Validate(cfg, out); err != nil {
fmt.Fprintf(os.Stderr, "failed validating resources: %s - %s\n", err.Error(), out)
os.Exit(1)
}
}
53 changes: 20 additions & 33 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,24 @@ type Stream struct {
}

type Config struct {
Cache string
Debug bool
ExitOnError bool
Files []string
SchemaLocations []string
SkipTLS bool
SkipKinds map[string]struct{}
RejectKinds map[string]struct{}
OutputFormat string
KubernetesVersion string
NumberOfWorkers int
Summary bool
Strict bool
Verbose bool
IgnoreMissingSchemas bool
IgnoreFilenamePatterns []string
Help bool
Version bool
Cache string `yaml:"cache" json:"cache"`
Debug bool `yaml:"debug" json:"debug"`
ExitOnError bool `yaml:"exitOnError" json:"exitOnError"`
Files []string `yaml:"files" json:"files"`
Help bool `yaml:"help" json:"help"`
IgnoreFilenamePatterns []string `yaml:"ignoreFilenamePatterns" json:"ignoreFilenamePatterns"`
IgnoreMissingSchemas bool `yaml:"ignoreMissingSchemas" json:"ignoreMissingSchemas"`
KubernetesVersion string `yaml:"kubernetesVersion" json:"kubernetesVersion"`
NumberOfWorkers int `yaml:"numberOfWorkers" json:"numberOfWorkers"`
OutputFormat string `yaml:"output" json:"output"`
RejectKinds []string `yaml:"reject" json:"reject"`
SchemaLocations []string `yaml:"schemaLocations" json:"schemaLocations"`
SkipKinds []string `yaml:"skip" json:"skip"`
SkipTLS bool `yaml:"insecureSkipTLSVerify" json:"insecureSkipTLSVerify"`
Strict bool `yaml:"strict" json:"strict"`
Summary bool `yaml:"summary" json:"summary"`
Verbose bool `yaml:"verbose" json:"verbose"`
Version bool `yaml:"version" json:"version"`
Stream *Stream
}

Expand All @@ -48,19 +48,6 @@ func (ap *arrayParam) Set(value string) error {
return nil
}

func splitCSV(csvStr string) map[string]struct{} {
splitValues := strings.Split(csvStr, ",")
valuesMap := map[string]struct{}{}

for _, kind := range splitValues {
if len(kind) > 0 {
valuesMap[kind] = struct{}{}
}
}

return valuesMap
}

// FromFlags retrieves kubeconform's runtime configuration from the command-line parameters
func FromFlags(progName string, args []string) (Config, string, error) {
var schemaLocationsParam, ignoreFilenamePatterns arrayParam
Expand Down Expand Up @@ -98,8 +85,8 @@ func FromFlags(progName string, args []string) (Config, string, error) {

err := flags.Parse(args)

c.SkipKinds = splitCSV(skipKindsCSV)
c.RejectKinds = splitCSV(rejectKindsCSV)
c.SkipKinds = strings.Split(skipKindsCSV, ",")
c.RejectKinds = strings.Split(rejectKindsCSV, ",")
c.IgnoreFilenamePatterns = ignoreFilenamePatterns
c.SchemaLocations = schemaLocationsParam
c.Files = flags.Args()
Expand Down
27 changes: 14 additions & 13 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"reflect"
"strings"
"testing"
)

Expand Down Expand Up @@ -33,7 +34,7 @@ func TestSkipKindMaps(t *testing.T) {
},
},
} {
got := splitCSV(testCase.csvSkipKinds)
got := strings.Split(testCase.csvSkipKinds, ",")
if !reflect.DeepEqual(got, testCase.expect) {
t.Errorf("%s - got %+v, expected %+v", testCase.name, got, testCase.expect)
}
Expand All @@ -53,8 +54,8 @@ func TestFromFlags(t *testing.T) {
NumberOfWorkers: 4,
OutputFormat: "text",
SchemaLocations: nil,
SkipKinds: map[string]struct{}{},
RejectKinds: map[string]struct{}{},
SkipKinds: []string{},
RejectKinds: []string{},
},
},
{
Expand All @@ -66,8 +67,8 @@ func TestFromFlags(t *testing.T) {
NumberOfWorkers: 4,
OutputFormat: "text",
SchemaLocations: nil,
SkipKinds: map[string]struct{}{},
RejectKinds: map[string]struct{}{},
SkipKinds: []string{},
RejectKinds: []string{},
},
},
{
Expand All @@ -79,8 +80,8 @@ func TestFromFlags(t *testing.T) {
NumberOfWorkers: 4,
OutputFormat: "text",
SchemaLocations: nil,
SkipKinds: map[string]struct{}{},
RejectKinds: map[string]struct{}{},
SkipKinds: []string{},
RejectKinds: []string{},
},
},
{
Expand All @@ -91,8 +92,8 @@ func TestFromFlags(t *testing.T) {
NumberOfWorkers: 4,
OutputFormat: "text",
SchemaLocations: nil,
SkipKinds: map[string]struct{}{"a": {}, "b": {}, "c": {}},
RejectKinds: map[string]struct{}{},
SkipKinds: []string{"a", "b", "c"},
RejectKinds: []string{},
},
},
{
Expand All @@ -103,8 +104,8 @@ func TestFromFlags(t *testing.T) {
NumberOfWorkers: 4,
OutputFormat: "text",
SchemaLocations: nil,
SkipKinds: map[string]struct{}{},
RejectKinds: map[string]struct{}{},
SkipKinds: []string{},
RejectKinds: []string{},
Summary: true,
Verbose: true,
},
Expand All @@ -122,8 +123,8 @@ func TestFromFlags(t *testing.T) {
NumberOfWorkers: 2,
OutputFormat: "json",
SchemaLocations: []string{"folder", "anotherfolder"},
SkipKinds: map[string]struct{}{"kinda": {}, "kindb": {}},
RejectKinds: map[string]struct{}{"kindc": {}, "kindd": {}},
SkipKinds: []string{"kinda", "kindb"},
RejectKinds: []string{"kindc", "kindd"},
Strict: true,
Summary: true,
Verbose: true,
Expand Down
12 changes: 12 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package utils

// Check if element is in an array.
func InArray(arr []string, str string) bool {
for _, elem := range arr {
if elem == str {
return true
}
}

return false
}
31 changes: 15 additions & 16 deletions pkg/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/yannh/kubeconform/pkg/cache"
"github.com/yannh/kubeconform/pkg/registry"
"github.com/yannh/kubeconform/pkg/resource"
"github.com/yannh/kubeconform/pkg/utils"
"sigs.k8s.io/yaml"
)

Expand Down Expand Up @@ -53,14 +54,14 @@ type Validator interface {

// Opts contains a set of options for the validator.
type Opts struct {
Cache string // Cache schemas downloaded via HTTP to this folder
Debug bool // Debug infos will be print here
SkipTLS bool // skip TLS validation when downloading from an HTTP Schema Registry
SkipKinds map[string]struct{} // List of resource Kinds to ignore
RejectKinds map[string]struct{} // List of resource Kinds to reject
KubernetesVersion string // Kubernetes Version - has to match one in https://github.com/instrumenta/kubernetes-json-schema
Strict bool // thros an error if resources contain undocumented fields
IgnoreMissingSchemas bool // skip a resource if no schema for that resource can be found
Cache string // Cache schemas downloaded via HTTP to this folder
Debug bool // Debug infos will be print here
SkipTLS bool // skip TLS validation when downloading from an HTTP Schema Registry
SkipKinds []string // List of resource Kinds to ignore
RejectKinds []string // List of resource Kinds to reject
KubernetesVersion string // Kubernetes Version - has to match one in https://github.com/instrumenta/kubernetes-json-schema
Strict bool // thros an error if resources contain undocumented fields
IgnoreMissingSchemas bool // skip a resource if no schema for that resource can be found
}

// New returns a new Validator
Expand All @@ -85,10 +86,10 @@ func New(schemaLocations []string, opts Opts) (Validator, error) {
}

if opts.SkipKinds == nil {
opts.SkipKinds = map[string]struct{}{}
opts.SkipKinds = []string{}
}
if opts.RejectKinds == nil {
opts.RejectKinds = map[string]struct{}{}
opts.RejectKinds = []string{}
}

return &v{
Expand All @@ -115,19 +116,17 @@ func (val *v) ValidateResource(res resource.Resource) Result {
// for skipping/rejecting resources) and the raw Kind.

skip := func(signature resource.Signature) bool {
if _, ok := val.opts.SkipKinds[signature.GroupVersionKind()]; ok {
if ok := utils.InArray(val.opts.SkipKinds, signature.GroupVersionKind()); ok {
return ok
}
_, ok := val.opts.SkipKinds[signature.Kind]
return ok
return utils.InArray(val.opts.SkipKinds, signature.Kind)
}

reject := func(signature resource.Signature) bool {
if _, ok := val.opts.RejectKinds[signature.GroupVersionKind()]; ok {
if ok := utils.InArray(val.opts.RejectKinds, signature.GroupVersionKind()); ok {
return ok
}
_, ok := val.opts.RejectKinds[signature.Kind]
return ok
return utils.InArray(val.opts.RejectKinds, signature.Kind)
}

if len(res.Bytes) == 0 {
Expand Down
8 changes: 4 additions & 4 deletions pkg/validator/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ lastName: bar
} {
val := v{
opts: Opts{
SkipKinds: map[string]struct{}{},
RejectKinds: map[string]struct{}{},
SkipKinds: []string{},
RejectKinds: []string{},
IgnoreMissingSchemas: testCase.ignoreMissingSchema,
Strict: testCase.strict,
},
Expand Down Expand Up @@ -418,8 +418,8 @@ age: not a number

val := v{
opts: Opts{
SkipKinds: map[string]struct{}{},
RejectKinds: map[string]struct{}{},
SkipKinds: []string{},
RejectKinds: []string{},
},
schemaCache: nil,
schemaDownload: downloadSchema,
Expand Down

0 comments on commit 7029e22

Please sign in to comment.