From fcfe30804a1d8170f424c7bff839feb54d9d3e78 Mon Sep 17 00:00:00 2001 From: Victor Fernandes Date: Thu, 16 Nov 2023 17:06:08 +0100 Subject: [PATCH 1/4] chore: removing deprecated ioutil package --- pkg/cache/ondisk.go | 6 +++--- pkg/registry/http.go | 4 ++-- pkg/registry/http_test.go | 8 ++++---- pkg/registry/local.go | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/cache/ondisk.go b/pkg/cache/ondisk.go index 5d7e41b0..91868795 100644 --- a/pkg/cache/ondisk.go +++ b/pkg/cache/ondisk.go @@ -4,7 +4,7 @@ import ( "crypto/sha256" "encoding/hex" "fmt" - "io/ioutil" + "io" "os" "path" "sync" @@ -37,12 +37,12 @@ func (c *onDisk) Get(resourceKind, resourceAPIVersion, k8sVersion string) (inter return nil, err } - return ioutil.ReadAll(f) + return io.ReadAll(f) } // Set adds a JSON schema to the schema cache func (c *onDisk) Set(resourceKind, resourceAPIVersion, k8sVersion string, schema interface{}) error { c.Lock() defer c.Unlock() - return ioutil.WriteFile(cachePath(c.folder, resourceKind, resourceAPIVersion, k8sVersion), schema.([]byte), 0644) + return os.WriteFile(cachePath(c.folder, resourceKind, resourceAPIVersion, k8sVersion), schema.([]byte), 0644) } diff --git a/pkg/registry/http.go b/pkg/registry/http.go index 2af0c6c3..9d342d29 100644 --- a/pkg/registry/http.go +++ b/pkg/registry/http.go @@ -4,7 +4,7 @@ import ( "crypto/tls" "errors" "fmt" - "io/ioutil" + "io" "log" "net/http" "os" @@ -99,7 +99,7 @@ func (r SchemaRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVers return url, nil, fmt.Errorf(msg) } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { msg := fmt.Sprintf("failed parsing schema from %s: %s", url, err) if r.debug { diff --git a/pkg/registry/http_test.go b/pkg/registry/http_test.go index 1ab47913..53962c96 100644 --- a/pkg/registry/http_test.go +++ b/pkg/registry/http_test.go @@ -3,7 +3,7 @@ package registry import ( "bytes" "fmt" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -50,7 +50,7 @@ func TestDownloadSchema(t *testing.T) { newMockHTTPGetter(func(url string) (resp *http.Response, err error) { return &http.Response{ StatusCode: http.StatusNotFound, - Body: ioutil.NopCloser(strings.NewReader("http response mock body")), + Body: io.NopCloser(strings.NewReader("http response mock body")), }, nil }), "http://kubernetesjson.dev", @@ -66,7 +66,7 @@ func TestDownloadSchema(t *testing.T) { newMockHTTPGetter(func(url string) (resp *http.Response, err error) { return &http.Response{ StatusCode: http.StatusServiceUnavailable, - Body: ioutil.NopCloser(strings.NewReader("http response mock body")), + Body: io.NopCloser(strings.NewReader("http response mock body")), }, nil }), "http://kubernetesjson.dev", @@ -82,7 +82,7 @@ func TestDownloadSchema(t *testing.T) { newMockHTTPGetter(func(url string) (resp *http.Response, err error) { return &http.Response{ StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader("http response mock body")), + Body: io.NopCloser(strings.NewReader("http response mock body")), }, nil }), "http://kubernetesjson.dev", diff --git a/pkg/registry/local.go b/pkg/registry/local.go index ec9e0476..7501290e 100644 --- a/pkg/registry/local.go +++ b/pkg/registry/local.go @@ -3,7 +3,7 @@ package registry import ( "errors" "fmt" - "io/ioutil" + "io" "log" "os" ) @@ -47,7 +47,7 @@ func (r LocalRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVersi } defer f.Close() - content, err := ioutil.ReadAll(f) + content, err := io.ReadAll(f) if err != nil { msg := fmt.Sprintf("failed to read schema at %s: %s", schemaFile, err) if r.debug { From d6fea4f72c74b5dccc5d2fe94a8928a838cda7e1 Mon Sep 17 00:00:00 2001 From: Victor Fernandes Date: Thu, 16 Nov 2023 18:25:43 +0100 Subject: [PATCH 2/4] docs: updating docs to add new private repo feature --- Readme.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Readme.md b/Readme.md index f135f597..610ec5ce 100644 --- a/Readme.md +++ b/Readme.md @@ -290,6 +290,13 @@ kubeconform -kubernetes-version 3.8.0 -schema-location 'https://raw.githubuserc Summary: 1 resource found in 1 file - Valid: 1, Invalid: 0, Errors: 0 Skipped: 0 ``` +### Schemas behind private GitHub repos + +By setting the environment variable `GITHUB_TOKEN=x` you can use schemas that are behind a private repository. +See [getting a token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) for info on how to get one command line token. +> Tip: if using GitHub CLI, `gh auth token` will give a valid token. + + ## Integrating Kubeconform in the CI `Kubeconform` publishes Docker Images to Github's new Container Registry (ghcr.io). These images From f8e9196791233466fba13f6df7edf3a189a9eb43 Mon Sep 17 00:00:00 2001 From: Victor Fernandes Date: Thu, 16 Nov 2023 18:26:31 +0100 Subject: [PATCH 3/4] feature: adding env to allow for private repo usage --- pkg/registry/http.go | 13 +++++++++---- pkg/registry/http_test.go | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/pkg/registry/http.go b/pkg/registry/http.go index 9d342d29..5c763152 100644 --- a/pkg/registry/http.go +++ b/pkg/registry/http.go @@ -13,13 +13,13 @@ import ( "github.com/yannh/kubeconform/pkg/cache" ) -type httpGetter interface { - Get(url string) (resp *http.Response, err error) +type httpDoer interface { + Do(*http.Request) (resp *http.Response, err error) } // SchemaRegistry is a file repository (local or remote) that contains JSON schemas for Kubernetes resources type SchemaRegistry struct { - c httpGetter + c httpDoer schemaPathTemplate string cache cache.Cache strict bool @@ -72,8 +72,13 @@ func (r SchemaRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVers return url, b.([]byte), nil } } + req, _ := http.NewRequest("GET", url, nil) - resp, err := r.c.Get(url) + if token, exist := os.LookupEnv("GITHUB_TOKEN"); exist { + req.Header.Add("Authorization", fmt.Sprintf("token %s", token)) + } + + resp, err := r.c.Do(req) if err != nil { msg := fmt.Sprintf("failed downloading schema at %s: %s", url, err) if r.debug { diff --git a/pkg/registry/http_test.go b/pkg/registry/http_test.go index 53962c96..9376b63d 100644 --- a/pkg/registry/http_test.go +++ b/pkg/registry/http_test.go @@ -9,23 +9,23 @@ import ( "testing" ) -type mockHTTPGetter struct { - httpGet func(string) (*http.Response, error) +type mockHTTPDoer struct { + httpDo func(*http.Request) (*http.Response, error) } -func newMockHTTPGetter(f func(string) (*http.Response, error)) *mockHTTPGetter { - return &mockHTTPGetter{ - httpGet: f, +func newMockHTTPDoer(f func(*http.Request) (*http.Response, error)) *mockHTTPDoer { + return &mockHTTPDoer{ + httpDo: f, } } -func (m mockHTTPGetter) Get(url string) (resp *http.Response, err error) { - return m.httpGet(url) +func (m mockHTTPDoer) Do(req *http.Request) (resp *http.Response, err error) { + return m.httpDo(req) } func TestDownloadSchema(t *testing.T) { for _, testCase := range []struct { name string - c httpGetter + c httpDoer schemaPathTemplate string strict bool resourceKind, resourceAPIVersion, k8sversion string @@ -34,7 +34,7 @@ func TestDownloadSchema(t *testing.T) { }{ { "error when downloading", - newMockHTTPGetter(func(url string) (resp *http.Response, err error) { + newMockHTTPDoer(func(req *http.Request) (resp *http.Response, err error) { return nil, fmt.Errorf("failed downloading from registry") }), "http://kubernetesjson.dev", @@ -47,7 +47,7 @@ func TestDownloadSchema(t *testing.T) { }, { "getting 404", - newMockHTTPGetter(func(url string) (resp *http.Response, err error) { + newMockHTTPDoer(func(req *http.Request) (resp *http.Response, err error) { return &http.Response{ StatusCode: http.StatusNotFound, Body: io.NopCloser(strings.NewReader("http response mock body")), @@ -63,7 +63,7 @@ func TestDownloadSchema(t *testing.T) { }, { "getting 503", - newMockHTTPGetter(func(url string) (resp *http.Response, err error) { + newMockHTTPDoer(func(req *http.Request) (resp *http.Response, err error) { return &http.Response{ StatusCode: http.StatusServiceUnavailable, Body: io.NopCloser(strings.NewReader("http response mock body")), @@ -79,7 +79,7 @@ func TestDownloadSchema(t *testing.T) { }, { "200", - newMockHTTPGetter(func(url string) (resp *http.Response, err error) { + newMockHTTPDoer(func(req *http.Request) (resp *http.Response, err error) { return &http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader("http response mock body")), From 3b00739e622db9b553eddce4d725aec4fb353c2b Mon Sep 17 00:00:00 2001 From: Victor Fernandes Date: Wed, 3 Jan 2024 09:35:24 +0100 Subject: [PATCH 4/4] chore: checking error --- pkg/registry/http.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pkg/registry/http.go b/pkg/registry/http.go index 5c763152..870932d0 100644 --- a/pkg/registry/http.go +++ b/pkg/registry/http.go @@ -72,9 +72,16 @@ func (r SchemaRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVers return url, b.([]byte), nil } } - req, _ := http.NewRequest("GET", url, nil) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + msg := fmt.Sprintf("failed to create http request for schemas at %s: %s", url, err) + if r.debug { + log.Println(msg) + } + return url, nil, errors.New(msg) + } - if token, exist := os.LookupEnv("GITHUB_TOKEN"); exist { + if token, exist := os.LookupEnv("KUBECONFORM_AUTH_TOKEN"); exist { req.Header.Add("Authorization", fmt.Sprintf("token %s", token)) }