From 0949b76f51dc8fea4638c82099e7a055cb3969d4 Mon Sep 17 00:00:00 2001 From: Yann Hamon Date: Sun, 18 Oct 2020 14:28:19 +0200 Subject: [PATCH] rename -regitry to -schema-location, make its syntax more compatible to kubeval --- Readme.md | 22 +++++++++++----------- acceptance.bats | 18 +++++++++--------- cmd/kubeconform/main.go | 24 +++++++++++++----------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/Readme.md b/Readme.md index 3d24d87..16a526f 100644 --- a/Readme.md +++ b/Readme.md @@ -42,8 +42,8 @@ Usage of ./bin/kubeconform: number of routines to run in parallel (default 4) -output string output format - text, json (default "text") - -registry value - override schemas registry path (can be specified multiple times) + -schema-location value + override schemas location search path (can be specified multiple times) -skip string comma-separated list of kinds to ignore -strict @@ -90,24 +90,24 @@ $ echo $? * Validating a folder, increasing the number of parallel workers ``` $ ./bin/kubeconform -summary -n 16 fixtures -fixtures/multi_invalid.yaml - Service is invalid: Invalid type. Expected: integer, given: string -fixtures/invalid.yaml - ReplicationController is invalid: Invalid type. Expected: [integer,null], given: string +fixtures/crd_schema.yaml - CustomResourceDefinition trainingjobs.sagemaker.aws.amazon.com failed validation: could not find schema for CustomResourceDefinition +fixtures/invalid.yaml - ReplicationController bob is invalid: Invalid type. Expected: [integer,null], given: string [...] -Summary: 48 resources found in 25 files - Valid: 39, Invalid: 2, Errors: 7 Skipped: 0 +Summary: 65 resources found in 34 files - Valid: 55, Invalid: 2, Errors: 8 Skipped: 0 ``` -### Overriding schemas registries lookup order - CRD support +### Overriding schemas location - CRD support -When the `-registry` file is not used, kubeconform will default to downloading schemas from -`kubernetesjsonschema.dev`. Kubeconform however supports the use of one, or multiple, custom schemas +When the `-schema-location` file is not used, kubeconform will default to downloading schemas from +`https://kubernetesjsonschema.dev`. Kubeconform however supports the use of one, or multiple, custom schemas registries - with access over HTTP or local filesystem. Kubeconform will lookup for schema definitions in each of them, in order, stopping as soon as a matching file is found. All 3 following command lines are equivalent: ``` $ ./bin/kubeconform fixtures/valid.yaml -$ ./bin/kubeconform -registry kubernetesjsonschema.dev fixtures/valid.yaml -$ ./bin/kubeconform -registry 'https://kubernetesjsonschema.dev/{{ .NormalizedVersion }}-standalone{{ .StrictSuffix }}/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/valid.yaml +$ ./bin/kubeconform -schema-location https://kubernetesjsonschema.dev fixtures/valid.yaml +$ ./bin/kubeconform -schema-location 'https://kubernetesjsonschema.dev/{{ .NormalizedVersion }}-standalone{{ .StrictSuffix }}/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/valid.yaml ``` To support validating CRDs, we need to convert OpenAPI files to JSON schema, storing the JSON schemas @@ -115,7 +115,7 @@ in a local folder - for example schemas. Then we specify this folder as an addit ``` # If the resource Kind is not found in kubernetesjsonschema.dev, also lookup in the schemas/ folder for a matching file -$ ./bin/kubeconform -registry kubernetesjsonschema.dev -registry 'schemas/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/custom-resource.yaml +$ ./bin/kubeconform -registry kubernetesjsonschema.dev -schema-location 'schemas/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/custom-resource.yaml ``` ### Generating a JSON schema from an OpenAPI file diff --git a/acceptance.bats b/acceptance.bats index c460b0d..be4ff61 100755 --- a/acceptance.bats +++ b/acceptance.bats @@ -86,7 +86,7 @@ } @test "Pass when parsing a Custom Resource and using a local schema registry with appropriate CRD" { - run bin/kubeconform -registry './fixtures/registry/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/test_crd.yaml + run bin/kubeconform -schema-location './fixtures/registry/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/test_crd.yaml [ "$status" -eq 0 ] } @@ -96,22 +96,22 @@ [ "$output" = "Summary: 1 resource found in 1 file - Valid: 1, Invalid: 0, Errors: 0 Skipped: 0" ] } -@test "Pass when using a valid, preset --registry" { - run bin/kubeconform --registry kubernetesjsonschema.dev fixtures/valid.yaml +@test "Pass when using a valid, preset -schema-location" { + run bin/kubeconform -schema-location https://kubernetesjsonschema.dev fixtures/valid.yaml [ "$status" -eq 0 ] } -@test "Pass when using a valid HTTP --registry" { - run bin/kubeconform --registry 'https://kubernetesjsonschema.dev/{{ .NormalizedVersion }}-standalone{{ .StrictSuffix }}/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/valid.yaml +@test "Pass when using a valid HTTP -schema-location" { + run bin/kubeconform -schema-location 'https://kubernetesjsonschema.dev/{{ .NormalizedVersion }}-standalone{{ .StrictSuffix }}/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/valid.yaml [ "$status" -eq 0 ] } -@test "Fail when using an invalid HTTP --registry" { - run bin/kubeconform --registry 'http://foo' fixtures/valid.yaml +@test "Fail when using an invalid HTTP -schema-location" { + run bin/kubeconform -schema-location 'http://foo' fixtures/valid.yaml [ "$status" -eq 1 ] } -@test "Fail when using an invalid non-HTTP --registry" { - run bin/kubeconform --registry 'foo' fixtures/valid.yaml +@test "Fail when using an invalid non-HTTP -schema-location" { + run bin/kubeconform -schema-location 'foo' fixtures/valid.yaml [ "$status" -eq 1 ] } diff --git a/cmd/kubeconform/main.go b/cmd/kubeconform/main.go index 1dcf969..7cabdef 100644 --- a/cmd/kubeconform/main.go +++ b/cmd/kubeconform/main.go @@ -215,7 +215,7 @@ func getFiles(files []string, fileBatches chan []string, validationResults chan } func realMain() int { - var regs arrayParam + var schemaLocationsParam arrayParam var skipKindsCSV, k8sVersion, outputFormat string var summary, strict, verbose, ignoreMissingSchemas bool var nWorkers int @@ -223,7 +223,7 @@ func realMain() int { var files []string flag.StringVar(&k8sVersion, "k8sversion", "1.18.0", "version of Kubernetes to test against") - flag.Var(®s, "registry", "override schemas registry path (can be specified multiple times)") + flag.Var(&schemaLocationsParam, "schema-location", "override schemas location search path (can be specified multiple times)") flag.BoolVar(&ignoreMissingSchemas, "ignore-missing-schemas", false, "skip files with missing schemas instead of failing") flag.BoolVar(&summary, "summary", false, "print a summary at the end") flag.IntVar(&nWorkers, "n", 4, "number of routines to run in parallel") @@ -244,18 +244,20 @@ func realMain() int { return ok && isSkipKind } - registries := []registry.Registry{} - if len(regs) == 0 { - regs = append(regs, "kubernetesjsonschema.dev") // if not specified, default behaviour is to use kubernetesjson-schema.dev as registry + if len(schemaLocationsParam) == 0 { + schemaLocationsParam = append(schemaLocationsParam, "https://kubernetesjsonschema.dev") // if not specified, default behaviour is to use kubernetesjson-schema.dev as registry } - for _, reg := range regs { - if reg == "kubernetesjsonschema.dev" { - registries = append(registries, registry.NewHTTPRegistry("https://kubernetesjsonschema.dev/{{ .NormalizedVersion }}-standalone{{ .StrictSuffix }}/{{ .ResourceKind }}{{ .KindSuffix }}.json", strict)) - } else if strings.HasPrefix(reg, "http") { - registries = append(registries, registry.NewHTTPRegistry(reg, strict)) + registries := []registry.Registry{} + for _, schemaLocation := range schemaLocationsParam { + if strings.HasSuffix(schemaLocation, "json") { // If we dont specify a full templated path, we assume the paths of kubernetesjsonschema.dev + schemaLocation += "/{{ .NormalizedVersion }}-standalone{{ .StrictSuffix }}/{{ .ResourceKind }}{{ .KindSuffix }}.json" + } + + if strings.HasPrefix(schemaLocation, "http") { + registries = append(registries, registry.NewHTTPRegistry(schemaLocation, strict)) } else { - registries = append(registries, registry.NewLocalRegistry(reg, strict)) + registries = append(registries, registry.NewLocalRegistry(schemaLocation, strict)) } }