From 160be0f96a78a81f7a4d6bfe1f3b24ec31f67623 Mon Sep 17 00:00:00 2001 From: Edwin Smith Date: Tue, 8 Oct 2024 12:37:07 -0500 Subject: [PATCH] fix: default to injecting missing defaults --- cmd/kubeconform/main.go | 31 +++++++++++++++++++++---------- pkg/config/config.go | 4 ++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/cmd/kubeconform/main.go b/cmd/kubeconform/main.go index 5bb8c33..8a7121b 100644 --- a/cmd/kubeconform/main.go +++ b/cmd/kubeconform/main.go @@ -44,8 +44,8 @@ func loadManifestAndSchema(manifestPath, schemaPath string) (map[string]interfac return manifest, schema, nil } -// New function to inject defaults recursively -func injectDefaultsRecursively(schema map[string]interface{}, manifest map[string]interface{}) { +// New function to inject defaults recursively and return the injected defaults in a list form +func injectDefaultsRecursively(schema map[string]interface{}, manifest map[string]interface{}, injectedDefaults *[]string) { properties, propertiesExist := schema["properties"].(map[string]interface{}) if !propertiesExist { return @@ -57,7 +57,7 @@ func injectDefaultsRecursively(schema map[string]interface{}, manifest map[strin if ok { if defaultValue, hasDefault := subSchemaMap["default"]; hasDefault { manifest[key] = defaultValue - fmt.Printf("Injected default for %s: %v\\n", key, defaultValue) + *injectedDefaults = append(*injectedDefaults, fmt.Sprintf("%s: %v", key, defaultValue)) } } } else { @@ -65,14 +65,14 @@ func injectDefaultsRecursively(schema map[string]interface{}, manifest map[strin if subSchemaType, typeExists := subSchemaMap["type"].(string); typeExists { if subSchemaType == "object" { if nestedManifest, isMap := manifest[key].(map[string]interface{}); isMap { - injectDefaultsRecursively(subSchemaMap, nestedManifest) + injectDefaultsRecursively(subSchemaMap, nestedManifest, injectedDefaults) } } else if subSchemaType == "array" { if arrayItems, hasItems := subSchemaMap["items"].(map[string]interface{}); hasItems { if manifestArray, isArray := manifest[key].([]interface{}); isArray { for _, item := range manifestArray { if itemMap, isMap := item.(map[string]interface{}); isMap { - injectDefaultsRecursively(arrayItems, itemMap) + injectDefaultsRecursively(arrayItems, itemMap, injectedDefaults) } } } @@ -95,7 +95,7 @@ func processResults(cancel context.CancelFunc, o output.Output, validationResult } if o != nil { if err := o.Write(res); err != nil { - fmt.Fprint(os.Stderr, "failed writing log\\n") + fmt.Fprint(os.Stderr, "failed writing log\n") } } if !success && exitOnError { @@ -171,17 +171,28 @@ func kubeconform(cfg config.Config) int { if cfg.InjectMissingDefaults { manifest, schema, err := loadManifestAndSchema(cfg.Files[0], cfg.SchemaLocations[0]) if err != nil { - fmt.Fprintf(os.Stderr, "error loading manifest or schema: %s\\n", err) + fmt.Fprintf(os.Stderr, "error loading manifest or schema: %s\n", err) os.Exit(1) } + // List to store injected defaults + var injectedDefaults []string + // Inject defaults into the manifest - injectDefaultsRecursively(schema, manifest) + injectDefaultsRecursively(schema, manifest, &injectedDefaults) + + // Display injected defaults in list form if verbose flag is enabled + if cfg.Verbose && len(injectedDefaults) > 0 { + fmt.Println("Injected Defaults:") + for _, def := range injectedDefaults { + fmt.Printf(" - %s\n", def) + } + } // Convert the modified manifest back to YAML for validation updatedManifest, err := yaml.Marshal(manifest) if err != nil { - fmt.Fprintf(os.Stderr, "error converting updated manifest to YAML: %s\\n", err) + fmt.Fprintf(os.Stderr, "error converting updated manifest to YAML: %s\n", err) os.Exit(1) } @@ -268,7 +279,7 @@ func main() { } if err != nil { - fmt.Fprintf(os.Stderr, "failed parsing command line: %s\\n", err.Error()) + fmt.Fprintf(os.Stderr, "failed parsing command line: %s\n", err.Error()) os.Exit(1) } diff --git a/pkg/config/config.go b/pkg/config/config.go index c48a27b..acb912c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -52,7 +52,7 @@ func (kv k8sVersionValue) MarshalText() ([]byte, error) { } func (kv *k8sVersionValue) UnmarshalText(v []byte) error { - if ok, _ := regexp.MatchString(`^(master|\d+\.\d+\.\d+)$`, string(v)); ok != true { + if ok, _ := regexp.MatchString(`^(master|\d+\.\d+\.\d+)$`, string(v)); !ok { return fmt.Errorf("%v is not a valid version. Valid values are \"master\" (default) or full version x.y.z (e.g. \"1.27.2\")", string(v)) } *kv = k8sVersionValue(v) @@ -103,7 +103,7 @@ func FromFlags(progName string, args []string) (Config, string, error) { flags.BoolVar(&c.Version, "v", false, "show version information") // New flag added for injecting missing defaults - flags.BoolVar(&c.InjectMissingDefaults, "inject-missing-defaults", false, "Inject missing required fields with defaults from the schema") + flags.BoolVar(&c.InjectMissingDefaults, "inject-missing-defaults", true, "Inject missing required fields with defaults from the schema") flags.Usage = func() { fmt.Fprintf(&buf, "Usage: %s [OPTION]... [FILE OR FOLDER]...\n", progName)