Skip to content

Commit

Permalink
validate ObjectMeta
Browse files Browse the repository at this point in the history
  • Loading branch information
chonton committed Sep 25, 2024
1 parent 1bd4498 commit a09d17a
Show file tree
Hide file tree
Showing 18 changed files with 302 additions and 36 deletions.
40 changes: 40 additions & 0 deletions acceptance.bats
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,46 @@ resetCacheFolder() {
[ "$status" -eq 1 ]
}

@test "Fail when annotation key is invalid" {
run bin/kubeconform fixtures/annotation_key_invalid.yaml
[ "$status" -eq 1 ]
}

@test "Fail when annotation value is missing" {
run bin/kubeconform fixtures/annotation_missing_value.yaml
[ "$status" -eq 1 ]
}

@test "Fail when annotation value is null" {
run bin/kubeconform fixtures/annotation_null_value.yaml
[ "$status" -eq 1 ]
}

@test "Fail when label name is too long" {
run bin/kubeconform fixtures/label_name_length.yaml
[ "$status" -eq 1 ]
}

@test "Fail when label namespace is invalid domain" {
run bin/kubeconform fixtures/label_namespace.yaml
[ "$status" -eq 1 ]
}

@test "Fail when label value is too long" {
run bin/kubeconform fixtures/label_value_length.yaml
[ "$status" -eq 1 ]
}

@test "Fail when metadata name is missing" {
run bin/kubeconform fixtures/metadata_name_missing.yaml
[ "$status" -eq 1 ]
}

@test "Pass if skip-metadata added" {
run bin/kubeconform -skip-metadata fixtures/metadata_name_missing.yaml
[ "$status" -eq 0 ]
}

@test "Return relevant error for non-existent file" {
run bin/kubeconform fixtures/not-here
[ "$status" -eq 1 ]
Expand Down
1 change: 1 addition & 0 deletions cmd/kubeconform/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func kubeconform(cfg config.Config) int {
SkipKinds: cfg.SkipKinds,
RejectKinds: cfg.RejectKinds,
KubernetesVersion: cfg.KubernetesVersion.String(),
SkipMetadata: cfg.SkipMetadata,
Strict: cfg.Strict,
IgnoreMissingSchemas: cfg.IgnoreMissingSchemas,
})
Expand Down
8 changes: 8 additions & 0 deletions fixtures/annotation_key_invalid.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: some-values
annotations:
cert(manager.io/cluster-issuer": issue #275
data:
file.name: "a value"
8 changes: 8 additions & 0 deletions fixtures/annotation_missing_value.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: some-values
annotations:
some.domain/some-key:
data:
file.name: "a value"
8 changes: 8 additions & 0 deletions fixtures/annotation_null_value.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: some-values
annotations:
some.domain/some-key: null
data:
file.name: "a value"
8 changes: 8 additions & 0 deletions fixtures/label_name_length.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: some-values
labels:
abcdefghijklmnopqrstuvwxyz-01234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ: "123456789_123456789_123456789_123456789_123456789_123456789_123"
data:
file.name: "a value"
8 changes: 8 additions & 0 deletions fixtures/label_namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: some-values
labels:
abcdefghijklmnopqrstuvwxyz-01234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ.example.com/ABCDEFGHIJKLMNOPQRSTUVWXYZ: "123456789_123456789_123456789_123456789_123456789_123456789_123"
data:
file.name: "a value"
8 changes: 8 additions & 0 deletions fixtures/label_value_length.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: some-values
labels:
some.domain/some-key: 123456789_123456789_123456789_123456789_123456789_123456789_1234
data:
file.name: "a value"
4 changes: 4 additions & 0 deletions fixtures/metadata_missing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: ConfigMap
data:
file.name: "a value"
6 changes: 6 additions & 0 deletions fixtures/metadata_name_missing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ConfigMap
metadata:

data:
file.name: "a value"
6 changes: 6 additions & 0 deletions fixtures/object_name-max_length.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: abcdefghijklmnopqrstuvwxyz-01234567890-ABCDEFGHIJKLMNOPQRSTUVWXYZ
data:
file.name: "a value"
2 changes: 2 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Config struct {
RejectKinds map[string]struct{} `yaml:"reject" json:"reject"`
SchemaLocations []string `yaml:"schemaLocations" json:"schemaLocations"`
SkipKinds map[string]struct{} `yaml:"skip" json:"skip"`
SkipMetadata bool `yaml:"skipMetadata" json:"skipMetadata"`
SkipTLS bool `yaml:"insecureSkipTLSVerify" json:"insecureSkipTLSVerify"`
Strict bool `yaml:"strict" json:"strict"`
Summary bool `yaml:"summary" json:"summary"`
Expand Down Expand Up @@ -97,6 +98,7 @@ func FromFlags(progName string, args []string) (Config, string, error) {
flags.StringVar(&c.OutputFormat, "output", "text", "output format - json, junit, pretty, tap, text")
flags.BoolVar(&c.Verbose, "verbose", false, "print results for all resources (ignored for tap and junit output)")
flags.BoolVar(&c.SkipTLS, "insecure-skip-tls-verify", false, "disable verification of the server's SSL certificate. This will make your HTTPS connections insecure")
flags.BoolVar(&c.SkipMetadata, "skip-metadata", false, "skip extra validations of metadata section")
flags.StringVar(&c.Cache, "cache", "", "cache schemas downloaded via HTTP to this folder")
flags.BoolVar(&c.Help, "h", false, "show help information")
flags.BoolVar(&c.Version, "v", false, "show version information")
Expand Down
28 changes: 28 additions & 0 deletions pkg/registry/embeded.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package registry

import (
"embed"
)

//go:embed *.json
var content embed.FS

type EmbeddedRegistry struct {
debug bool
}

// newEmbeddedRegistry creates a new "registry", that will serve schemas from embedded resource
func newEmbeddedRegistry(debug bool) (*EmbeddedRegistry, error) {
return &EmbeddedRegistry{
debug,
}, nil
}

// DownloadSchema retrieves the schema from a file for the resource
func (r EmbeddedRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVersion string) (string, []byte, error) {
bytes, err := content.ReadFile(resourceKind + ".json")
if err != nil {
return resourceKind, nil, nil
}
return resourceKind, bytes, nil
}
94 changes: 94 additions & 0 deletions pkg/registry/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"apiVersion": {
"$ref": "#/$defs/NAMESPACED"
},
"kind": {
"$ref": "#/$defs/NAME"
},
"metadata": {
"type": "object",
"properties": {
"name": {
"$ref": "#/$defs/RFC-1123"
},
"generateName": {
"$ref": "#/$defs/RFC-1123-prefix"
},
"annotations": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/NAMESPACED"
},
"patternProperties": {
"^.+$": {
"type": "string",
"minLength": 1
}
}
},
"labels": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/NAMESPACED"
},
"patternProperties": {
"^.+$": {
"$ref": "#/$defs/NAME"
}
}
}
},
"oneOf": [
{
"required": [
"name"
]
},
{
"required": [
"generateName"
]
}
]
}
},
"required": [
"apiVersion",
"kind",
"metadata"
],
"$defs": {
"NAMESPACED": {
"allOf": [
{
"pattern": "^(.{0,253}/)?.{1,63}$",
"type": "string"
},
{
"pattern": "^([a-z0-9-]{1,63}(\\.[a-z0-9-]{1,63})*/)?[a-z0-9A-Z]+([_.-][a-z0-9A-Z]+)*$"
}
]
},
"NAME": {
"type": "string",
"minLength": 1,
"maxLength": 63,
"pattern": "^[a-z0-9A-Z]+([_.-][a-z0-9A-Z]+)*$"
},
"RFC-1123": {
"type": "string",
"minLength": 1,
"maxLength": 63,
"pattern": "^[a-z0-9]+(-+[a-z0-9]+)*$"
},
"RFC-1123-prefix": {
"type": "string",
"minLength": 1,
"maxLength": 58,
"pattern": "^[a-z0-9]+[a-z0-9-]*$"
}
}
}
4 changes: 4 additions & 0 deletions pkg/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,9 @@ func New(schemaLocation string, cache string, strict bool, skipTLS bool, debug b
return newHTTPRegistry(schemaLocation, cache, strict, skipTLS, debug)
}

if strings.HasPrefix(schemaLocation, "embedded") {
return newEmbeddedRegistry(debug)
}

return newLocalRegistry(schemaLocation, strict, debug)
}
Loading

0 comments on commit a09d17a

Please sign in to comment.