commit fe33d14dc40b0c5c9b0d773c08d564ebe9d71de2 Author: Yann Hamon Date: Sat May 30 02:44:13 2020 +0200 first commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a938083 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +#!/usr/bin/make -f + +all: + go build diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..e69de29 diff --git a/fixtures/valid_1.yaml b/fixtures/valid_1.yaml new file mode 100644 index 0000000..a597e39 --- /dev/null +++ b/fixtures/valid_1.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +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 \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1e64db4 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/yannh/kubeconform + +go 1.14 + +require gopkg.in/yaml.v2 v2.3.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8fabe8d --- /dev/null +++ b/go.sum @@ -0,0 +1,3 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go new file mode 100644 index 0000000..b5231b7 --- /dev/null +++ b/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "log" + "os" + + "github.com/yannh/kubeconform/pkg/registry" + "github.com/yannh/kubeconform/pkg/resource" +) + +func realMain() int { + filename := "fixtures/valid_1.yaml" + f, err := os.Open(filename) + if err != nil { + log.Fatalf("failed opening %s", filename) + return 1 + } + defer f.Close() + + res, err := resource.Read(f) + if err != nil { + log.Printf("failed parsing %s", filename) + return 1 + } + + r := registry.NewKubernetesRegistry() + schema, err := r.DownloadSchema(res.Kind, res.Version, "1.18.0") + + if err != nil { + log.Printf("error downloading Schema: %s") + return 1 + } + + log.Printf("downloaded schema successfully: %s", schema) + + return 0 +} + +func main() { + os.Exit(realMain()) +} \ No newline at end of file diff --git a/pkg/registry/registry.go b/pkg/registry/registry.go new file mode 100644 index 0000000..8739d7f --- /dev/null +++ b/pkg/registry/registry.go @@ -0,0 +1,71 @@ +package registry + +import ( + "fmt" + "io/ioutil" + "net/http" + "strings" +) + +type Manifest struct { + Kind, Version string +} + +type Registry interface { + DownloadSchema(kind, apiVersion string) error +} + +type KubernetesRegistry struct { + baseURL string + strict bool +} + +func NewKubernetesRegistry() *KubernetesRegistry { + return &KubernetesRegistry{ + baseURL: "https://kubernetesjsonschema.dev", + strict: false, + } +} + + +func (r KubernetesRegistry) schemaURL(resourceKind, resourceAPIVersion, k8sVersion string) string { + normalisedVersion := k8sVersion + if normalisedVersion != "master" { + normalisedVersion = "v" + normalisedVersion + } + + strictSuffix := "" + if r.strict { + strictSuffix = "-strict" + } + + groupParts := strings.Split(resourceAPIVersion, "/") + versionParts := strings.Split(groupParts[0], ".") + + kindSuffix := "-" + strings.ToLower(versionParts[0]) + if len(groupParts) > 1 { + kindSuffix += "-" + strings.ToLower(groupParts[1]) + } + + return fmt.Sprintf("%s/%s-standalone%s/%s%s.json", r.baseURL, normalisedVersion, strictSuffix, strings.ToLower(resourceKind), kindSuffix) +} + +func (r KubernetesRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVersion string) (string, error) { + url := r.schemaURL(resourceKind, resourceAPIVersion, k8sVersion) + + resp, err := http.Get(url) + if err != nil { + return "", fmt.Errorf("failed downloading schema at %s: %s", url, err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("failed downloading schema at %s: %s", url, err) + } + + fmt.Printf("downloaded %s\n", url) + + return string(body), nil +} + diff --git a/pkg/resource/main.go b/pkg/resource/main.go new file mode 100644 index 0000000..cdc57f4 --- /dev/null +++ b/pkg/resource/main.go @@ -0,0 +1,30 @@ +package resource + +import ( + "io" + "io/ioutil" + yaml "gopkg.in/yaml.v2" +) + +type Resource struct { + Kind, Version, Namespace string +} + +// TODO: Support multi-resources yaml files +func Read(r io.Reader) (Resource, error) { + s, err := ioutil.ReadAll(r) + if err != nil { + return Resource{}, err + } + + resource := struct { + APIVersion string `yaml:"apiVersion"` + Kind string `yaml:"kind"` + Metadata struct { + Namespace string `yaml:"Namespace"` + } `yaml:"Metadata"` + }{} + err = yaml.Unmarshal(s, &resource) + + return Resource{Kind: resource.Kind, Version: resource.APIVersion, Namespace: resource.Metadata.Namespace}, err +} \ No newline at end of file