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 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..870932d0 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" @@ -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,20 @@ func (r SchemaRegistry) DownloadSchema(resourceKind, resourceAPIVersion, k8sVers return url, b.([]byte), 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("KUBECONFORM_AUTH_TOKEN"); exist { + req.Header.Add("Authorization", fmt.Sprintf("token %s", token)) + } - resp, err := r.c.Get(url) + resp, err := r.c.Do(req) if err != nil { msg := fmt.Sprintf("failed downloading schema at %s: %s", url, err) if r.debug { @@ -99,7 +111,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..9376b63d 100644 --- a/pkg/registry/http_test.go +++ b/pkg/registry/http_test.go @@ -3,29 +3,29 @@ package registry import ( "bytes" "fmt" - "io/ioutil" + "io" "net/http" "strings" "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,10 +47,10 @@ 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: ioutil.NopCloser(strings.NewReader("http response mock body")), + Body: io.NopCloser(strings.NewReader("http response mock body")), }, nil }), "http://kubernetesjson.dev", @@ -63,10 +63,10 @@ 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: ioutil.NopCloser(strings.NewReader("http response mock body")), + Body: io.NopCloser(strings.NewReader("http response mock body")), }, nil }), "http://kubernetesjson.dev", @@ -79,10 +79,10 @@ 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: 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 {