diff --git a/acceptance.bats b/acceptance.bats index 287f22e..8617d5b 100755 --- a/acceptance.bats +++ b/acceptance.bats @@ -85,13 +85,19 @@ @test "Fail when parsing a config that is missing a Kind" { run bin/kubeconform -summary fixtures/missing_kind.yaml [ "$status" -eq 1 ] - [[ "$output" == *"resource missing a Kind"* ]] + [[ "$output" == *"missing 'kind' key"* ]] +} + +@test "Fail when parsing a config that is missing an apiVersion" { + run bin/kubeconform -summary fixtures/missing_apiversion.yaml + [ "$status" -eq 1 ] + [[ "$output" == *"missing 'apiVersion' key"* ]] } @test "Fail when parsing a config that is missing a Kind value" { run bin/kubeconform -summary fixtures/missing_kind_value.yaml [ "$status" -eq 1 ] - [[ "$output" == *"resource missing a Kind"* ]] + [[ "$output" == *"missing 'kind' key"* ]] } @test "Fail when parsing a config with CRD" { diff --git a/fixtures/missing_apiversion.yaml b/fixtures/missing_apiversion.yaml new file mode 100644 index 0000000..05f338f --- /dev/null +++ b/fixtures/missing_apiversion.yaml @@ -0,0 +1,18 @@ +kind: ReplicationController +metadata: + name: "bob" +spec: + replicas: 2 + selector: + app: nginx + template: + metadata: + name: nginx + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 diff --git a/pkg/resource/resource.go b/pkg/resource/resource.go index 96a46ef..1d32c60 100644 --- a/pkg/resource/resource.go +++ b/pkg/resource/resource.go @@ -1,6 +1,8 @@ package resource import ( + "fmt" + "sigs.k8s.io/yaml" ) @@ -40,6 +42,19 @@ func (res *Resource) Signature() (*Signature, error) { // We cache the result to not unmarshall every time we want to access the signature res.sig = &Signature{Kind: resource.Kind, Version: resource.APIVersion, Namespace: resource.Metadata.Namespace, Name: name} + + if err != nil { // Exit if there was an error unmarshalling + return res.sig, err + } + + if resource.Kind == "" { + return res.sig, fmt.Errorf("missing 'kind' key") + } + + if resource.APIVersion == "" { + return res.sig, fmt.Errorf("missing 'apiVersion' key") + } + return res.sig, err } @@ -48,8 +63,15 @@ func (res *Resource) SignatureFromMap(m map[string]interface{}) (*Signature, err return res.sig, nil } - APIVersion, _ := m["apiVersion"].(string) - Kind, _ := m["kind"].(string) + Kind, ok := m["kind"].(string) + if !ok { + return res.sig, fmt.Errorf("missing 'kind' key") + } + + APIVersion, ok := m["apiVersion"].(string) + if !ok { + return res.sig, fmt.Errorf("missing 'apiVersion' key") + } var name, ns string Metadata, ok := m["metadata"].(map[string]interface{}) diff --git a/pkg/validator/validator.go b/pkg/validator/validator.go index fefc7e1..9415e55 100644 --- a/pkg/validator/validator.go +++ b/pkg/validator/validator.go @@ -123,10 +123,6 @@ func (val *v) ValidateResource(res resource.Resource) Result { return Result{Resource: res, Err: fmt.Errorf("error while parsing: %s", err), Status: Error} } - if sig.Kind == "" { // Resource contains key/values but no Kind - return Result{Resource: res, Err: fmt.Errorf("resource missing a Kind"), Status: Error} - } - if skip(*sig) { return Result{Resource: res, Err: nil, Status: Skipped} } diff --git a/pkg/validator/validator_test.go b/pkg/validator/validator_test.go index 3184936..f97e284 100644 --- a/pkg/validator/validator_test.go +++ b/pkg/validator/validator_test.go @@ -19,6 +19,7 @@ func TestValidate(t *testing.T) { "valid resource", []byte(` kind: name +apiVersion: v1 firstName: foo lastName: bar `), @@ -49,6 +50,7 @@ lastName: bar "invalid resource", []byte(` kind: name +apiVersion: v1 firstName: foo lastName: bar `), @@ -79,6 +81,7 @@ lastName: bar "missing required field", []byte(` kind: name +apiVersion: v1 firstName: foo `), []byte(`{ @@ -108,6 +111,7 @@ firstName: foo "resource has invalid yaml", []byte(` kind: name +apiVersion: v1 firstName foo lastName: bar `), @@ -118,6 +122,9 @@ lastName: bar "kind": { "type": "string" }, + "apiVersion": { + "type": "string" + }, "firstName": { "type": "number" },