From abd75bdce889e070d2892c991214f8c720475a78 Mon Sep 17 00:00:00 2001 From: caliskanugur Date: Wed, 20 Mar 2024 09:07:40 -0400 Subject: [PATCH] Add a workflow that checks lint, build and go mod. On every repo push and pull requestas to main and release branches. --- .github/scripts/build-packages.sh | 13 ++++++ .github/scripts/check-go-mod.sh | 12 +++++ .github/workflows/verify-changes.yaml | 45 +++++++++++++++++++ .golangci.yaml | 41 +++++++++++++++++ clients/k3d/config.go | 3 +- clients/tfexec/tfexec.go | 2 +- extensions/kubectl/template.go | 6 +-- extensions/rancherleader/rancherleader.go | 3 +- pkg/clientbase/common.go | 23 +++++----- pkg/clientbase/ops.go | 25 ++++++----- pkg/schemas/management.cattle.io/v3/schema.go | 34 +++++++------- 11 files changed, 158 insertions(+), 49 deletions(-) create mode 100755 .github/scripts/build-packages.sh create mode 100755 .github/scripts/check-go-mod.sh create mode 100644 .github/workflows/verify-changes.yaml create mode 100644 .golangci.yaml diff --git a/.github/scripts/build-packages.sh b/.github/scripts/build-packages.sh new file mode 100755 index 00000000..f9b82085 --- /dev/null +++ b/.github/scripts/build-packages.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +oldPWD="$(pwd)" + +dirs=("./clients" "./extensions" "./pkg") + +for dir in "${dirs[@]}"; do + echo "Building $dir" + cd "$dir" + go build ./... + cd "$oldPWD" +done diff --git a/.github/scripts/check-go-mod.sh b/.github/scripts/check-go-mod.sh new file mode 100755 index 00000000..9c3a8634 --- /dev/null +++ b/.github/scripts/check-go-mod.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +go mod tidy +go mod verify + +if [ -n "$(git status --porcelain --untracked-files=no)" ]; then + echo "Go mod isn't up to date. Please run go mod tidy." + echo "The following go files did differ after tidying them:" + git status --porcelain + exit 1 +fi diff --git a/.github/workflows/verify-changes.yaml b/.github/workflows/verify-changes.yaml new file mode 100644 index 00000000..0335a2e0 --- /dev/null +++ b/.github/workflows/verify-changes.yaml @@ -0,0 +1,45 @@ +name: Verify Changes + +on: + push: + pull_request: + branches: + - 'release/*' + - 'main' + +jobs: + verify-changes: + name: verify-changes + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + submodules: recursive + + - name: Setup Go + uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0 + with: + go-version-file: './go.mod' + + - name: Go Version + run: go version + + - name: Generate Golang + run: | + export PATH=$PATH:/home/runner/go/bin/ + + - name: Verify Go Mod + run: ./.github/scripts/check-go-mod.sh + + - name: Build Packages + run: ./.github/scripts/build-packages.sh + + - name: Golangci Lint + uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0 + with: + # Patch version isn't needed; https://github.com/golangci/golangci-lint-action?tab=readme-ov-file#internals + version: v1.57 + # Skip cache cause: https://github.com/golangci/golangci-lint-action/issues/135 + skip-cache: true diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 00000000..bb013d5e --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,41 @@ +linters: + disable-all: true + enable: + - ineffassign + - goimports + - govet + - misspell + - revive + - unused + - goconst + - forbidigo + - predeclared +linters-settings: + revive: + rules: + - name: confusing-naming + disabled: true + - name: exported + disabled: false + goconst: + min-len: 2 + min-occurrences: 10 + match-constant: true + ignore-strings: "metadata.+" + forbidigo: + forbid: + - p: ^*\.Sleep.*$ + msg: "No sleeps please use the appropriate polls and watch" + - p: ^fmt\.Print.*$ + msg: "No format prints, please testing or logrus packages" +run: + tests: false + timeout: 10m +issues: + exclude-dirs: + - pkg/generated/* + - clients/rancher/generated/* + exclude-files: + - ^*\.yaml$ + - ^*\.yml$ + exclude-generated-strict: true diff --git a/clients/k3d/config.go b/clients/k3d/config.go index f1bcdf86..61d88a0b 100644 --- a/clients/k3d/config.go +++ b/clients/k3d/config.go @@ -5,6 +5,5 @@ const ConfigurationFileKey = "k3d" // Config is configuration needed to create k3d cluster for integration testing. type Config struct { - image string `yaml:"image" default:"rancher/k3s:v1.21.3-k3s1"` - createTimeout int `yaml:"createTimeout" default:"120s"` + createTimeout int `yaml:"createTimeout" default:"120s"` } diff --git a/clients/tfexec/tfexec.go b/clients/tfexec/tfexec.go index 9768c4e5..b9c6b7e8 100644 --- a/clients/tfexec/tfexec.go +++ b/clients/tfexec/tfexec.go @@ -241,7 +241,7 @@ func (c *Client) Output(opts ...tfexec.OutputOption) ([]map[string]any, error) { } // WorkingDir simply returns the configured terraform working directory for terraform -// The WorkingDir is the directory that terraform is targetting when it runs a command +// The WorkingDir is the directory that terraform is targeting when it runs a command func (c *Client) WorkingDir() string { return c.Terraform.WorkingDir() } diff --git a/extensions/kubectl/template.go b/extensions/kubectl/template.go index 35f8931a..e28b00c4 100644 --- a/extensions/kubectl/template.go +++ b/extensions/kubectl/template.go @@ -31,11 +31,7 @@ const ( JobName = "kubectl" ) -var ( - importTimeout = int64(60 * 1) - group int64 - user int64 -) +var importTimeout = int64(60 * 1) // CreateJobAndRunKubectlCommands is a helper to create a job and run the kubectl commands in the pods of the Job. // It then returns errors or nil from the job. diff --git a/extensions/rancherleader/rancherleader.go b/extensions/rancherleader/rancherleader.go index 11d54984..8aebc1b3 100644 --- a/extensions/rancherleader/rancherleader.go +++ b/extensions/rancherleader/rancherleader.go @@ -1,10 +1,11 @@ package rancherleader import ( + "net/url" + "github.com/rancher/shepherd/clients/rancher" v1 "github.com/rancher/shepherd/clients/rancher/v1" coordinationv1 "k8s.io/api/coordination/v1" - "net/url" ) const ( diff --git a/pkg/clientbase/common.go b/pkg/clientbase/common.go index d6c098d3..8a507cbf 100644 --- a/pkg/clientbase/common.go +++ b/pkg/clientbase/common.go @@ -13,6 +13,8 @@ import ( "os" "time" + "github.com/sirupsen/logrus" + "github.com/gorilla/websocket" "github.com/pkg/errors" "github.com/rancher/norman/types" @@ -23,9 +25,7 @@ const ( COLLECTION = "collection" ) -var ( - Debug = false -) +var Debug = false type APIBaseClientInterface interface { Websocket(url string, headers map[string][]string) (*websocket.Conn, *http.Response, error) @@ -185,7 +185,7 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) { if opts.CACerts != "" { if Debug { - fmt.Println("Some CAcerts are provided.") + logrus.Infoln("Some CAcerts are provided.") } roots := x509.NewCertPool() ok := roots.AppendCertsFromPEM([]byte(opts.CACerts)) @@ -203,7 +203,7 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) { if opts.Insecure { if Debug { - fmt.Println("Insecure TLS set.") + logrus.Infoln("Insecure TLS set.") } tr := &http.Transport{ TLSClientConfig: &tls.Config{ @@ -216,7 +216,7 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) { if !(opts.Insecure) && (opts.CACerts == "") { if Debug { - fmt.Println("Insecure TLS not set and no CAcerts is provided.") + logrus.Infoln("Insecure TLS not set and no CAcerts is provided.") } tr := &http.Transport{ Proxy: http.ProxyFromEnvironment, @@ -255,7 +255,7 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) { req.Header.Add("Authorization", opts.getAuthHeader()) if Debug { - fmt.Println("GET " + req.URL.String()) + logrus.Infoln("GET " + req.URL.String()) } resp, err = client.Do(req) @@ -278,7 +278,7 @@ func NewAPIClient(opts *ClientOpts) (APIBaseClient, error) { } if Debug { - fmt.Println("Response <= " + string(bytes)) + logrus.Infoln("Response <= " + string(bytes)) } err = json.Unmarshal(bytes, &schemas) @@ -327,7 +327,7 @@ func (a *APIBaseClient) Websocket(url string, headers map[string][]string) (*web } if Debug { - fmt.Println("WS " + url) + logrus.Infoln("WS " + url) } return a.Ops.Dialer.Dial(url, http.Header(httpHeaders)) @@ -383,13 +383,14 @@ func (a *APIBaseClient) Reload(existing *types.Resource, output interface{}) err } func (a *APIBaseClient) Action(schemaType string, action string, - existing *types.Resource, inputObject, respObject interface{}) error { + existing *types.Resource, inputObject, respObject interface{}, +) error { return a.Ops.DoAction(schemaType, action, existing, inputObject, respObject) } func init() { Debug = os.Getenv("RANCHER_CLIENT_DEBUG") == "true" if Debug { - fmt.Println("Rancher client debug on") + logrus.Infoln("Rancher client debug on") } } diff --git a/pkg/clientbase/ops.go b/pkg/clientbase/ops.go index 7fe12b60..cdfb2dcc 100644 --- a/pkg/clientbase/ops.go +++ b/pkg/clientbase/ops.go @@ -15,6 +15,7 @@ import ( "github.com/pkg/errors" "github.com/rancher/norman/types" "github.com/rancher/shepherd/pkg/session" + "github.com/sirupsen/logrus" ) type APIOperations struct { @@ -63,7 +64,7 @@ func (a *APIOperations) DoGet(url string, opts *types.ListOpts, respObject inter } if Debug { - fmt.Println("GET " + url) + logrus.Infoln("GET " + url) } req, err := http.NewRequest("GET", url, nil) @@ -90,7 +91,7 @@ func (a *APIOperations) DoGet(url string, opts *types.ListOpts, respObject inter } if Debug { - fmt.Println("Response <= " + string(byteContent)) + logrus.Infoln("Response <= " + string(byteContent)) } if err := json.Unmarshal(byteContent, respObject); err != nil { @@ -142,8 +143,8 @@ func (a *APIOperations) DoModify(method string, url string, createObj interface{ } if Debug { - fmt.Println(method + " " + url) - fmt.Println("Request => " + string(bodyContent)) + logrus.Infoln(method + " " + url) + logrus.Infoln("Request => " + string(bodyContent)) } req, err := http.NewRequest(method, url, bytes.NewBuffer(bodyContent)) @@ -172,7 +173,7 @@ func (a *APIOperations) DoModify(method string, url string, createObj interface{ if len(byteContent) > 0 { if Debug { - fmt.Println("Response <= " + string(byteContent)) + logrus.Infoln("Response <= " + string(byteContent)) } return json.Unmarshal(byteContent, respObject) } @@ -329,8 +330,8 @@ func (a *APIOperations) DoResourceDelete(schemaType string, existing *types.Reso } func (a *APIOperations) DoAction(schemaType string, action string, - existing *types.Resource, inputObject, respObject interface{}) error { - + existing *types.Resource, inputObject, respObject interface{}, +) error { if existing == nil { return errors.New("Existing object is nil") } @@ -344,8 +345,8 @@ func (a *APIOperations) DoAction(schemaType string, action string, } func (a *APIOperations) DoCollectionAction(schemaType string, action string, - existing *types.Collection, inputObject, respObject interface{}) error { - + existing *types.Collection, inputObject, respObject interface{}, +) error { if existing == nil { return errors.New("Existing object is nil") } @@ -373,7 +374,7 @@ func (a *APIOperations) doAction( var input io.Reader if Debug { - fmt.Println("POST " + actionURL) + logrus.Infoln("POST " + actionURL) } if inputObject != nil { @@ -382,7 +383,7 @@ func (a *APIOperations) doAction( return err } if Debug { - fmt.Println("Request => " + string(bodyContent)) + logrus.Infoln("Request => " + string(bodyContent)) } input = bytes.NewBuffer(bodyContent) } @@ -413,7 +414,7 @@ func (a *APIOperations) doAction( } if Debug { - fmt.Println("Response <= " + string(byteContent)) + logrus.Infoln("Response <= " + string(byteContent)) } if nil != respObject { diff --git a/pkg/schemas/management.cattle.io/v3/schema.go b/pkg/schemas/management.cattle.io/v3/schema.go index 855c4b0a..0177db2f 100644 --- a/pkg/schemas/management.cattle.io/v3/schema.go +++ b/pkg/schemas/management.cattle.io/v3/schema.go @@ -255,7 +255,8 @@ func clusterTypes(schemas *types.Schemas) *types.Schemas { schema.MustCustomizeField("extraArgs", func(field types.Field) types.Field { field.Default = map[string]interface{}{ "election-timeout": "5000", - "heartbeat-interval": "500"} + "heartbeat-interval": "500", + } return field }) }). @@ -495,6 +496,7 @@ func tokens(schemas *types.Schemas) *types.Schemas { } func authnTypes(schemas *types.Schemas) *types.Schemas { + authConfig := "authConfig" return schemas. AddMapperForType(&Version, v3.User{}, m.DisplayName{}, &m.Embed{Field: "status"}). @@ -536,13 +538,13 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { }). // Local Config MustImportAndCustomize(&Version, v3.LocalConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.CollectionMethods = []string{} schema.ResourceMethods = []string{http.MethodGet} }). - //Github Config + // Github Config MustImportAndCustomize(&Version, v3.GithubConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "configureTest": { @@ -558,9 +560,9 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { }). MustImport(&Version, v3.GithubConfigTestOutput{}). MustImport(&Version, v3.GithubConfigApplyInput{}). - //AzureAD Config + // AzureAD Config MustImportAndCustomize(&Version, v3.AzureADConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "configureTest": { @@ -579,7 +581,7 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { MustImport(&Version, v3.AzureADConfigApplyInput{}). // Active Directory Config MustImportAndCustomize(&Version, v3.ActiveDirectoryConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "testAndApply": { @@ -592,7 +594,7 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { MustImport(&Version, v3.ActiveDirectoryTestAndApplyInput{}). // OpenLdap Config MustImportAndCustomize(&Version, v3.OpenLdapConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "testAndApply": { @@ -606,7 +608,7 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { // FreeIpa Config AddMapperForType(&Version, v3.FreeIpaConfig{}, m.Drop{Field: "nestedGroupMembershipEnabled"}). MustImportAndCustomize(&Version, v3.FreeIpaConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "testAndApply": { @@ -647,9 +649,9 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { MustImportAndCustomize(&Version, v3.ShibbolethConfig{}, configSchema). MustImport(&Version, v3.SamlConfigTestInput{}). MustImport(&Version, v3.SamlConfigTestOutput{}). - //GoogleOAuth Config + // GoogleOAuth Config MustImportAndCustomize(&Version, v3.GoogleOauthConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "configureTest": { @@ -665,9 +667,9 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { }). MustImport(&Version, v3.GoogleOauthConfigApplyInput{}). MustImport(&Version, v3.GoogleOauthConfigTestOutput{}). - //OIDC Config + // OIDC Config MustImportAndCustomize(&Version, v3.OIDCConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "configureTest": { @@ -683,9 +685,9 @@ func authnTypes(schemas *types.Schemas) *types.Schemas { }). MustImport(&Version, v3.OIDCApplyInput{}). MustImport(&Version, v3.OIDCTestOutput{}). - //KeyCloakOIDC Config + // KeyCloakOIDC Config MustImportAndCustomize(&Version, v3.KeyCloakOIDCConfig{}, func(schema *types.Schema) { - schema.BaseType = "authConfig" + schema.BaseType = authConfig schema.ResourceActions = map[string]types.Action{ "disable": {}, "configureTest": { @@ -838,7 +840,6 @@ func alertTypes(schema *types.Schemas) *types.Schemas { "unmute": {}, } }) - } func composeType(schemas *types.Schemas) *types.Schemas { @@ -1022,7 +1023,6 @@ func clusterTemplateTypes(schemas *types.Schemas) *types.Schemas { }, } }) - } func encryptionTypes(schemas *types.Schemas) *types.Schemas {