From 02ff6a11f02de3d2991c6ac44883d5870f2f7041 Mon Sep 17 00:00:00 2001 From: Marc Brugger Date: Tue, 25 Mar 2025 21:30:22 +0100 Subject: [PATCH] feat: implement stricter lint rules git golanci-lint v2 (#538) * feat: implement stricter lint rules git golanci-lint v2 * fix lint issues * fix lint issues --- .github/workflows/go.yml | 6 +- .golangci.yaml | 209 +++++++++++++++++++++++++ .golangci.yml | 37 ----- .toolbox.mk | 8 +- cmd/root.go | 7 +- cmd/run.go | 27 ++-- openapi/main.go | 39 +++-- pkg/client/client-methods.go | 14 +- pkg/client/client.go | 27 ++-- pkg/client/client_test.go | 13 +- pkg/client/model/client/client.go | 11 +- pkg/client/model/client/resty.go | 3 +- pkg/client/model/model-functions.go | 89 +++++------ pkg/client/model/model_private_test.go | 5 +- pkg/client/model/model_test.go | 7 +- pkg/config/config.go | 11 +- pkg/config/config_test.go | 35 +++-- pkg/config/deprecated_env_test.go | 3 +- pkg/config/env.go | 11 +- pkg/config/file.go | 3 +- pkg/config/file_test.go | 5 +- pkg/config/flag-names.go | 18 +-- pkg/config/flags.go | 104 +++++------- pkg/config/flags_test.go | 23 +-- pkg/config/print-config.go | 15 +- pkg/config/print-config_test.go | 19 ++- pkg/config/validate.go | 3 +- pkg/config/validate_test.go | 3 +- pkg/log/log.go | 6 +- pkg/metrics/metrics.go | 35 +++-- pkg/metrics/metrics_test.go | 9 +- pkg/metrics/stats.go | 28 ++-- pkg/mocks/client/mock.go | 32 ++-- pkg/sync/action-general.go | 3 +- pkg/sync/action.go | 3 +- pkg/sync/http.go | 11 +- pkg/sync/scrape.go | 7 +- pkg/sync/sync.go | 30 ++-- pkg/sync/sync_test.go | 9 +- pkg/types/features.go | 18 +-- pkg/types/types.go | 92 +++++------ pkg/utils/clone.go | 11 +- pkg/utils/ptr.go | 6 +- pkg/versions/versions.go | 6 +- pkg/versions/versions_test.go | 3 +- version/version.go | 4 +- 46 files changed, 625 insertions(+), 443 deletions(-) create mode 100644 .golangci.yaml delete mode 100644 .golangci.yml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 184e641..babe9a4 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -22,10 +22,8 @@ jobs: with: go-version-file: "go.mod" - - name: golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - skip-cache: true + - name: Lint + run: make lint test: name: test diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..93b45d7 --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,209 @@ +version: '2' +linters: + enable: + - asciicheck + - bidichk + - bodyclose + - canonicalheader + - containedctx + - copyloopvar + - decorder + - dogsled + - dupword + - durationcheck + - err113 + - errname + - errorlint + - exptostd + - fatcontext + - forcetypeassert + - gocheckcompilerdirectives + - gochecksumtype + - gocritic + - godot + - gomodguard + - goprintffuncname + - gosmopolitan + - grouper + - iface + - importas + - inamedparam + - interfacebloat + - intrange + - loggercheck + - makezero + - mirror + - misspell + - nilerr + - nilnesserr + - noctx + - nolintlint + - nosprintfhostport + - perfsprint + - predeclared + - promlinter + - protogetter + - reassign + - revive + - rowserrcheck + - sloglint + - spancheck + - sqlclosecheck + - staticcheck + - tagalign + - testableexamples + - testifylint + - thelper + - unconvert + - unparam + - usestdlibvars + - usetesting + - wastedassign + - whitespace + - zerologlint + disable: + - asasalint + - contextcheck + - cyclop + - depguard + - dupl + - errchkjson + - exhaustive + - exhaustruct + - forbidigo + - funlen + - ginkgolinter + - gochecknoglobals + - gochecknoinits + - gocognit + - goconst + - gocyclo + - godox + - goheader + - gomoddirectives + - gosec + - ireturn + - lll + - maintidx + - musttag + - nakedret + - nestif + - nilnil + - nlreturn + - nonamedreturns + - paralleltest + - prealloc + - recvcheck + - tagliatelle + - testpackage + - tparallel + - varnamelen + - wrapcheck + - wsl + settings: + gocritic: + enable-all: true + disabled-checks: + - emptyFallthrough + - hugeParam + - rangeValCopy + - unnamedResult + - whyNoLint + govet: + disable: + - fieldalignment + - shadow + enable-all: true + misspell: + locale: US + revive: + enable-all-rules: true + rules: + - name: add-constant + disabled: true + - name: cognitive-complexity + disabled: true + - name: cyclomatic + disabled: true + - name: deep-exit + disabled: true + - name: dot-imports + severity: warning + disabled: false + exclude: [""] + arguments: + - allowedPackages: ["github.com/onsi/ginkgo/v2", "github.com/onsi/gomega"] + - name: empty-block + disabled: true + - name: exported + disabled: true + - name: filename-format + arguments: + - ^[a-z][-0-9_a-z]*(?:\.gen)?\.go$ + - name: flag-parameter + disabled: true + - name: function-length + disabled: true + - name: function-result-limit + disabled: true + - name: import-shadowing + disabled: true + - name: line-length-limit + disabled: true + - name: max-control-nesting + disabled: true + - name: max-public-structs + disabled: true + - name: nested-structs + disabled: true + - name: package-comments + disabled: true + - name: unused-parameter + disabled: true + - name: unused-receiver + disabled: true + staticcheck: + checks: + - 'all' + - '-ST1000' + exclusions: + generated: lax + presets: + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - err113 + text: do not define dynamic errors, use wrapped static errors instead + - linters: + - forbidigo + path: ^internal/cmds/ + - linters: + - forcetypeassert + path: _test\.go$ + - linters: + - forbidigo + path: assets/scripts/generate-commit.go +formatters: + enable: + - gci + - gofmt + - gofumpt + - goimports + - golines + settings: + gci: + sections: + - standard + - default + - prefix(github.com/bakito/adguardhome-sync) + gofumpt: + module-path: github.com/bakito/adguardhome-sync + extra-rules: true + goimports: + local-prefixes: + - github.com/bakito/adguardhome-sync + golines: + max-len: 128 + tab-len: 4 diff --git a/.golangci.yml b/.golangci.yml deleted file mode 100644 index ff6a682..0000000 --- a/.golangci.yml +++ /dev/null @@ -1,37 +0,0 @@ -run: - timeout: 5m - -linters: - enable: - - asciicheck - - bodyclose - - dogsled - - durationcheck - - errcheck - - errorlint - - gci - - gofmt - - gofumpt - - goimports - - gosec - - gosimple - - govet - - importas - - ineffassign - - misspell - - nakedret - - nolintlint - - staticcheck - - unconvert - - unparam - - unused -linters-settings: - gosec: - # Exclude generated files - exclude-generated: true - excludes: - - G601 # not applicable in go 1.22 anymore - gofmt: - # simplify code: gofmt with `-s` option, true by default - simplify: true - diff --git a/.toolbox.mk b/.toolbox.mk index c48693e..8902985 100644 --- a/.toolbox.mk +++ b/.toolbox.mk @@ -24,8 +24,8 @@ TB_SEMVER ?= $(TB_LOCALBIN)/semver TB_DEEPCOPY_GEN_VERSION ?= v0.32.3 # renovate: packageName=mvdan.cc/gofumpt TB_GOFUMPT_VERSION ?= v0.7.0 -# renovate: packageName=github.com/golangci/golangci-lint/cmd/golangci-lint -TB_GOLANGCI_LINT_VERSION ?= v1.64.8 +# renovate: packageName=github.com/golangci/golangci-lint/v2/cmd/golangci-lint +TB_GOLANGCI_LINT_VERSION ?= v2.0.1 # renovate: packageName=github.com/segmentio/golines TB_GOLINES_VERSION ?= v0.12.2 # renovate: packageName=github.com/goreleaser/goreleaser/v2 @@ -53,7 +53,7 @@ $(TB_GOFUMPT): $(TB_LOCALBIN) .PHONY: tb.golangci-lint tb.golangci-lint: $(TB_GOLANGCI_LINT) ## Download golangci-lint locally if necessary. $(TB_GOLANGCI_LINT): $(TB_LOCALBIN) - test -s $(TB_LOCALBIN)/golangci-lint || GOBIN=$(TB_LOCALBIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(TB_GOLANGCI_LINT_VERSION) + test -s $(TB_LOCALBIN)/golangci-lint || GOBIN=$(TB_LOCALBIN) go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(TB_GOLANGCI_LINT_VERSION) .PHONY: tb.golines tb.golines: $(TB_GOLINES) ## Download golines locally if necessary. $(TB_GOLINES): $(TB_LOCALBIN) @@ -95,7 +95,7 @@ tb.update: tb.reset toolbox makefile --renovate -f $(TB_LOCALDIR)/Makefile \ k8s.io/code-generator/cmd/deepcopy-gen@github.com/kubernetes/code-generator \ mvdan.cc/gofumpt@github.com/mvdan/gofumpt \ - github.com/golangci/golangci-lint/cmd/golangci-lint \ + github.com/golangci/golangci-lint/v2/cmd/golangci-lint \ github.com/segmentio/golines \ github.com/goreleaser/goreleaser/v2 \ go.uber.org/mock/mockgen@github.com/uber-go/mock \ diff --git a/cmd/root.go b/cmd/root.go index 595eceb..ee1191e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,9 +4,10 @@ import ( "fmt" "os" + "github.com/spf13/cobra" + "github.com/bakito/adguardhome-sync/pkg/log" "github.com/bakito/adguardhome-sync/version" - "github.com/spf13/cobra" ) var ( @@ -14,7 +15,7 @@ var ( logger = log.GetLogger("root") ) -// rootCmd represents the base command when called without any subcommands +// rootCmd represents the base command when called without any subcommands. var rootCmd = &cobra.Command{ Use: "adguardhome-sync", Short: "Synchronize config from one AdGuardHome instance to another", @@ -25,7 +26,7 @@ var rootCmd = &cobra.Command{ // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { if err := rootCmd.Execute(); err != nil { - fmt.Println(err) + _, _ = fmt.Println(err) os.Exit(1) } } diff --git a/cmd/run.go b/cmd/run.go index 69e12b8..9776344 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -1,16 +1,17 @@ package cmd import ( + "github.com/spf13/cobra" + "github.com/bakito/adguardhome-sync/pkg/config" "github.com/bakito/adguardhome-sync/pkg/log" "github.com/bakito/adguardhome-sync/pkg/sync" - "github.com/spf13/cobra" ) -// runCmd represents the run command +// runCmd represents the run command. var doCmd = &cobra.Command{ Use: "run", - Short: "Start a synchronisation from origin to replica", + Short: "Start a synchronization from origin to replica", Long: `Synchronizes the configuration form an origin instance to a replica`, RunE: func(cmd *cobra.Command, args []string) error { logger = log.GetLogger("run") @@ -44,21 +45,21 @@ func init() { doCmd.PersistentFlags().Bool(config.FlagRunOnStart, true, "Run the sync job on start.") doCmd.PersistentFlags().Bool(config.FlagPrintConfigOnly, false, "Prints the configuration only and exists. "+ "Can be used to debug the config E.g: when having authentication issues.") - doCmd.PersistentFlags().Bool(config.FlagContinueOnError, false, "If enabled, the synchronisation task "+ + doCmd.PersistentFlags().Bool(config.FlagContinueOnError, false, "If enabled, the synchronization task "+ "will not fail on single errors, but will log the errors and continue.") doCmd.PersistentFlags(). - Int(config.FlagApiPort, 8080, "Sync API Port, the API endpoint will be started to enable remote triggering; if 0 port API is disabled.") - doCmd.PersistentFlags().String(config.FlagApiUsername, "", "Sync API username") - doCmd.PersistentFlags().String(config.FlagApiPassword, "", "Sync API password") - doCmd.PersistentFlags().String(config.FlagApiDarkMode, "", "API UI in dark mode") + Int(config.FlagAPIPort, 8080, "Sync API Port, the API endpoint will be started to enable remote triggering; if 0 port API is disabled.") + doCmd.PersistentFlags().String(config.FlagAPIUsername, "", "Sync API username") + doCmd.PersistentFlags().String(config.FlagAPIPassword, "", "Sync API password") + doCmd.PersistentFlags().String(config.FlagAPIDarkMode, "", "API UI in dark mode") doCmd.PersistentFlags().Bool(config.FlagFeatureDhcpServerConfig, true, "Enable DHCP server config feature") doCmd.PersistentFlags().Bool(config.FlagFeatureDhcpStaticLeases, true, "Enable DHCP server static leases feature") - doCmd.PersistentFlags().Bool(config.FlagFeatureDnsServerConfig, true, "Enable DNS server config feature") - doCmd.PersistentFlags().Bool(config.FlagFeatureDnsAccessLists, true, "Enable DNS server access lists feature") - doCmd.PersistentFlags().Bool(config.FlagFeatureDnsRewrites, true, "Enable DNS rewrites feature") + doCmd.PersistentFlags().Bool(config.FlagFeatureDNSServerConfig, true, "Enable DNS server config feature") + doCmd.PersistentFlags().Bool(config.FlagFeatureDNSAccessLists, true, "Enable DNS server access lists feature") + doCmd.PersistentFlags().Bool(config.FlagFeatureDNSRewrites, true, "Enable DNS rewrites feature") doCmd.PersistentFlags().Bool(config.FlagFeatureGeneral, true, "Enable general settings feature") doCmd.PersistentFlags().Bool(config.FlagFeatureQueryLog, true, "Enable query log config feature") @@ -70,7 +71,7 @@ func init() { doCmd.PersistentFlags().String(config.FlagOriginURL, "", "Origin instance url") doCmd.PersistentFlags(). String(config.FlagOriginWebURL, "", "Origin instance web url used in the web interface (default: )") - doCmd.PersistentFlags().String(config.FlagOriginApiPath, "/control", "Origin instance API path") + doCmd.PersistentFlags().String(config.FlagOriginAPIPath, "/control", "Origin instance API path") doCmd.PersistentFlags().String(config.FlagOriginUsername, "", "Origin instance username") doCmd.PersistentFlags().String(config.FlagOriginPassword, "", "Origin instance password") doCmd.PersistentFlags().String(config.FlagOriginCookie, "", "If Set, uses a cookie for authentication") @@ -79,7 +80,7 @@ func init() { doCmd.PersistentFlags().String(config.FlagReplicaURL, "", "Replica instance url") doCmd.PersistentFlags(). String(config.FlagReplicaWebURL, "", "Replica instance web url used in the web interface (default: )") - doCmd.PersistentFlags().String(config.FlagReplicaApiPath, "/control", "Replica instance API path") + doCmd.PersistentFlags().String(config.FlagReplicaAPIPath, "/control", "Replica instance API path") doCmd.PersistentFlags().String(config.FlagReplicaUsername, "", "Replica instance username") doCmd.PersistentFlags().String(config.FlagReplicaPassword, "", "Replica instance password") doCmd.PersistentFlags().String(config.FlagReplicaCookie, "", "If Set, uses a cookie for authentication") diff --git a/openapi/main.go b/openapi/main.go index 623f113..5984c22 100644 --- a/openapi/main.go +++ b/openapi/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "io" "log" @@ -20,21 +21,33 @@ func main() { } log.Printf("Patching schema version %s\n", version) - resp, err := http.Get( + ctx := context.Background() // Or use context.WithTimeout + req, err := http.NewRequestWithContext( + ctx, + http.MethodGet, fmt.Sprintf("https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/%s/openapi/openapi.yaml", version), + http.NoBody, ) + if err != nil { + log.Fatal(err) + } + + client := &http.Client{} + resp, err := client.Do(req) if err != nil { log.Fatalln(err) } defer func() { _ = resp.Body.Close() }() data, err := io.ReadAll(resp.Body) if err != nil { - log.Fatalln(err) + log.Println(err) + return } - schema := make(map[string]interface{}) + schema := make(map[string]any) err = yaml.Unmarshal(data, &schema) if err != nil { - log.Fatalln(err) + log.Println(err) + return } if requestBodies, ok, _ := unstructured.NestedMap(schema, "components", "requestBodies"); ok { @@ -47,9 +60,11 @@ func main() { "paths", "/dns_info", "get", "responses", "200", "content", "application/json", "schema"); ok { if allOf, ok, _ := unstructured.NestedSlice(dnsInfo, "allOf"); ok && len(allOf) == 2 { delete(dnsInfo, "allOf") - if err := unstructured.SetNestedMap(schema, allOf[0].(map[string]interface{}), + //nolint:forcetypeassert + if err := unstructured.SetNestedMap(schema, allOf[0].(map[string]any), "paths", "/dns_info", "get", "responses", "200", "content", "application/json", "schema"); err != nil { - log.Fatalln(err) + log.Println(err) + return } } } @@ -60,24 +75,26 @@ func main() { b, err := yaml.Marshal(&schema) if err != nil { - log.Fatalln(err) + log.Println(err) + return } log.Printf("Writing schema file tmp/%s", fileName) err = os.WriteFile("tmp/"+fileName, b, 0o600) if err != nil { - log.Fatalln(err) + log.Println(err) + return } } -func correctEntries(schema map[string]interface{}) { +func correctEntries(schema map[string]any) { // https://github.com/AdguardTeam/AdGuardHome/pull/7678 if err := unstructured.SetNestedField(schema, "string", "components", "schemas", "QueryLogItem", "properties", "client_proto", "type"); err != nil { log.Fatalln(err) } } -func addFakeTags(schema map[string]interface{}) { - fake := map[string]interface{}{"faker": `slice_len=24`} +func addFakeTags(schema map[string]any) { + fake := map[string]any{"faker": `slice_len=24`} if err := unstructured.SetNestedMap(schema, fake, "components", "schemas", "Stats", "properties", "blocked_filtering", "x-oapi-codegen-extra-tags"); err != nil { log.Fatalln(err) } diff --git a/pkg/client/client-methods.go b/pkg/client/client-methods.go index e24ea80..5dfd79d 100644 --- a/pkg/client/client-methods.go +++ b/pkg/client/client-methods.go @@ -17,14 +17,18 @@ func (cl *client) doGet(req *resty.Request, url string) error { rl.Debug("do get") resp, err := req.Get(url) if err != nil { - if resp != nil && resp.StatusCode() == http.StatusFound { - loc := resp.Header().Get("Location") - if loc == "/install.html" || loc == "/control/install.html" { - return ErrSetupNeeded + l := rl + if resp != nil { + if resp.StatusCode() == http.StatusFound { + loc := resp.Header().Get("Location") + if loc == "/install.html" || loc == "/control/install.html" { + return ErrSetupNeeded + } } + l = l.With("status", resp.StatusCode(), "body", string(resp.Body()), "error", err) } - rl.With("status", resp.StatusCode(), "body", string(resp.Body()), "error", err).Debug("error in do get") + l.Debug("error in do get") return detailedError(resp, err) } diff --git a/pkg/client/client.go b/pkg/client/client.go index 008c213..ea776ec 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -11,19 +11,20 @@ import ( "strconv" "strings" + "github.com/go-resty/resty/v2" + "go.uber.org/zap" + "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/bakito/adguardhome-sync/pkg/log" "github.com/bakito/adguardhome-sync/pkg/types" "github.com/bakito/adguardhome-sync/pkg/utils" - "github.com/go-resty/resty/v2" - "go.uber.org/zap" ) const envRedirectPolicyNoOfRedirects = "REDIRECT_POLICY_NO_OF_REDIRECTS" var ( l = log.GetLogger("client") - // ErrSetupNeeded custom error + // ErrSetupNeeded custom error. ErrSetupNeeded = errors.New("setup needed") ) @@ -33,16 +34,16 @@ func detailedError(resp *resty.Response, err error) error { e += fmt.Sprintf("(%s)", string(resp.Body())) } if err != nil { - e += fmt.Sprintf(": %s", err.Error()) + e += ": " + err.Error() } return errors.New(e) } -// New create a new client +// New create a new client. func New(config types.AdGuardInstance) (Client, error) { var apiURL string if config.APIPath == "" { - apiURL = fmt.Sprintf("%s/control", config.URL) + apiURL = config.URL + "/control" } else { apiURL = fmt.Sprintf("%s/%s", config.URL, config.APIPath) } @@ -84,7 +85,9 @@ func New(config types.AdGuardInstance) (Client, error) { }, nil } -// Client AdguardHome API client interface +// Client AdguardHome API client interface. +// +//nolint:interfacebloat type Client interface { Host() string Status() (*model.ServerStatus, error) @@ -116,16 +119,16 @@ type Client interface { UpdateClient(client *model.Client) error DeleteClient(client *model.Client) error QueryLogConfig() (*model.QueryLogConfigWithIgnored, error) - SetQueryLogConfig(*model.QueryLogConfigWithIgnored) error + SetQueryLogConfig(ql *model.QueryLogConfigWithIgnored) error StatsConfig() (*model.GetStatsConfigResponse, error) SetStatsConfig(sc *model.PutStatsConfigUpdateRequest) error Setup() error AccessList() (*model.AccessList, error) - SetAccessList(*model.AccessList) error + SetAccessList(accessList *model.AccessList) error DNSConfig() (*model.DNSConfig, error) - SetDNSConfig(*model.DNSConfig) error + SetDNSConfig(config *model.DNSConfig) error DhcpConfig() (*model.DhcpStatus, error) - SetDhcpConfig(*model.DhcpStatus) error + SetDhcpConfig(status *model.DhcpStatus) error AddDHCPStaticLease(lease model.DhcpStaticLease) error DeleteDHCPStaticLease(lease model.DhcpStaticLease) error } @@ -224,7 +227,7 @@ func (cl *client) toggleStatus(mode string) (bool, error) { } func (cl *client) toggleBool(mode string, enable bool) error { - cl.log.With("enable", enable).Info(fmt.Sprintf("Toggle %s", mode)) + cl.log.With("enable", enable).Info("Toggle " + mode) var target string if enable { target = "enable" diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index cf48cdb..4b0e1fd 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -8,13 +8,14 @@ import ( "os" "path/filepath" + "github.com/google/uuid" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/bakito/adguardhome-sync/pkg/client" "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/bakito/adguardhome-sync/pkg/types" "github.com/bakito/adguardhome-sync/pkg/utils" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" ) var ( @@ -140,7 +141,7 @@ var _ = Describe("Client", func() { ts, cl = ClientPost( "/install/configure", fmt.Sprintf( - `{"web":{"ip":"0.0.0.0","port":3000,"status":"","can_autofix":false},"dns":{"ip":"0.0.0.0","port":53,"status":"","can_autofix":false},"username":"%s","password":"%s"}`, + `{"web":{"ip":"0.0.0.0","port":3000,"status":"","can_autofix":false},"dns":{"ip":"0.0.0.0","port":53,"status":"","can_autofix":false},"username":%q,"password":%q}`, username, password, ), @@ -373,10 +374,10 @@ var _ = Describe("Client", func() { }) }) -func ClientGet(file string, path string) (*httptest.Server, client.Client) { +func ClientGet(file, path string) (*httptest.Server, client.Client) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { Ω(r.URL.Path).Should(Equal(types.DefaultAPIPath + path)) - b, err := os.ReadFile(filepath.Join("../../testdata", file)) + b, err := os.ReadFile(filepath.Join("..", "..", "testdata", file)) Ω(err).ShouldNot(HaveOccurred()) w.Header().Set("Content-Type", "application/json") _, err = w.Write(b) diff --git a/pkg/client/model/client/client.go b/pkg/client/model/client/client.go index c7acfab..2932cef 100644 --- a/pkg/client/model/client/client.go +++ b/pkg/client/model/client/client.go @@ -11,19 +11,20 @@ import ( "net/url" "path" + "go.uber.org/zap" + "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/bakito/adguardhome-sync/pkg/log" "github.com/bakito/adguardhome-sync/pkg/types" - "go.uber.org/zap" ) var l = log.GetLogger("client") -// New create a new api client +// New create a new api client. func New(config types.AdGuardInstance) (Client, error) { var apiURL string if config.APIPath == "" { - apiURL = fmt.Sprintf("%s/control", config.URL) + apiURL = config.URL + "/control" } else { apiURL = fmt.Sprintf("%s/%s", config.URL, config.APIPath) } @@ -96,7 +97,7 @@ func (a apiClient) SetFilteringConfig(ctx context.Context, config model.FilterCo return write(ctx, config, a.client.FilteringConfig) } -func write[B interface{}]( +func write[B any]( ctx context.Context, body B, req func(ctx context.Context, body B, reqEditors ...model.RequestEditorFn) (*http.Response, error), @@ -112,7 +113,7 @@ func write[B interface{}]( return nil } -func read[I interface{}]( +func read[I any]( ctx context.Context, req func(ctx context.Context, reqEditors ...model.RequestEditorFn) (*http.Response, error), parse func(rsp *http.Response) (*I, error), diff --git a/pkg/client/model/client/resty.go b/pkg/client/model/client/resty.go index 3341bfb..3d4f3e1 100644 --- a/pkg/client/model/client/resty.go +++ b/pkg/client/model/client/resty.go @@ -3,8 +3,9 @@ package client import ( "net/http" - "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/go-resty/resty/v2" + + "github.com/bakito/adguardhome-sync/pkg/client/model" ) var _ model.HttpRequestDoer = &adapter{} diff --git a/pkg/client/model/model-functions.go b/pkg/client/model/model-functions.go index 9a70533..d45f391 100644 --- a/pkg/client/model/model-functions.go +++ b/pkg/client/model/model-functions.go @@ -5,13 +5,14 @@ import ( "sort" "strings" - "github.com/bakito/adguardhome-sync/pkg/utils" "github.com/jinzhu/copier" "go.uber.org/zap" "k8s.io/utils/ptr" + + "github.com/bakito/adguardhome-sync/pkg/utils" ) -// Clone the config +// Clone the config. func (c *DhcpStatus) Clone() *DhcpStatus { clone := &DhcpStatus{} _ = copier.Copy(clone, c) @@ -27,16 +28,16 @@ func (c *DhcpStatus) cleanV4V6() { } } -// CleanAndEquals dhcp server config equal check where V4 and V6 are cleaned in advance +// CleanAndEquals dhcp server config equal check where V4 and V6 are cleaned in advance. func (c *DhcpStatus) CleanAndEquals(o *DhcpStatus) bool { c.cleanV4V6() o.cleanV4V6() return c.Equals(o) } -// Equals dhcp server config equal check +// Equals dhcp server config equal check. func (c *DhcpStatus) Equals(o *DhcpStatus) bool { - return utils.JsonEquals(c, o) + return utils.JSONEquals(c, o) } func (c *DhcpStatus) HasConfig() bool { @@ -56,8 +57,8 @@ func (j DhcpConfigV6) isValid() bool { type DhcpStaticLeases []DhcpStaticLease -// MergeDhcpStaticLeases the leases -func MergeDhcpStaticLeases(l *[]DhcpStaticLease, other *[]DhcpStaticLease) (DhcpStaticLeases, DhcpStaticLeases) { +// MergeDhcpStaticLeases the leases. +func MergeDhcpStaticLeases(l, other *[]DhcpStaticLease) (adds, removes DhcpStaticLeases) { var thisLeases []DhcpStaticLease var otherLeases []DhcpStaticLease @@ -69,8 +70,6 @@ func MergeDhcpStaticLeases(l *[]DhcpStaticLease, other *[]DhcpStaticLease) (Dhcp } current := make(map[string]DhcpStaticLease) - var adds DhcpStaticLeases - var removes DhcpStaticLeases for _, le := range thisLeases { current[le.Mac] = le } @@ -90,21 +89,21 @@ func MergeDhcpStaticLeases(l *[]DhcpStaticLease, other *[]DhcpStaticLease) (Dhcp return adds, removes } -// Equals dns config equal check +// Equals dns config equal check. func (c *DNSConfig) Equals(o *DNSConfig) bool { cc := c.Clone() oo := o.Clone() cc.Sort() oo.Sort() - return utils.JsonEquals(cc, oo) + return utils.JSONEquals(cc, oo) } func (c *DNSConfig) Clone() *DNSConfig { return utils.Clone(c, &DNSConfig{}) } -// Sort sort dns config +// Sort dns config. func (c *DNSConfig) Sort() { if c.UpstreamDns != nil { sort.Strings(*c.UpstreamDns) @@ -119,14 +118,14 @@ func (c *DNSConfig) Sort() { } } -// Equals access list equal check +// Equals access list equal check. func (al *AccessList) Equals(o *AccessList) bool { return EqualsStringSlice(al.AllowedClients, o.AllowedClients, true) && EqualsStringSlice(al.DisallowedClients, o.DisallowedClients, true) && EqualsStringSlice(al.BlockedHosts, o.BlockedHosts, true) } -func EqualsStringSlice(a *[]string, b *[]string, sortIt bool) bool { +func EqualsStringSlice(a, b *[]string, sortIt bool) bool { if a == nil && b == nil { return true } @@ -152,7 +151,7 @@ func EqualsStringSlice(a *[]string, b *[]string, sortIt bool) bool { return true } -// Sort clients +// Sort clients. func (cl *Client) Sort() { if cl.Ids != nil { sort.Strings(*cl.Ids) @@ -168,28 +167,26 @@ func (cl *Client) Sort() { } } -// PrepareDiff timezone BlockedServicesSchedule might differ if all other fields are empty, -// so we skip it in diff +// PrepareDiff so we skip it in diff. func (cl *Client) PrepareDiff() *string { var tz *string bss := cl.BlockedServicesSchedule if bss != nil && bss.Mon == nil && bss.Tue == nil && bss.Wed == nil && bss.Thu == nil && bss.Fri == nil && bss.Sat == nil && bss.Sun == nil { - tz = cl.BlockedServicesSchedule.TimeZone cl.BlockedServicesSchedule.TimeZone = nil } return tz } -// AfterDiff reset after diff +// AfterDiff reset after diff. func (cl *Client) AfterDiff(tz *string) { if cl.BlockedServicesSchedule != nil { cl.BlockedServicesSchedule.TimeZone = tz } } -// Equals Clients equal check +// Equals Clients equal check. func (cl *Client) Equals(o *Client) bool { cl.Sort() o.Sort() @@ -202,10 +199,10 @@ func (cl *Client) Equals(o *Client) bool { o.AfterDiff(bssO) }() - return utils.JsonEquals(cl, o) + return utils.JSONEquals(cl, o) } -// Add ac client +// Add ac client. func (clients *Clients) Add(cl Client) { if clients.Clients == nil { clients.Clients = &ClientsArray{cl} @@ -215,8 +212,8 @@ func (clients *Clients) Add(cl Client) { } } -// Merge merge Clients -func (clients *Clients) Merge(other *Clients) ([]*Client, []*Client, []*Client) { +// Merge merge Clients. +func (clients *Clients) Merge(other *Clients) (adds, removes, updates []*Client) { current := make(map[string]*Client) if clients.Clients != nil { cc := *clients.Clients @@ -233,10 +230,6 @@ func (clients *Clients) Merge(other *Clients) ([]*Client, []*Client, []*Client) } } - var adds []*Client - var removes []*Client - var updates []*Client - for _, cl := range expected { if oc, ok := current[*cl.Name]; ok { if !cl.Equals(oc) { @@ -255,7 +248,7 @@ func (clients *Clients) Merge(other *Clients) ([]*Client, []*Client, []*Client) return adds, updates, removes } -// Key RewriteEntry key +// Key RewriteEntry key. func (re *RewriteEntry) Key() string { var d string var a string @@ -268,16 +261,13 @@ func (re *RewriteEntry) Key() string { return fmt.Sprintf("%s#%s", d, a) } -// RewriteEntries list of RewriteEntry +// RewriteEntries list of RewriteEntry. type RewriteEntries []RewriteEntry -// Merge RewriteEntries -func (rwe *RewriteEntries) Merge(other *RewriteEntries) (RewriteEntries, RewriteEntries, RewriteEntries) { +// Merge RewriteEntries. +func (rwe *RewriteEntries) Merge(other *RewriteEntries) (adds, removes, duplicates RewriteEntries) { current := make(map[string]RewriteEntry) - var adds RewriteEntries - var removes RewriteEntries - var duplicates RewriteEntries processed := make(map[string]bool) for _, rr := range *rwe { if _, ok := processed[rr.Key()]; !ok { @@ -310,16 +300,13 @@ func (rwe *RewriteEntries) Merge(other *RewriteEntries) (RewriteEntries, Rewrite return adds, removes, duplicates } -func MergeFilters(this *[]Filter, other *[]Filter) ([]Filter, []Filter, []Filter) { +func MergeFilters(this, other *[]Filter) (adds, updates, removes []Filter) { if this == nil && other == nil { return nil, nil, nil } current := make(map[string]*Filter) - var adds []Filter - var updates []Filter - var removes []Filter if this != nil { for _, fi := range *this { current[fi.Url] = &fi @@ -346,7 +333,7 @@ func MergeFilters(this *[]Filter, other *[]Filter) ([]Filter, []Filter, []Filter return adds, updates, removes } -// Equals Filter equal check +// Equals Filter equal check. func (f *Filter) Equals(o *Filter) bool { return f.Enabled == o.Enabled && f.Url == o.Url && f.Name == o.Name } @@ -358,17 +345,17 @@ type QueryLogConfigWithIgnored struct { Ignored []string `json:"ignored,omitempty"` } -// Equals QueryLogConfig equal check +// Equals QueryLogConfig equal check. func (qlc *QueryLogConfigWithIgnored) Equals(o *QueryLogConfigWithIgnored) bool { - return utils.JsonEquals(qlc, o) + return utils.JSONEquals(qlc, o) } -// Equals QueryLogConfigInterval equal check +// Equals QueryLogConfigInterval equal check. func (qlc *QueryLogConfigInterval) Equals(o *QueryLogConfigInterval) bool { return ptrEquals(qlc, o) } -func ptrEquals[T comparable](a *T, b *T) bool { +func ptrEquals[T comparable](a, b *T) bool { if a == nil && b == nil { return true } @@ -384,7 +371,7 @@ func ptrEquals[T comparable](a *T, b *T) bool { return aa == bb } -// EnableConfig API struct +// EnableConfig API struct. type EnableConfig struct { Enabled bool `json:"enabled"` } @@ -421,7 +408,7 @@ func (pi *ProfileInfo) ShouldSyncFor(o *ProfileInfo, withTheme bool) *ProfileInf } func (bss *BlockedServicesSchedule) Equals(o *BlockedServicesSchedule) bool { - return utils.JsonEquals(bss, o) + return utils.JSONEquals(bss, o) } func (bss *BlockedServicesSchedule) ServicesString() string { @@ -449,9 +436,9 @@ func (c *DNSConfig) Sanitize(l *zap.SugaredLogger) { } } -// Equals GetStatsConfigResponse equal check +// Equals GetStatsConfigResponse equal check. func (sc *GetStatsConfigResponse) Equals(o *GetStatsConfigResponse) bool { - return utils.JsonEquals(sc, o) + return utils.JSONEquals(sc, o) } func NewStats() *Stats { @@ -482,19 +469,19 @@ func (s *Stats) Add(other *Stats) { s.ReplacedSafebrowsing = sumUp(s.ReplacedSafebrowsing, other.ReplacedSafebrowsing) } -func addInt(t *int, add *int) *int { +func addInt(t, add *int) *int { if add != nil { return ptr.To(*t + *add) } return t } -func sumUp(t *[]int, o *[]int) *[]int { +func sumUp(t, o *[]int) *[]int { if o != nil { tt := *t oo := *o var sum []int - for i := 0; i < len(tt); i++ { + for i := range tt { if len(oo) >= i { sum = append(sum, tt[i]+oo[i]) } diff --git a/pkg/client/model/model_private_test.go b/pkg/client/model/model_private_test.go index 6efa465..95064b0 100644 --- a/pkg/client/model/model_private_test.go +++ b/pkg/client/model/model_private_test.go @@ -1,11 +1,12 @@ package model import ( - "github.com/bakito/adguardhome-sync/pkg/log" - "github.com/bakito/adguardhome-sync/pkg/utils" . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" "go.uber.org/zap" + + "github.com/bakito/adguardhome-sync/pkg/log" + "github.com/bakito/adguardhome-sync/pkg/utils" ) var _ = Describe("Types", func() { diff --git a/pkg/client/model/model_test.go b/pkg/client/model/model_test.go index 95bdd3d..afd2097 100644 --- a/pkg/client/model/model_test.go +++ b/pkg/client/model/model_test.go @@ -4,12 +4,13 @@ import ( "encoding/json" "os" - "github.com/bakito/adguardhome-sync/pkg/client/model" - "github.com/bakito/adguardhome-sync/pkg/types" - "github.com/bakito/adguardhome-sync/pkg/utils" "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + + "github.com/bakito/adguardhome-sync/pkg/client/model" + "github.com/bakito/adguardhome-sync/pkg/types" + "github.com/bakito/adguardhome-sync/pkg/utils" ) var _ = Describe("Types", func() { diff --git a/pkg/config/config.go b/pkg/config/config.go index d104c2f..67412b2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -4,9 +4,10 @@ import ( "errors" "regexp" + "github.com/caarlos0/env/v11" + "github.com/bakito/adguardhome-sync/pkg/log" "github.com/bakito/adguardhome-sync/pkg/types" - "github.com/caarlos0/env/v11" ) var ( @@ -38,7 +39,7 @@ func Get(configFile string, flags Flags) (*AppConfig, error) { return nil, err } - if err = validateSchema(path); err != nil { + if err := validateSchema(path); err != nil { return nil, err } @@ -67,10 +68,10 @@ func Get(configFile string, flags Flags) (*AppConfig, error) { cfg.Replicas = nil // overwrite from env vars - if err = env.Parse(cfg); err != nil { + if err := env.Parse(cfg); err != nil { return nil, err } - if err = env.ParseWithOptions(cfg.Replica, env.Options{Prefix: "REPLICA_"}); err != nil { + if err := env.ParseWithOptions(cfg.Replica, env.Options{Prefix: "REPLICA_"}); err != nil { return nil, err } // restore the replica @@ -81,7 +82,7 @@ func Get(configFile string, flags Flags) (*AppConfig, error) { cfg.Replica.DHCPServerEnabled = replicaDhcpServer } - if err = env.ParseWithOptions(&cfg.Origin, env.Options{Prefix: "ORIGIN_"}); err != nil { + if err := env.ParseWithOptions(&cfg.Origin, env.Options{Prefix: "ORIGIN_"}); err != nil { return nil, err } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 34c2812..5816cbe 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -3,11 +3,12 @@ package config_test import ( "os" - "github.com/bakito/adguardhome-sync/pkg/config" - flagsmock "github.com/bakito/adguardhome-sync/pkg/mocks/flags" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" gm "go.uber.org/mock/gomock" + + "github.com/bakito/adguardhome-sync/pkg/config" + flagsmock "github.com/bakito/adguardhome-sync/pkg/mocks/flags" ) var _ = Describe("Config", func() { @@ -16,7 +17,7 @@ var _ = Describe("Config", func() { flags *flagsmock.MockFlags mockCtrl *gm.Controller changedEnvVars []string - setEnv = func(name string, value string) { + setEnv = func(name, value string) { _ = os.Setenv(name, value) changedEnvVars = append(changedEnvVars, name) } @@ -125,9 +126,9 @@ var _ = Describe("Config", func() { Ω(cfg.Get().API.Port).Should(Equal(9090)) }) It("should have the api port from the config flags", func() { - flags.EXPECT().Changed(config.FlagApiPort).Return(true).AnyTimes() + flags.EXPECT().Changed(config.FlagAPIPort).Return(true).AnyTimes() flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes() - flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes() + flags.EXPECT().GetInt(config.FlagAPIPort).Return(9990, nil).AnyTimes() cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags) Ω(err).ShouldNot(HaveOccurred()) @@ -135,9 +136,9 @@ var _ = Describe("Config", func() { }) It("should have the api port from the config env var", func() { setEnv("API_PORT", "9999") - flags.EXPECT().Changed(config.FlagApiPort).Return(true).AnyTimes() + flags.EXPECT().Changed(config.FlagAPIPort).Return(true).AnyTimes() flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes() - flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes() + flags.EXPECT().GetInt(config.FlagAPIPort).Return(9990, nil).AnyTimes() cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags) Ω(err).ShouldNot(HaveOccurred()) @@ -174,9 +175,9 @@ var _ = Describe("Config", func() { Ω(cfg.Get().API.Port).Should(Equal(9090)) }) It("should have the api port from the config flags", func() { - flags.EXPECT().Changed(config.FlagApiPort).Return(true).AnyTimes() + flags.EXPECT().Changed(config.FlagAPIPort).Return(true).AnyTimes() flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes() - flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes() + flags.EXPECT().GetInt(config.FlagAPIPort).Return(9990, nil).AnyTimes() cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags) Ω(err).ShouldNot(HaveOccurred()) @@ -184,9 +185,9 @@ var _ = Describe("Config", func() { }) It("should have the api port from the config env var", func() { setEnv("API_PORT", "9999") - flags.EXPECT().Changed(config.FlagApiPort).Return(true).AnyTimes() + flags.EXPECT().Changed(config.FlagAPIPort).Return(true).AnyTimes() flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes() - flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes() + flags.EXPECT().GetInt(config.FlagAPIPort).Return(9990, nil).AnyTimes() cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags) Ω(err).ShouldNot(HaveOccurred()) @@ -202,9 +203,9 @@ var _ = Describe("Config", func() { Ω(cfg.Get().Features.DNS.ServerConfig).Should(BeFalse()) }) It("should have the feature dns server config from the config flags", func() { - flags.EXPECT().Changed(config.FlagFeatureDnsServerConfig).Return(true).AnyTimes() + flags.EXPECT().Changed(config.FlagFeatureDNSServerConfig).Return(true).AnyTimes() flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes() - flags.EXPECT().GetBool(config.FlagFeatureDnsServerConfig).Return(true, nil).AnyTimes() + flags.EXPECT().GetBool(config.FlagFeatureDNSServerConfig).Return(true, nil).AnyTimes() cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags) Ω(err).ShouldNot(HaveOccurred()) @@ -212,9 +213,9 @@ var _ = Describe("Config", func() { }) It("should have the feature dns server config from the config env var", func() { setEnv("FEATURES_DNS_SERVER_CONFIG", "false") - flags.EXPECT().Changed(config.FlagFeatureDnsServerConfig).Return(true).AnyTimes() + flags.EXPECT().Changed(config.FlagFeatureDNSServerConfig).Return(true).AnyTimes() flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes() - flags.EXPECT().GetBool(config.FlagFeatureDnsServerConfig).Return(true, nil).AnyTimes() + flags.EXPECT().GetBool(config.FlagFeatureDNSServerConfig).Return(true, nil).AnyTimes() cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags) Ω(err).ShouldNot(HaveOccurred()) @@ -222,9 +223,9 @@ var _ = Describe("Config", func() { }) It("should have the feature dns server config from the config DEPRECATED env var", func() { setEnv("FEATURES_DNS_SERVERCONFIG", "false") - flags.EXPECT().Changed(config.FlagFeatureDnsServerConfig).Return(true).AnyTimes() + flags.EXPECT().Changed(config.FlagFeatureDNSServerConfig).Return(true).AnyTimes() flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes() - flags.EXPECT().GetBool(config.FlagFeatureDnsServerConfig).Return(true, nil).AnyTimes() + flags.EXPECT().GetBool(config.FlagFeatureDNSServerConfig).Return(true, nil).AnyTimes() cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags) Ω(err).ShouldNot(HaveOccurred()) diff --git a/pkg/config/deprecated_env_test.go b/pkg/config/deprecated_env_test.go index eebd887..aadafa6 100644 --- a/pkg/config/deprecated_env_test.go +++ b/pkg/config/deprecated_env_test.go @@ -4,9 +4,10 @@ import ( "fmt" "os" - "github.com/bakito/adguardhome-sync/pkg/config" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + + "github.com/bakito/adguardhome-sync/pkg/config" ) var envVars = []string{ diff --git a/pkg/config/env.go b/pkg/config/env.go index ed26a9e..7fd7ac8 100644 --- a/pkg/config/env.go +++ b/pkg/config/env.go @@ -6,9 +6,10 @@ import ( "strconv" "strings" + "github.com/caarlos0/env/v11" + "github.com/bakito/adguardhome-sync/pkg/types" "github.com/bakito/adguardhome-sync/pkg/utils" - "github.com/caarlos0/env/v11" ) func handleDeprecatedEnvVars(cfg *types.Config) { @@ -61,20 +62,20 @@ func handleDeprecatedEnvVars(cfg *types.Config) { } } -func checkDeprecatedEnvVar(oldName string, newName string) (string, bool) { +func checkDeprecatedEnvVar(oldName, newName string) (string, bool) { old, oldOK := os.LookupEnv(oldName) if oldOK { logger.With("deprecated", oldName, "replacement", newName). Warn("Deprecated env variable is used, please use the correct one") } - new, newOK := os.LookupEnv(newName) + newVal, newOK := os.LookupEnv(newName) if newOK { - return new, true + return newVal, true } return old, oldOK } -func checkDeprecatedReplicaEnvVar(oldPattern string, newPattern string, replicaID int) (string, bool) { +func checkDeprecatedReplicaEnvVar(oldPattern, newPattern string, replicaID int) (string, bool) { return checkDeprecatedEnvVar(fmt.Sprintf(oldPattern, replicaID), fmt.Sprintf(newPattern, replicaID)) } diff --git a/pkg/config/file.go b/pkg/config/file.go index 4f4534e..dbe43d8 100644 --- a/pkg/config/file.go +++ b/pkg/config/file.go @@ -4,8 +4,9 @@ import ( "os" "path/filepath" - "github.com/bakito/adguardhome-sync/pkg/types" "gopkg.in/yaml.v3" + + "github.com/bakito/adguardhome-sync/pkg/types" ) func readFile(cfg *types.Config, path string) (string, error) { diff --git a/pkg/config/file_test.go b/pkg/config/file_test.go index 619ce69..7f92105 100644 --- a/pkg/config/file_test.go +++ b/pkg/config/file_test.go @@ -10,9 +10,6 @@ import ( ) var _ = Describe("Config", func() { - var () - BeforeEach(func() { - }) Context("configFilePath", func() { It("should return the same value", func() { path := uuid.NewString() @@ -26,7 +23,7 @@ var _ = Describe("Config", func() { result, err := configFilePath("") Ω(err).ShouldNot(HaveOccurred()) - Ω(result).Should(Equal(filepath.Join(home, "/.adguardhome-sync.yaml"))) + Ω(result).Should(Equal(filepath.Join(home, ".adguardhome-sync.yaml"))) }) }) }) diff --git a/pkg/config/flag-names.go b/pkg/config/flag-names.go index 34ce7cd..ae20917 100644 --- a/pkg/config/flag-names.go +++ b/pkg/config/flag-names.go @@ -6,16 +6,16 @@ const ( FlagPrintConfigOnly = "printConfigOnly" FlagContinueOnError = "continueOnError" - FlagApiPort = "api-port" - FlagApiUsername = "api-username" - FlagApiPassword = "api-password" - FlagApiDarkMode = "api-dark-mode" + FlagAPIPort = "api-port" + FlagAPIUsername = "api-username" + FlagAPIPassword = "api-password" + FlagAPIDarkMode = "api-dark-mode" FlagFeatureDhcpServerConfig = "feature-dhcp-server-config" FlagFeatureDhcpStaticLeases = "feature-dhcp-static-leases" - FlagFeatureDnsServerConfig = "feature-dns-server-config" - FlagFeatureDnsAccessLists = "feature-dns-access-lists" - FlagFeatureDnsRewrites = "feature-dns-rewrites" + FlagFeatureDNSServerConfig = "feature-dns-server-config" + FlagFeatureDNSAccessLists = "feature-dns-access-lists" + FlagFeatureDNSRewrites = "feature-dns-rewrites" FlagFeatureGeneral = "feature-general-settings" FlagFeatureQueryLog = "feature-query-log-config" FlagFeatureStats = "feature-stats-config" @@ -25,7 +25,7 @@ const ( FlagOriginURL = "origin-url" FlagOriginWebURL = "origin-web-url" - FlagOriginApiPath = "origin-api-path" + FlagOriginAPIPath = "origin-api-path" FlagOriginUsername = "origin-username" FlagOriginPassword = "origin-password" @@ -34,7 +34,7 @@ const ( FlagReplicaURL = "replica-url" FlagReplicaWebURL = "replica-web-url" - FlagReplicaApiPath = "replica-api-path" + FlagReplicaAPIPath = "replica-api-path" FlagReplicaUsername = "replica-username" FlagReplicaPassword = "replica-password" FlagReplicaCookie = "replica-cookie" diff --git a/pkg/config/flags.go b/pkg/config/flags.go index 42dc2e4..7f36bac 100644 --- a/pkg/config/flags.go +++ b/pkg/config/flags.go @@ -18,7 +18,7 @@ func readFlags(cfg *types.Config, flags Flags) error { return err } - if err := fr.readApiFlags(); err != nil { + if err := fr.readAPIFlags(); err != nil { return err } @@ -30,11 +30,7 @@ func readFlags(cfg *types.Config, flags Flags) error { return err } - if err := fr.readReplicaFlags(); err != nil { - return err - } - - return nil + return fr.readReplicaFlags() } type flagReader struct { @@ -53,7 +49,7 @@ func (fr *flagReader) readReplicaFlags() error { }); err != nil { return err } - if err := fr.setStringFlag(FlagReplicaApiPath, func(cgf *types.Config, value string) { + if err := fr.setStringFlag(FlagReplicaAPIPath, func(cgf *types.Config, value string) { fr.cfg.Replica.APIPath = value }); err != nil { return err @@ -83,12 +79,9 @@ func (fr *flagReader) readReplicaFlags() error { }); err != nil { return err } - if err := fr.setStringFlag(FlagReplicaInterfaceName, func(cgf *types.Config, value string) { + return fr.setStringFlag(FlagReplicaInterfaceName, func(cgf *types.Config, value string) { fr.cfg.Replica.InterfaceName = value - }); err != nil { - return err - } - return nil + }) } func (fr *flagReader) readOriginFlags() error { @@ -102,7 +95,7 @@ func (fr *flagReader) readOriginFlags() error { }); err != nil { return err } - if err := fr.setStringFlag(FlagOriginApiPath, func(cgf *types.Config, value string) { + if err := fr.setStringFlag(FlagOriginAPIPath, func(cgf *types.Config, value string) { fr.cfg.Origin.APIPath = value }); err != nil { return err @@ -122,12 +115,9 @@ func (fr *flagReader) readOriginFlags() error { }); err != nil { return err } - if err := fr.setBoolFlag(FlagOriginISV, func(cgf *types.Config, value bool) { + return fr.setBoolFlag(FlagOriginISV, func(cgf *types.Config, value bool) { fr.cfg.Origin.InsecureSkipVerify = value - }); err != nil { - return err - } - return nil + }) } func (fr *flagReader) readFeatureFlags() error { @@ -142,17 +132,17 @@ func (fr *flagReader) readFeatureFlags() error { return err } - if err := fr.setBoolFlag(FlagFeatureDnsServerConfig, func(cgf *types.Config, value bool) { + if err := fr.setBoolFlag(FlagFeatureDNSServerConfig, func(cgf *types.Config, value bool) { fr.cfg.Features.DNS.ServerConfig = value }); err != nil { return err } - if err := fr.setBoolFlag(FlagFeatureDnsAccessLists, func(cgf *types.Config, value bool) { + if err := fr.setBoolFlag(FlagFeatureDNSAccessLists, func(cgf *types.Config, value bool) { fr.cfg.Features.DNS.AccessLists = value }); err != nil { return err } - if err := fr.setBoolFlag(FlagFeatureDnsRewrites, func(cgf *types.Config, value bool) { + if err := fr.setBoolFlag(FlagFeatureDNSRewrites, func(cgf *types.Config, value bool) { fr.cfg.Features.DNS.Rewrites = value }); err != nil { return err @@ -183,61 +173,51 @@ func (fr *flagReader) readFeatureFlags() error { }); err != nil { return err } - if err := fr.setBoolFlag(FlagFeatureFilters, func(cgf *types.Config, value bool) { + return fr.setBoolFlag(FlagFeatureFilters, func(cgf *types.Config, value bool) { fr.cfg.Features.Filters = value + }) +} + +func (fr *flagReader) readAPIFlags() error { + if err := fr.setIntFlag(FlagAPIPort, func(cgf *types.Config, value int) { + fr.cfg.API.Port = value }); err != nil { return err } - - return nil -} - -func (fr *flagReader) readApiFlags() (err error) { - if err = fr.setIntFlag(FlagApiPort, func(cgf *types.Config, value int) { - fr.cfg.API.Port = value - }); err != nil { - return - } - if err = fr.setStringFlag(FlagApiUsername, func(cgf *types.Config, value string) { + if err := fr.setStringFlag(FlagAPIUsername, func(cgf *types.Config, value string) { fr.cfg.API.Username = value }); err != nil { - return + return err } - if err = fr.setStringFlag(FlagApiPassword, func(cgf *types.Config, value string) { + if err := fr.setStringFlag(FlagAPIPassword, func(cgf *types.Config, value string) { fr.cfg.API.Password = value }); err != nil { - return + return err } - if err = fr.setBoolFlag(FlagApiDarkMode, func(cgf *types.Config, value bool) { + return fr.setBoolFlag(FlagAPIDarkMode, func(cgf *types.Config, value bool) { fr.cfg.API.DarkMode = value - }); err != nil { - return - } - return + }) } -func (fr *flagReader) readRootFlags() (err error) { - if err = fr.setStringFlag(FlagCron, func(cgf *types.Config, value string) { +func (fr *flagReader) readRootFlags() error { + if err := fr.setStringFlag(FlagCron, func(cgf *types.Config, value string) { fr.cfg.Cron = value }); err != nil { - return + return err } - if err = fr.setBoolFlag(FlagRunOnStart, func(cgf *types.Config, value bool) { + if err := fr.setBoolFlag(FlagRunOnStart, func(cgf *types.Config, value bool) { fr.cfg.RunOnStart = value }); err != nil { - return + return err } - if err = fr.setBoolFlag(FlagPrintConfigOnly, func(cgf *types.Config, value bool) { + if err := fr.setBoolFlag(FlagPrintConfigOnly, func(cgf *types.Config, value bool) { fr.cfg.PrintConfigOnly = value }); err != nil { - return + return err } - if err = fr.setBoolFlag(FlagContinueOnError, func(cgf *types.Config, value bool) { + return fr.setBoolFlag(FlagContinueOnError, func(cgf *types.Config, value bool) { fr.cfg.ContinueOnError = value - }); err != nil { - return - } - return + }) } type Flags interface { @@ -249,33 +229,33 @@ type Flags interface { func (fr *flagReader) setStringFlag(name string, cb callback[string]) (err error) { if fr.flags.Changed(name) { - if value, err := fr.flags.GetString(name); err != nil { + var value string + if value, err = fr.flags.GetString(name); err != nil { return err - } else { - cb(fr.cfg, value) } + cb(fr.cfg, value) } return nil } func (fr *flagReader) setBoolFlag(name string, cb callback[bool]) (err error) { if fr.flags.Changed(name) { - if value, err := fr.flags.GetBool(name); err != nil { + var value bool + if value, err = fr.flags.GetBool(name); err != nil { return err - } else { - cb(fr.cfg, value) } + cb(fr.cfg, value) } return nil } func (fr *flagReader) setIntFlag(name string, cb callback[int]) (err error) { if fr.flags.Changed(name) { - if value, err := fr.flags.GetInt(name); err != nil { + var value int + if value, err = fr.flags.GetInt(name); err != nil { return err - } else { - cb(fr.cfg, value) } + cb(fr.cfg, value) } return nil } diff --git a/pkg/config/flags_test.go b/pkg/config/flags_test.go index 36ec2df..2124939 100644 --- a/pkg/config/flags_test.go +++ b/pkg/config/flags_test.go @@ -3,11 +3,12 @@ package config import ( "strings" - flagsmock "github.com/bakito/adguardhome-sync/pkg/mocks/flags" - "github.com/bakito/adguardhome-sync/pkg/types" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" gm "go.uber.org/mock/gomock" + + flagsmock "github.com/bakito/adguardhome-sync/pkg/mocks/flags" + "github.com/bakito/adguardhome-sync/pkg/types" ) var _ = Describe("Config", func() { @@ -88,7 +89,7 @@ var _ = Describe("Config", func() { })) }) }) - Context("readApiFlags", func() { + Context("readAPIFlags", func() { It("should change all values", func() { cfg.API = types.API{ Port: 1111, @@ -99,10 +100,10 @@ var _ = Describe("Config", func() { flags.EXPECT().Changed(gm.Any()).DoAndReturn(func(name string) bool { return strings.HasPrefix(name, "api") }).AnyTimes() - flags.EXPECT().GetInt(FlagApiPort).Return(9999, nil) - flags.EXPECT().GetString(FlagApiUsername).Return("aaaa", nil) - flags.EXPECT().GetString(FlagApiPassword).Return("bbbb", nil) - flags.EXPECT().GetBool(FlagApiDarkMode).Return(true, nil) + flags.EXPECT().GetInt(FlagAPIPort).Return(9999, nil) + flags.EXPECT().GetString(FlagAPIUsername).Return("aaaa", nil) + flags.EXPECT().GetString(FlagAPIPassword).Return("bbbb", nil) + flags.EXPECT().GetBool(FlagAPIDarkMode).Return(true, nil) err := readFlags(cfg, flags) Ω(err).ShouldNot(HaveOccurred()) @@ -154,7 +155,7 @@ var _ = Describe("Config", func() { flags.EXPECT().Changed(FlagOriginURL).Return(true) flags.EXPECT().Changed(FlagOriginWebURL).Return(true) - flags.EXPECT().Changed(FlagOriginApiPath).Return(true) + flags.EXPECT().Changed(FlagOriginAPIPath).Return(true) flags.EXPECT().Changed(FlagOriginUsername).Return(true) flags.EXPECT().Changed(FlagOriginPassword).Return(true) flags.EXPECT().Changed(FlagOriginCookie).Return(true) @@ -163,7 +164,7 @@ var _ = Describe("Config", func() { flags.EXPECT().GetString(FlagOriginURL).Return("a", nil) flags.EXPECT().GetString(FlagOriginWebURL).Return("b", nil) - flags.EXPECT().GetString(FlagOriginApiPath).Return("c", nil) + flags.EXPECT().GetString(FlagOriginAPIPath).Return("c", nil) flags.EXPECT().GetString(FlagOriginUsername).Return("d", nil) flags.EXPECT().GetString(FlagOriginPassword).Return("e", nil) flags.EXPECT().GetString(FlagOriginCookie).Return("f", nil) @@ -198,7 +199,7 @@ var _ = Describe("Config", func() { flags.EXPECT().Changed(FlagReplicaURL).Return(true) flags.EXPECT().Changed(FlagReplicaWebURL).Return(true) - flags.EXPECT().Changed(FlagReplicaApiPath).Return(true) + flags.EXPECT().Changed(FlagReplicaAPIPath).Return(true) flags.EXPECT().Changed(FlagReplicaUsername).Return(true) flags.EXPECT().Changed(FlagReplicaPassword).Return(true) flags.EXPECT().Changed(FlagReplicaCookie).Return(true) @@ -209,7 +210,7 @@ var _ = Describe("Config", func() { flags.EXPECT().GetString(FlagReplicaURL).Return("a", nil) flags.EXPECT().GetString(FlagReplicaWebURL).Return("b", nil) - flags.EXPECT().GetString(FlagReplicaApiPath).Return("c", nil) + flags.EXPECT().GetString(FlagReplicaAPIPath).Return("c", nil) flags.EXPECT().GetString(FlagReplicaUsername).Return("d", nil) flags.EXPECT().GetString(FlagReplicaPassword).Return("e", nil) flags.EXPECT().GetString(FlagReplicaCookie).Return("f", nil) diff --git a/pkg/config/print-config.go b/pkg/config/print-config.go index 8368351..8627250 100644 --- a/pkg/config/print-config.go +++ b/pkg/config/print-config.go @@ -9,10 +9,11 @@ import ( "strings" "text/template" + "gopkg.in/yaml.v3" + "github.com/bakito/adguardhome-sync/pkg/client" "github.com/bakito/adguardhome-sync/pkg/types" "github.com/bakito/adguardhome-sync/version" - "gopkg.in/yaml.v3" ) //go:embed print-config.md @@ -25,7 +26,7 @@ func (ac *AppConfig) Print() error { replicaVersions = append(replicaVersions, aghVersion(replica)) } - out, err := ac.print(os.Environ(), originVersion, replicaVersions) + out, err := ac.printInternal(os.Environ(), originVersion, replicaVersions) if err != nil { return err } @@ -50,7 +51,7 @@ func aghVersion(i types.AdGuardInstance) string { return stats.Version } -func (ac *AppConfig) print(env []string, originVersion string, replicaVersions []string) (string, error) { +func (ac *AppConfig) printInternal(env []string, originVersion string, replicaVersions []string) (string, error) { config, err := yaml.Marshal(ac.Get()) if err != nil { return "", err @@ -72,7 +73,7 @@ func (ac *AppConfig) print(env []string, originVersion string, replicaVersions [ var buf bytes.Buffer - if err = t.Execute(&buf, map[string]interface{}{ + err = t.Execute(&buf, map[string]any{ "Version": version.Version, "Build": version.Build, "OperatingSystem": runtime.GOOS, @@ -83,8 +84,6 @@ func (ac *AppConfig) print(env []string, originVersion string, replicaVersions [ "EnvironmentVariables": strings.Join(env, "\n"), "OriginVersion": originVersion, "ReplicaVersions": replicaVersions, - }); err != nil { - return "", err - } - return buf.String(), nil + }) + return buf.String(), err } diff --git a/pkg/config/print-config_test.go b/pkg/config/print-config_test.go index 191088e..abe7b46 100644 --- a/pkg/config/print-config_test.go +++ b/pkg/config/print-config_test.go @@ -7,10 +7,11 @@ import ( "path/filepath" "runtime" - "github.com/bakito/adguardhome-sync/pkg/types" - "github.com/bakito/adguardhome-sync/version" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + + "github.com/bakito/adguardhome-sync/pkg/types" + "github.com/bakito/adguardhome-sync/version" ) var _ = Describe("AppConfig", func() { @@ -32,17 +33,17 @@ origin: } env = []string{"FOO=foo", "BAR=bar"} }) - Context("print", func() { - It("should print config without file", func() { - out, err := ac.print(env, "v0.0.1", []string{"v0.0.2"}) + Context("printInternal", func() { + It("should printInternal config without file", func() { + out, err := ac.printInternal(env, "v0.0.1", []string{"v0.0.2"}) Ω(err).ShouldNot(HaveOccurred()) Ω( out, ).Should(Equal(fmt.Sprintf(expected(1), version.Version, version.Build, runtime.GOOS, runtime.GOARCH))) }) - It("should print config with file", func() { + It("should printInternal config with file", func() { ac.filePath = "config.yaml" - out, err := ac.print(env, "v0.0.1", []string{"v0.0.2"}) + out, err := ac.printInternal(env, "v0.0.1", []string{"v0.0.2"}) Ω(err).ShouldNot(HaveOccurred()) Ω( out, @@ -52,7 +53,9 @@ origin: }) func expected(id int) string { - b, err := os.ReadFile(filepath.Join("../../testdata/config", fmt.Sprintf("print-config_test_expected%d.md", id))) + b, err := os.ReadFile( + filepath.Join("..", "..", "testdata", "config", fmt.Sprintf("print-config_test_expected%d.md", id)), + ) Ω(err).ShouldNot(HaveOccurred()) return string(b) } diff --git a/pkg/config/validate.go b/pkg/config/validate.go index 5ebcc81..b15a80a 100644 --- a/pkg/config/validate.go +++ b/pkg/config/validate.go @@ -17,6 +17,7 @@ var schemaData string func validateSchema(cfgFile string) error { // ignore if file not exists if _, err := os.Stat(cfgFile); err != nil { + //nolint:nilerr return nil } // Load YAML file @@ -30,7 +31,7 @@ func validateSchema(cfgFile string) error { func validateYAML(yamlContent []byte) error { // Convert YAML to JSON - var yamlData interface{} + var yamlData any err := yaml.Unmarshal(yamlContent, &yamlData) if err != nil { return err diff --git a/pkg/config/validate_test.go b/pkg/config/validate_test.go index e3e7552..efc2dc1 100644 --- a/pkg/config/validate_test.go +++ b/pkg/config/validate_test.go @@ -1,11 +1,12 @@ package config import ( - "github.com/bakito/adguardhome-sync/pkg/types" "github.com/go-faker/faker/v4" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "gopkg.in/yaml.v3" + + "github.com/bakito/adguardhome-sync/pkg/types" ) var _ = Describe("Config", func() { diff --git a/pkg/log/log.go b/pkg/log/log.go index 3c18d44..463bc39 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -18,7 +18,7 @@ var ( logs []string ) -// GetLogger returns a named logger +// GetLogger returns a named logger. func GetLogger(name string) *zap.SugaredLogger { return rootLogger.Named(name).Sugar() } @@ -101,12 +101,12 @@ func (l *logList) Sync() error { return nil } -// Logs get the current logs +// Logs get the current logs. func Logs() []string { return logs } -// Clear the current logs +// Clear the current logs. func Clear() { logs = nil } diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 72c5ee3..cce82a5 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -1,9 +1,10 @@ package metrics import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/bakito/adguardhome-sync/pkg/log" - "github.com/prometheus/client_golang/prometheus" ) const StatsTotal = "total" @@ -11,7 +12,7 @@ const StatsTotal = "total" var ( l = log.GetLogger("metrics") - // avgProcessingTime - Average processing time for a DNS query + // avgProcessingTime - Average processing time for a DNS query. avgProcessingTime = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "avg_processing_time", @@ -21,7 +22,7 @@ var ( []string{"hostname"}, ) - // dnsQueries - Number of DNS queries + // dnsQueries - Number of DNS queries. dnsQueries = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "num_dns_queries", @@ -31,7 +32,7 @@ var ( []string{"hostname"}, ) - // blockedFiltering - Number of DNS queries blocked + // blockedFiltering - Number of DNS queries blocked. blockedFiltering = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "num_blocked_filtering", @@ -41,7 +42,7 @@ var ( []string{"hostname"}, ) - // parentalFiltering - Number of DNS queries replaced by parental control + // parentalFiltering - Number of DNS queries replaced by parental control. parentalFiltering = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "num_replaced_parental", @@ -51,7 +52,7 @@ var ( []string{"hostname"}, ) - // safeBrowsingFiltering - Number of DNS queries replaced by safe browsing + // safeBrowsingFiltering - Number of DNS queries replaced by safe browsing. safeBrowsingFiltering = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "num_replaced_safebrowsing", @@ -61,7 +62,7 @@ var ( []string{"hostname"}, ) - // safeSearchFiltering - Number of DNS queries replaced by safe search + // safeSearchFiltering - Number of DNS queries replaced by safe search. safeSearchFiltering = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "num_replaced_safesearch", @@ -71,7 +72,7 @@ var ( []string{"hostname"}, ) - // topQueries - The number of top queries + // topQueries - The number of top queries. topQueries = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "top_queried_domains", @@ -81,7 +82,7 @@ var ( []string{"hostname", "domain"}, ) - // topBlocked - The number of top domains blocked + // topBlocked - The number of top domains blocked. topBlocked = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "top_blocked_domains", @@ -91,7 +92,7 @@ var ( []string{"hostname", "domain"}, ) - // topClients - The number of top clients + // topClients - The number of top clients. topClients = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "top_clients", @@ -111,7 +112,7 @@ var ( []string{"hostname", "type"}, ) - // running - If Adguard is running + // running - If Adguard is running. running = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "running", @@ -121,7 +122,7 @@ var ( []string{"hostname"}, ) - // protectionEnabled - If Adguard protection is enabled + // protectionEnabled - If Adguard protection is enabled. protectionEnabled = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "protection_enabled", @@ -157,22 +158,22 @@ func initMetric(name string, metric *prometheus.GaugeVec) { func Update(iml InstanceMetricsList) { for _, im := range iml.Metrics { - update(im) + updateMetrics(im) stats[im.HostName] = im.Stats } l.Debug("updated") } -func update(im InstanceMetrics) { +func updateMetrics(im InstanceMetrics) { // Status - var isRunning int = 0 + isRunning := 0 if im.Status.Running { isRunning = 1 } running.WithLabelValues(im.HostName).Set(float64(isRunning)) - var isProtected int = 0 + isProtected := 0 if im.Status.ProtectionEnabled { isProtected = 1 } @@ -218,7 +219,7 @@ func update(im InstanceMetrics) { if len(dnsanswer) > 0 { for _, dnsa := range dnsanswer { dnsType := *dnsa.Type - m[dnsType] += 1 + m[dnsType]++ } } } diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go index 81b71f4..8afcd52 100644 --- a/pkg/metrics/metrics_test.go +++ b/pkg/metrics/metrics_test.go @@ -1,11 +1,12 @@ package metrics import ( - "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/go-faker/faker/v4" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "k8s.io/utils/ptr" + + "github.com/bakito/adguardhome-sync/pkg/client/model" ) var _ = Describe("Metrics", func() { @@ -85,15 +86,15 @@ var _ = Describe("Metrics", func() { }) }) -func verifyStats(lines []line) { - var total line +func verifyStats(lines []Line) { + var total Line sum := make([]int, len(lines[0].Data)) for _, l := range lines { if l.Title == labelTotal { total = l } else { for i, d := range l.Data { - sum[i] = sum[i] + d + sum[i] += d } } } diff --git a/pkg/metrics/stats.go b/pkg/metrics/stats.go index 9f075f6..10cb3e1 100644 --- a/pkg/metrics/stats.go +++ b/pkg/metrics/stats.go @@ -47,19 +47,19 @@ var ( } ) -func StatsGraph() (*model.Stats, []line, []line, []line, []line) { +func StatsGraph() (t *model.Stats, dns, blocked, malware, adult []Line) { s := getStats() - t := s.Total() - dns := graphLines(t, s, blue, blueAlternatives, func(s *model.Stats) []int { + t = s.Total() + dns = graphLines(t, s, blue, blueAlternatives, func(s *model.Stats) []int { return safeStats(s.DnsQueries) }) - blocked := graphLines(t, s, red, redAlternatives, func(s *model.Stats) []int { + blocked = graphLines(t, s, red, redAlternatives, func(s *model.Stats) []int { return safeStats(s.BlockedFiltering) }) - malware := graphLines(t, s, green, greenAlternatives, func(s *model.Stats) []int { + malware = graphLines(t, s, green, greenAlternatives, func(s *model.Stats) []int { return safeStats(s.ReplacedSafebrowsing) }) - adult := graphLines(t, s, yellow, yellowAlternatives, func(s *model.Stats) []int { + adult = graphLines(t, s, yellow, yellowAlternatives, func(s *model.Stats) []int { return safeStats(s.ReplacedParental) }) @@ -79,9 +79,9 @@ func graphLines( baseColor []int, altColors [][]int, dataCB func(s *model.Stats) []int, -) []line { +) []Line { g := &graph{ - total: line{ + total: Line{ Fill: true, Title: labelTotal, Data: dataCB(t), @@ -94,7 +94,7 @@ func graphLines( var i int for name, data := range s { if name != StatsTotal { - g.replicas = append(g.replicas, line{ + g.replicas = append(g.replicas, Line{ Fill: false, Title: name, Data: dataCB(data), @@ -106,9 +106,9 @@ func graphLines( } } - lines := []line{g.total} + lines := []Line{g.total} - slices.SortFunc(g.replicas, func(a, b line) int { + slices.SortFunc(g.replicas, func(a, b Line) int { return strings.Compare(a.Title, b.Title) }) lines = append(lines, g.replicas...) @@ -116,11 +116,11 @@ func graphLines( } type graph struct { - total line - replicas []line + total Line + replicas []Line } -type line struct { +type Line struct { Data []int `json:"data"` R int `json:"r"` G int `json:"g"` diff --git a/pkg/mocks/client/mock.go b/pkg/mocks/client/mock.go index 9a37647..5db410e 100644 --- a/pkg/mocks/client/mock.go +++ b/pkg/mocks/client/mock.go @@ -384,17 +384,17 @@ func (mr *MockClientMockRecorder) SafeSearchConfig() *gomock.Call { } // SetAccessList mocks base method. -func (m *MockClient) SetAccessList(arg0 *model.AccessList) error { +func (m *MockClient) SetAccessList(accessList *model.AccessList) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetAccessList", arg0) + ret := m.ctrl.Call(m, "SetAccessList", accessList) ret0, _ := ret[0].(error) return ret0 } // SetAccessList indicates an expected call of SetAccessList. -func (mr *MockClientMockRecorder) SetAccessList(arg0 any) *gomock.Call { +func (mr *MockClientMockRecorder) SetAccessList(accessList any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAccessList", reflect.TypeOf((*MockClient)(nil).SetAccessList), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAccessList", reflect.TypeOf((*MockClient)(nil).SetAccessList), accessList) } // SetBlockedServicesSchedule mocks base method. @@ -426,31 +426,31 @@ func (mr *MockClientMockRecorder) SetCustomRules(rules any) *gomock.Call { } // SetDNSConfig mocks base method. -func (m *MockClient) SetDNSConfig(arg0 *model.DNSConfig) error { +func (m *MockClient) SetDNSConfig(config *model.DNSConfig) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDNSConfig", arg0) + ret := m.ctrl.Call(m, "SetDNSConfig", config) ret0, _ := ret[0].(error) return ret0 } // SetDNSConfig indicates an expected call of SetDNSConfig. -func (mr *MockClientMockRecorder) SetDNSConfig(arg0 any) *gomock.Call { +func (mr *MockClientMockRecorder) SetDNSConfig(config any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDNSConfig", reflect.TypeOf((*MockClient)(nil).SetDNSConfig), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDNSConfig", reflect.TypeOf((*MockClient)(nil).SetDNSConfig), config) } // SetDhcpConfig mocks base method. -func (m *MockClient) SetDhcpConfig(arg0 *model.DhcpStatus) error { +func (m *MockClient) SetDhcpConfig(status *model.DhcpStatus) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetDhcpConfig", arg0) + ret := m.ctrl.Call(m, "SetDhcpConfig", status) ret0, _ := ret[0].(error) return ret0 } // SetDhcpConfig indicates an expected call of SetDhcpConfig. -func (mr *MockClientMockRecorder) SetDhcpConfig(arg0 any) *gomock.Call { +func (mr *MockClientMockRecorder) SetDhcpConfig(status any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDhcpConfig", reflect.TypeOf((*MockClient)(nil).SetDhcpConfig), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDhcpConfig", reflect.TypeOf((*MockClient)(nil).SetDhcpConfig), status) } // SetProfileInfo mocks base method. @@ -468,17 +468,17 @@ func (mr *MockClientMockRecorder) SetProfileInfo(settings any) *gomock.Call { } // SetQueryLogConfig mocks base method. -func (m *MockClient) SetQueryLogConfig(arg0 *model.QueryLogConfigWithIgnored) error { +func (m *MockClient) SetQueryLogConfig(ql *model.QueryLogConfigWithIgnored) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetQueryLogConfig", arg0) + ret := m.ctrl.Call(m, "SetQueryLogConfig", ql) ret0, _ := ret[0].(error) return ret0 } // SetQueryLogConfig indicates an expected call of SetQueryLogConfig. -func (mr *MockClientMockRecorder) SetQueryLogConfig(arg0 any) *gomock.Call { +func (mr *MockClientMockRecorder) SetQueryLogConfig(ql any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetQueryLogConfig", reflect.TypeOf((*MockClient)(nil).SetQueryLogConfig), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetQueryLogConfig", reflect.TypeOf((*MockClient)(nil).SetQueryLogConfig), ql) } // SetSafeSearchConfig mocks base method. diff --git a/pkg/sync/action-general.go b/pkg/sync/action-general.go index 1b7a822..f10a967 100644 --- a/pkg/sync/action-general.go +++ b/pkg/sync/action-general.go @@ -1,10 +1,11 @@ package sync import ( + "go.uber.org/zap" + "github.com/bakito/adguardhome-sync/pkg/client" "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/bakito/adguardhome-sync/pkg/utils" - "go.uber.org/zap" ) var ( diff --git a/pkg/sync/action.go b/pkg/sync/action.go index b1fe4e6..7ed6b86 100644 --- a/pkg/sync/action.go +++ b/pkg/sync/action.go @@ -1,10 +1,11 @@ package sync import ( + "go.uber.org/zap" + "github.com/bakito/adguardhome-sync/pkg/client" "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/bakito/adguardhome-sync/pkg/types" - "go.uber.org/zap" ) func setupActions(cfg *types.Config) (actions []syncAction) { diff --git a/pkg/sync/http.go b/pkg/sync/http.go index 9f3a2b9..f906677 100644 --- a/pkg/sync/http.go +++ b/pkg/sync/http.go @@ -14,10 +14,11 @@ import ( "syscall" "time" + "github.com/gin-gonic/gin" + "github.com/bakito/adguardhome-sync/pkg/log" "github.com/bakito/adguardhome-sync/pkg/metrics" "github.com/bakito/adguardhome-sync/version" - "github.com/gin-gonic/gin" ) var ( @@ -35,13 +36,13 @@ func (w *worker) handleSync(c *gin.Context) { func (w *worker) handleRoot(c *gin.Context) { total, dns, blocked, malware, adult := metrics.StatsGraph() - c.HTML(http.StatusOK, "index.html", map[string]interface{}{ + c.HTML(http.StatusOK, "index.html", map[string]any{ "DarkMode": w.cfg.API.DarkMode, "Metrics": w.cfg.API.Metrics.Enabled, "Version": version.Version, "Build": version.Build, "SyncStatus": w.status(), - "Stats": map[string]interface{}{ + "Stats": map[string]any{ "Labels": getLast24Hours(), "DNS": dns, "Blocked": blocked, @@ -169,8 +170,6 @@ func (w *worker) listenAndServe() { // manually cancel context if not using httpServer.RegisterOnShutdown(cancel) cancel() - - defer os.Exit(0) } type syncStatus struct { @@ -192,7 +191,7 @@ func getLast24Hours() []string { currentTime := time.Now() // Loop to get the last 24 hours - for i := 0; i < 24; i++ { + for i := range 24 { // Calculate the time for the current hour in the loop timeInstance := currentTime.Add(time.Duration(-i) * time.Hour) timeInstance = timeInstance.Truncate(time.Hour) diff --git a/pkg/sync/scrape.go b/pkg/sync/scrape.go index 97683a0..56c34a6 100644 --- a/pkg/sync/scrape.go +++ b/pkg/sync/scrape.go @@ -35,16 +35,17 @@ func (w *worker) scrape() { metrics.Update(iml) } -func (w *worker) getMetrics(inst types.AdGuardInstance) (im metrics.InstanceMetrics) { +func (w *worker) getMetrics(inst types.AdGuardInstance) metrics.InstanceMetrics { + var im metrics.InstanceMetrics client, err := w.createClient(inst) if err != nil { l.With("error", err, "url", w.cfg.Origin.URL).Error("Error creating origin client") - return + return im } im.HostName = inst.Host im.Status, _ = client.Status() im.Stats, _ = client.Stats() im.QueryLog, _ = client.QueryLog(w.cfg.API.Metrics.QueryLogLimit) - return + return im } diff --git a/pkg/sync/sync.go b/pkg/sync/sync.go index 1ca189e..ca18940 100644 --- a/pkg/sync/sync.go +++ b/pkg/sync/sync.go @@ -2,11 +2,13 @@ package sync import ( "errors" - "fmt" "runtime" "sort" "time" + "github.com/robfig/cron/v3" + "go.uber.org/zap" + "github.com/bakito/adguardhome-sync/pkg/client" "github.com/bakito/adguardhome-sync/pkg/client/model" "github.com/bakito/adguardhome-sync/pkg/log" @@ -14,20 +16,18 @@ import ( "github.com/bakito/adguardhome-sync/pkg/utils" "github.com/bakito/adguardhome-sync/pkg/versions" "github.com/bakito/adguardhome-sync/version" - "github.com/robfig/cron/v3" - "go.uber.org/zap" ) var l = log.GetLogger("sync") -// Sync config from origin to replica +// Sync config from origin to replica. func Sync(cfg *types.Config) error { if cfg.Origin.URL == "" { - return fmt.Errorf("origin URL is required") + return errors.New("origin URL is required") } if len(cfg.UniqueReplicas()) == 0 { - return fmt.Errorf("no replicas configured") + return errors.New("no replicas configured") } l.With( @@ -41,10 +41,8 @@ func Sync(cfg *types.Config) error { cfg.Origin.AutoSetup = false w := &worker{ - cfg: cfg, - createClient: func(ai types.AdGuardInstance) (client.Client, error) { - return client.New(ai) - }, + cfg: cfg, + createClient: client.New, } if cfg.Cron != "" { w.cron = cron.New() @@ -120,15 +118,15 @@ func (w *worker) status() *syncStatus { return syncStatus } -func (w *worker) getStatus(inst types.AdGuardInstance) (st replicaStatus) { - st = replicaStatus{Host: inst.WebHost, URL: inst.WebURL} +func (w *worker) getStatus(inst types.AdGuardInstance) replicaStatus { + st := replicaStatus{Host: inst.WebHost, URL: inst.WebURL} oc, err := w.createClient(inst) if err != nil { l.With("error", err, "url", w.cfg.Origin.URL).Error("Error creating origin client") st.Status = "danger" st.Error = err.Error() - return + return st } sl := l.With("from", inst.WebHost) status, err := oc.Status() @@ -136,16 +134,16 @@ func (w *worker) getStatus(inst types.AdGuardInstance) (st replicaStatus) { if errors.Is(err, client.ErrSetupNeeded) { st.Status = "warning" st.Error = err.Error() - return + return st } sl.With("error", err).Error("Error getting origin status") st.Status = "danger" st.Error = err.Error() - return + return st } st.Status = "success" st.ProtectionEnabled = utils.Ptr(status.ProtectionEnabled) - return + return st } func (w *worker) sync() { diff --git a/pkg/sync/sync_test.go b/pkg/sync/sync_test.go index 468e3ed..ae40ef7 100644 --- a/pkg/sync/sync_test.go +++ b/pkg/sync/sync_test.go @@ -3,16 +3,17 @@ package sync import ( "errors" + "github.com/google/uuid" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + gm "go.uber.org/mock/gomock" + "github.com/bakito/adguardhome-sync/pkg/client" "github.com/bakito/adguardhome-sync/pkg/client/model" clientmock "github.com/bakito/adguardhome-sync/pkg/mocks/client" "github.com/bakito/adguardhome-sync/pkg/types" "github.com/bakito/adguardhome-sync/pkg/utils" "github.com/bakito/adguardhome-sync/pkg/versions" - "github.com/google/uuid" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - gm "go.uber.org/mock/gomock" ) var _ = Describe("Sync", func() { diff --git a/pkg/types/features.go b/pkg/types/features.go index ed09f06..99adab6 100644 --- a/pkg/types/features.go +++ b/pkg/types/features.go @@ -25,7 +25,7 @@ func NewFeatures(enabled bool) Features { } } -// Features feature flags +// Features feature flags. type Features struct { DNS DNS `json:"dns" yaml:"dns"` DHCP DHCP `json:"dhcp" yaml:"dhcp"` @@ -38,20 +38,20 @@ type Features struct { Theme bool `json:"theme" yaml:"theme" env:"FEATURES_THEME"` } -// DHCP features +// DHCP features. type DHCP struct { - ServerConfig bool `json:"serverConfig" yaml:"serverConfig" env:"FEATURES_DHCP_SERVER_CONFIG"` - StaticLeases bool `json:"staticLeases" yaml:"staticLeases" env:"FEATURES_DHCP_STATIC_LEASES"` + ServerConfig bool `env:"FEATURES_DHCP_SERVER_CONFIG" json:"serverConfig" yaml:"serverConfig"` + StaticLeases bool `env:"FEATURES_DHCP_STATIC_LEASES" json:"staticLeases" yaml:"staticLeases"` } -// DNS features +// DNS features. type DNS struct { - AccessLists bool `json:"accessLists" yaml:"accessLists" env:"FEATURES_DNS_ACCESS_LISTS"` - ServerConfig bool `json:"serverConfig" yaml:"serverConfig" env:"FEATURES_DNS_SERVER_CONFIG"` - Rewrites bool `json:"rewrites" yaml:"rewrites" env:"FEATURES_DNS_REWRITES"` + AccessLists bool `env:"FEATURES_DNS_ACCESS_LISTS" json:"accessLists" yaml:"accessLists"` + ServerConfig bool `env:"FEATURES_DNS_SERVER_CONFIG" json:"serverConfig" yaml:"serverConfig"` + Rewrites bool `env:"FEATURES_DNS_REWRITES" json:"rewrites" yaml:"rewrites"` } -// LogDisabled log all disabled features +// LogDisabled log all disabled features. func (f *Features) LogDisabled(l *zap.SugaredLogger) { features := f.collectDisabled() diff --git a/pkg/types/types.go b/pkg/types/types.go index 764506c..8c5eadc 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -11,72 +11,72 @@ import ( ) const ( - // DefaultAPIPath default api path + // DefaultAPIPath default api path. DefaultAPIPath = "/control" ) // Config application configuration struct // +k8s:deepcopy-gen=true type Config struct { - Origin AdGuardInstance `json:"origin" yaml:"origin" env:"ORIGIN"` - Replica *AdGuardInstance `json:"replica,omitempty" yaml:"replica,omitempty" env:"REPLICA"` - Replicas []AdGuardInstance `json:"replicas,omitempty" yaml:"replicas,omitempty" faker:"slice_len=2"` - Cron string `json:"cron,omitempty" yaml:"cron,omitempty" env:"CRON"` - RunOnStart bool `json:"runOnStart,omitempty" yaml:"runOnStart,omitempty" env:"RUN_ON_START"` - PrintConfigOnly bool `json:"printConfigOnly,omitempty" yaml:"printConfigOnly,omitempty" env:"PRINT_CONFIG_ONLY"` - ContinueOnError bool `json:"continueOnError,omitempty" yaml:"continueOnError,omitempty" env:"CONTINUE_ON_ERROR"` - API API `json:"api,omitempty" yaml:"api,omitempty" env:"API"` - Features Features `json:"features,omitempty" yaml:"features,omitempty" env:"FEATURES_"` + Origin AdGuardInstance `env:"ORIGIN" json:"origin" yaml:"origin"` + Replica *AdGuardInstance `env:"REPLICA" json:"replica,omitempty" yaml:"replica,omitempty"` + Replicas []AdGuardInstance ` json:"replicas,omitempty" yaml:"replicas,omitempty" faker:"slice_len=2"` + Cron string `env:"CRON" json:"cron,omitempty" yaml:"cron,omitempty"` + RunOnStart bool `env:"RUN_ON_START" json:"runOnStart,omitempty" yaml:"runOnStart,omitempty"` + PrintConfigOnly bool `env:"PRINT_CONFIG_ONLY" json:"printConfigOnly,omitempty" yaml:"printConfigOnly,omitempty"` + ContinueOnError bool `env:"CONTINUE_ON_ERROR" json:"continueOnError,omitempty" yaml:"continueOnError,omitempty"` + API API `env:"API" json:"api,omitempty" yaml:"api,omitempty"` + Features Features `env:"FEATURES_" json:"features,omitempty" yaml:"features,omitempty"` } -// API configuration +// API configuration. type API struct { - Port int `json:"port,omitempty" yaml:"port,omitempty" env:"API_PORT"` - Username string `json:"username,omitempty" yaml:"username,omitempty" env:"API_USERNAME"` - Password string `json:"password,omitempty" yaml:"password,omitempty" env:"API_PASSWORD"` - DarkMode bool `json:"darkMode,omitempty" yaml:"darkMode,omitempty" env:"API_DARK_MODE"` - Metrics Metrics `json:"metrics,omitempty" yaml:"metrics,omitempty" env:"API_METRICS"` - TLS TLS `json:"tls,omitempty" yaml:"tls,omitempty" env:"API_TLS"` + Port int `env:"API_PORT" json:"port,omitempty" yaml:"port,omitempty"` + Username string `env:"API_USERNAME" json:"username,omitempty" yaml:"username,omitempty"` + Password string `env:"API_PASSWORD" json:"password,omitempty" yaml:"password,omitempty"` + DarkMode bool `env:"API_DARK_MODE" json:"darkMode,omitempty" yaml:"darkMode,omitempty"` + Metrics Metrics `env:"API_METRICS" json:"metrics,omitempty" yaml:"metrics,omitempty"` + TLS TLS `env:"API_TLS" json:"tls,omitempty" yaml:"tls,omitempty"` } -// Metrics configuration +// Metrics configuration. type Metrics struct { - Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty" env:"API_METRICS_ENABLED"` - ScrapeInterval time.Duration `json:"scrapeInterval,omitempty" yaml:"scrapeInterval,omitempty" env:"API_METRICS_SCRAPE_INTERVAL"` - QueryLogLimit int `json:"queryLogLimit,omitempty" yaml:"queryLogLimit,omitempty" env:"API_METRICS_QUERY_LOG_LIMIT"` + Enabled bool `env:"API_METRICS_ENABLED" json:"enabled,omitempty" yaml:"enabled,omitempty"` + ScrapeInterval time.Duration `env:"API_METRICS_SCRAPE_INTERVAL" json:"scrapeInterval,omitempty" yaml:"scrapeInterval,omitempty"` + QueryLogLimit int `env:"API_METRICS_QUERY_LOG_LIMIT" json:"queryLogLimit,omitempty" yaml:"queryLogLimit,omitempty"` } -// TLS configuration +// TLS configuration. type TLS struct { - CertDir string `json:"certDir,omitempty" yaml:"certDir,omitempty" env:"API_TLS_CERT_DIR"` - CertName string `json:"certName,omitempty" yaml:"certName,omitempty" env:"API_TLS_CERT_NAME"` - KeyName string `json:"keyName,omitempty" yaml:"keyName,omitempty" env:"API_TLS_KEY_NAME"` + CertDir string `env:"API_TLS_CERT_DIR" json:"certDir,omitempty" yaml:"certDir,omitempty"` + CertName string `env:"API_TLS_CERT_NAME" json:"certName,omitempty" yaml:"certName,omitempty"` + KeyName string `env:"API_TLS_KEY_NAME" json:"keyName,omitempty" yaml:"keyName,omitempty"` } func (t TLS) Enabled() bool { return strings.TrimSpace(t.CertDir) != "" } -func (t TLS) Certs() (cert string, key string) { +func (t TLS) Certs() (cert, key string) { cert = filepath.Join(t.CertDir, defaultIfEmpty(t.CertName, "tls.crt")) key = filepath.Join(t.CertDir, defaultIfEmpty(t.KeyName, "tls.key")) - return + return cert, key } -func defaultIfEmpty(val string, fallback string) string { +func defaultIfEmpty(val, fallback string) string { if strings.TrimSpace(val) == "" { return fallback } return val } -// Mask maks username and password +// Mask maks username and password. func (a *API) Mask() { a.Username = mask(a.Username) a.Password = mask(a.Password) } -// UniqueReplicas get unique replication instances +// UniqueReplicas get unique replication instances. func (cfg *Config) UniqueReplicas() []AdGuardInstance { dedup := make(map[string]AdGuardInstance) if cfg.Replica != nil && cfg.Replica.URL != "" { @@ -101,7 +101,7 @@ func (cfg *Config) UniqueReplicas() []AdGuardInstance { return r } -// Log the current config +// Log the current config. func (cfg *Config) Log(l *zap.SugaredLogger) { c := cfg.mask() l.With("config", c).Debug("Using config") @@ -140,27 +140,27 @@ func (cfg *Config) Init() error { // AdGuardInstance AdguardHome config instance // +k8s:deepcopy-gen=true type AdGuardInstance struct { - URL string `json:"url" yaml:"url" env:"URL" faker:"url"` - WebURL string `json:"webURL" yaml:"webURL" env:"WEB_URL" faker:"url"` - APIPath string `json:"apiPath,omitempty" yaml:"apiPath,omitempty" env:"API_PATH"` - Username string `json:"username,omitempty" yaml:"username,omitempty" env:"USERNAME"` - Password string `json:"password,omitempty" yaml:"password,omitempty" env:"PASSWORD"` - Cookie string `json:"cookie,omitempty" yaml:"cookie,omitempty" env:"COOKIE"` - InsecureSkipVerify bool `json:"insecureSkipVerify" yaml:"insecureSkipVerify" env:"INSECURE_SKIP_VERIFY"` - AutoSetup bool `json:"autoSetup" yaml:"autoSetup" env:"AUTO_SETUP"` - InterfaceName string `json:"interfaceName,omitempty" yaml:"interfaceName,omitempty" env:"INTERFACE_NAME"` - DHCPServerEnabled *bool `json:"dhcpServerEnabled,omitempty" yaml:"dhcpServerEnabled,omitempty" env:"DHCP_SERVER_ENABLED"` + URL string `env:"URL" faker:"url" json:"url" yaml:"url"` + WebURL string `env:"WEB_URL" faker:"url" json:"webURL" yaml:"webURL"` + APIPath string `env:"API_PATH" json:"apiPath,omitempty" yaml:"apiPath,omitempty"` + Username string `env:"USERNAME" json:"username,omitempty" yaml:"username,omitempty"` + Password string `env:"PASSWORD" json:"password,omitempty" yaml:"password,omitempty"` + Cookie string `env:"COOKIE" json:"cookie,omitempty" yaml:"cookie,omitempty"` + InsecureSkipVerify bool `env:"INSECURE_SKIP_VERIFY" json:"insecureSkipVerify" yaml:"insecureSkipVerify"` + AutoSetup bool `env:"AUTO_SETUP" json:"autoSetup" yaml:"autoSetup"` + InterfaceName string `env:"INTERFACE_NAME" json:"interfaceName,omitempty" yaml:"interfaceName,omitempty"` + DHCPServerEnabled *bool `env:"DHCP_SERVER_ENABLED" json:"dhcpServerEnabled,omitempty" yaml:"dhcpServerEnabled,omitempty"` Host string `json:"-" yaml:"-"` WebHost string `json:"-" yaml:"-"` } -// Key AdGuardInstance key +// Key AdGuardInstance key. func (i *AdGuardInstance) Key() string { return fmt.Sprintf("%s#%s", i.URL, i.APIPath) } -// Mask maks username and password +// Mask maks username and password. func (i *AdGuardInstance) Mask() { i.Username = mask(i.Username) i.Password = mask(i.Password) @@ -194,12 +194,12 @@ func mask(s string) string { return fmt.Sprintf("%v%s%v", string(s[0]), mask, string(s[len(s)-1])) } -// Protection API struct +// Protection API struct. type Protection struct { ProtectionEnabled bool `json:"protection_enabled"` } -// InstallConfig AdguardHome install config +// InstallConfig AdguardHome install config. type InstallConfig struct { Web InstallPort `json:"web"` DNS InstallPort `json:"dns"` @@ -207,7 +207,7 @@ type InstallConfig struct { Password string `json:"password"` } -// InstallPort AdguardHome install config port +// InstallPort AdguardHome install config port. type InstallPort struct { IP string `json:"ip"` Port int `json:"port"` diff --git a/pkg/utils/clone.go b/pkg/utils/clone.go index ae0c1a8..bb38e99 100644 --- a/pkg/utils/clone.go +++ b/pkg/utils/clone.go @@ -1,15 +1,18 @@ package utils -import "encoding/json" +import ( + "bytes" + "encoding/json" +) -func Clone[I interface{}](in I, out I) I { +func Clone[I any](in, out I) I { b, _ := json.Marshal(in) _ = json.Unmarshal(b, out) return out } -func JsonEquals(a interface{}, b interface{}) bool { +func JSONEquals(a, b any) bool { ja, _ := json.Marshal(a) jb, _ := json.Marshal(b) - return string(ja) == string(jb) + return bytes.Equal(ja, jb) } diff --git a/pkg/utils/ptr.go b/pkg/utils/ptr.go index 6bfd8c4..0bc6cc4 100644 --- a/pkg/utils/ptr.go +++ b/pkg/utils/ptr.go @@ -2,18 +2,18 @@ package utils import "fmt" -func Ptr[I interface{}](i I) *I { +func Ptr[I any](i I) *I { return &i } -func PtrToString[I interface{}](i *I) string { +func PtrToString[I any](i *I) string { if i == nil { return "" } return fmt.Sprintf("%v", i) } -func PtrEquals[I comparable](a *I, b *I) bool { +func PtrEquals[I comparable](a, b *I) bool { if a == nil && b == nil { return true } diff --git a/pkg/versions/versions.go b/pkg/versions/versions.go index d7978b6..5bbb9c0 100644 --- a/pkg/versions/versions.go +++ b/pkg/versions/versions.go @@ -3,15 +3,15 @@ package versions import "golang.org/x/mod/semver" const ( - // MinAgh minimal adguardhome version + // MinAgh minimal adguardhome version. MinAgh = "v0.107.40" ) -func IsNewerThan(v1 string, v2 string) bool { +func IsNewerThan(v1, v2 string) bool { return semver.Compare(sanitize(v1), sanitize(v2)) == 1 } -func IsSame(v1 string, v2 string) bool { +func IsSame(v1, v2 string) bool { return semver.Compare(sanitize(v1), sanitize(v2)) == 0 } diff --git a/pkg/versions/versions_test.go b/pkg/versions/versions_test.go index 1084010..495fe11 100644 --- a/pkg/versions/versions_test.go +++ b/pkg/versions/versions_test.go @@ -1,9 +1,10 @@ package versions_test import ( - "github.com/bakito/adguardhome-sync/pkg/versions" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + + "github.com/bakito/adguardhome-sync/pkg/versions" ) var _ = Describe("Versions", func() { diff --git a/version/version.go b/version/version.go index 5cce660..f18317c 100644 --- a/version/version.go +++ b/version/version.go @@ -1,8 +1,8 @@ package version var ( - // Version the module version + // Version the module version. Version = "devel" - // Build the build time + // Build the build time. Build = "N/A" )