Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32c728ccf8 | ||
|
|
327d67c9ef | ||
|
|
edd7f82351 | ||
|
|
012d43b950 | ||
|
|
e2298f6f1e | ||
|
|
18350f94a6 | ||
|
|
1a9d5df5cb | ||
|
|
8ef1eb8c2a | ||
|
|
7c2018acbc | ||
|
|
2079f6a3eb | ||
|
|
d9419446bf | ||
|
|
c0cbccb63c | ||
|
|
5444dda08a | ||
|
|
224617aae6 | ||
|
|
c941c8a100 | ||
|
|
07a25cd094 | ||
|
|
54d98c10fe |
16
.github/workflows/virustotal.yaml
vendored
Normal file
16
.github/workflows/virustotal.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: Scan GitHub Release with VirusTotal
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
jobs:
|
||||
scan_release:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Analyze Build Assets
|
||||
uses: bakito/virustotal-action@main
|
||||
with:
|
||||
release_name: ${{github.event.release.tag_name}}
|
||||
vt_api_key: ${{secrets.VT_API_KEY}}
|
||||
@@ -21,15 +21,15 @@ TB_SEMVER ?= $(TB_LOCALBIN)/semver
|
||||
|
||||
## Tool Versions
|
||||
# renovate: packageName=k8s.io/code-generator/cmd/deepcopy-gen
|
||||
TB_DEEPCOPY_GEN_VERSION ?= v0.32.2
|
||||
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.5
|
||||
TB_GOLANGCI_LINT_VERSION ?= v1.64.7
|
||||
# renovate: packageName=github.com/segmentio/golines
|
||||
TB_GOLINES_VERSION ?= v0.12.2
|
||||
# renovate: packageName=github.com/goreleaser/goreleaser/v2
|
||||
TB_GORELEASER_VERSION ?= v2.7.0
|
||||
TB_GORELEASER_VERSION ?= v2.8.0
|
||||
# renovate: packageName=go.uber.org/mock/mockgen
|
||||
TB_MOCKGEN_VERSION ?= v0.5.0
|
||||
# renovate: packageName=github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen
|
||||
|
||||
3
Makefile
3
Makefile
@@ -20,6 +20,9 @@ fmt: tb.golines tb.gofumpt
|
||||
# Run tests
|
||||
test: generate fmt lint test-ci
|
||||
|
||||
fuzz:
|
||||
go test -fuzz=FuzzMask -v ./pkg/types/ -fuzztime=60s
|
||||
|
||||
# Run ci tests
|
||||
test-ci: mocks tidy tb.ginkgo
|
||||
$(TB_GINKGO) --cover --coverprofile coverage.out.tmp ./...
|
||||
|
||||
@@ -245,6 +245,11 @@ services:
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### Unraid
|
||||
|
||||
Note when running the Docker container in Unraid please remove unneeded env variables if don't needed.
|
||||
If replica2 isn't used this can cause sync errors.
|
||||
|
||||
### Config file
|
||||
|
||||
location: $HOME/.adguardhome-sync.yaml
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
//go:embed print-config.md
|
||||
var printConfigTemplate string
|
||||
|
||||
func printConfig(cfg *types.Config, usedCfgFile string, cfgContent string) error {
|
||||
config, err := yaml.Marshal(cfg)
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
t, err := template.New("printConfigTemplate").Parse(printConfigTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
env := os.Environ()
|
||||
sort.Strings(env)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err = t.Execute(&buf, map[string]interface{}{
|
||||
"AggregatedConfig": string(config),
|
||||
"ConfigFilePath": usedCfgFile,
|
||||
"ConfigFileContent": cfgContent,
|
||||
"EnvironmentVariables": strings.Join(env, "\n"),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Infof(
|
||||
"Printing adguardhome-sync aggregated config (THE APPLICATION WILL NOT START IN THIS MODE):\n%s",
|
||||
buf.String(),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
<!-- PLEASE COPY THE FOLLOWING OUTPUT AS IS INTO THE GITHUB ISSUE (Don't forget to mask your usernames, passwords and IPs when using this in an issue ) -->
|
||||
|
||||
### AdGuardHome sync aggregated config
|
||||
|
||||
```yaml
|
||||
{{ .AggregatedConfig }}
|
||||
```
|
||||
{{- if .ConfigFilePath }}
|
||||
### AdGuardHome sync unmodified config file
|
||||
|
||||
Config file path: {{ .ConfigFilePath }}
|
||||
|
||||
```yaml
|
||||
{{ .ConfigFileContent }}
|
||||
```
|
||||
{{- end }}
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```ini
|
||||
{{ .EnvironmentVariables }}
|
||||
```
|
||||
|
||||
<!-- END OF GITHUB ISSUE CONTENT -->
|
||||
@@ -14,7 +14,7 @@ var doCmd = &cobra.Command{
|
||||
Long: `Synchronizes the configuration form an origin instance to a replica`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
logger = log.GetLogger("run")
|
||||
cfg, usedCfgFile, cfgContent, err := config.Get(cfgFile, cmd.Flags())
|
||||
cfg, err := config.Get(cfgFile, cmd.Flags())
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
return err
|
||||
@@ -25,9 +25,8 @@ var doCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.PrintConfigOnly {
|
||||
if err := printConfig(cfg, usedCfgFile, cfgContent); err != nil {
|
||||
|
||||
if cfg.PrintConfigOnly() {
|
||||
if err := cfg.Print(); err != nil {
|
||||
logger.Error(err)
|
||||
return err
|
||||
}
|
||||
@@ -35,7 +34,7 @@ var doCmd = &cobra.Command{
|
||||
return nil
|
||||
}
|
||||
|
||||
return sync.Sync(cfg)
|
||||
return sync.Sync(cfg.Get())
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
16
go.mod
16
go.mod
@@ -10,17 +10,17 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/oapi-codegen/runtime v1.1.1
|
||||
github.com/onsi/ginkgo/v2 v2.22.2
|
||||
github.com/onsi/ginkgo/v2 v2.23.0
|
||||
github.com/onsi/gomega v1.36.2
|
||||
github.com/prometheus/client_golang v1.21.0
|
||||
github.com/prometheus/client_golang v1.21.1
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
|
||||
github.com/spf13/cobra v1.9.1
|
||||
go.uber.org/mock v0.5.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/mod v0.23.0
|
||||
golang.org/x/mod v0.24.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.32.2
|
||||
k8s.io/apimachinery v0.32.3
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758
|
||||
)
|
||||
|
||||
@@ -64,11 +64,11 @@ require (
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/net v0.36.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
golang.org/x/tools v0.30.0 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
|
||||
32
go.sum
32
go.sum
@@ -95,8 +95,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
|
||||
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||
github.com/onsi/ginkgo/v2 v2.23.0 h1:FA1xjp8ieYDzlgS5ABTpdUDB7wtngggONc8a7ku2NqQ=
|
||||
github.com/onsi/ginkgo/v2 v2.23.0/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
|
||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
@@ -104,8 +104,8 @@ github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
|
||||
github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
|
||||
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
@@ -159,18 +159,18 @@ golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA=
|
||||
golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -179,8 +179,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
@@ -191,8 +191,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
||||
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
||||
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -207,8 +207,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/apimachinery v0.32.2 h1:yoQBR9ZGkA6Rgmhbp/yuT9/g+4lxtsGYwW6dR6BDPLQ=
|
||||
k8s.io/apimachinery v0.32.2/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
|
||||
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
|
||||
|
||||
@@ -53,6 +53,11 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
correctEntries(schema)
|
||||
|
||||
addFakeTags(schema)
|
||||
|
||||
b, err := yaml.Marshal(&schema)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
@@ -63,3 +68,26 @@ func main() {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func correctEntries(schema map[string]interface{}) {
|
||||
// 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`}
|
||||
if err := unstructured.SetNestedMap(schema, fake, "components", "schemas", "Stats", "properties", "blocked_filtering", "x-oapi-codegen-extra-tags"); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
if err := unstructured.SetNestedMap(schema, fake, "components", "schemas", "Stats", "properties", "dns_queries", "x-oapi-codegen-extra-tags"); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
if err := unstructured.SetNestedMap(schema, fake, "components", "schemas", "Stats", "properties", "replaced_parental", "x-oapi-codegen-extra-tags"); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
if err := unstructured.SetNestedMap(schema, fake, "components", "schemas", "Stats", "properties", "replaced_safebrowsing", "x-oapi-codegen-extra-tags"); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,15 @@ const (
|
||||
QueryLogConfigIntervalN90 QueryLogConfigInterval = 90
|
||||
)
|
||||
|
||||
// Defines values for QueryLogItemClientProto.
|
||||
const (
|
||||
Dnscrypt QueryLogItemClientProto = "dnscrypt"
|
||||
Doh QueryLogItemClientProto = "doh"
|
||||
Doq QueryLogItemClientProto = "doq"
|
||||
Dot QueryLogItemClientProto = "dot"
|
||||
Empty QueryLogItemClientProto = ""
|
||||
)
|
||||
|
||||
// Defines values for QueryLogItemReason.
|
||||
const (
|
||||
QueryLogItemReasonFilteredBlackList QueryLogItemReason = "FilteredBlackList"
|
||||
@@ -812,8 +821,8 @@ type QueryLogItem struct {
|
||||
ClientId *string `json:"client_id,omitempty"`
|
||||
|
||||
// ClientInfo Client information for a query log item.
|
||||
ClientInfo *QueryLogItemClient `json:"client_info,omitempty"`
|
||||
ClientProto *interface{} `json:"client_proto,omitempty"`
|
||||
ClientInfo *QueryLogItemClient `json:"client_info,omitempty"`
|
||||
ClientProto *QueryLogItemClientProto `json:"client_proto,omitempty"`
|
||||
|
||||
// Ecs The IP network defined by an EDNS Client-Subnet option in the request message if any.
|
||||
Ecs *string `json:"ecs,omitempty"`
|
||||
@@ -854,6 +863,9 @@ type QueryLogItem struct {
|
||||
Upstream *string `json:"upstream,omitempty"`
|
||||
}
|
||||
|
||||
// QueryLogItemClientProto defines model for QueryLogItem.ClientProto.
|
||||
type QueryLogItemClientProto string
|
||||
|
||||
// QueryLogItemReason Request filtering status.
|
||||
type QueryLogItemReason string
|
||||
|
||||
@@ -989,8 +1001,8 @@ type SetRulesRequest struct {
|
||||
type Stats struct {
|
||||
// AvgProcessingTime Average time in seconds on processing a DNS request
|
||||
AvgProcessingTime *float32 `json:"avg_processing_time,omitempty"`
|
||||
BlockedFiltering *[]int `json:"blocked_filtering,omitempty"`
|
||||
DnsQueries *[]int `json:"dns_queries,omitempty"`
|
||||
BlockedFiltering *[]int `faker:"slice_len=24" json:"blocked_filtering,omitempty"`
|
||||
DnsQueries *[]int `faker:"slice_len=24" json:"dns_queries,omitempty"`
|
||||
|
||||
// NumBlockedFiltering Number of requests blocked by filtering rules
|
||||
NumBlockedFiltering *int `json:"num_blocked_filtering,omitempty"`
|
||||
@@ -1006,8 +1018,8 @@ type Stats struct {
|
||||
|
||||
// NumReplacedSafesearch Number of requests blocked by safesearch module
|
||||
NumReplacedSafesearch *int `json:"num_replaced_safesearch,omitempty"`
|
||||
ReplacedParental *[]int `json:"replaced_parental,omitempty"`
|
||||
ReplacedSafebrowsing *[]int `json:"replaced_safebrowsing,omitempty"`
|
||||
ReplacedParental *[]int `faker:"slice_len=24" json:"replaced_parental,omitempty"`
|
||||
ReplacedSafebrowsing *[]int `faker:"slice_len=24" json:"replaced_safebrowsing,omitempty"`
|
||||
|
||||
// TimeUnits Time units
|
||||
TimeUnits *StatsTimeUnits `json:"time_units,omitempty"`
|
||||
|
||||
@@ -14,14 +14,32 @@ var (
|
||||
logger = log.GetLogger("config")
|
||||
)
|
||||
|
||||
func Get(configFile string, flags Flags) (*types.Config, string, string, error) {
|
||||
type AppConfig struct {
|
||||
cfg *types.Config
|
||||
filePath string
|
||||
content string
|
||||
}
|
||||
|
||||
func (ac *AppConfig) PrintConfigOnly() bool {
|
||||
return ac.cfg.PrintConfigOnly
|
||||
}
|
||||
|
||||
func (ac *AppConfig) Get() *types.Config {
|
||||
return ac.cfg
|
||||
}
|
||||
|
||||
func (ac *AppConfig) Init() error {
|
||||
return ac.cfg.Init()
|
||||
}
|
||||
|
||||
func Get(configFile string, flags Flags) (*AppConfig, error) {
|
||||
path, err := configFilePath(configFile)
|
||||
if err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = validateSchema(path); err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg := initialConfig()
|
||||
@@ -29,12 +47,12 @@ func Get(configFile string, flags Flags) (*types.Config, string, string, error)
|
||||
// read yaml config
|
||||
var content string
|
||||
if content, err = readFile(cfg, path); err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// overwrite from command flags
|
||||
if err := readFlags(cfg, flags); err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// *bool field creates issues when already not nil
|
||||
@@ -50,10 +68,10 @@ func Get(configFile string, flags Flags) (*types.Config, string, string, error)
|
||||
|
||||
// overwrite from env vars
|
||||
if err = env.Parse(cfg); err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, err
|
||||
}
|
||||
if err = env.ParseWithOptions(cfg.Replica, env.Options{Prefix: "REPLICA_"}); err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, err
|
||||
}
|
||||
// restore the replica
|
||||
cfg.Replicas = replicas
|
||||
@@ -64,7 +82,7 @@ func Get(configFile string, flags Flags) (*types.Config, string, string, error)
|
||||
}
|
||||
|
||||
if err = env.ParseWithOptions(&cfg.Origin, env.Options{Prefix: "ORIGIN_"}); err != nil {
|
||||
return nil, "", "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cfg.Replica != nil &&
|
||||
@@ -74,7 +92,7 @@ func Get(configFile string, flags Flags) (*types.Config, string, string, error)
|
||||
}
|
||||
|
||||
if len(cfg.Replicas) > 0 && cfg.Replica != nil {
|
||||
return nil, "", "", errors.New("mixed replica config in use. " +
|
||||
return nil, errors.New("mixed replica config in use. " +
|
||||
"Do not use single replica and numbered (list) replica config combined")
|
||||
}
|
||||
|
||||
@@ -87,7 +105,7 @@ func Get(configFile string, flags Flags) (*types.Config, string, string, error)
|
||||
|
||||
cfg.Replicas, err = enrichReplicasFromEnv(cfg.Replicas)
|
||||
|
||||
return cfg, path, content, err
|
||||
return &AppConfig{cfg: cfg, filePath: path, content: content}, err
|
||||
}
|
||||
|
||||
func initialConfig() *types.Config {
|
||||
|
||||
@@ -38,7 +38,7 @@ var _ = Describe("Config", func() {
|
||||
It("should have the origin URL from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
|
||||
_, _, _, err := config.Get("../../testdata/config_test_replicas_and_replica.yaml", flags)
|
||||
_, err := config.Get("../../testdata/config_test_replicas_and_replica.yaml", flags)
|
||||
Ω(err).Should(HaveOccurred())
|
||||
Ω(err.Error()).Should(ContainSubstring("mixed replica config in use"))
|
||||
})
|
||||
@@ -47,20 +47,18 @@ var _ = Describe("Config", func() {
|
||||
It("should have the origin URL from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
|
||||
cfg, path, content, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Origin.URL).Should(Equal("https://origin-file:443"))
|
||||
Ω(path).Should(Equal("../../testdata/config_test_replicas.yaml"))
|
||||
Ω(content).ShouldNot(BeEmpty())
|
||||
Ω(cfg.Get().Origin.URL).Should(Equal("https://origin-file:443"))
|
||||
})
|
||||
It("should have the origin URL from the config flags", func() {
|
||||
flags.EXPECT().Changed(config.FlagOriginURL).Return(true).AnyTimes()
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetString(config.FlagOriginURL).Return("https://origin-flag:443", nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Origin.URL).Should(Equal("https://origin-flag:443"))
|
||||
Ω(cfg.Get().Origin.URL).Should(Equal("https://origin-flag:443"))
|
||||
})
|
||||
It("should have the origin URL from the config env var", func() {
|
||||
setEnv("ORIGIN_URL", "https://origin-env:443")
|
||||
@@ -68,27 +66,27 @@ var _ = Describe("Config", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetString(config.FlagOriginURL).Return("https://origin-flag:443", nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Origin.URL).Should(Equal("https://origin-env:443"))
|
||||
Ω(cfg.Get().Origin.URL).Should(Equal("https://origin-env:443"))
|
||||
})
|
||||
})
|
||||
Context("Replica insecure skip verify", func() {
|
||||
It("should have the insecure skip verify from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].InsecureSkipVerify).Should(BeFalse())
|
||||
Ω(cfg.Get().Replicas[0].InsecureSkipVerify).Should(BeFalse())
|
||||
})
|
||||
It("should have the insecure skip verify from the config flags", func() {
|
||||
flags.EXPECT().Changed(config.FlagReplicaISV).Return(true).AnyTimes()
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetBool(config.FlagReplicaISV).Return(true, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].InsecureSkipVerify).Should(BeTrue())
|
||||
Ω(cfg.Get().Replicas[0].InsecureSkipVerify).Should(BeTrue())
|
||||
})
|
||||
It("should have the insecure skip verify from the config env var", func() {
|
||||
setEnv("REPLICA_INSECURE_SKIP_VERIFY", "false")
|
||||
@@ -96,9 +94,9 @@ var _ = Describe("Config", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetBool(config.FlagReplicaISV).Return(true, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].InsecureSkipVerify).Should(BeFalse())
|
||||
Ω(cfg.Get().Replicas[0].InsecureSkipVerify).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -106,34 +104,34 @@ var _ = Describe("Config", func() {
|
||||
It("should have the insecure skip verify from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].InsecureSkipVerify).Should(BeFalse())
|
||||
Ω(cfg.Get().Replicas[0].InsecureSkipVerify).Should(BeFalse())
|
||||
})
|
||||
It("should have the insecure skip verify from the config env var", func() {
|
||||
setEnv("REPLICA1_INSECURE_SKIP_VERIFY", "true")
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].InsecureSkipVerify).Should(BeTrue())
|
||||
Ω(cfg.Get().Replicas[0].InsecureSkipVerify).Should(BeTrue())
|
||||
})
|
||||
})
|
||||
Context("API Port", func() {
|
||||
It("should have the api port from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.API.Port).Should(Equal(9090))
|
||||
Ω(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(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.API.Port).Should(Equal(9990))
|
||||
Ω(cfg.Get().API.Port).Should(Equal(9990))
|
||||
})
|
||||
It("should have the api port from the config env var", func() {
|
||||
setEnv("API_PORT", "9999")
|
||||
@@ -141,9 +139,9 @@ var _ = Describe("Config", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.API.Port).Should(Equal(9999))
|
||||
Ω(cfg.Get().API.Port).Should(Equal(9999))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -151,10 +149,10 @@ var _ = Describe("Config", func() {
|
||||
It("should have the dhcp server enabled from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replica.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
Ω(cfg.Get().Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Get().Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -162,27 +160,27 @@ var _ = Describe("Config", func() {
|
||||
It("should have the dhcp server enabled from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
Ω(cfg.Get().Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Get().Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
Context("API Port", func() {
|
||||
It("should have the api port from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.API.Port).Should(Equal(9090))
|
||||
Ω(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(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.API.Port).Should(Equal(9990))
|
||||
Ω(cfg.Get().API.Port).Should(Equal(9990))
|
||||
})
|
||||
It("should have the api port from the config env var", func() {
|
||||
setEnv("API_PORT", "9999")
|
||||
@@ -190,27 +188,27 @@ var _ = Describe("Config", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetInt(config.FlagApiPort).Return(9990, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.API.Port).Should(Equal(9999))
|
||||
Ω(cfg.Get().API.Port).Should(Equal(9999))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Feature DNS Server Config", func() {
|
||||
It("should have the feature dns server config from the config file", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Features.DNS.ServerConfig).Should(BeFalse())
|
||||
Ω(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(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetBool(config.FlagFeatureDnsServerConfig).Return(true, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Features.DNS.ServerConfig).Should(BeTrue())
|
||||
Ω(cfg.Get().Features.DNS.ServerConfig).Should(BeTrue())
|
||||
})
|
||||
It("should have the feature dns server config from the config env var", func() {
|
||||
setEnv("FEATURES_DNS_SERVER_CONFIG", "false")
|
||||
@@ -218,9 +216,9 @@ var _ = Describe("Config", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetBool(config.FlagFeatureDnsServerConfig).Return(true, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Features.DNS.ServerConfig).Should(BeFalse())
|
||||
Ω(cfg.Get().Features.DNS.ServerConfig).Should(BeFalse())
|
||||
})
|
||||
It("should have the feature dns server config from the config DEPRECATED env var", func() {
|
||||
setEnv("FEATURES_DNS_SERVERCONFIG", "false")
|
||||
@@ -228,9 +226,9 @@ var _ = Describe("Config", func() {
|
||||
flags.EXPECT().Changed(gm.Any()).Return(false).AnyTimes()
|
||||
flags.EXPECT().GetBool(config.FlagFeatureDnsServerConfig).Return(true, nil).AnyTimes()
|
||||
|
||||
cfg, _, _, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
cfg, err := config.Get("../../testdata/config_test_replicas.yaml", flags)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Features.DNS.ServerConfig).Should(BeFalse())
|
||||
Ω(cfg.Get().Features.DNS.ServerConfig).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/config"
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
@@ -57,7 +56,7 @@ var _ = Describe("Config", func() {
|
||||
})
|
||||
Context("Get", func() {
|
||||
It("features should be false", func() {
|
||||
cfg, _, _, err := config.Get("", nil)
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, false)
|
||||
})
|
||||
@@ -76,12 +75,12 @@ var _ = Describe("Config", func() {
|
||||
})
|
||||
Context("Get", func() {
|
||||
It("features should be true by default", func() {
|
||||
cfg, _, _, err := config.Get("", nil)
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, true)
|
||||
})
|
||||
It("features should be true by default", func() {
|
||||
cfg, _, _, err := config.Get("", nil)
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, true)
|
||||
})
|
||||
@@ -89,7 +88,7 @@ var _ = Describe("Config", func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Setenv(envVar, "false")).ShouldNot(HaveOccurred())
|
||||
}
|
||||
cfg, _, _, err := config.Get("", nil)
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, false)
|
||||
})
|
||||
@@ -97,43 +96,43 @@ var _ = Describe("Config", func() {
|
||||
It("should set interface name of replica 1", func() {
|
||||
Ω(os.Setenv("REPLICA1_URL", "https://foo.bar")).ShouldNot(HaveOccurred())
|
||||
Ω(os.Setenv(fmt.Sprintf("REPLICA%s_INTERFACE_NAME", "1"), "eth0")).ShouldNot(HaveOccurred())
|
||||
cfg, _, _, err := config.Get("", nil)
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].InterfaceName).Should(Equal("eth0"))
|
||||
Ω(cfg.Get().Replicas[0].InterfaceName).Should(Equal("eth0"))
|
||||
})
|
||||
})
|
||||
Context("dhcp server", func() {
|
||||
It("should enable the dhcp server of replica 1", func() {
|
||||
Ω(os.Setenv("REPLICA1_URL", "https://foo.bar")).ShouldNot(HaveOccurred())
|
||||
Ω(os.Setenv(fmt.Sprintf("REPLICA%s_DHCPSERVERENABLED", "1"), "true")).ShouldNot(HaveOccurred())
|
||||
cfg, _, _, err := config.Get("", nil)
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Replicas[0].DHCPServerEnabled).Should(BeTrue())
|
||||
Ω(cfg.Get().Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Get().Replicas[0].DHCPServerEnabled).Should(BeTrue())
|
||||
})
|
||||
It("should disable the dhcp server of replica 1", func() {
|
||||
Ω(os.Setenv("REPLICA1_URL", "https://foo.bar")).ShouldNot(HaveOccurred())
|
||||
Ω(os.Setenv(fmt.Sprintf("REPLICA%s_DHCPSERVERENABLED", "1"), "false")).ShouldNot(HaveOccurred())
|
||||
cfg, _, _, err := config.Get("", nil)
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
Ω(cfg.Get().Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Get().Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func verifyFeatures(cfg *types.Config, value bool) {
|
||||
Ω(cfg.Features.GeneralSettings).Should(Equal(value))
|
||||
Ω(cfg.Features.QueryLogConfig).Should(Equal(value))
|
||||
Ω(cfg.Features.StatsConfig).Should(Equal(value))
|
||||
Ω(cfg.Features.ClientSettings).Should(Equal(value))
|
||||
Ω(cfg.Features.Services).Should(Equal(value))
|
||||
Ω(cfg.Features.Filters).Should(Equal(value))
|
||||
Ω(cfg.Features.DHCP.ServerConfig).Should(Equal(value))
|
||||
Ω(cfg.Features.DHCP.StaticLeases).Should(Equal(value))
|
||||
Ω(cfg.Features.DNS.ServerConfig).Should(Equal(value))
|
||||
Ω(cfg.Features.DNS.AccessLists).Should(Equal(value))
|
||||
Ω(cfg.Features.DNS.Rewrites).Should(Equal(value))
|
||||
func verifyFeatures(cfg *config.AppConfig, value bool) {
|
||||
Ω(cfg.Get().Features.GeneralSettings).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.QueryLogConfig).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.StatsConfig).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.ClientSettings).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.Services).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.Filters).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.DHCP.ServerConfig).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.DHCP.StaticLeases).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.DNS.ServerConfig).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.DNS.AccessLists).Should(Equal(value))
|
||||
Ω(cfg.Get().Features.DNS.Rewrites).Should(Equal(value))
|
||||
}
|
||||
|
||||
90
pkg/config/print-config.go
Normal file
90
pkg/config/print-config.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"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
|
||||
var printConfigTemplate string
|
||||
|
||||
func (ac *AppConfig) Print() error {
|
||||
originVersion := aghVersion(ac.cfg.Origin)
|
||||
var replicaVersions []string
|
||||
for _, replica := range ac.cfg.Replicas {
|
||||
replicaVersions = append(replicaVersions, aghVersion(replica))
|
||||
}
|
||||
|
||||
out, err := ac.print(os.Environ(), originVersion, replicaVersions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Infof(
|
||||
"Printing adguardhome-sync aggregated config (THE APPLICATION WILL NOT START IN THIS MODE):\n%s",
|
||||
out,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func aghVersion(i types.AdGuardInstance) string {
|
||||
cl, err := client.New(i)
|
||||
if err != nil {
|
||||
return "N/A"
|
||||
}
|
||||
stats, err := cl.Status()
|
||||
if err != nil {
|
||||
return "N/A"
|
||||
}
|
||||
return stats.Version
|
||||
}
|
||||
|
||||
func (ac *AppConfig) print(env []string, originVersion string, replicaVersions []string) (string, error) {
|
||||
config, err := yaml.Marshal(ac.Get())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
// The name "inc" is what the function will be called in the template text.
|
||||
"inc": func(i int) int {
|
||||
return i + 1
|
||||
},
|
||||
}
|
||||
|
||||
t, err := template.New("printConfigTemplate").Funcs(funcMap).Parse(printConfigTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sort.Strings(env)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
if err = t.Execute(&buf, map[string]interface{}{
|
||||
"Version": version.Version,
|
||||
"Build": version.Build,
|
||||
"OperatingSystem": runtime.GOOS,
|
||||
"Architecture": runtime.GOARCH,
|
||||
"AggregatedConfig": string(config),
|
||||
"ConfigFilePath": ac.filePath,
|
||||
"ConfigFileContent": ac.content,
|
||||
"EnvironmentVariables": strings.Join(env, "\n"),
|
||||
"OriginVersion": originVersion,
|
||||
"ReplicaVersions": replicaVersions,
|
||||
}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
36
pkg/config/print-config.md
Normal file
36
pkg/config/print-config.md
Normal file
@@ -0,0 +1,36 @@
|
||||
<!-- PLEASE COPY THE FOLLOWING OUTPUT AS IS INTO THE GITHUB ISSUE (Don't forget to mask your usernames, passwords, IPs and other sensitive information when using this in an issue ) -->
|
||||
|
||||
### Runtime
|
||||
|
||||
AdguardHome-Sync Version: {{ .Version }}
|
||||
Build: {{ .Build }}
|
||||
OperatingSystem: {{ .OperatingSystem }}
|
||||
Architecture: {{ .Architecture }}
|
||||
OriginVersion: {{ .OriginVersion }}
|
||||
ReplicaVersions:
|
||||
{{- range $i,$rep := .ReplicaVersions }}
|
||||
- Replica {{ inc $i }}: {{ $rep }}
|
||||
{{- end }}
|
||||
|
||||
### AdGuardHome sync aggregated config
|
||||
|
||||
```yaml
|
||||
{{ .AggregatedConfig }}
|
||||
```
|
||||
{{- if .ConfigFilePath }}
|
||||
### AdGuardHome sync unmodified config file
|
||||
|
||||
Config file path: {{ .ConfigFilePath }}
|
||||
|
||||
```yaml
|
||||
{{ .ConfigFileContent }}
|
||||
```
|
||||
{{- end }}
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```ini
|
||||
{{ .EnvironmentVariables }}
|
||||
```
|
||||
|
||||
<!-- END OF GITHUB ISSUE CONTENT -->
|
||||
58
pkg/config/print-config_test.go
Normal file
58
pkg/config/print-config_test.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"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"
|
||||
)
|
||||
|
||||
var _ = Describe("AppConfig", func() {
|
||||
var (
|
||||
ac *AppConfig
|
||||
env []string
|
||||
)
|
||||
BeforeEach(func() {
|
||||
ac = &AppConfig{
|
||||
cfg: &types.Config{
|
||||
Origin: types.AdGuardInstance{
|
||||
URL: "https://ha.xxxx.net:3000",
|
||||
},
|
||||
},
|
||||
content: `
|
||||
origin:
|
||||
url: https://ha.xxxx.net:3000
|
||||
`,
|
||||
}
|
||||
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"})
|
||||
Ω(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() {
|
||||
ac.filePath = "config.yaml"
|
||||
out, err := ac.print(env, "v0.0.1", []string{"v0.0.2"})
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(
|
||||
out,
|
||||
).Should(Equal(fmt.Sprintf(expected(2), version.Version, version.Build, runtime.GOOS, runtime.GOARCH)))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func expected(id int) string {
|
||||
b, err := os.ReadFile(filepath.Join("../../testdata/config", fmt.Sprintf("print-config_test_expected%d.md", id)))
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
return string(b)
|
||||
}
|
||||
@@ -155,8 +155,8 @@ func initMetric(name string, metric *prometheus.GaugeVec) {
|
||||
l.With("name", name).Info("New Prometheus metric registered")
|
||||
}
|
||||
|
||||
func Update(ims ...InstanceMetrics) {
|
||||
for _, im := range ims {
|
||||
func Update(iml InstanceMetricsList) {
|
||||
for _, im := range iml.Metrics {
|
||||
update(im)
|
||||
stats[im.HostName] = im.Stats
|
||||
}
|
||||
@@ -230,6 +230,10 @@ func update(im InstanceMetrics) {
|
||||
}
|
||||
}
|
||||
|
||||
type InstanceMetricsList struct {
|
||||
Metrics []InstanceMetrics `faker:"slice_len=5"`
|
||||
}
|
||||
|
||||
type InstanceMetrics struct {
|
||||
HostName string
|
||||
Status *model.ServerStatus
|
||||
@@ -255,7 +259,7 @@ func safeMetric[T int | float64 | float32](v *T) float64 {
|
||||
return float64(*v)
|
||||
}
|
||||
|
||||
func GetStats() OverallStats {
|
||||
func getStats() OverallStats {
|
||||
return stats.consolidate()
|
||||
}
|
||||
|
||||
|
||||
13
pkg/metrics/metrics_suite_test.go
Normal file
13
pkg/metrics/metrics_suite_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package metrics_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestSync(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Metrics Suite")
|
||||
}
|
||||
101
pkg/metrics/metrics_test.go
Normal file
101
pkg/metrics/metrics_test.go
Normal file
@@ -0,0 +1,101 @@
|
||||
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"
|
||||
)
|
||||
|
||||
var _ = Describe("Metrics", func() {
|
||||
BeforeEach(func() {
|
||||
stats = make(OverallStats)
|
||||
})
|
||||
Context("Update / getStats", func() {
|
||||
It("generate correct stats", func() {
|
||||
Update(InstanceMetricsList{[]InstanceMetrics{
|
||||
{HostName: "foo", Status: &model.ServerStatus{}, Stats: &model.Stats{
|
||||
NumDnsQueries: ptr.To(100),
|
||||
DnsQueries: ptr.To(
|
||||
[]int{10, 20, 30, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
),
|
||||
}},
|
||||
{HostName: "bar", Status: &model.ServerStatus{}, Stats: &model.Stats{
|
||||
NumDnsQueries: ptr.To(200),
|
||||
DnsQueries: ptr.To(
|
||||
[]int{20, 40, 60, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
),
|
||||
}},
|
||||
{HostName: "aaa", Status: &model.ServerStatus{}, Stats: &model.Stats{
|
||||
NumDnsQueries: ptr.To(300),
|
||||
DnsQueries: ptr.To(
|
||||
[]int{30, 60, 90, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
),
|
||||
}},
|
||||
}})
|
||||
Ω(stats).Should(HaveKey("foo"))
|
||||
Ω(stats["foo"].NumDnsQueries).Should(Equal(ptr.To(100)))
|
||||
Ω(stats).Should(HaveKey("bar"))
|
||||
Ω(stats["bar"].NumDnsQueries).Should(Equal(ptr.To(200)))
|
||||
Ω(stats).Should(HaveKey("aaa"))
|
||||
Ω(stats["aaa"].NumDnsQueries).Should(Equal(ptr.To(300)))
|
||||
|
||||
os := getStats()
|
||||
tot := os.Total()
|
||||
Ω(*tot.NumDnsQueries).Should(Equal(600))
|
||||
Ω(
|
||||
*tot.DnsQueries,
|
||||
).Should(Equal([]int{60, 120, 180, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}))
|
||||
|
||||
foo := os["foo"]
|
||||
bar := os["bar"]
|
||||
aaa := os["aaa"]
|
||||
|
||||
Ω(*foo.NumDnsQueries).Should(Equal(100))
|
||||
Ω(*bar.NumDnsQueries).Should(Equal(200))
|
||||
Ω(*aaa.NumDnsQueries).Should(Equal(300))
|
||||
Ω(
|
||||
*foo.DnsQueries,
|
||||
).Should(Equal([]int{10, 20, 30, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}))
|
||||
Ω(
|
||||
*bar.DnsQueries,
|
||||
).Should(Equal([]int{20, 40, 60, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}))
|
||||
Ω(
|
||||
*aaa.DnsQueries,
|
||||
).Should(Equal([]int{30, 60, 90, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}))
|
||||
})
|
||||
})
|
||||
Context("StatsGraph", func() {
|
||||
var metrics InstanceMetricsList
|
||||
BeforeEach(func() {
|
||||
err := faker.FakeData(&metrics)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
It("should provide correct results with faked values", func() {
|
||||
Update(metrics)
|
||||
|
||||
_, dns, blocked, malware, adult := StatsGraph()
|
||||
|
||||
verifyStats(dns)
|
||||
verifyStats(blocked)
|
||||
verifyStats(malware)
|
||||
verifyStats(adult)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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).Should(Equal(total.Data))
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
package sync
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/client/model"
|
||||
"github.com/bakito/adguardhome-sync/pkg/metrics"
|
||||
)
|
||||
|
||||
const labelTotal = "Total"
|
||||
|
||||
var (
|
||||
blue = []int{78, 141, 245}
|
||||
blueAlternatives = [][]int{
|
||||
@@ -46,8 +47,8 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func statsGraph() (*model.Stats, []line, []line, []line, []line) {
|
||||
s := metrics.GetStats()
|
||||
func StatsGraph() (*model.Stats, []line, []line, []line, []line) {
|
||||
s := getStats()
|
||||
t := s.Total()
|
||||
dns := graphLines(t, s, blue, blueAlternatives, func(s *model.Stats) []int {
|
||||
return safeStats(s.DnsQueries)
|
||||
@@ -74,7 +75,7 @@ func safeStats(stats *[]int) []int {
|
||||
|
||||
func graphLines(
|
||||
t *model.Stats,
|
||||
s metrics.OverallStats,
|
||||
s OverallStats,
|
||||
baseColor []int,
|
||||
altColors [][]int,
|
||||
dataCB func(s *model.Stats) []int,
|
||||
@@ -82,7 +83,7 @@ func graphLines(
|
||||
g := &graph{
|
||||
total: line{
|
||||
Fill: true,
|
||||
Title: "Total",
|
||||
Title: labelTotal,
|
||||
Data: dataCB(t),
|
||||
R: baseColor[0],
|
||||
G: baseColor[1],
|
||||
@@ -92,7 +93,7 @@ func graphLines(
|
||||
|
||||
var i int
|
||||
for name, data := range s {
|
||||
if name != metrics.StatsTotal {
|
||||
if name != StatsTotal {
|
||||
g.replicas = append(g.replicas, line{
|
||||
Fill: false,
|
||||
Title: name,
|
||||
@@ -33,7 +33,7 @@ func (w *worker) handleSync(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (w *worker) handleRoot(c *gin.Context) {
|
||||
total, dns, blocked, malware, adult := statsGraph()
|
||||
total, dns, blocked, malware, adult := metrics.StatsGraph()
|
||||
|
||||
c.HTML(http.StatusOK, "index.html", map[string]interface{}{
|
||||
"DarkMode": w.cfg.API.DarkMode,
|
||||
|
||||
@@ -26,13 +26,13 @@ func (w *worker) startScraping() {
|
||||
}
|
||||
|
||||
func (w *worker) scrape() {
|
||||
var ims []metrics.InstanceMetrics
|
||||
var iml metrics.InstanceMetricsList
|
||||
|
||||
ims = append(ims, w.getMetrics(w.cfg.Origin))
|
||||
iml.Metrics = append(iml.Metrics, w.getMetrics(w.cfg.Origin))
|
||||
for _, replica := range w.cfg.Replicas {
|
||||
ims = append(ims, w.getMetrics(replica))
|
||||
iml.Metrics = append(iml.Metrics, w.getMetrics(replica))
|
||||
}
|
||||
metrics.Update(ims...)
|
||||
metrics.Update(iml)
|
||||
}
|
||||
|
||||
func (w *worker) getMetrics(inst types.AdGuardInstance) (im metrics.InstanceMetrics) {
|
||||
|
||||
@@ -187,8 +187,8 @@ func (i *AdGuardInstance) Init() error {
|
||||
}
|
||||
|
||||
func mask(s string) string {
|
||||
if s == "" {
|
||||
return "***"
|
||||
if len(s) < 3 {
|
||||
return strings.Repeat("*", len(s))
|
||||
}
|
||||
mask := strings.Repeat("*", len(s)-2)
|
||||
return fmt.Sprintf("%v%s%v", string(s[0]), mask, string(s[len(s)-1]))
|
||||
|
||||
15
pkg/types/types_fuzz_test.go
Normal file
15
pkg/types/types_fuzz_test.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func FuzzMask(f *testing.F) {
|
||||
testcases := []string{"", "a", "ab", "abc", "abcd"}
|
||||
for _, tc := range testcases {
|
||||
f.Add(tc)
|
||||
}
|
||||
f.Fuzz(func(t *testing.T, value string) {
|
||||
_ = mask(value)
|
||||
})
|
||||
}
|
||||
@@ -83,6 +83,15 @@ var _ = Describe("Types", func() {
|
||||
Ω(masked.API.Password).Should(Equal("p**s"))
|
||||
})
|
||||
})
|
||||
DescribeTable("mask should work correctly",
|
||||
func(value, expected string) {
|
||||
Ω(mask(value)).Should(Equal(expected))
|
||||
},
|
||||
Entry(`Empty password`, "", ""),
|
||||
Entry(`1 char password`, "a", "*"),
|
||||
Entry(`2 char password`, "ab", "**"),
|
||||
Entry(`3 char password`, "abc", "a*c"),
|
||||
)
|
||||
})
|
||||
Context("Feature", func() {
|
||||
Context("LogDisabled", func() {
|
||||
|
||||
31
testdata/config/print-config_test_expected1.md
vendored
Normal file
31
testdata/config/print-config_test_expected1.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
<!-- PLEASE COPY THE FOLLOWING OUTPUT AS IS INTO THE GITHUB ISSUE (Don't forget to mask your usernames, passwords, IPs and other sensitive information when using this in an issue ) -->
|
||||
|
||||
### Runtime
|
||||
|
||||
AdguardHome-Sync Version: %s
|
||||
Build: %s
|
||||
OperatingSystem: %s
|
||||
Architecture: %s
|
||||
OriginVersion: v0.0.1
|
||||
ReplicaVersions:
|
||||
- Replica 1: v0.0.2
|
||||
|
||||
### AdGuardHome sync aggregated config
|
||||
|
||||
```yaml
|
||||
origin:
|
||||
url: https://ha.xxxx.net:3000
|
||||
webURL: ""
|
||||
insecureSkipVerify: false
|
||||
autoSetup: false
|
||||
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```ini
|
||||
BAR=bar
|
||||
FOO=foo
|
||||
```
|
||||
|
||||
<!-- END OF GITHUB ISSUE CONTENT -->
|
||||
41
testdata/config/print-config_test_expected2.md
vendored
Normal file
41
testdata/config/print-config_test_expected2.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<!-- PLEASE COPY THE FOLLOWING OUTPUT AS IS INTO THE GITHUB ISSUE (Don't forget to mask your usernames, passwords, IPs and other sensitive information when using this in an issue ) -->
|
||||
|
||||
### Runtime
|
||||
|
||||
AdguardHome-Sync Version: %s
|
||||
Build: %s
|
||||
OperatingSystem: %s
|
||||
Architecture: %s
|
||||
OriginVersion: v0.0.1
|
||||
ReplicaVersions:
|
||||
- Replica 1: v0.0.2
|
||||
|
||||
### AdGuardHome sync aggregated config
|
||||
|
||||
```yaml
|
||||
origin:
|
||||
url: https://ha.xxxx.net:3000
|
||||
webURL: ""
|
||||
insecureSkipVerify: false
|
||||
autoSetup: false
|
||||
|
||||
```
|
||||
### AdGuardHome sync unmodified config file
|
||||
|
||||
Config file path: config.yaml
|
||||
|
||||
```yaml
|
||||
|
||||
origin:
|
||||
url: https://ha.xxxx.net:3000
|
||||
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```ini
|
||||
BAR=bar
|
||||
FOO=foo
|
||||
```
|
||||
|
||||
<!-- END OF GITHUB ISSUE CONTENT -->
|
||||
Reference in New Issue
Block a user