Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2244fb6666 | ||
|
|
d76a633ceb | ||
|
|
91682b1867 | ||
|
|
a56663cf73 | ||
|
|
22439e0de1 | ||
|
|
81ea4311bd | ||
|
|
2d9df306a8 | ||
|
|
b6c6c0d87a | ||
|
|
afee473692 | ||
|
|
dde2356599 | ||
|
|
c4557f71e5 | ||
|
|
35159a4f64 | ||
|
|
053a9890e2 | ||
|
|
6c9489e80e | ||
|
|
cd82169016 | ||
|
|
6f498aedc6 | ||
|
|
57f8938ccc | ||
|
|
25e7aeeecb | ||
|
|
b77248d82d | ||
|
|
85f996c516 | ||
|
|
0d04d693aa | ||
|
|
e5f5321f45 | ||
|
|
8b4e78b148 | ||
|
|
d306fba8e2 | ||
|
|
5648639607 | ||
|
|
35c1af2cea | ||
|
|
2be15795e5 | ||
|
|
2fe94ec964 | ||
|
|
e0c00c3ccb | ||
|
|
a90113f470 | ||
|
|
46ec505fd9 | ||
|
|
5a47f8857d | ||
|
|
05485821c0 | ||
|
|
3cce67b220 | ||
|
|
0429d86f40 | ||
|
|
731d92e9d8 | ||
|
|
7f99704566 | ||
|
|
5acd3beff5 | ||
|
|
e10830434b | ||
|
|
c7a1d5dcef | ||
|
|
7b4c342631 | ||
|
|
700dbd2d63 | ||
|
|
f5c9e822a7 | ||
|
|
fb5afb2505 | ||
|
|
2882785b9b | ||
|
|
7d9edf4fa0 | ||
|
|
bc70795769 | ||
|
|
ea92d376c7 | ||
|
|
16e97cd9b2 | ||
|
|
20fe83745f | ||
|
|
961cf4dbb5 | ||
|
|
81d1bbf27b | ||
|
|
0fe6bb3a0b | ||
|
|
847a38fe1c | ||
|
|
1db6a5a4e0 | ||
|
|
6388eec95f | ||
|
|
31ac480737 | ||
|
|
6877b58b02 | ||
|
|
d212045058 | ||
|
|
83f34fb377 | ||
|
|
f1a943491a | ||
|
|
75d9724db6 | ||
|
|
531d63d04f | ||
|
|
84999be6fc | ||
|
|
190ccdad8a | ||
|
|
49054242f8 | ||
|
|
930684ffc2 | ||
|
|
3fac1d2ced | ||
|
|
c85579ce4a | ||
|
|
d0dd73220d | ||
|
|
80f4436d98 | ||
|
|
fecc60cfca | ||
|
|
b3d052db80 | ||
|
|
9cd88a0b47 | ||
|
|
56eb522ea5 | ||
|
|
e6feaddc15 | ||
|
|
70ae93f73a | ||
|
|
c3d6e696a1 | ||
|
|
89f2a1eb82 | ||
|
|
307b050579 | ||
|
|
caddf2a029 | ||
|
|
20ff0192d5 | ||
|
|
7d8cfbaeed | ||
|
|
b07101c97a | ||
|
|
447bfb24a9 | ||
|
|
4fff8f4302 | ||
|
|
04bd12d7dd | ||
|
|
4e33a88163 |
4
.github/workflows/codeql-analysis.yml
vendored
4
.github/workflows/codeql-analysis.yml
vendored
@@ -42,11 +42,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
|
||||
|
||||
2
.github/workflows/docker-images.yml
vendored
2
.github/workflows/docker-images.yml
vendored
@@ -45,7 +45,7 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Modify Dockerfile
|
||||
run: |
|
||||
|
||||
2
.github/workflows/e2e.yaml
vendored
2
.github/workflows/e2e.yaml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
protocol: http
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup jq
|
||||
uses: dcarbone/install-jq-action@v3
|
||||
|
||||
31
.github/workflows/go.yml
vendored
31
.github/workflows/go.yml
vendored
@@ -15,13 +15,19 @@ jobs:
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
|
||||
- name: Cache toolbox binaries
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/bin
|
||||
key: ${{ runner.os }}-${{ github.job }}-tools-${{ hashFiles('.toolbox.mk') }}
|
||||
|
||||
- name: Lint
|
||||
run: make lint
|
||||
|
||||
@@ -31,17 +37,22 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
|
||||
- name: Cache toolbox binaries
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/bin
|
||||
key: ${{ runner.os }}-${{ github.job }}-tools-${{ hashFiles('.toolbox.mk') }}
|
||||
|
||||
- name: Model
|
||||
run: make model
|
||||
|
||||
@@ -61,12 +72,18 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version-file: "go.mod"
|
||||
|
||||
- name: Cache toolbox binaries
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/bin
|
||||
key: ${{ runner.os }}-${{ github.job }}-tools-${{ hashFiles('.toolbox.mk') }}
|
||||
|
||||
- name: Run GoReleaser
|
||||
run: make test-release
|
||||
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue has been inactive for 60 days. If the issue is still relevant please comment to re-activate the issue. If no action is taken within 7 days, the issue will be marked closed.'
|
||||
|
||||
@@ -164,6 +164,10 @@ linters:
|
||||
disabled: true
|
||||
- name: var-naming
|
||||
disabled: true
|
||||
- name: enforce-switch-style
|
||||
disabled: true
|
||||
- name: blank-imports
|
||||
disabled: true
|
||||
staticcheck:
|
||||
checks:
|
||||
- 'all'
|
||||
|
||||
@@ -10,11 +10,13 @@ builds:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
- openbsd
|
||||
goarch:
|
||||
- 386
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
- riscv64
|
||||
goarm:
|
||||
- 5
|
||||
- 6
|
||||
@@ -24,14 +26,22 @@ builds:
|
||||
goarch: arm
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
- goos: darwin
|
||||
goarch: riscv64
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
- goos: windows
|
||||
goarch: riscv64
|
||||
- goos: openbsd
|
||||
goarch: 386
|
||||
- goos: openbsd
|
||||
goarch: arm
|
||||
hooks:
|
||||
post:
|
||||
# don't upx windows binaries as they make trouble with virus scanners
|
||||
- bash -c 'if [[ "{{ .Path }}" != *.exe ]] && [[ "{{ .Path }}" != *darwin* ]]; then upx {{ .Path }}; fi'
|
||||
- bash -c 'if [[ "{{ .Path }}" != *.exe ]] && [[ "{{ .Path }}" != *darwin* ]] && [[ "{{ .Path }}" != *openbsd* ]] && [[ "{{ .Path }}" != *riscv* ]]; then upx {{ .Path }}; fi'
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
@@ -45,3 +55,5 @@ changelog:
|
||||
- '^chore'
|
||||
release:
|
||||
prerelease: auto
|
||||
sboms:
|
||||
- artifacts: archive
|
||||
|
||||
114
.toolbox.mk
114
.toolbox.mk
@@ -8,97 +8,95 @@ TB_LOCALBIN ?= $(TB_LOCALDIR)/bin
|
||||
$(TB_LOCALBIN):
|
||||
if [ ! -e $(TB_LOCALBIN) ]; then mkdir -p $(TB_LOCALBIN); fi
|
||||
|
||||
# Helper functions
|
||||
STRIP_V = $(patsubst v%,%,$(1))
|
||||
|
||||
## Tool Binaries
|
||||
TB_CONTROLLER_GEN ?= $(TB_LOCALBIN)/controller-gen
|
||||
TB_GINKGO ?= $(TB_LOCALBIN)/ginkgo
|
||||
TB_GOFUMPT ?= $(TB_LOCALBIN)/gofumpt
|
||||
TB_GOLANGCI_LINT ?= $(TB_LOCALBIN)/golangci-lint
|
||||
TB_GOLINES ?= $(TB_LOCALBIN)/golines
|
||||
TB_GORELEASER ?= $(TB_LOCALBIN)/goreleaser
|
||||
TB_MOCKGEN ?= $(TB_LOCALBIN)/mockgen
|
||||
TB_OAPI_CODEGEN ?= $(TB_LOCALBIN)/oapi-codegen
|
||||
TB_SEMVER ?= $(TB_LOCALBIN)/semver
|
||||
TB_SYFT ?= $(TB_LOCALBIN)/syft
|
||||
|
||||
## Tool Versions
|
||||
# renovate: packageName=sigs.k8s.io/controller-tools/cmd/controller-gen
|
||||
TB_CONTROLLER_GEN_VERSION ?= v0.18.0
|
||||
# renovate: packageName=mvdan.cc/gofumpt
|
||||
TB_GOFUMPT_VERSION ?= v0.8.0
|
||||
# renovate: packageName=github.com/kubernetes-sigs/controller-tools
|
||||
TB_CONTROLLER_GEN_VERSION ?= v0.19.0
|
||||
# renovate: packageName=github.com/golangci/golangci-lint/v2
|
||||
TB_GOLANGCI_LINT_VERSION ?= v2.2.2
|
||||
# renovate: packageName=github.com/segmentio/golines
|
||||
TB_GOLINES_VERSION ?= v0.12.2
|
||||
TB_GOLANGCI_LINT_VERSION ?= v2.6.2
|
||||
TB_GOLANGCI_LINT_VERSION_NUM ?= $(call STRIP_V,$(TB_GOLANGCI_LINT_VERSION))
|
||||
# renovate: packageName=github.com/goreleaser/goreleaser/v2
|
||||
TB_GORELEASER_VERSION ?= v2.11.0
|
||||
# renovate: packageName=go.uber.org/mock/mockgen
|
||||
TB_MOCKGEN_VERSION ?= v0.5.2
|
||||
TB_GORELEASER_VERSION ?= v2.13.0
|
||||
TB_GORELEASER_VERSION_NUM ?= $(call STRIP_V,$(TB_GORELEASER_VERSION))
|
||||
# renovate: packageName=github.com/uber-go/mock
|
||||
TB_MOCKGEN_VERSION ?= v0.6.0
|
||||
# renovate: packageName=github.com/oapi-codegen/oapi-codegen/v2
|
||||
TB_OAPI_CODEGEN_VERSION ?= v2.4.1
|
||||
TB_OAPI_CODEGEN_VERSION ?= v2.5.1
|
||||
# renovate: packageName=github.com/bakito/semver
|
||||
TB_SEMVER_VERSION ?= v1.1.3
|
||||
TB_SEMVER_VERSION ?= v1.1.7
|
||||
TB_SEMVER_VERSION_NUM ?= $(call STRIP_V,$(TB_SEMVER_VERSION))
|
||||
# renovate: packageName=github.com/anchore/syft/cmd/syft
|
||||
TB_SYFT_VERSION ?= v1.38.0
|
||||
TB_SYFT_VERSION_NUM ?= $(call STRIP_V,$(TB_SYFT_VERSION))
|
||||
|
||||
## Tool Installer
|
||||
.PHONY: tb.controller-gen
|
||||
tb.controller-gen: $(TB_CONTROLLER_GEN) ## Download controller-gen locally if necessary.
|
||||
$(TB_CONTROLLER_GEN): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/controller-gen || GOBIN=$(TB_LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(TB_CONTROLLER_GEN_VERSION)
|
||||
tb.controller-gen: ## Download controller-gen locally if necessary.
|
||||
@test -s $(TB_CONTROLLER_GEN) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(TB_CONTROLLER_GEN_VERSION)
|
||||
.PHONY: tb.ginkgo
|
||||
tb.ginkgo: $(TB_GINKGO) ## Download ginkgo locally if necessary.
|
||||
$(TB_GINKGO): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/ginkgo || GOBIN=$(TB_LOCALBIN) go install github.com/onsi/ginkgo/v2/ginkgo
|
||||
.PHONY: tb.gofumpt
|
||||
tb.gofumpt: $(TB_GOFUMPT) ## Download gofumpt locally if necessary.
|
||||
$(TB_GOFUMPT): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/gofumpt || GOBIN=$(TB_LOCALBIN) go install mvdan.cc/gofumpt@$(TB_GOFUMPT_VERSION)
|
||||
tb.ginkgo: ## Download ginkgo locally if necessary.
|
||||
@test -s $(TB_GINKGO) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install github.com/onsi/ginkgo/v2/ginkgo
|
||||
.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/v2/cmd/golangci-lint@$(TB_GOLANGCI_LINT_VERSION)
|
||||
.PHONY: tb.golines
|
||||
tb.golines: $(TB_GOLINES) ## Download golines locally if necessary.
|
||||
$(TB_GOLINES): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/golines || GOBIN=$(TB_LOCALBIN) go install github.com/segmentio/golines@$(TB_GOLINES_VERSION)
|
||||
tb.golangci-lint: ## Download golangci-lint locally if necessary.
|
||||
@test -s $(TB_GOLANGCI_LINT) && $(TB_GOLANGCI_LINT) --version | grep -q $(TB_GOLANGCI_LINT_VERSION_NUM) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(TB_GOLANGCI_LINT_VERSION)
|
||||
.PHONY: tb.goreleaser
|
||||
tb.goreleaser: $(TB_GORELEASER) ## Download goreleaser locally if necessary.
|
||||
$(TB_GORELEASER): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/goreleaser || GOBIN=$(TB_LOCALBIN) go install github.com/goreleaser/goreleaser/v2@$(TB_GORELEASER_VERSION)
|
||||
tb.goreleaser: ## Download goreleaser locally if necessary.
|
||||
@test -s $(TB_GORELEASER) && $(TB_GORELEASER) --version | grep -q $(TB_GORELEASER_VERSION_NUM) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install github.com/goreleaser/goreleaser/v2@$(TB_GORELEASER_VERSION)
|
||||
.PHONY: tb.mockgen
|
||||
tb.mockgen: $(TB_MOCKGEN) ## Download mockgen locally if necessary.
|
||||
$(TB_MOCKGEN): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/mockgen || GOBIN=$(TB_LOCALBIN) go install go.uber.org/mock/mockgen@$(TB_MOCKGEN_VERSION)
|
||||
tb.mockgen: ## Download mockgen locally if necessary.
|
||||
@test -s $(TB_MOCKGEN) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install go.uber.org/mock/mockgen@$(TB_MOCKGEN_VERSION)
|
||||
.PHONY: tb.oapi-codegen
|
||||
tb.oapi-codegen: $(TB_OAPI_CODEGEN) ## Download oapi-codegen locally if necessary.
|
||||
$(TB_OAPI_CODEGEN): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/oapi-codegen || GOBIN=$(TB_LOCALBIN) go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@$(TB_OAPI_CODEGEN_VERSION)
|
||||
tb.oapi-codegen: ## Download oapi-codegen locally if necessary.
|
||||
@test -s $(TB_OAPI_CODEGEN) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@$(TB_OAPI_CODEGEN_VERSION)
|
||||
.PHONY: tb.semver
|
||||
tb.semver: $(TB_SEMVER) ## Download semver locally if necessary.
|
||||
$(TB_SEMVER): $(TB_LOCALBIN)
|
||||
test -s $(TB_LOCALBIN)/semver || GOBIN=$(TB_LOCALBIN) go install github.com/bakito/semver@$(TB_SEMVER_VERSION)
|
||||
tb.semver: ## Download semver locally if necessary.
|
||||
@test -s $(TB_SEMVER) && $(TB_SEMVER) -version | grep -q $(TB_SEMVER_VERSION_NUM) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install github.com/bakito/semver@$(TB_SEMVER_VERSION)
|
||||
.PHONY: tb.syft
|
||||
tb.syft: ## Download syft locally if necessary.
|
||||
@test -s $(TB_SYFT) && $(TB_SYFT) --version | grep -q $(TB_SYFT_VERSION_NUM) || \
|
||||
GOBIN=$(TB_LOCALBIN) go install github.com/anchore/syft/cmd/syft@$(TB_SYFT_VERSION)
|
||||
|
||||
## Reset Tools
|
||||
.PHONY: tb.reset
|
||||
tb.reset:
|
||||
@rm -f \
|
||||
$(TB_LOCALBIN)/controller-gen \
|
||||
$(TB_LOCALBIN)/ginkgo \
|
||||
$(TB_LOCALBIN)/gofumpt \
|
||||
$(TB_LOCALBIN)/golangci-lint \
|
||||
$(TB_LOCALBIN)/golines \
|
||||
$(TB_LOCALBIN)/goreleaser \
|
||||
$(TB_LOCALBIN)/mockgen \
|
||||
$(TB_LOCALBIN)/oapi-codegen \
|
||||
$(TB_LOCALBIN)/semver
|
||||
$(TB_CONTROLLER_GEN) \
|
||||
$(TB_GINKGO) \
|
||||
$(TB_GOLANGCI_LINT) \
|
||||
$(TB_GORELEASER) \
|
||||
$(TB_MOCKGEN) \
|
||||
$(TB_OAPI_CODEGEN) \
|
||||
$(TB_SEMVER) \
|
||||
$(TB_SYFT)
|
||||
|
||||
## Update Tools
|
||||
.PHONY: tb.update
|
||||
tb.update: tb.reset
|
||||
toolbox makefile --renovate -f $(TB_LOCALDIR)/Makefile \
|
||||
sigs.k8s.io/controller-tools/cmd/controller-gen@github.com/kubernetes-sigs/controller-tools \
|
||||
mvdan.cc/gofumpt@github.com/mvdan/gofumpt \
|
||||
github.com/golangci/golangci-lint/v2/cmd/golangci-lint \
|
||||
github.com/segmentio/golines \
|
||||
github.com/goreleaser/goreleaser/v2 \
|
||||
github.com/golangci/golangci-lint/v2/cmd/golangci-lint?--version \
|
||||
github.com/goreleaser/goreleaser/v2?--version \
|
||||
go.uber.org/mock/mockgen@github.com/uber-go/mock \
|
||||
github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen \
|
||||
github.com/bakito/semver
|
||||
## toolbox - end
|
||||
github.com/bakito/semver?-version \
|
||||
github.com/anchore/syft/cmd/syft?--version
|
||||
## toolbox - end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.24-alpine AS builder
|
||||
FROM golang:1.25-alpine AS builder
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
|
||||
33
Makefile
33
Makefile
@@ -13,16 +13,17 @@ generate: model mocks deepcopy-gen
|
||||
deepcopy-gen: tb.controller-gen
|
||||
@mkdir -p ./tmp
|
||||
@touch ./tmp/deepcopy-gen-boilerplate.go.txt
|
||||
$(TB_CONTROLLER_GEN) paths=./pkg/types object
|
||||
$(TB_CONTROLLER_GEN) paths=./internal/types object
|
||||
|
||||
fmt: tb.golines tb.gofumpt
|
||||
$(TB_GOLINES) --base-formatter="$(TB_GOFUMPT)" --max-len=120 --write-output .
|
||||
.PHONY: docs
|
||||
docs:
|
||||
go run cmd/docs/main.go
|
||||
|
||||
# Run tests
|
||||
test: generate fmt lint test-ci
|
||||
test: generate lint test-ci
|
||||
|
||||
fuzz:
|
||||
go test -fuzz=FuzzMask -v ./pkg/types/ -fuzztime=60s
|
||||
go test -fuzz=FuzzMask -v ./internal/types/ -fuzztime=60s
|
||||
|
||||
# Run ci tests
|
||||
test-ci: mocks tidy tb.ginkgo
|
||||
@@ -31,16 +32,16 @@ test-ci: mocks tidy tb.ginkgo
|
||||
go tool cover -func=coverage.out
|
||||
|
||||
mocks: tb.mockgen
|
||||
$(TB_MOCKGEN) -package client -destination pkg/mocks/client/mock.go github.com/bakito/adguardhome-sync/pkg/client Client
|
||||
$(TB_MOCKGEN) -package client -destination pkg/mocks/flags/mock.go github.com/bakito/adguardhome-sync/pkg/config Flags
|
||||
$(TB_MOCKGEN) -package client -destination internal/mocks/client/mock.go github.com/bakito/adguardhome-sync/internal/client Client
|
||||
$(TB_MOCKGEN) -package client -destination internal/mocks/flags/mock.go github.com/bakito/adguardhome-sync/internal/config Flags
|
||||
|
||||
release: tb.semver tb.goreleaser
|
||||
release: tb.semver tb.goreleaser tb.syft
|
||||
@version=$$($(TB_SEMVER)); \
|
||||
git tag -s $$version -m"Release $$version"
|
||||
$(TB_GORELEASER) --clean
|
||||
PATH=$(TB_LOCALBIN):$${PATH} $(TB_GORELEASER) --clean --parallelism 2
|
||||
|
||||
test-release: tb.goreleaser
|
||||
$(TB_GORELEASER) --skip=publish --snapshot --clean
|
||||
test-release: tb.goreleaser tb.syft
|
||||
PATH=$(TB_LOCALBIN):$${PATH} $(TB_GORELEASER) --skip=publish --snapshot --clean --parallelism 2
|
||||
|
||||
start-replica:
|
||||
docker rm -f adguardhome-replica
|
||||
@@ -74,16 +75,16 @@ kind-test:
|
||||
@./testdata/e2e/bin/install-chart.sh
|
||||
|
||||
# renovate: packageName=AdguardTeam/AdGuardHome
|
||||
ADGUARD_HOME_VERSION ?= v0.107.63
|
||||
ADGUARD_HOME_VERSION ?= v0.107.69
|
||||
|
||||
model: tb.oapi-codegen
|
||||
@mkdir -p tmp
|
||||
go run openapi/main.go $(ADGUARD_HOME_VERSION)
|
||||
$(TB_OAPI_CODEGEN) -package model -generate types,client -config .oapi-codegen.yaml tmp/schema.yaml > pkg/client/model/model_generated.go
|
||||
go run cmd/openapi/main.go $(ADGUARD_HOME_VERSION)
|
||||
$(TB_OAPI_CODEGEN) -package model -generate types,client -config .oapi-codegen.yaml tmp/schema.yaml > internal/client/model/model_generated.go
|
||||
|
||||
model-diff:
|
||||
go run openapi/main.go $(ADGUARD_HOME_VERSION)
|
||||
go run openapi/main.go
|
||||
go run cmd/openapi/main.go $(ADGUARD_HOME_VERSION)
|
||||
go run cmd/openapi/main.go
|
||||
diff tmp/schema.yaml tmp/schema-master.yaml
|
||||
|
||||
zellij:
|
||||
|
||||
289
README.md
289
README.md
@@ -3,8 +3,6 @@
|
||||
[](https://goreportcard.com/report/github.com/bakito/adguardhome-sync)
|
||||
[](https://coveralls.io/github/bakito/adguardhome-sync?branch=main)
|
||||
|
||||
|
||||
|
||||
# <img src="./media/adguardhome-sync.svg" alt="AdGuardHome sync" width="50"/> AdGuardHome sync
|
||||
|
||||
Synchronize [AdGuardHome](https://github.com/AdguardTeam/AdGuardHome) config to replica instances.
|
||||
@@ -45,7 +43,144 @@ go install github.com/bakito/adguardhome-sync@latest
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Both the origin instance and replica(s) must be initially set up with AdguardHome via the AdguardHome installation wizard.
|
||||
Both the origin instance and replica(s) must be initially set up with AdguardHome via the AdguardHome installation
|
||||
wizard.
|
||||
|
||||
|
||||
## Config via environment variables
|
||||
|
||||
For Replicas replace `#` with the index number for the replica. E.g.: `REPLICA#_URL` -> `REPLICA1_URL`
|
||||
<!-- env-doc-start -->
|
||||
| Name | Type | Description |
|
||||
| :--- | ---- |:----------- |
|
||||
| CRON (string) | string | Cron expression for the sync interval |
|
||||
| RUN_ON_START (bool) | bool | Run the sync on startup |
|
||||
| PRINT_CONFIG_ONLY (bool) | bool | Print current config only and stop the application |
|
||||
| CONTINUE_ON_ERROR (bool) | bool | Continue sync on errors |
|
||||
| ORIGIN_URL (string) | string | URL of adguardhome instance |
|
||||
| ORIGIN_WEB_URL (string) | string | Web URL of adguardhome instance |
|
||||
| ORIGIN_API_PATH (string) | string | API Path |
|
||||
| ORIGIN_USERNAME (string) | string | Adguardhome username |
|
||||
| ORIGIN_PASSWORD (string) | string | Adguardhome password |
|
||||
| ORIGIN_COOKIE (string) | string | Adguardhome cookie |
|
||||
| ORIGIN_REQUEST_HEADERS (map) | map | Request Headers 'key1:value1,key2:value2' |
|
||||
| ORIGIN_INSECURE_SKIP_VERIFY (bool) | bool | Skip TLS verification |
|
||||
| ORIGIN_AUTO_SETUP (bool) | bool | Automatically setup the instance if it is not initialized |
|
||||
| ORIGIN_INTERFACE_NAME (string) | string | Network interface name |
|
||||
| ORIGIN_DHCP_SERVER_ENABLED (bool) | bool | Enable DHCP server |
|
||||
| REPLICA#_URL (string) | string | URL of adguardhome instance |
|
||||
| REPLICA#_WEB_URL (string) | string | Web URL of adguardhome instance |
|
||||
| REPLICA#_API_PATH (string) | string | API Path |
|
||||
| REPLICA#_USERNAME (string) | string | Adguardhome username |
|
||||
| REPLICA#_PASSWORD (string) | string | Adguardhome password |
|
||||
| REPLICA#_COOKIE (string) | string | Adguardhome cookie |
|
||||
| REPLICA#_REQUEST_HEADERS (map) | map | Request Headers 'key1:value1,key2:value2' |
|
||||
| REPLICA#_INSECURE_SKIP_VERIFY (bool) | bool | Skip TLS verification |
|
||||
| REPLICA#_AUTO_SETUP (bool) | bool | Automatically setup the instance if it is not initialized |
|
||||
| REPLICA#_INTERFACE_NAME (string) | string | Network interface name |
|
||||
| REPLICA#_DHCP_SERVER_ENABLED (bool) | bool | Enable DHCP server |
|
||||
| API_PORT (int) | int | API port (API is disabled if port is set to 0) |
|
||||
| API_USERNAME (string) | string | API username |
|
||||
| API_PASSWORD (string) | string | API password |
|
||||
| API_DARK_MODE (bool) | bool | API dark mode |
|
||||
| API_METRICS_ENABLED (bool) | bool | Enable metrics |
|
||||
| API_METRICS_SCRAPE_INTERVAL (int64) | int64 | Interval for metrics scraping |
|
||||
| API_METRICS_QUERY_LOG_LIMIT (int) | int | Metrics log query limit |
|
||||
| API_TLS_CERT_DIR (string) | string | API TLS certificate directory |
|
||||
| API_TLS_CERT_NAME (string) | string | API TLS certificate file name |
|
||||
| API_TLS_KEY_NAME (string) | string | API TLS key file name |
|
||||
| FEATURES_DNS_ACCESS_LISTS (bool) | bool | Sync DNS access lists |
|
||||
| FEATURES_DNS_SERVER_CONFIG (bool) | bool | Sync DNS server config |
|
||||
| FEATURES_DNS_REWRITES (bool) | bool | Sync DNS rewrites |
|
||||
| FEATURES_DHCP_SERVER_CONFIG (bool) | bool | Sync DHCP server config |
|
||||
| FEATURES_DHCP_STATIC_LEASES (bool) | bool | Sync DHCP static leases |
|
||||
| FEATURES_GENERAL_SETTINGS (bool) | bool | Sync general settings |
|
||||
| FEATURES_QUERY_LOG_CONFIG (bool) | bool | Sync query log config |
|
||||
| FEATURES_STATS_CONFIG (bool) | bool | Sync stats config |
|
||||
| FEATURES_CLIENT_SETTINGS (bool) | bool | Sync client settings |
|
||||
| FEATURES_SERVICES (bool) | bool | Sync services |
|
||||
| FEATURES_FILTERS (bool) | bool | Sync filters |
|
||||
| FEATURES_THEME (bool) | bool | Sync the web UI theme |
|
||||
| FEATURES_TLS_CONFIG (bool) | bool | Sync the TLS config |
|
||||
<!-- env-doc-end -->
|
||||
|
||||
### YAML Configuration file
|
||||
|
||||
location: $HOME/.adguardhome-sync.yaml
|
||||
|
||||
<!-- yaml-doc-start -->
|
||||
```yaml
|
||||
cron: # (string) Cron expression for the sync interval
|
||||
runOnStart: # (bool) Run the sync on startup
|
||||
printConfigOnly: # (bool) Print current config only and stop the application
|
||||
continueOnError: # (bool) Continue sync on errors
|
||||
origin: # (struct) Origin instance
|
||||
url: # (string) URL of adguardhome instance
|
||||
webURL: # (string) Web URL of adguardhome instance
|
||||
apiPath: # (string) API Path
|
||||
username: # (string) Adguardhome username
|
||||
password: # (string) Adguardhome password
|
||||
cookie: # (string) Adguardhome cookie
|
||||
requestHeaders: # (map) Request Headers 'key1:value1,key2:value2'
|
||||
insecureSkipVerify: # (bool) Skip TLS verification
|
||||
autoSetup: # (bool) Automatically setup the instance if it is not initialized
|
||||
interfaceName: # (string) Network interface name
|
||||
dhcpServerEnabled: # (bool) Enable DHCP server
|
||||
replica: # (struct) Single or replica instance (don't use in combination with replicas')
|
||||
url: # (string) URL of adguardhome instance
|
||||
webURL: # (string) Web URL of adguardhome instance
|
||||
apiPath: # (string) API Path
|
||||
username: # (string) Adguardhome username
|
||||
password: # (string) Adguardhome password
|
||||
cookie: # (string) Adguardhome cookie
|
||||
requestHeaders: # (map) Request Headers 'key1:value1,key2:value2'
|
||||
insecureSkipVerify: # (bool) Skip TLS verification
|
||||
autoSetup: # (bool) Automatically setup the instance if it is not initialized
|
||||
interfaceName: # (string) Network interface name
|
||||
dhcpServerEnabled: # (bool) Enable DHCP server
|
||||
replicas: # (struct) List or replica instances (don't use in combination with replicas')
|
||||
- url: # (string) URL of adguardhome instance
|
||||
webURL: # (string) Web URL of adguardhome instance
|
||||
apiPath: # (string) API Path
|
||||
username: # (string) Adguardhome username
|
||||
password: # (string) Adguardhome password
|
||||
cookie: # (string) Adguardhome cookie
|
||||
requestHeaders: # (map) Request Headers 'key1:value1,key2:value2'
|
||||
insecureSkipVerify: # (bool) Skip TLS verification
|
||||
autoSetup: # (bool) Automatically setup the instance if it is not initialized
|
||||
interfaceName: # (string) Network interface name
|
||||
dhcpServerEnabled: # (bool) Enable DHCP server
|
||||
api: # (struct)
|
||||
port: # (int) API port (API is disabled if port is set to 0)
|
||||
username: # (string) API username
|
||||
password: # (string) API password
|
||||
darkMode: # (bool) API dark mode
|
||||
metrics: # (struct)
|
||||
enabled: # (bool) Enable metrics
|
||||
scrapeInterval: # (int64) Interval for metrics scraping
|
||||
queryLogLimit: # (int) Metrics log query limit
|
||||
tls: # (struct)
|
||||
certDir: # (string) API TLS certificate directory
|
||||
certName: # (string) API TLS certificate file name
|
||||
keyName: # (string) API TLS key file name
|
||||
features: # (struct)
|
||||
dns: # (struct)
|
||||
accessLists: # (bool) Sync DNS access lists
|
||||
serverConfig: # (bool) Sync DNS server config
|
||||
rewrites: # (bool) Sync DNS rewrites
|
||||
dhcp: # (struct)
|
||||
serverConfig: # (bool) Sync DHCP server config
|
||||
staticLeases: # (bool) Sync DHCP static leases
|
||||
generalSettings: # (bool) Sync general settings
|
||||
queryLogConfig: # (bool) Sync query log config
|
||||
statsConfig: # (bool) Sync stats config
|
||||
clientSettings: # (bool) Sync client settings
|
||||
services: # (bool) Sync services
|
||||
filters: # (bool) Sync filters
|
||||
theme: # (bool) Sync the web UI theme
|
||||
tlsConfig: # (bool) Sync the TLS config
|
||||
```
|
||||
<!-- yaml-doc-end -->
|
||||
|
||||
## Username / Password vs. Cookie
|
||||
|
||||
@@ -183,151 +318,13 @@ services:
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
## Config via environment variables
|
||||
## Unraid
|
||||
|
||||
For Replicas replace `#` with the index number for the replica. E.g: `REPLICA#_URL` -> `REPLICA1_URL`
|
||||
⚠️ Disclaimer: There exists an unraid template for this application. This project does not manage this template.
|
||||
Also, as unraid is not known to me, I cannot give any support on unraind templates.
|
||||
|
||||
| Name | Type | Description |
|
||||
|:-------------------------------------|--------|:----------------------------------------------------------|
|
||||
| ORIGIN_URL (string) | string | URL of adguardhome instance |
|
||||
| ORIGIN_WEB_URL (string) | string | Web URL of adguardhome instance |
|
||||
| ORIGIN_API_PATH (string) | string | API Path |
|
||||
| ORIGIN_USERNAME (string) | string | Adguardhome username |
|
||||
| ORIGIN_PASSWORD (string) | string | Adguardhome password |
|
||||
| ORIGIN_COOKIE (string) | string | Adguardhome cookie |
|
||||
| ORIGIN_REQUEST_HEADERS (map) | map | Request Headers 'key1:value1,key2:value2' |
|
||||
| ORIGIN_INSECURE_SKIP_VERIFY (bool) | bool | Skip TLS verification |
|
||||
| ORIGIN_AUTO_SETUP (bool) | bool | Automatically setup the instance if it is not initialized |
|
||||
| ORIGIN_INTERFACE_NAME (string) | string | Network interface name |
|
||||
| ORIGIN_DHCP_SERVER_ENABLED (bool) | bool | Enable DHCP server |
|
||||
| REPLICA#_URL (string) | string | URL of adguardhome instance |
|
||||
| REPLICA#_WEB_URL (string) | string | Web URL of adguardhome instance |
|
||||
| REPLICA#_API_PATH (string) | string | API Path |
|
||||
| REPLICA#_USERNAME (string) | string | Adguardhome username |
|
||||
| REPLICA#_PASSWORD (string) | string | Adguardhome password |
|
||||
| REPLICA#_COOKIE (string) | string | Adguardhome cookie |
|
||||
| REPLICA#_REQUEST_HEADERS (map) | map | Request Headers 'key1:value1,key2:value2' |
|
||||
| REPLICA#_INSECURE_SKIP_VERIFY (bool) | bool | Skip TLS verification |
|
||||
| REPLICA#_AUTO_SETUP (bool) | bool | Automatically setup the instance if it is not initialized |
|
||||
| REPLICA#_INTERFACE_NAME (string) | string | Network interface name |
|
||||
| REPLICA#_DHCP_SERVER_ENABLED (bool) | bool | Enable DHCP server |
|
||||
| CRON (string) | string | Cron expression for the sync interval |
|
||||
| RUN_ON_START (bool) | bool | Run the sung on startup |
|
||||
| PRINT_CONFIG_ONLY (bool) | bool | Print current config only and stop the application |
|
||||
| CONTINUE_ON_ERROR (bool) | bool | Continue sync on errors |
|
||||
| API_PORT (int) | int | API port |
|
||||
| API_USERNAME (string) | string | API username |
|
||||
| API_PASSWORD (string) | string | API password |
|
||||
| API_DARK_MODE (bool) | bool | API dark mode |
|
||||
| API_METRICS_ENABLED (bool) | bool | Enable metrics |
|
||||
| API_METRICS_SCRAPE_INTERVAL (int64) | int64 | Interval for metrics scraping |
|
||||
| API_METRICS_QUERY_LOG_LIMIT (int) | int | Metrics log query limit |
|
||||
| API_TLS_CERT_DIR (string) | string | API TLS certificate directory |
|
||||
| API_TLS_CERT_NAME (string) | string | API TLS certificate file name |
|
||||
| API_TLS_KEY_NAME (string) | string | API TLS key file name |
|
||||
| FEATURES_DNS_ACCESS_LISTS (bool) | bool | Sync DNS access lists |
|
||||
| FEATURES_DNS_SERVER_CONFIG (bool) | bool | Sync DNS server config |
|
||||
| FEATURES_DNS_REWRITES (bool) | bool | Sync DNS rewrites |
|
||||
| FEATURES_DHCP_SERVER_CONFIG (bool) | bool | Sync DHCP server config |
|
||||
| FEATURES_DHCP_STATIC_LEASES (bool) | bool | Sync DHCP static leases |
|
||||
| FEATURES_GENERAL_SETTINGS (bool) | bool | Sync general settings |
|
||||
| FEATURES_QUERY_LOG_CONFIG (bool) | bool | Sync query log config |
|
||||
| FEATURES_STATS_CONFIG (bool) | bool | Sync stats config |
|
||||
| FEATURES_CLIENT_SETTINGS (bool) | bool | Sync client settings |
|
||||
| FEATURES_SERVICES (bool) | bool | Sync services |
|
||||
| FEATURES_FILTERS (bool) | bool | Sync filters |
|
||||
| FEATURES_THEME (bool) | bool | Sync the weg UI theme |
|
||||
|
||||
### Unraid
|
||||
|
||||
⚠️ Disclaimer: Tere exists an unraid tepmlate for this application. This template is not managed by this project.
|
||||
Also, as unraid is not known to me, I can not give any support on unraind templates.
|
||||
|
||||
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
|
||||
|
||||
```yaml
|
||||
# cron expression to run in daemon mode. (default; "" = runs only once)
|
||||
cron: "0 */2 * * *"
|
||||
|
||||
# runs the synchronisation on startup
|
||||
runOnStart: true
|
||||
|
||||
# If enabled, the synchronisation task will not fail on single errors, but will log the errors and continue
|
||||
continueOnError: false
|
||||
|
||||
origin:
|
||||
# url of the origin instance
|
||||
url: https://192.168.1.2:3000
|
||||
# apiPath: define an api path if other than "/control"
|
||||
# insecureSkipVerify: true # disable tls check
|
||||
username: username
|
||||
password: password
|
||||
# cookie: Origin-Cookie-Name=CCCOOOKKKIIIEEE
|
||||
# requestHeaders: # Additional request headers
|
||||
# AAA: bbb
|
||||
|
||||
# replicas instances
|
||||
replicas:
|
||||
# url of the replica instance
|
||||
- url: http://192.168.1.3
|
||||
username: username
|
||||
password: password
|
||||
# cookie: Replica1-Cookie-Name=CCCOOOKKKIIIEEE
|
||||
- url: http://192.168.1.4
|
||||
username: username
|
||||
password: password
|
||||
# cookie: Replica2-Cookie-Name=CCCOOOKKKIIIEEE
|
||||
# autoSetup: true # if true, AdGuardHome is automatically initialized.
|
||||
# webURL: "https://some-other.url" # used in the web interface (default: <replica-url>
|
||||
# requestHeaders: # Additional request headers
|
||||
# AAA: bbb
|
||||
|
||||
# Configure the sync API server, disabled if api port is 0
|
||||
api:
|
||||
# Port, default 8080
|
||||
port: 8080
|
||||
# if username and password are defined, basic auth is applied to the sync API
|
||||
username: username
|
||||
password: password
|
||||
# enable api dark mode
|
||||
darkMode: true
|
||||
|
||||
# enable metrics on path '/metrics' (api port must be != 0)
|
||||
# metrics:
|
||||
# enabled: true
|
||||
# scrapeInterval: 30s
|
||||
# queryLogLimit: 10000
|
||||
|
||||
# enable tls for the api server
|
||||
# tls:
|
||||
# # the directory of the provided tls certs
|
||||
# certDir: /path/to/certs
|
||||
# # the name of the cert file (default: tls.crt)
|
||||
# certName: foo.crt
|
||||
# # the name of the key file (default: tls.key)
|
||||
# keyName: bar.key
|
||||
|
||||
# Configure sync features; by default all features are enabled.
|
||||
features:
|
||||
generalSettings: true
|
||||
queryLogConfig: true
|
||||
statsConfig: true
|
||||
clientSettings: true
|
||||
services: true
|
||||
filters: true
|
||||
dhcp:
|
||||
serverConfig: true
|
||||
staticLeases: true
|
||||
dns:
|
||||
serverConfig: true
|
||||
accessLists: true
|
||||
rewrites: true
|
||||
```
|
||||
Note when running the Docker container in Unraid please remove unneeded env variables.
|
||||
If replica2 isn't used, this can cause sync errors.
|
||||
|
||||
## Home Assistant AdGuard Home Add-on users
|
||||
|
||||
|
||||
174
cmd/docs/main.go
Normal file
174
cmd/docs/main.go
Normal file
@@ -0,0 +1,174 @@
|
||||
// Print the available environment variables
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
const (
|
||||
envStartMarker = "<!-- env-doc-start -->"
|
||||
envEndMarker = "<!-- env-doc-end -->"
|
||||
yamlStartMarker = "<!-- yaml-doc-start -->"
|
||||
yamlEndMarker = "<!-- yaml-doc-end -->"
|
||||
)
|
||||
|
||||
func main() {
|
||||
slog.Info("Reading README.md")
|
||||
content, err := os.ReadFile("README.md")
|
||||
if err != nil {
|
||||
slog.Error("Error reading README.md", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fileContent := string(content)
|
||||
|
||||
slog.Info("Generating environment variables")
|
||||
fileContent = generateEnvDocumentation(fileContent)
|
||||
|
||||
slog.Info("Generating yaml configuration")
|
||||
fileContent = generateYAMLDocumentation(fileContent)
|
||||
|
||||
slog.Info("Writing README.md")
|
||||
err = os.WriteFile("README.md", []byte(fileContent), 0o644)
|
||||
if err != nil {
|
||||
slog.Error("Error writing README.md", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func generateEnvDocumentation(fileContent string) string {
|
||||
var buf strings.Builder
|
||||
_, _ = buf.WriteString("| Name | Type | Description |\n")
|
||||
_, _ = buf.WriteString("| :--- | ---- |:----------- |\n")
|
||||
writeEnvDocumentation(&buf, reflect.TypeOf(types.Config{}), "")
|
||||
|
||||
return updateDocumentationSection(fileContent, envStartMarker, envEndMarker, buf.String())
|
||||
}
|
||||
|
||||
func generateYAMLDocumentation(fileContent string) string {
|
||||
var buf strings.Builder
|
||||
_, _ = buf.WriteString("```yaml\n")
|
||||
writeYAMLDocumentation(&buf, reflect.TypeOf(types.Config{}), "", "")
|
||||
_, _ = buf.WriteString("```\n")
|
||||
|
||||
return updateDocumentationSection(fileContent, yamlStartMarker, yamlEndMarker, buf.String())
|
||||
}
|
||||
|
||||
func updateDocumentationSection(fileContent, startMarker, endMarker, newContent string) string {
|
||||
startIdx := strings.Index(fileContent, startMarker)
|
||||
endIdx := strings.Index(fileContent, endMarker)
|
||||
|
||||
if startIdx == -1 || endIdx == -1 {
|
||||
slog.Error(fmt.Sprintf("Could not find markers %s and %s in README.md", startMarker, endMarker))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return fileContent[:startIdx+len(startMarker)] + "\n" + newContent + fileContent[endIdx:]
|
||||
}
|
||||
|
||||
func writeEnvDocumentation(w io.Writer, t reflect.Type, prefix string) {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Kind() != reflect.Struct {
|
||||
return
|
||||
}
|
||||
|
||||
for _, field := range reflect.VisibleFields(t) {
|
||||
if field.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
envTag := field.Tag.Get("env")
|
||||
if envTag == "" {
|
||||
switch field.Name {
|
||||
case "Origin":
|
||||
envTag = "ORIGIN"
|
||||
case "Replica":
|
||||
envTag = "REPLICA#"
|
||||
}
|
||||
}
|
||||
|
||||
combinedTag := buildCombinedTag(prefix, envTag)
|
||||
|
||||
ft := field.Type
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
|
||||
if ft.Kind() == reflect.Struct && ft.Name() != "Time" {
|
||||
writeEnvDocumentation(w, ft, strings.TrimSuffix(combinedTag, "_"))
|
||||
} else if envTag != "" {
|
||||
envVar := strings.Trim(combinedTag, "_") + " (" + ft.Kind().String() + ")"
|
||||
docs := field.Tag.Get("documentation")
|
||||
_, _ = fmt.Fprintf(w, "| %s | %s | %s |\n", envVar, ft.Kind().String(), docs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func writeYAMLDocumentation(w io.Writer, t reflect.Type, firstPrefix, otherPrefix string) {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Kind() != reflect.Struct {
|
||||
return
|
||||
}
|
||||
|
||||
var i int
|
||||
for _, field := range reflect.VisibleFields(t) {
|
||||
if field.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
|
||||
yamlTag := field.Tag.Get("yaml")
|
||||
if yamlTag == "-" {
|
||||
continue
|
||||
}
|
||||
yamlTag = strings.TrimSuffix(yamlTag, ",omitempty")
|
||||
|
||||
ft := field.Type
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
|
||||
pf := otherPrefix
|
||||
if i == 0 {
|
||||
pf = firstPrefix
|
||||
}
|
||||
|
||||
newFirstPrefix := pf + " "
|
||||
newOtherPrefix := otherPrefix + " "
|
||||
|
||||
if yamlTag == "replicas" && ft.Kind() == reflect.Slice {
|
||||
ft = ft.Elem()
|
||||
newFirstPrefix += "- "
|
||||
newOtherPrefix += " "
|
||||
}
|
||||
|
||||
if yamlTag != "" {
|
||||
docs := field.Tag.Get("documentation")
|
||||
_, _ = fmt.Fprintf(w, "%s%s: # (%s) %s\n", pf, yamlTag, ft.Kind().String(), docs)
|
||||
i++
|
||||
}
|
||||
|
||||
if ft.Kind() == reflect.Struct && ft.Name() != "Time" {
|
||||
writeYAMLDocumentation(w, ft, newFirstPrefix, newOtherPrefix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func buildCombinedTag(prefix, envTag string) string {
|
||||
if prefix != "" && envTag != "" {
|
||||
return prefix + "_" + envTag
|
||||
} else if prefix != "" {
|
||||
return prefix
|
||||
}
|
||||
return envTag
|
||||
}
|
||||
@@ -87,10 +87,6 @@ func main() {
|
||||
}
|
||||
|
||||
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]any) {
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/version"
|
||||
)
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ 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/bakito/adguardhome-sync/internal/config"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/sync"
|
||||
)
|
||||
|
||||
// runCmd represents the run command.
|
||||
@@ -67,6 +67,7 @@ func init() {
|
||||
doCmd.PersistentFlags().Bool(config.FlagFeatureClient, true, "Enable client settings feature")
|
||||
doCmd.PersistentFlags().Bool(config.FlagFeatureServices, true, "Enable services sync feature")
|
||||
doCmd.PersistentFlags().Bool(config.FlagFeatureFilters, true, "Enable filters sync feature")
|
||||
doCmd.PersistentFlags().Bool(config.FlagFeatureTLSConfig, false, "Enable TLS config sync feature")
|
||||
|
||||
doCmd.PersistentFlags().String(config.FlagOriginURL, "", "Origin instance url")
|
||||
doCmd.PersistentFlags().
|
||||
|
||||
62
docs/main.go
62
docs/main.go
@@ -1,62 +0,0 @@
|
||||
// Print the available environment variables
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
_, _ = fmt.Println("| Name | Type | Description |")
|
||||
_, _ = fmt.Println("| :--- | ---- |:----------- |")
|
||||
printEnvTags(reflect.TypeOf(types.Config{}), "")
|
||||
}
|
||||
|
||||
// printEnvTags recursively prints all fields with `env` tags.
|
||||
func printEnvTags(t reflect.Type, prefix string) {
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
if t.Kind() != reflect.Struct {
|
||||
return
|
||||
}
|
||||
|
||||
for _, field := range reflect.VisibleFields(t) {
|
||||
if field.PkgPath != "" { // unexported field
|
||||
continue
|
||||
}
|
||||
|
||||
envTag := field.Tag.Get("env")
|
||||
if envTag == "" {
|
||||
switch field.Name {
|
||||
case "Origin":
|
||||
envTag = "ORIGIN"
|
||||
case "Replica":
|
||||
envTag = "REPLICA#"
|
||||
}
|
||||
}
|
||||
combinedTag := envTag
|
||||
if prefix != "" && envTag != "" {
|
||||
combinedTag = prefix + "_" + envTag
|
||||
} else if prefix != "" {
|
||||
combinedTag = prefix
|
||||
}
|
||||
|
||||
ft := field.Type
|
||||
if ft.Kind() == reflect.Ptr {
|
||||
ft = ft.Elem()
|
||||
}
|
||||
|
||||
if ft.Kind() == reflect.Struct && ft.Name() != "Time" { // skip time.Time
|
||||
printEnvTags(ft, strings.TrimSuffix(combinedTag, "_"))
|
||||
} else if envTag != "" {
|
||||
envVar := strings.Trim(combinedTag, "_") + " (" + ft.Kind().String() + ")"
|
||||
docs := field.Tag.Get("documentation")
|
||||
|
||||
_, _ = fmt.Printf("| %s | %s | %s |\n", envVar, ft.Kind().String(), docs)
|
||||
}
|
||||
}
|
||||
}
|
||||
77
go.mod
77
go.mod
@@ -1,77 +1,82 @@
|
||||
module github.com/bakito/adguardhome-sync
|
||||
|
||||
go 1.24.2
|
||||
go 1.25.4
|
||||
|
||||
require (
|
||||
github.com/caarlos0/env/v11 v11.3.1
|
||||
github.com/gin-gonic/gin v1.10.1
|
||||
github.com/go-faker/faker/v4 v4.6.1
|
||||
github.com/go-resty/resty/v2 v2.16.5
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/go-faker/faker/v4 v4.7.0
|
||||
github.com/go-resty/resty/v2 v2.17.0
|
||||
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.23.4
|
||||
github.com/onsi/gomega v1.37.0
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/oapi-codegen/runtime v1.1.2
|
||||
github.com/onsi/ginkgo/v2 v2.27.2
|
||||
github.com/onsi/gomega v1.38.2
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
|
||||
github.com/spf13/cobra v1.9.1
|
||||
go.uber.org/mock v0.5.2
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/mod v0.25.0
|
||||
github.com/spf13/cobra v1.10.1
|
||||
go.uber.org/mock v0.6.0
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/mod v0.30.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/apimachinery v0.33.2
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
|
||||
k8s.io/apimachinery v0.34.2
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/bytedance/sonic v1.14.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.26.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.27.0 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.18.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a // indirect
|
||||
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.63.0 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.54.1 // indirect
|
||||
github.com/spf13/pflag v1.0.9 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.16.0 // indirect
|
||||
golang.org/x/crypto v0.37.0 // indirect
|
||||
golang.org/x/net v0.39.0 // indirect
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/tools v0.32.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/tools v0.38.0 // indirect
|
||||
google.golang.org/protobuf v1.36.9 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
||||
)
|
||||
|
||||
189
go.sum
189
go.sum
@@ -1,67 +1,76 @@
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
|
||||
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
|
||||
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
|
||||
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
|
||||
github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
|
||||
github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
|
||||
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
|
||||
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/go-faker/faker/v4 v4.6.1 h1:xUyVpAjEtB04l6XFY0V/29oR332rOSPWV4lU8RwDt4k=
|
||||
github.com/go-faker/faker/v4 v4.6.1/go.mod h1:arSdxNCSt7mOhdk8tEolvHeIJ7eX4OX80wXjKKvkKBY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
||||
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
|
||||
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
|
||||
github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=
|
||||
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
|
||||
github.com/go-faker/faker/v4 v4.7.0 h1:VboC02cXHl/NuQh5lM2W8b87yp4iFXIu59x4w0RZi4E=
|
||||
github.com/go-faker/faker/v4 v4.7.0/go.mod h1:u1dIRP5neLB6kTzgyVjdBOV5R1uP7BdxkcWk7tiKQXk=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
|
||||
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM=
|
||||
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
|
||||
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
|
||||
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
|
||||
github.com/go-resty/resty/v2 v2.17.0 h1:pW9DeXcaL4Rrym4EZ8v7L19zZiIlWPg5YXAcVmt+gN0=
|
||||
github.com/go-resty/resty/v2 v2.17.0/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a h1:rDA3FfmxwXR+BVKKdz55WwMJ1pD2hJQNW31d+l3mPk4=
|
||||
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY=
|
||||
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
|
||||
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
@@ -69,10 +78,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -81,35 +88,42 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
|
||||
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
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.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
|
||||
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
|
||||
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
|
||||
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI=
|
||||
github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
|
||||
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
|
||||
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
|
||||
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
|
||||
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
|
||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.54.1 h1:4ZAWm0AhCb6+hE+l5Q1NAL0iRn/ZrMwqHRGQiFwj2eg=
|
||||
github.com/quic-go/quic-go v0.54.1/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
@@ -117,83 +131,94 @@ github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWN
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
|
||||
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.16.0 h1:foMtLTdyOmIniqWCHjY6+JxuC54XP1fDwx4N0ASyW+U=
|
||||
golang.org/x/arch v0.16.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
||||
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
||||
golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
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.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
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.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
||||
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
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.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
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=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
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.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
|
||||
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
|
||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
|
||||
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
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=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
@@ -202,19 +227,17 @@ 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.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY=
|
||||
k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4=
|
||||
k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
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-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
|
||||
@@ -14,14 +14,27 @@ import (
|
||||
"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/bakito/adguardhome-sync/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
)
|
||||
|
||||
const envRedirectPolicyNoOfRedirects = "REDIRECT_POLICY_NO_OF_REDIRECTS"
|
||||
|
||||
type Error struct {
|
||||
message string
|
||||
errorCode int
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func (e *Error) Code() int {
|
||||
return e.errorCode
|
||||
}
|
||||
|
||||
var (
|
||||
l = log.GetLogger("client")
|
||||
// ErrSetupNeeded custom error.
|
||||
@@ -36,7 +49,10 @@ func detailedError(resp *resty.Response, err error) error {
|
||||
if err != nil {
|
||||
e += ": " + err.Error()
|
||||
}
|
||||
return errors.New(e)
|
||||
return &Error{
|
||||
message: e,
|
||||
errorCode: resp.StatusCode(),
|
||||
}
|
||||
}
|
||||
|
||||
// New create a new client.
|
||||
@@ -131,6 +147,8 @@ type Client interface {
|
||||
SetDhcpConfig(status *model.DhcpStatus) error
|
||||
AddDHCPStaticLease(lease model.DhcpStaticLease) error
|
||||
DeleteDHCPStaticLease(lease model.DhcpStaticLease) error
|
||||
TLSConfig() (*model.TlsConfig, error)
|
||||
SetTLSConfig(tls *model.TlsConfig) error
|
||||
}
|
||||
|
||||
type client struct {
|
||||
@@ -450,3 +468,14 @@ func (cl *client) SetProfileInfo(profile *model.ProfileInfo) error {
|
||||
cl.log.With("language", profile.Language, "theme", profile.Theme).Info("Set profile")
|
||||
return cl.doPut(cl.client.R().EnableTrace().SetBody(profile), "/profile/update")
|
||||
}
|
||||
|
||||
func (cl *client) TLSConfig() (*model.TlsConfig, error) {
|
||||
tlsc := &model.TlsConfig{}
|
||||
err := cl.doGet(cl.client.R().EnableTrace().SetResult(tlsc), "/tls/status")
|
||||
return tlsc, err
|
||||
}
|
||||
|
||||
func (cl *client) SetTLSConfig(tlsc *model.TlsConfig) error {
|
||||
cl.log.With("enabled", tlsc.Enabled).Info("Set TLS config")
|
||||
return cl.doPost(cl.client.R().EnableTrace().SetBody(tlsc), "/tls/configure")
|
||||
}
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
. "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/bakito/adguardhome-sync/internal/client"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
|
||||
"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/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
var l = log.GetLogger("client")
|
||||
@@ -3,7 +3,7 @@ package client
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
)
|
||||
|
||||
var _ model.HttpRequestDoer = &adapter{}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/utils"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
)
|
||||
|
||||
// Clone the config.
|
||||
@@ -490,3 +490,7 @@ func sumUp(t, o *[]int) *[]int {
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (c *TlsConfig) Equals(config *TlsConfig) bool {
|
||||
return utils.JSONEquals(c, config)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Package model provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT.
|
||||
// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.5.1 DO NOT EDIT.
|
||||
package model
|
||||
|
||||
import (
|
||||
@@ -195,6 +195,9 @@ type AddressesInfo struct {
|
||||
|
||||
// BlockedService defines model for BlockedService.
|
||||
type BlockedService struct {
|
||||
// GroupId The ID of the group, that the service belongs to.
|
||||
GroupId *string `json:"group_id,omitempty"`
|
||||
|
||||
// IconSvg The SVG icon as a Base64-encoded string to make it easier to embed it into a data URL.
|
||||
IconSvg string `json:"icon_svg"`
|
||||
|
||||
@@ -211,6 +214,7 @@ type BlockedService struct {
|
||||
// BlockedServicesAll defines model for BlockedServicesAll.
|
||||
type BlockedServicesAll struct {
|
||||
BlockedServices []BlockedService `json:"blocked_services"`
|
||||
Groups interface{} `json:"groups"`
|
||||
}
|
||||
|
||||
// BlockedServicesArray defines model for BlockedServicesArray.
|
||||
@@ -303,7 +307,7 @@ type Client struct {
|
||||
// SafeSearch Safe search settings.
|
||||
SafeSearch *SafeSearchConfig `json:"safe_search,omitempty"`
|
||||
SafebrowsingEnabled *bool `json:"safebrowsing_enabled,omitempty"`
|
||||
// Deprecated:
|
||||
// Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set
|
||||
SafesearchEnabled *bool `json:"safesearch_enabled,omitempty"`
|
||||
Tags *[]string `json:"tags,omitempty"`
|
||||
Upstreams *[]string `json:"upstreams,omitempty"`
|
||||
@@ -369,7 +373,7 @@ type ClientFindSubEntry struct {
|
||||
// SafeSearch Safe search settings.
|
||||
SafeSearch *SafeSearchConfig `json:"safe_search,omitempty"`
|
||||
SafebrowsingEnabled *bool `json:"safebrowsing_enabled,omitempty"`
|
||||
// Deprecated:
|
||||
// Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set
|
||||
SafesearchEnabled *bool `json:"safesearch_enabled,omitempty"`
|
||||
Upstreams *[]string `json:"upstreams,omitempty"`
|
||||
UseGlobalBlockedServices *bool `json:"use_global_blocked_services,omitempty"`
|
||||
@@ -426,16 +430,23 @@ type DNSConfig struct {
|
||||
BlockingMode *DNSConfigBlockingMode `json:"blocking_mode,omitempty"`
|
||||
|
||||
// BootstrapDns Bootstrap servers, port is optional after colon. Empty value will reset it to default values.
|
||||
BootstrapDns *[]string `json:"bootstrap_dns,omitempty"`
|
||||
CacheOptimistic *bool `json:"cache_optimistic,omitempty"`
|
||||
CacheSize *int `json:"cache_size,omitempty"`
|
||||
CacheTtlMax *int `json:"cache_ttl_max,omitempty"`
|
||||
CacheTtlMin *int `json:"cache_ttl_min,omitempty"`
|
||||
DisableIpv6 *bool `json:"disable_ipv6,omitempty"`
|
||||
DnssecEnabled *bool `json:"dnssec_enabled,omitempty"`
|
||||
EdnsCsCustomIp *string `json:"edns_cs_custom_ip,omitempty"`
|
||||
EdnsCsEnabled *bool `json:"edns_cs_enabled,omitempty"`
|
||||
EdnsCsUseCustom *bool `json:"edns_cs_use_custom,omitempty"`
|
||||
BootstrapDns *[]string `json:"bootstrap_dns,omitempty"`
|
||||
|
||||
// CacheEnabled Enables or disables the DNS response cache.
|
||||
//
|
||||
// If `cache_enabled` is `true`, the companion field `cache_size` must
|
||||
// be present and greater than 0, or the `dns.cache_size` setting in
|
||||
// the configuration file must already be greater than 0.
|
||||
CacheEnabled *bool `json:"cache_enabled,omitempty"`
|
||||
CacheOptimistic *bool `json:"cache_optimistic,omitempty"`
|
||||
CacheSize *int `json:"cache_size,omitempty"`
|
||||
CacheTtlMax *int `json:"cache_ttl_max,omitempty"`
|
||||
CacheTtlMin *int `json:"cache_ttl_min,omitempty"`
|
||||
DisableIpv6 *bool `json:"disable_ipv6,omitempty"`
|
||||
DnssecEnabled *bool `json:"dnssec_enabled,omitempty"`
|
||||
EdnsCsCustomIp *string `json:"edns_cs_custom_ip,omitempty"`
|
||||
EdnsCsEnabled *bool `json:"edns_cs_enabled,omitempty"`
|
||||
EdnsCsUseCustom *bool `json:"edns_cs_use_custom,omitempty"`
|
||||
|
||||
// FallbackDns List of fallback DNS servers used when upstream DNS servers are not responding. Empty value will clear the list.
|
||||
FallbackDns *[]string `json:"fallback_dns,omitempty"`
|
||||
@@ -618,7 +629,7 @@ type FilterCheckHostResponse struct {
|
||||
|
||||
// FilterId In case if there's a rule applied to this DNS request, this is ID of the filter list that the rule belongs to.
|
||||
// Deprecated: use `rules[*].filter_list_id` instead.
|
||||
// Deprecated:
|
||||
// Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set
|
||||
FilterId *int `json:"filter_id,omitempty"`
|
||||
|
||||
// IpAddrs Set if reason=Rewrite
|
||||
@@ -629,7 +640,7 @@ type FilterCheckHostResponse struct {
|
||||
|
||||
// Rule Filtering rule applied to the request (if any).
|
||||
// Deprecated: use `rules[*].text` instead.
|
||||
// Deprecated:
|
||||
// Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set
|
||||
Rule *string `json:"rule,omitempty"`
|
||||
|
||||
// Rules Applied rules.
|
||||
@@ -830,7 +841,7 @@ type QueryLogItem struct {
|
||||
|
||||
// FilterId In case if there's a rule applied to this DNS request, this is ID of the filter list that the rule belongs to.
|
||||
// Deprecated: use `rules[*].filter_list_id` instead.
|
||||
// Deprecated:
|
||||
// Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set
|
||||
FilterId *int `json:"filterId,omitempty"`
|
||||
|
||||
// OriginalAnswer Answer from upstream server (optional)
|
||||
@@ -844,7 +855,7 @@ type QueryLogItem struct {
|
||||
|
||||
// Rule Filtering rule applied to the request (if any).
|
||||
// Deprecated: use `rules[*].text` instead.
|
||||
// Deprecated:
|
||||
// Deprecated: this property has been marked as deprecated upstream, but no `x-deprecated-reason` was set
|
||||
Rule *string `json:"rule,omitempty"`
|
||||
|
||||
// Rules Applied rules.
|
||||
@@ -919,11 +930,20 @@ type RewriteEntry struct {
|
||||
|
||||
// Domain Domain name
|
||||
Domain *string `json:"domain,omitempty"`
|
||||
|
||||
// Enabled Optional. If omitted on add, defaults to `true`. On update, omitted preserves previous value.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
// RewriteList Rewrite rules array
|
||||
type RewriteList = []RewriteEntry
|
||||
|
||||
// RewriteSettings DNS rewrite settings
|
||||
type RewriteSettings struct {
|
||||
// Enabled indicates whether rewrites are applied
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
// RewriteUpdate Rewrite rule update object
|
||||
type RewriteUpdate struct {
|
||||
// Target Rewrite rule
|
||||
@@ -985,6 +1005,12 @@ type ServerStatus struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// ServiceGroup defines model for ServiceGroup.
|
||||
type ServiceGroup struct {
|
||||
// Id The ID of this group.
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
// SetProtectionRequest Protection state configuration
|
||||
type SetProtectionRequest struct {
|
||||
// Duration Duration of a pause, in milliseconds. Enabled should be false.
|
||||
@@ -1165,6 +1191,9 @@ type DhcpStaticLeaseBody = DhcpStaticLease
|
||||
// RewriteEntryBody Rewrite rule
|
||||
type RewriteEntryBody = RewriteEntry
|
||||
|
||||
// RewriteSettingsBody DNS rewrite settings
|
||||
type RewriteSettingsBody = RewriteSettings
|
||||
|
||||
// RewriteUpdateBody Rewrite rule update object
|
||||
type RewriteUpdateBody = RewriteUpdate
|
||||
|
||||
@@ -1316,6 +1345,9 @@ type RewriteAddJSONRequestBody = RewriteEntry
|
||||
// RewriteDeleteJSONRequestBody defines body for RewriteDelete for application/json ContentType.
|
||||
type RewriteDeleteJSONRequestBody = RewriteEntry
|
||||
|
||||
// RewriteSettingsUpdateJSONRequestBody defines body for RewriteSettingsUpdate for application/json ContentType.
|
||||
type RewriteSettingsUpdateJSONRequestBody = RewriteSettings
|
||||
|
||||
// RewriteUpdateJSONRequestBody defines body for RewriteUpdate for application/json ContentType.
|
||||
type RewriteUpdateJSONRequestBody = RewriteUpdate
|
||||
|
||||
@@ -1713,6 +1745,14 @@ type ClientInterface interface {
|
||||
// RewriteList request
|
||||
RewriteList(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
// RewriteSettingsGet request
|
||||
RewriteSettingsGet(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
// RewriteSettingsUpdateWithBody request with any body
|
||||
RewriteSettingsUpdateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
RewriteSettingsUpdate(ctx context.Context, body RewriteSettingsUpdateJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
// RewriteUpdateWithBody request with any body
|
||||
RewriteUpdateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
|
||||
|
||||
@@ -2837,6 +2877,42 @@ func (c *AdguardHomeClient) RewriteList(ctx context.Context, reqEditors ...Reque
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *AdguardHomeClient) RewriteSettingsGet(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewRewriteSettingsGetRequest(c.Server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *AdguardHomeClient) RewriteSettingsUpdateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewRewriteSettingsUpdateRequestWithBody(c.Server, contentType, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *AdguardHomeClient) RewriteSettingsUpdate(ctx context.Context, body RewriteSettingsUpdateJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewRewriteSettingsUpdateRequest(c.Server, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
if err := c.applyEditors(ctx, req, reqEditors); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Client.Do(req)
|
||||
}
|
||||
|
||||
func (c *AdguardHomeClient) RewriteUpdateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
|
||||
req, err := NewRewriteUpdateRequestWithBody(c.Server, contentType, body)
|
||||
if err != nil {
|
||||
@@ -5354,6 +5430,73 @@ func NewRewriteListRequest(server string) (*http.Request, error) {
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewRewriteSettingsGetRequest generates requests for RewriteSettingsGet
|
||||
func NewRewriteSettingsGetRequest(server string) (*http.Request, error) {
|
||||
var err error
|
||||
|
||||
serverURL, err := url.Parse(server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
operationPath := fmt.Sprintf("/rewrite/settings")
|
||||
if operationPath[0] == '/' {
|
||||
operationPath = "." + operationPath
|
||||
}
|
||||
|
||||
queryURL, err := serverURL.Parse(operationPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", queryURL.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewRewriteSettingsUpdateRequest calls the generic RewriteSettingsUpdate builder with application/json body
|
||||
func NewRewriteSettingsUpdateRequest(server string, body RewriteSettingsUpdateJSONRequestBody) (*http.Request, error) {
|
||||
var bodyReader io.Reader
|
||||
buf, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyReader = bytes.NewReader(buf)
|
||||
return NewRewriteSettingsUpdateRequestWithBody(server, "application/json", bodyReader)
|
||||
}
|
||||
|
||||
// NewRewriteSettingsUpdateRequestWithBody generates requests for RewriteSettingsUpdate with any type of body
|
||||
func NewRewriteSettingsUpdateRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) {
|
||||
var err error
|
||||
|
||||
serverURL, err := url.Parse(server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
operationPath := fmt.Sprintf("/rewrite/settings/update")
|
||||
if operationPath[0] == '/' {
|
||||
operationPath = "." + operationPath
|
||||
}
|
||||
|
||||
queryURL, err := serverURL.Parse(operationPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("PUT", queryURL.String(), body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Content-Type", contentType)
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewRewriteUpdateRequest calls the generic RewriteUpdate builder with application/json body
|
||||
func NewRewriteUpdateRequest(server string, body RewriteUpdateJSONRequestBody) (*http.Request, error) {
|
||||
var bodyReader io.Reader
|
||||
@@ -6300,6 +6443,14 @@ type ClientWithResponsesInterface interface {
|
||||
// RewriteListWithResponse request
|
||||
RewriteListWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*RewriteListResp, error)
|
||||
|
||||
// RewriteSettingsGetWithResponse request
|
||||
RewriteSettingsGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*RewriteSettingsGetResp, error)
|
||||
|
||||
// RewriteSettingsUpdateWithBodyWithResponse request with any body
|
||||
RewriteSettingsUpdateWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RewriteSettingsUpdateResp, error)
|
||||
|
||||
RewriteSettingsUpdateWithResponse(ctx context.Context, body RewriteSettingsUpdateJSONRequestBody, reqEditors ...RequestEditorFn) (*RewriteSettingsUpdateResp, error)
|
||||
|
||||
// RewriteUpdateWithBodyWithResponse request with any body
|
||||
RewriteUpdateWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RewriteUpdateResp, error)
|
||||
|
||||
@@ -7636,6 +7787,49 @@ func (r RewriteListResp) StatusCode() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
type RewriteSettingsGetResp struct {
|
||||
Body []byte
|
||||
HTTPResponse *http.Response
|
||||
JSON200 *RewriteSettings
|
||||
}
|
||||
|
||||
// Status returns HTTPResponse.Status
|
||||
func (r RewriteSettingsGetResp) Status() string {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.Status
|
||||
}
|
||||
return http.StatusText(0)
|
||||
}
|
||||
|
||||
// StatusCode returns HTTPResponse.StatusCode
|
||||
func (r RewriteSettingsGetResp) StatusCode() int {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.StatusCode
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type RewriteSettingsUpdateResp struct {
|
||||
Body []byte
|
||||
HTTPResponse *http.Response
|
||||
}
|
||||
|
||||
// Status returns HTTPResponse.Status
|
||||
func (r RewriteSettingsUpdateResp) Status() string {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.Status
|
||||
}
|
||||
return http.StatusText(0)
|
||||
}
|
||||
|
||||
// StatusCode returns HTTPResponse.StatusCode
|
||||
func (r RewriteSettingsUpdateResp) StatusCode() int {
|
||||
if r.HTTPResponse != nil {
|
||||
return r.HTTPResponse.StatusCode
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type RewriteUpdateResp struct {
|
||||
Body []byte
|
||||
HTTPResponse *http.Response
|
||||
@@ -8844,6 +9038,32 @@ func (c *ClientWithResponses) RewriteListWithResponse(ctx context.Context, reqEd
|
||||
return ParseRewriteListResp(rsp)
|
||||
}
|
||||
|
||||
// RewriteSettingsGetWithResponse request returning *RewriteSettingsGetResp
|
||||
func (c *ClientWithResponses) RewriteSettingsGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*RewriteSettingsGetResp, error) {
|
||||
rsp, err := c.RewriteSettingsGet(ctx, reqEditors...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ParseRewriteSettingsGetResp(rsp)
|
||||
}
|
||||
|
||||
// RewriteSettingsUpdateWithBodyWithResponse request with arbitrary body returning *RewriteSettingsUpdateResp
|
||||
func (c *ClientWithResponses) RewriteSettingsUpdateWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RewriteSettingsUpdateResp, error) {
|
||||
rsp, err := c.RewriteSettingsUpdateWithBody(ctx, contentType, body, reqEditors...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ParseRewriteSettingsUpdateResp(rsp)
|
||||
}
|
||||
|
||||
func (c *ClientWithResponses) RewriteSettingsUpdateWithResponse(ctx context.Context, body RewriteSettingsUpdateJSONRequestBody, reqEditors ...RequestEditorFn) (*RewriteSettingsUpdateResp, error) {
|
||||
rsp, err := c.RewriteSettingsUpdate(ctx, body, reqEditors...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ParseRewriteSettingsUpdateResp(rsp)
|
||||
}
|
||||
|
||||
// RewriteUpdateWithBodyWithResponse request with arbitrary body returning *RewriteUpdateResp
|
||||
func (c *ClientWithResponses) RewriteUpdateWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RewriteUpdateResp, error) {
|
||||
rsp, err := c.RewriteUpdateWithBody(ctx, contentType, body, reqEditors...)
|
||||
@@ -10369,6 +10589,48 @@ func ParseRewriteListResp(rsp *http.Response) (*RewriteListResp, error) {
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ParseRewriteSettingsGetResp parses an HTTP response from a RewriteSettingsGetWithResponse call
|
||||
func ParseRewriteSettingsGetResp(rsp *http.Response) (*RewriteSettingsGetResp, error) {
|
||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||
defer func() { _ = rsp.Body.Close() }()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := &RewriteSettingsGetResp{
|
||||
Body: bodyBytes,
|
||||
HTTPResponse: rsp,
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
|
||||
var dest RewriteSettings
|
||||
if err := json.Unmarshal(bodyBytes, &dest); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.JSON200 = &dest
|
||||
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ParseRewriteSettingsUpdateResp parses an HTTP response from a RewriteSettingsUpdateWithResponse call
|
||||
func ParseRewriteSettingsUpdateResp(rsp *http.Response) (*RewriteSettingsUpdateResp, error) {
|
||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||
defer func() { _ = rsp.Body.Close() }()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := &RewriteSettingsUpdateResp{
|
||||
Body: bodyBytes,
|
||||
HTTPResponse: rsp,
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ParseRewriteUpdateResp parses an HTTP response from a RewriteUpdateWithResponse call
|
||||
func ParseRewriteUpdateResp(rsp *http.Response) (*RewriteUpdateResp, error) {
|
||||
bodyBytes, err := io.ReadAll(rsp.Body)
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"github.com/onsi/gomega"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/log"
|
||||
"github.com/bakito/adguardhome-sync/pkg/utils"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
)
|
||||
|
||||
var _ = Describe("Types", func() {
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
. "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"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
)
|
||||
|
||||
var _ = Describe("Types", func() {
|
||||
@@ -150,6 +150,9 @@
|
||||
},
|
||||
"theme": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tlsConfig": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
|
||||
"github.com/caarlos0/env/v11"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/log"
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -102,8 +102,6 @@ func Get(configFile string, flags Flags) (*AppConfig, error) {
|
||||
"Do not use single replica and numbered (list) replica config combined")
|
||||
}
|
||||
|
||||
handleDeprecatedEnvVars(cfg)
|
||||
|
||||
if cfg.Replica != nil {
|
||||
cfg.Replicas = []types.AdGuardInstance{*cfg.Replica}
|
||||
cfg.Replica = nil
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
. "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"
|
||||
"github.com/bakito/adguardhome-sync/internal/config"
|
||||
flagsmock "github.com/bakito/adguardhome-sync/internal/mocks/flags"
|
||||
)
|
||||
|
||||
var _ = Describe("Config", func() {
|
||||
@@ -229,16 +229,6 @@ 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)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(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")
|
||||
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)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Get().Features.DNS.ServerConfig).Should(BeFalse())
|
||||
57
internal/config/env.go
Normal file
57
internal/config/env.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/caarlos0/env/v11"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
// Manually collect replicas from env.
|
||||
func enrichReplicasFromEnv(initialReplicas []types.AdGuardInstance) ([]types.AdGuardInstance, error) {
|
||||
var replicas []types.AdGuardInstance
|
||||
for _, v := range os.Environ() {
|
||||
if envReplicasURLPattern.MatchString(v) {
|
||||
sm := envReplicasURLPattern.FindStringSubmatch(v)
|
||||
id, _ := strconv.Atoi(sm[1])
|
||||
|
||||
if id <= 0 {
|
||||
return nil, fmt.Errorf("numbered replica env variables must have a number id >= 1, got %q", v)
|
||||
}
|
||||
|
||||
if id > len(initialReplicas) {
|
||||
replicas = append(replicas, types.AdGuardInstance{URL: sm[2]})
|
||||
} else {
|
||||
re := initialReplicas[id-1]
|
||||
re.URL = sm[2]
|
||||
replicas = append(replicas, re)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(replicas) == 0 {
|
||||
replicas = initialReplicas
|
||||
}
|
||||
|
||||
for i := range replicas {
|
||||
reID := i + 1
|
||||
|
||||
// keep the previously set value
|
||||
replicaDhcpServer := replicas[i].DHCPServerEnabled
|
||||
replicas[i].DHCPServerEnabled = nil
|
||||
if err := env.ParseWithOptions(&replicas[i], env.Options{Prefix: fmt.Sprintf("REPLICA%d_", reID)}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if replicas[i].DHCPServerEnabled == nil {
|
||||
replicas[i].DHCPServerEnabled = replicaDhcpServer
|
||||
}
|
||||
if replicas[i].APIPath == "" {
|
||||
replicas[i].APIPath = "/control"
|
||||
}
|
||||
}
|
||||
|
||||
return replicas, nil
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
func readFile(cfg *types.Config, path string) (string, error) {
|
||||
@@ -22,6 +22,7 @@ const (
|
||||
FlagFeatureClient = "feature-client-settings"
|
||||
FlagFeatureServices = "feature-services"
|
||||
FlagFeatureFilters = "feature-filters"
|
||||
FlagFeatureTLSConfig = "feature-tls-config"
|
||||
|
||||
FlagOriginURL = "origin-url"
|
||||
FlagOriginWebURL = "origin-web-url"
|
||||
@@ -1,7 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
func readFlags(cfg *types.Config, flags Flags) error {
|
||||
@@ -173,8 +173,13 @@ func (fr *flagReader) readFeatureFlags() error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return fr.setBoolFlag(FlagFeatureFilters, func(cgf *types.Config, value bool) {
|
||||
if err := fr.setBoolFlag(FlagFeatureFilters, func(cgf *types.Config, value bool) {
|
||||
fr.cfg.Features.Filters = value
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return fr.setBoolFlag(FlagFeatureTLSConfig, func(cgf *types.Config, value bool) {
|
||||
fr.cfg.Features.TLSConfig = value
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
. "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"
|
||||
flagsmock "github.com/bakito/adguardhome-sync/internal/mocks/flags"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
var _ = Describe("Config", func() {
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/client"
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/client"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
"github.com/bakito/adguardhome-sync/version"
|
||||
)
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/test/matchers"
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/test/matchers"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
"github.com/bakito/adguardhome-sync/version"
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
var _ = Describe("Config", func() {
|
||||
@@ -3,8 +3,8 @@ 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/bakito/adguardhome-sync/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
)
|
||||
|
||||
const StatsTotal = "total"
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
"k8s.io/utils/ptr"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
)
|
||||
|
||||
var _ = Describe("Metrics", func() {
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
)
|
||||
|
||||
const labelTotal = "Total"
|
||||
@@ -1,9 +1,9 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/bakito/adguardhome-sync/pkg/client (interfaces: Client)
|
||||
// Source: github.com/bakito/adguardhome-sync/internal/client (interfaces: Client)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package client -destination pkg/mocks/client/mock.go github.com/bakito/adguardhome-sync/pkg/client Client
|
||||
// mockgen -package client -destination internal/mocks/client/mock.go github.com/bakito/adguardhome-sync/internal/client Client
|
||||
//
|
||||
|
||||
// Package client is a generated GoMock package.
|
||||
@@ -12,7 +12,7 @@ package client
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
model "github.com/bakito/adguardhome-sync/pkg/client/model"
|
||||
model "github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
@@ -509,6 +509,20 @@ func (mr *MockClientMockRecorder) SetStatsConfig(sc any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStatsConfig", reflect.TypeOf((*MockClient)(nil).SetStatsConfig), sc)
|
||||
}
|
||||
|
||||
// SetTLSConfig mocks base method.
|
||||
func (m *MockClient) SetTLSConfig(tls *model.TlsConfig) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SetTLSConfig", tls)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SetTLSConfig indicates an expected call of SetTLSConfig.
|
||||
func (mr *MockClientMockRecorder) SetTLSConfig(tls any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTLSConfig", reflect.TypeOf((*MockClient)(nil).SetTLSConfig), tls)
|
||||
}
|
||||
|
||||
// Setup mocks base method.
|
||||
func (m *MockClient) Setup() error {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -568,6 +582,21 @@ func (mr *MockClientMockRecorder) Status() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Status", reflect.TypeOf((*MockClient)(nil).Status))
|
||||
}
|
||||
|
||||
// TLSConfig mocks base method.
|
||||
func (m *MockClient) TLSConfig() (*model.TlsConfig, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "TLSConfig")
|
||||
ret0, _ := ret[0].(*model.TlsConfig)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// TLSConfig indicates an expected call of TLSConfig.
|
||||
func (mr *MockClientMockRecorder) TLSConfig() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TLSConfig", reflect.TypeOf((*MockClient)(nil).TLSConfig))
|
||||
}
|
||||
|
||||
// ToggleFiltering mocks base method.
|
||||
func (m *MockClient) ToggleFiltering(enabled bool, interval int) error {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -1,9 +1,9 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/bakito/adguardhome-sync/pkg/config (interfaces: Flags)
|
||||
// Source: github.com/bakito/adguardhome-sync/internal/config (interfaces: Flags)
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -package client -destination pkg/mocks/flags/mock.go github.com/bakito/adguardhome-sync/pkg/config Flags
|
||||
// mockgen -package client -destination internal/mocks/flags/mock.go github.com/bakito/adguardhome-sync/internal/config Flags
|
||||
//
|
||||
|
||||
// Package client is a generated GoMock package.
|
||||
@@ -3,9 +3,9 @@ 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"
|
||||
"github.com/bakito/adguardhome-sync/internal/client"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -236,6 +236,22 @@ var (
|
||||
}
|
||||
return nil
|
||||
}
|
||||
tlsConfig = func(ac *actionContext) error {
|
||||
tlsc, err := ac.client.TLSConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !tlsc.Equals(ac.origin.tlsConfig) {
|
||||
if err := ac.client.SetTLSConfig(ac.origin.tlsConfig); err != nil {
|
||||
ac.rl.With("enabled", ac.origin.tlsConfig.Enabled, "error", err).Error("error setting tls config")
|
||||
if !ac.cfg.ContinueOnError {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
)
|
||||
|
||||
func syncFilterType(
|
||||
@@ -3,9 +3,9 @@ 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"
|
||||
"github.com/bakito/adguardhome-sync/internal/client"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
func setupActions(cfg *types.Config) (actions []syncAction) {
|
||||
@@ -68,6 +68,11 @@ func setupActions(cfg *types.Config) (actions []syncAction) {
|
||||
action("DHCP static leases", actionDHCPStaticLeases),
|
||||
)
|
||||
}
|
||||
if cfg.Features.TLSConfig {
|
||||
actions = append(actions,
|
||||
action("TLS config", tlsConfig),
|
||||
)
|
||||
}
|
||||
return actions
|
||||
}
|
||||
|
||||
@@ -16,20 +16,12 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/log"
|
||||
"github.com/bakito/adguardhome-sync/pkg/metrics"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/metrics"
|
||||
"github.com/bakito/adguardhome-sync/internal/sync/static"
|
||||
"github.com/bakito/adguardhome-sync/version"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed index.html
|
||||
index []byte
|
||||
//go:embed favicon.ico
|
||||
favicon []byte
|
||||
//go:embed logo.svg
|
||||
logo []byte
|
||||
)
|
||||
|
||||
func (w *worker) handleSync(c *gin.Context) {
|
||||
l.With("remote-addr", c.Request.RemoteAddr).Info("Starting sync from API")
|
||||
w.sync()
|
||||
@@ -45,39 +37,28 @@ func (w *worker) handleRoot(c *gin.Context) {
|
||||
"Build": version.Build,
|
||||
"SyncStatus": w.status(),
|
||||
"Stats": map[string]any{
|
||||
"Labels": getLast24Hours(),
|
||||
"DNS": dns,
|
||||
"Blocked": blocked,
|
||||
"BlockedPercentage": fmt.Sprintf(
|
||||
"%.2f",
|
||||
(float64(*total.NumBlockedFiltering)*100.0)/float64(*total.NumDnsQueries),
|
||||
),
|
||||
"Malware": malware,
|
||||
"MalwarePercentage": fmt.Sprintf(
|
||||
"%.2f",
|
||||
(float64(*total.NumReplacedSafebrowsing)*100.0)/float64(*total.NumDnsQueries),
|
||||
),
|
||||
"Adult": adult,
|
||||
"AdultPercentage": fmt.Sprintf(
|
||||
"%.2f",
|
||||
(float64(*total.NumReplacedParental)*100.0)/float64(*total.NumDnsQueries),
|
||||
),
|
||||
|
||||
"TotalDNS": total.NumDnsQueries,
|
||||
"TotalBlocked": total.NumBlockedFiltering,
|
||||
"TotalMalware": total.NumReplacedSafebrowsing,
|
||||
"TotalAdult": total.NumReplacedParental,
|
||||
"Labels": getLast24Hours(),
|
||||
"DNS": dns,
|
||||
"Blocked": blocked,
|
||||
"BlockedPercentage": percent(total.NumBlockedFiltering, total.NumDnsQueries),
|
||||
"Malware": malware,
|
||||
"MalwarePercentage": percent(total.NumReplacedSafebrowsing, total.NumDnsQueries),
|
||||
"Adult": adult,
|
||||
"AdultPercentage": percent(total.NumReplacedParental, total.NumDnsQueries),
|
||||
"TotalDNS": total.NumDnsQueries,
|
||||
"TotalBlocked": total.NumBlockedFiltering,
|
||||
"TotalMalware": total.NumReplacedSafebrowsing,
|
||||
"TotalAdult": total.NumReplacedParental,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (w *worker) handleFavicon(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "image/x-icon", favicon)
|
||||
}
|
||||
|
||||
func (w *worker) handleLogo(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "image/svg+xml", logo)
|
||||
func percent(a, b *int) string {
|
||||
if a == nil || b == nil || *b == 0 {
|
||||
return "0.00"
|
||||
}
|
||||
return fmt.Sprintf("%.2f", (float64(*a)*100.0)/float64(*b))
|
||||
}
|
||||
|
||||
func (w *worker) handleLogs(c *gin.Context) {
|
||||
@@ -94,7 +75,21 @@ func (w *worker) handleStatus(c *gin.Context) {
|
||||
}
|
||||
|
||||
func (w *worker) handleHealthz(c *gin.Context) {
|
||||
c.Status(w.healthz())
|
||||
status := w.status()
|
||||
|
||||
if status.Origin.Status != "success" {
|
||||
c.Status(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
|
||||
for _, replica := range status.Replicas {
|
||||
if replica.Status != "success" {
|
||||
c.Status(http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.Status(http.StatusOK)
|
||||
}
|
||||
|
||||
func (w *worker) listenAndServe() {
|
||||
@@ -123,8 +118,7 @@ func (w *worker) listenAndServe() {
|
||||
group.GET("/api/v1/logs", w.handleLogs)
|
||||
group.POST("/api/v1/clear-logs", w.handleClearLogs)
|
||||
group.GET("/api/v1/status", w.handleStatus)
|
||||
group.GET("/favicon.ico", w.handleFavicon)
|
||||
group.GET("/logo.svg", w.handleLogo)
|
||||
static.HandleResources(group, w.cfg.API.DarkMode)
|
||||
group.GET("/", w.handleRoot)
|
||||
if w.cfg.API.Metrics.Enabled {
|
||||
group.GET("/metrics", metrics.Handler())
|
||||
@@ -139,7 +133,7 @@ func (w *worker) listenAndServe() {
|
||||
ReadHeaderTimeout: 1 * time.Second,
|
||||
}
|
||||
|
||||
r.SetHTMLTemplate(template.Must(template.New("index.html").Parse(string(index))))
|
||||
r.SetHTMLTemplate(template.Must(template.New("index.html").Parse(static.Index())))
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
30
internal/sync/http_test.go
Normal file
30
internal/sync/http_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Percent", func() {
|
||||
DescribeTable("calculating percentage",
|
||||
func(a, b *int, want string) {
|
||||
Expect(percent(a, b)).To(Equal(want))
|
||||
},
|
||||
Entry("both inputs are nil", nil, nil, "0.00"),
|
||||
Entry("a is nil, b is non-zero", nil, intPtr(10), "0.00"),
|
||||
Entry("b is nil, a is non-zero", intPtr(10), nil, "0.00"),
|
||||
Entry("b is zero", intPtr(10), intPtr(0), "0.00"),
|
||||
Entry("normal case with positive int values", intPtr(25), intPtr(100), "25.00"),
|
||||
Entry("a and b are equal", intPtr(50), intPtr(50), "100.00"),
|
||||
Entry("a is zero, b is positive", intPtr(0), intPtr(50), "0.00"),
|
||||
Entry("large positive values", intPtr(1000), intPtr(4000), "25.00"),
|
||||
Entry("a greater than b", intPtr(150), intPtr(100), "150.00"),
|
||||
Entry("negative values for a and b", intPtr(-25), intPtr(-50), "50.00"),
|
||||
Entry("a is positive, b is negative", intPtr(25), intPtr(-50), "-50.00"),
|
||||
Entry("a is negative, b is positive", intPtr(-25), intPtr(50), "-50.00"),
|
||||
)
|
||||
})
|
||||
|
||||
func intPtr(i int) *int {
|
||||
return &i
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package sync
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/metrics"
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/metrics"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
)
|
||||
|
||||
func (w *worker) startScraping() {
|
||||
6
internal/sync/static/bootstrap.min-5.3.3.css
vendored
Normal file
6
internal/sync/static/bootstrap.min-5.3.3.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
internal/sync/static/bootstrap.min-5.3.3.js
vendored
Normal file
7
internal/sync/static/bootstrap.min-5.3.3.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
internal/sync/static/bootstrap.min-darkly-5.3.css
vendored
Normal file
12
internal/sync/static/bootstrap.min-darkly-5.3.css
vendored
Normal file
File diff suppressed because one or more lines are too long
20
internal/sync/static/chart.umd.min-4.4.7.js
Normal file
20
internal/sync/static/chart.umd.min-4.4.7.js
Normal file
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -1,16 +1,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>AdGuard Home sync</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-3.7.1.min.js">
|
||||
</script>
|
||||
{{- if .DarkMode }}
|
||||
<link rel="stylesheet" href="https://bootswatch.com/5/darkly/bootstrap.min.css"
|
||||
crossorigin="anonymous">
|
||||
{{- else }}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
||||
crossorigin="anonymous">
|
||||
{{- end }}
|
||||
<script type="text/javascript" src="lib/jquery.js"></script>
|
||||
<link rel="stylesheet" href="lib/bootstrap.css">
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$("#showLogs").click(function () {
|
||||
@@ -168,16 +160,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- openssl dgst -sha384 -binary popper.min.js | openssl base64 -A -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"
|
||||
integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous">
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
||||
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous">
|
||||
</script>
|
||||
<script src="lib/popper.js" ></script>
|
||||
<script src="lib/bootstrap.js" ></script>
|
||||
{{- if .Metrics }}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"ŝ
|
||||
integrity="sha384-vsrfeLOOY6KuIYKDlmVH5UiBmgIdB1oEf7p01YgWHuqmOHfZr374+odEv96n9tNC" crossorigin="anonymous">
|
||||
</script>
|
||||
<script src="lib/chart.js" ></script>
|
||||
<script>
|
||||
// Function to create minimal line charts
|
||||
function createChart(canvasId, data) {
|
||||
2
internal/sync/static/jquery-3.7.1.min.js
vendored
Normal file
2
internal/sync/static/jquery-3.7.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
internal/sync/static/logo.svg
Normal file
1
internal/sync/static/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg3" version="1.2" viewBox="0 0 1000 1000"><defs id="defs3"><linearGradient id="swatch26"><stop style="stop-color:#000;stop-opacity:1" id="stop26" offset="0"/></linearGradient><linearGradient id="swatch25"><stop style="stop-color:#407b28;stop-opacity:1" id="stop25" offset="0"/></linearGradient></defs><path id="path1" fill="#68bc71" d="m 993.75002,114.1 c 0,171.8 3.1,595.3 -493.8,885.9 C 3.0500233,709.4 6.2500233,285.9 6.2500233,114.1 159.35002,35.9 345.25002,0 499.95002,0 c 154.7,0 340.6,35.9 493.8,114.1 z"/><path id="path2" fill="#67b279" d="M500 1000C3.1 709.4 6.2 285.9 6.2 114.1 159.4 35.9 345.3 0 500 0z"/><path id="path3" fill="#fff" d="m 225,449.6 c 15,-11.7 80,-53.4 128.3,1.6 L 453.3,569.6 720,297.9 c 11.7,-10 31.7,-23.3 55,-5 L 455,716.2 Z" style="display:none"/><circle style="display:none;fill:#fff;fill-opacity:.5;stroke:#fff;stroke-width:8e-08;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:.502604" id="path18" cx="-500" cy="426" r="400" transform="scale(-1,1)"/><path id="path12-8" style="fill:#fff;fill-opacity:1;stroke:#fff;stroke-width:4.00001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:1" d="m -75.867249,555.75073 c -1.469322,-39.92741 -12.296964,-76.43624 -30.823861,-104.61661 -21.05517,28.18037 -47.89663,45.38022 -75.18829,53.68483 l 42.51192,20.42415 c -33.35434,61.94297 -101.60764,105.3289 -167.51689,101.23666 -42.42317,-1.43193 -82.3318,-22.18867 -112.01355,-52.33871 -21.09944,-21.43232 -53.37423,-31.44115 -79.38397,-16.1329 l -10.3958,6.11853 c 43.49744,68.86447 120.54256,113.80911 201.79332,112.04834 87.97224,-4.41047 162.60077,-62.73987 194.96448,-137.74518 z M -537.90127,346.51705 c 1.46924,39.92741 12.29681,76.43626 30.82364,104.61667 21.05523,-28.18031 47.89674,-45.38011 75.18842,-53.68467 l -42.51189,-20.42423 c 33.35441,-61.94281 101.60759,-105.32857 167.51673,-101.23635 42.4233,1.43194 82.33203,22.18879 112.01381,52.33897 21.0994,21.43235 53.37417,31.44124 79.38393,16.13305 l 10.39581,-6.11852 c -43.49739,-68.86468 -120.54264,-113.8095 -201.79355,-112.04872 -87.97208,4.41046 -162.60049,62.73965 -194.96429,137.74477 z" transform="matrix(0,-1.3167476,1.3167476,0,-94.029776,21.910887)"/></svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
6
internal/sync/static/popper.min-2.9.2.js
Normal file
6
internal/sync/static/popper.min-2.9.2.js
Normal file
File diff suppressed because one or more lines are too long
80
internal/sync/static/static.go
Normal file
80
internal/sync/static/static.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed index.html
|
||||
index string
|
||||
|
||||
//go:embed favicon.ico
|
||||
favicon []byte
|
||||
|
||||
//go:embed logo.svg
|
||||
logo []byte
|
||||
|
||||
//go:embed bootstrap.min-5.3.3.js
|
||||
bootstrapJS []byte
|
||||
|
||||
// https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css
|
||||
//go:embed bootstrap.min-5.3.3.css
|
||||
bootstrapCSS []byte
|
||||
|
||||
// https://bootswatch.com/5/darkly/bootstrap.min.css
|
||||
//go:embed bootstrap.min-darkly-5.3.css
|
||||
bootstrapDarkCSS []byte
|
||||
|
||||
// https://code.jquery.com/jquery-3.7.1.min.js
|
||||
//go:embed jquery-3.7.1.min.js
|
||||
jquery []byte
|
||||
|
||||
// https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js
|
||||
//go:embed popper.min-2.9.2.js
|
||||
popper []byte
|
||||
|
||||
// https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js
|
||||
//go:embed chart.umd.min-4.4.7.js
|
||||
chart []byte
|
||||
)
|
||||
|
||||
func handleFavicon(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "image/x-icon", favicon)
|
||||
}
|
||||
|
||||
func handleLogo(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "image/svg+xml", logo)
|
||||
}
|
||||
|
||||
func Index() string {
|
||||
return index
|
||||
}
|
||||
|
||||
func HandleResources(group gin.IRouter, dark bool) {
|
||||
group.GET("/favicon.ico", handleFavicon)
|
||||
group.GET("/logo.svg", handleLogo)
|
||||
group.GET("/lib/jquery.js", handleJS(jquery))
|
||||
group.GET("/lib/popper.js", handleJS(popper))
|
||||
group.GET("/lib/chart.js", handleJS(chart))
|
||||
group.GET("/lib/bootstrap.js", handleJS(bootstrapJS))
|
||||
if dark {
|
||||
group.GET("/lib/bootstrap.css", handleCSS(bootstrapDarkCSS))
|
||||
} else {
|
||||
group.GET("/lib/bootstrap.css", handleCSS(bootstrapCSS))
|
||||
}
|
||||
}
|
||||
|
||||
func handleJS(bytes []byte) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "application/javascript", bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func handleCSS(bytes []byte) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "text/css", bytes)
|
||||
}
|
||||
}
|
||||
@@ -3,28 +3,25 @@ package sync
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"sort"
|
||||
"time"
|
||||
"regexp"
|
||||
|
||||
"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"
|
||||
"github.com/bakito/adguardhome-sync/pkg/metrics"
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/pkg/utils"
|
||||
"github.com/bakito/adguardhome-sync/pkg/versions"
|
||||
"github.com/bakito/adguardhome-sync/internal/client"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
"github.com/bakito/adguardhome-sync/internal/log"
|
||||
"github.com/bakito/adguardhome-sync/internal/metrics"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
"github.com/bakito/adguardhome-sync/internal/versions"
|
||||
"github.com/bakito/adguardhome-sync/version"
|
||||
)
|
||||
|
||||
var (
|
||||
l = log.GetLogger("sync")
|
||||
fixVersionCompareRegExp = regexp.MustCompile(`[^0-9.]`)
|
||||
)
|
||||
var l = log.GetLogger("sync")
|
||||
|
||||
// Sync config from origin to replica.
|
||||
func Sync(cfg *types.Config) error {
|
||||
@@ -124,22 +121,6 @@ func (w *worker) status() *syncStatus {
|
||||
return syncStatus
|
||||
}
|
||||
|
||||
func (w *worker) healthz() int {
|
||||
status := w.status()
|
||||
|
||||
if status.Origin.Status != "success" {
|
||||
return 503
|
||||
}
|
||||
|
||||
for _, replica := range status.Replicas {
|
||||
if replica.Status != "success" {
|
||||
return 503
|
||||
}
|
||||
}
|
||||
|
||||
return 200
|
||||
}
|
||||
|
||||
func (w *worker) getStatus(inst types.AdGuardInstance) replicaStatus {
|
||||
st := replicaStatus{Host: inst.WebHost, URL: inst.WebURL}
|
||||
|
||||
@@ -204,7 +185,14 @@ func (w *worker) sync() {
|
||||
o.profileInfo, err = oc.ProfileInfo()
|
||||
if err != nil {
|
||||
sl.With("error", err).Error("Error getting profileInfo info")
|
||||
return
|
||||
|
||||
// Workaround for https://github.com/AdguardTeam/AdGuardHome/issues/7987
|
||||
// and https://github.com/AdguardTeam/AdGuardHome/issues/7985
|
||||
|
||||
clientErr := &client.Error{}
|
||||
if !w.cfg.ContinueOnError || !errors.As(err, &clientErr) || clientErr.Code() != http.StatusUnauthorized {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
o.parental, err = oc.Parental()
|
||||
@@ -276,6 +264,14 @@ func (w *worker) sync() {
|
||||
}
|
||||
}
|
||||
|
||||
if w.cfg.Features.TLSConfig {
|
||||
o.tlsConfig, err = oc.TLSConfig()
|
||||
if err != nil {
|
||||
sl.With("error", err).Error("Error getting tls config")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
w.actions = setupActions(w.cfg)
|
||||
|
||||
replicas := w.cfg.UniqueReplicas()
|
||||
@@ -313,9 +309,6 @@ func (w *worker) syncTo(l *zap.SugaredLogger, o *origin, replica types.AdGuardIn
|
||||
return
|
||||
}
|
||||
|
||||
replicaStatus.Version = fixVersionCompareRegExp.ReplaceAllString(replicaStatus.Version, "")
|
||||
o.status.Version = fixVersionCompareRegExp.ReplaceAllString(o.status.Version, "")
|
||||
|
||||
rl.With("version", replicaStatus.Version).Info("Connected to replica")
|
||||
|
||||
if versions.IsNewerThan(versions.MinAgh, replicaStatus.Version) {
|
||||
@@ -384,4 +377,5 @@ type origin struct {
|
||||
safeSearch *model.SafeSearchConfig
|
||||
profileInfo *model.ProfileInfo
|
||||
safeBrowsing bool
|
||||
tlsConfig *model.TlsConfig
|
||||
}
|
||||
@@ -8,12 +8,12 @@ import (
|
||||
. "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/bakito/adguardhome-sync/internal/client"
|
||||
"github.com/bakito/adguardhome-sync/internal/client/model"
|
||||
clientmock "github.com/bakito/adguardhome-sync/internal/mocks/client"
|
||||
"github.com/bakito/adguardhome-sync/internal/types"
|
||||
"github.com/bakito/adguardhome-sync/internal/utils"
|
||||
"github.com/bakito/adguardhome-sync/internal/versions"
|
||||
)
|
||||
|
||||
var _ = Describe("Sync", func() {
|
||||
@@ -594,6 +594,7 @@ var _ = Describe("Sync", func() {
|
||||
GeneralSettings: true,
|
||||
StatsConfig: true,
|
||||
QueryLogConfig: true,
|
||||
TLSConfig: true,
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -614,6 +615,7 @@ var _ = Describe("Sync", func() {
|
||||
cl.EXPECT().AccessList().Return(&model.AccessList{}, nil)
|
||||
cl.EXPECT().DNSConfig().Return(&model.DNSConfig{}, nil)
|
||||
cl.EXPECT().DhcpConfig().Return(&model.DhcpStatus{}, nil)
|
||||
cl.EXPECT().TLSConfig().Return(&model.TlsConfig{}, nil)
|
||||
|
||||
// replica
|
||||
cl.EXPECT().Host()
|
||||
@@ -633,6 +635,7 @@ var _ = Describe("Sync", func() {
|
||||
cl.EXPECT().AccessList().Return(&model.AccessList{}, nil)
|
||||
cl.EXPECT().DNSConfig().Return(&model.DNSConfig{}, nil)
|
||||
cl.EXPECT().DhcpConfig().Return(&model.DhcpStatus{}, nil)
|
||||
cl.EXPECT().TLSConfig().Return(&model.TlsConfig{}, nil)
|
||||
w.sync()
|
||||
})
|
||||
It("should not sync DHCP", func() {
|
||||
@@ -653,6 +656,7 @@ var _ = Describe("Sync", func() {
|
||||
cl.EXPECT().StatsConfig().Return(&model.PutStatsConfigUpdateRequest{}, nil)
|
||||
cl.EXPECT().AccessList().Return(&model.AccessList{}, nil)
|
||||
cl.EXPECT().DNSConfig().Return(&model.DNSConfig{}, nil)
|
||||
cl.EXPECT().TLSConfig().Return(&model.TlsConfig{}, nil)
|
||||
|
||||
// replica
|
||||
cl.EXPECT().Host()
|
||||
@@ -671,6 +675,7 @@ var _ = Describe("Sync", func() {
|
||||
cl.EXPECT().Clients().Return(&model.Clients{}, nil)
|
||||
cl.EXPECT().AccessList().Return(&model.AccessList{}, nil)
|
||||
cl.EXPECT().DNSConfig().Return(&model.DNSConfig{}, nil)
|
||||
cl.EXPECT().TLSConfig().Return(&model.TlsConfig{}, nil)
|
||||
w.sync()
|
||||
})
|
||||
It("origin version is too small", func() {
|
||||
@@ -696,6 +701,7 @@ var _ = Describe("Sync", func() {
|
||||
cl.EXPECT().AccessList().Return(&model.AccessList{}, nil)
|
||||
cl.EXPECT().DNSConfig().Return(&model.DNSConfig{}, nil)
|
||||
cl.EXPECT().DhcpConfig().Return(&model.DhcpStatus{}, nil)
|
||||
cl.EXPECT().TLSConfig().Return(&model.TlsConfig{}, nil)
|
||||
|
||||
// replica
|
||||
cl.EXPECT().Host().Times(2)
|
||||
@@ -22,6 +22,7 @@ func NewFeatures(enabled bool) Features {
|
||||
Services: enabled,
|
||||
Filters: enabled,
|
||||
Theme: enabled,
|
||||
TLSConfig: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +36,8 @@ type Features struct {
|
||||
ClientSettings bool `json:"clientSettings" yaml:"clientSettings" documentation:"Sync client settings" env:"FEATURES_CLIENT_SETTINGS"`
|
||||
Services bool `json:"services" yaml:"services" documentation:"Sync services" env:"FEATURES_SERVICES"`
|
||||
Filters bool `json:"filters" yaml:"filters" documentation:"Sync filters" env:"FEATURES_FILTERS"`
|
||||
Theme bool `json:"theme" yaml:"theme" documentation:"Sync the weg UI theme" env:"FEATURES_THEME"`
|
||||
Theme bool `json:"theme" yaml:"theme" documentation:"Sync the web UI theme" env:"FEATURES_THEME"`
|
||||
TLSConfig bool `json:"tlsConfig" yaml:"tlsConfig" documentation:"Sync the TLS config" env:"FEATURES_TLS_CONFIG"`
|
||||
}
|
||||
|
||||
// DHCP features.
|
||||
@@ -95,5 +97,8 @@ func (f *Features) collectDisabled() []string {
|
||||
if !f.Filters {
|
||||
features = append(features, "Filters")
|
||||
}
|
||||
if !f.TLSConfig {
|
||||
features = append(features, "TLSConfig")
|
||||
}
|
||||
return features
|
||||
}
|
||||
@@ -20,28 +20,28 @@ const (
|
||||
// Config application configuration struct
|
||||
// +k8s:deepcopy-gen=true
|
||||
type Config struct {
|
||||
Cron string `documentation:"Cron expression for the sync interval" env:"CRON" json:"cron,omitempty" yaml:"cron,omitempty"`
|
||||
RunOnStart bool `documentation:"Run the sync on startup" env:"RUN_ON_START" json:"runOnStart,omitempty" yaml:"runOnStart,omitempty"`
|
||||
PrintConfigOnly bool `documentation:"Print current config only and stop the application" env:"PRINT_CONFIG_ONLY" json:"printConfigOnly,omitempty" yaml:"printConfigOnly,omitempty"`
|
||||
ContinueOnError bool `documentation:"Continue sync on errors" env:"CONTINUE_ON_ERROR" json:"continueOnError,omitempty" yaml:"continueOnError,omitempty"`
|
||||
// Origin adguardhome instance
|
||||
Origin *AdGuardInstance `json:"origin" yaml:"origin"`
|
||||
Origin *AdGuardInstance `documentation:"Origin instance" json:"origin" yaml:"origin"`
|
||||
// One single replica adguardhome instance
|
||||
Replica *AdGuardInstance `json:"replica,omitempty" yaml:"replica,omitempty"`
|
||||
Replica *AdGuardInstance `documentation:"Single or replica instance (don't use in combination with replicas')" json:"replica,omitempty" yaml:"replica,omitempty"`
|
||||
// Multiple replica instances
|
||||
Replicas []AdGuardInstance `json:"replicas,omitempty" yaml:"replicas,omitempty" faker:"slice_len=2"`
|
||||
Cron string `json:"cron,omitempty" yaml:"cron,omitempty" documentation:"Cron expression for the sync interval" env:"CRON"`
|
||||
RunOnStart bool `json:"runOnStart,omitempty" yaml:"runOnStart,omitempty" documentation:"Run the sung on startup" env:"RUN_ON_START"`
|
||||
PrintConfigOnly bool `json:"printConfigOnly,omitempty" yaml:"printConfigOnly,omitempty" documentation:"Print current config only and stop the application" env:"PRINT_CONFIG_ONLY"`
|
||||
ContinueOnError bool `json:"continueOnError,omitempty" yaml:"continueOnError,omitempty" documentation:"Continue sync on errors" env:"CONTINUE_ON_ERROR"`
|
||||
API API `json:"api,omitempty" yaml:"api,omitempty"`
|
||||
Features Features `json:"features,omitempty" yaml:"features,omitempty"`
|
||||
Replicas []AdGuardInstance `documentation:"List or replica instances (don't use in combination with replicas')" json:"replicas,omitempty" yaml:"replicas,omitempty" faker:"slice_len=2"`
|
||||
API API ` json:"api,omitempty" yaml:"api,omitempty"`
|
||||
Features Features ` json:"features,omitempty" yaml:"features,omitempty"`
|
||||
}
|
||||
|
||||
// API configuration.
|
||||
type API struct {
|
||||
Port int `documentation:"API port" env:"API_PORT" json:"port,omitempty" yaml:"port,omitempty"`
|
||||
Username string `documentation:"API username" env:"API_USERNAME" json:"username,omitempty" yaml:"username,omitempty"`
|
||||
Password string `documentation:"API password" env:"API_PASSWORD" json:"password,omitempty" yaml:"password,omitempty"`
|
||||
DarkMode bool `documentation:"API dark mode" env:"API_DARK_MODE" json:"darkMode,omitempty" yaml:"darkMode,omitempty"`
|
||||
Metrics Metrics ` json:"metrics,omitempty" yaml:"metrics,omitempty"`
|
||||
TLS TLS ` json:"tls,omitempty" yaml:"tls,omitempty"`
|
||||
Port int `documentation:"API port (API is disabled if port is set to 0)" env:"API_PORT" json:"port,omitempty" yaml:"port,omitempty"`
|
||||
Username string `documentation:"API username" env:"API_USERNAME" json:"username,omitempty" yaml:"username,omitempty"`
|
||||
Password string `documentation:"API password" env:"API_PASSWORD" json:"password,omitempty" yaml:"password,omitempty"`
|
||||
DarkMode bool `documentation:"API dark mode" env:"API_DARK_MODE" json:"darkMode,omitempty" yaml:"darkMode,omitempty"`
|
||||
Metrics Metrics ` json:"metrics,omitempty" yaml:"metrics,omitempty"`
|
||||
TLS TLS ` json:"tls,omitempty" yaml:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// Metrics configuration.
|
||||
@@ -102,11 +102,11 @@ var _ = Describe("Types", func() {
|
||||
Context("LogDisabled", func() {
|
||||
It("should log all features", func() {
|
||||
f := NewFeatures(false)
|
||||
Ω(f.collectDisabled()).Should(HaveLen(11))
|
||||
Ω(f.collectDisabled()).Should(HaveLen(12))
|
||||
})
|
||||
It("should log no features", func() {
|
||||
f := NewFeatures(true)
|
||||
Ω(f.collectDisabled()).Should(BeEmpty())
|
||||
Ω(f.collectDisabled()).Should(HaveLen(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/versions"
|
||||
"github.com/bakito/adguardhome-sync/internal/versions"
|
||||
)
|
||||
|
||||
var _ = Describe("Versions", func() {
|
||||
@@ -14,6 +14,11 @@ var _ = Describe("Versions", func() {
|
||||
Ω(versions.IsNewerThan("v0.106.9", "v0.106.10")).Should(BeFalse())
|
||||
Ω(versions.IsNewerThan("v0.106.10", "0.106.9")).Should(BeTrue())
|
||||
Ω(versions.IsNewerThan("v0.106.9", "0.106.10")).Should(BeFalse())
|
||||
// tests for #607
|
||||
Ω(versions.IsNewerThan("v0.108.0-b.72", versions.MinAgh)).Should(BeTrue())
|
||||
Ω(versions.IsNewerThan("0.108.0-b.72", versions.MinAgh)).Should(BeTrue())
|
||||
Ω(versions.IsNewerThan(versions.MinAgh, "v0.108.0-b.72")).Should(BeFalse())
|
||||
Ω(versions.IsNewerThan(versions.MinAgh, "0.108.0-b.72")).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
Context("IsSame", func() {
|
||||
@@ -1,190 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.2"
|
||||
viewBox="0 0 1000 1000"
|
||||
id="svg3"
|
||||
sodipodi:docname="adguardhome-sync.svg"
|
||||
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect18"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,54.646215,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,54.646212,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="skeletal"
|
||||
id="path-effect13"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
pattern="m 78.30448,0.02132 c -1.76356,0.0996 -3.48821,0.55822 -5.06836,1.34765 L 5.80252,35.08773 c -18.554321,9.281429 -18.766576,9.393634 0,18.78124 l 67.4336,33.71876 c 8.62996,4.31519 18.78393,-1.9607 18.7832,-11.60938 v -11.5 h 213 c 6.62742,0 12,-5.372583 12,-12 v -16 c 0,-6.627417 -5.37258,-12 -12,-12 h -213 v -11.5 C 92.01887,5.52137 85.74946,-0.40162 78.30448,0.02132 Z"
|
||||
copytype="repeated_stretched"
|
||||
prop_scale="1"
|
||||
scale_y_rel="false"
|
||||
spacing="100"
|
||||
normal_offset="0"
|
||||
tang_offset="0"
|
||||
prop_units="false"
|
||||
vertical_pattern="false"
|
||||
hide_knot="false"
|
||||
fuse_tolerance="0"
|
||||
pattern-nodetypes="cccccccssssccc" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect11"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,12,0,1 @ F,0,1,1,0,12,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect33"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param=""
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<linearGradient
|
||||
id="swatch26"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop26" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch25"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#407b28;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop25" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 500 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1000 : 500 : 1"
|
||||
inkscape:persp3d-origin="500 : 333.33333 : 1"
|
||||
id="perspective6" />
|
||||
<inkscape:path-effect
|
||||
effect="skeletal"
|
||||
id="path-effect13-9"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
pattern="m -435.41689,700.31394 -82.73956,27.87776 82.73956,31.49534 v -23.8092 l 434.54687,9.11337 v -33.59902 l -434.54687,9.11337 z"
|
||||
copytype="repeated_stretched"
|
||||
prop_scale="2"
|
||||
scale_y_rel="false"
|
||||
spacing="100"
|
||||
normal_offset="0"
|
||||
tang_offset="0"
|
||||
prop_units="false"
|
||||
vertical_pattern="false"
|
||||
hide_knot="false"
|
||||
fuse_tolerance="0"
|
||||
pattern-nodetypes="sccccccs" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="0.70710678"
|
||||
inkscape:cx="540.93669"
|
||||
inkscape:cy="502.04582"
|
||||
inkscape:window-width="1556"
|
||||
inkscape:window-height="1360"
|
||||
inkscape:window-x="1868"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg3" />
|
||||
<path
|
||||
fill="#68bc71"
|
||||
d="m 993.75002,114.1 c 0,171.8 3.1,595.3 -493.8,885.9 C 3.0500233,709.4 6.2500233,285.9 6.2500233,114.1 159.35002,35.9 345.25002,0 499.95002,0 c 154.7,0 340.6,35.9 493.8,114.1 z"
|
||||
id="path1"
|
||||
inkscape:label="shield" />
|
||||
<path
|
||||
fill="#67b279"
|
||||
d="M500 1000C3.1 709.4 6.2 285.9 6.2 114.1 159.4 35.9 345.3 0 500 0z"
|
||||
id="path2"
|
||||
inkscape:label="half-shield" />
|
||||
<path
|
||||
fill="#ffffff"
|
||||
d="m 225,449.6 c 15,-11.7 80,-53.4 128.3,1.6 L 453.3,569.6 720,297.9 c 11.7,-10 31.7,-23.3 55,-5 L 455,716.2 Z"
|
||||
id="path3"
|
||||
inkscape:label="checkmark"
|
||||
style="display:none" />
|
||||
<circle
|
||||
style="display:none;fill:#ffffff;fill-opacity:0.5;stroke:#ffffff;stroke-width:8e-08;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:0.502604"
|
||||
id="path18"
|
||||
cx="-500"
|
||||
cy="426"
|
||||
r="400"
|
||||
inkscape:label="badge"
|
||||
transform="scale(-1,1)" />
|
||||
<path
|
||||
id="path12-8"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:4.00001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -75.867249,555.75073 c -1.469322,-39.92741 -12.296964,-76.43624 -30.823861,-104.61661 -21.05517,28.18037 -47.89663,45.38022 -75.18829,53.68483 l 42.51192,20.42415 c -33.35434,61.94297 -101.60764,105.3289 -167.51689,101.23666 -42.42317,-1.43193 -82.3318,-22.18867 -112.01355,-52.33871 -21.09944,-21.43232 -53.37423,-31.44115 -79.38397,-16.1329 l -10.3958,6.11853 c 43.49744,68.86447 120.54256,113.80911 201.79332,112.04834 87.97224,-4.41047 162.60077,-62.73987 194.96448,-137.74518 z M -537.90127,346.51705 c 1.46924,39.92741 12.29681,76.43626 30.82364,104.61667 21.05523,-28.18031 47.89674,-45.38011 75.18842,-53.68467 l -42.51189,-20.42423 c 33.35441,-61.94281 101.60759,-105.32857 167.51673,-101.23635 42.4233,1.43194 82.33203,22.18879 112.01381,52.33897 21.0994,21.43235 53.37417,31.44124 79.38393,16.13305 l 10.39581,-6.11852 c -43.49739,-68.86468 -120.54264,-113.8095 -201.79355,-112.04872 -87.97208,4.41046 -162.60049,62.73965 -194.96429,137.74477 z"
|
||||
transform="matrix(0,-1.3167476,1.3167476,0,-94.029776,21.910887)"
|
||||
inkscape:label="double-arrow"
|
||||
inkscape:path-effect="#path-effect1"
|
||||
inkscape:original-d="m -75.867249,555.75073 c -1.469322,-39.92741 -12.296964,-76.43624 -30.823861,-104.61661 -21.05517,28.18037 -47.89663,45.38022 -75.18829,53.68483 l 42.51192,20.42415 c -33.35434,61.94297 -101.60764,105.3289 -167.51689,101.23666 -42.42317,-1.43193 -82.3318,-22.18867 -112.01355,-52.33871 -21.09944,-21.43232 -53.37423,-31.44115 -79.38397,-16.1329 l -10.3958,6.11853 c 43.49744,68.86447 120.54256,113.80911 201.79332,112.04834 87.97224,-4.41047 162.60077,-62.73987 194.96448,-137.74518 z M -537.90127,346.51705 c 1.46924,39.92741 12.29681,76.43626 30.82364,104.61667 21.05523,-28.18031 47.89674,-45.38011 75.18842,-53.68467 l -42.51189,-20.42423 c 33.35441,-61.94281 101.60759,-105.32857 167.51673,-101.23635 42.4233,1.43194 82.33203,22.18879 112.01381,52.33897 21.0994,21.43235 53.37417,31.44124 79.38393,16.13305 l 10.39581,-6.11852 c -43.49739,-68.86468 -120.54264,-113.8095 -201.79355,-112.04872 -87.97208,4.41046 -162.60049,62.73965 -194.96429,137.74477 z" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg3" version="1.2" viewBox="0 0 1000 1000"><defs id="defs3"><linearGradient id="swatch26"><stop style="stop-color:#000;stop-opacity:1" id="stop26" offset="0"/></linearGradient><linearGradient id="swatch25"><stop style="stop-color:#407b28;stop-opacity:1" id="stop25" offset="0"/></linearGradient></defs><path id="path1" fill="#68bc71" d="m 993.75002,114.1 c 0,171.8 3.1,595.3 -493.8,885.9 C 3.0500233,709.4 6.2500233,285.9 6.2500233,114.1 159.35002,35.9 345.25002,0 499.95002,0 c 154.7,0 340.6,35.9 493.8,114.1 z"/><path id="path2" fill="#67b279" d="M500 1000C3.1 709.4 6.2 285.9 6.2 114.1 159.4 35.9 345.3 0 500 0z"/><path id="path3" fill="#fff" d="m 225,449.6 c 15,-11.7 80,-53.4 128.3,1.6 L 453.3,569.6 720,297.9 c 11.7,-10 31.7,-23.3 55,-5 L 455,716.2 Z" style="display:none"/><circle style="display:none;fill:#fff;fill-opacity:.5;stroke:#fff;stroke-width:8e-08;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:.502604" id="path18" cx="-500" cy="426" r="400" transform="scale(-1,1)"/><path id="path12-8" style="fill:#fff;fill-opacity:1;stroke:#fff;stroke-width:4.00001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:1" d="m -75.867249,555.75073 c -1.469322,-39.92741 -12.296964,-76.43624 -30.823861,-104.61661 -21.05517,28.18037 -47.89663,45.38022 -75.18829,53.68483 l 42.51192,20.42415 c -33.35434,61.94297 -101.60764,105.3289 -167.51689,101.23666 -42.42317,-1.43193 -82.3318,-22.18867 -112.01355,-52.33871 -21.09944,-21.43232 -53.37423,-31.44115 -79.38397,-16.1329 l -10.3958,6.11853 c 43.49744,68.86447 120.54256,113.80911 201.79332,112.04834 87.97224,-4.41047 162.60077,-62.73987 194.96448,-137.74518 z M -537.90127,346.51705 c 1.46924,39.92741 12.29681,76.43626 30.82364,104.61667 21.05523,-28.18031 47.89674,-45.38011 75.18842,-53.68467 l -42.51189,-20.42423 c 33.35441,-61.94281 101.60759,-105.32857 167.51673,-101.23635 42.4233,1.43194 82.33203,22.18879 112.01381,52.33897 21.0994,21.43235 53.37417,31.44124 79.38393,16.13305 l 10.39581,-6.11852 c -43.49739,-68.86468 -120.54264,-113.8095 -201.79355,-112.04872 -87.97208,4.41046 -162.60049,62.73965 -194.96429,137.74477 z" transform="matrix(0,-1.3167476,1.3167476,0,-94.029776,21.910887)"/></svg>
|
||||
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 2.3 KiB |
@@ -1,139 +0,0 @@
|
||||
package config_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/config"
|
||||
)
|
||||
|
||||
var envVars = []string{
|
||||
"FEATURES_GENERAL_SETTINGS",
|
||||
"FEATURES_QUERY_LOG_CONFIG",
|
||||
"FEATURES_STATS_CONFIG",
|
||||
"FEATURES_CLIENT_SETTINGS",
|
||||
"FEATURES_SERVICES",
|
||||
"FEATURES_FILTERS",
|
||||
"FEATURES_THEME",
|
||||
"FEATURES_DHCP_SERVER_CONFIG",
|
||||
"FEATURES_DHCP_STATIC_LEASES",
|
||||
"FEATURES_DNS_SERVER_CONFIG",
|
||||
"FEATURES_DNS_ACCESS_LISTS",
|
||||
"FEATURES_DNS_REWRITES",
|
||||
"REPLICA1_INTERFACE_NAME",
|
||||
"REPLICA1_DHCP_SERVER_ENABLED",
|
||||
}
|
||||
|
||||
var deprecatedEnvVars = []string{
|
||||
"FEATURES_GENERALSETTINGS",
|
||||
"FEATURES_QUERYLOGCONFIG",
|
||||
"FEATURES_STATSCONFIG",
|
||||
"FEATURES_CLIENTSETTINGS",
|
||||
"FEATURES_SERVICES",
|
||||
"FEATURES_FILTERS",
|
||||
"FEATURES_DHCP_SERVERCONFIG",
|
||||
"FEATURES_DHCP_STATICLEASES",
|
||||
"FEATURES_DNS_SERVERCONFIG",
|
||||
"FEATURES_DNS_ACCESSLISTS",
|
||||
"FEATURES_DNS_REWRITES",
|
||||
"REPLICA1_INTERFACENAME",
|
||||
"REPLICA1_DHCPSERVERENABLED",
|
||||
}
|
||||
|
||||
var _ = Describe("Config", func() {
|
||||
Context("deprecated", func() {
|
||||
BeforeEach(func() {
|
||||
for _, envVar := range deprecatedEnvVars {
|
||||
Ω(os.Setenv(envVar, "false")).ShouldNot(HaveOccurred())
|
||||
}
|
||||
})
|
||||
AfterEach(func() {
|
||||
for _, envVar := range deprecatedEnvVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
})
|
||||
Context("Get", func() {
|
||||
It("features should be false", func() {
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, false)
|
||||
})
|
||||
})
|
||||
})
|
||||
Context("current", func() {
|
||||
BeforeEach(func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
})
|
||||
AfterEach(func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
})
|
||||
Context("Get", func() {
|
||||
It("features should be true by default", func() {
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, true)
|
||||
})
|
||||
It("features should be true by default", func() {
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, true)
|
||||
})
|
||||
It("features should be false", func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Setenv(envVar, "false")).ShouldNot(HaveOccurred())
|
||||
}
|
||||
cfg, err := config.Get("", nil)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, false)
|
||||
})
|
||||
Context("interface name", 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)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(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)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(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)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Get().Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Get().Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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))
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/caarlos0/env/v11"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/bakito/adguardhome-sync/pkg/utils"
|
||||
)
|
||||
|
||||
func handleDeprecatedEnvVars(cfg *types.Config) {
|
||||
if val, ok := checkDeprecatedEnvVar("RUNONSTART", "RUN_ON_START"); ok {
|
||||
cfg.RunOnStart, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("API_DARKMODE", "API_DARK_MODE"); ok {
|
||||
cfg.API.DarkMode, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_GENERALSETTINGS", "FEATURES_GENERAL_SETTINGS"); ok {
|
||||
cfg.Features.GeneralSettings, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_QUERYLOGCONFIG", "FEATURES_QUERY_LOG_CONFIG"); ok {
|
||||
cfg.Features.QueryLogConfig, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_STATSCONFIG", "FEATURES_STATS_CONFIG"); ok {
|
||||
cfg.Features.StatsConfig, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_CLIENTSETTINGS", "FEATURES_CLIENT_SETTINGS"); ok {
|
||||
cfg.Features.ClientSettings, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_DHCP_SERVERCONFIG", "FEATURES_DHCP_SERVER_CONFIG"); ok {
|
||||
cfg.Features.DHCP.ServerConfig, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_DHCP_STATICLEASES", "FEATURES_DHCP_STATIC_LEASES"); ok {
|
||||
cfg.Features.DHCP.StaticLeases, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_DNS_ACCESSLISTS", "FEATURES_DNS_ACCESS_LISTS"); ok {
|
||||
cfg.Features.DNS.AccessLists, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("FEATURES_DNS_SERVERCONFIG", "FEATURES_DNS_SERVER_CONFIG"); ok {
|
||||
cfg.Features.DNS.ServerConfig, _ = strconv.ParseBool(val)
|
||||
}
|
||||
|
||||
if cfg.Replica != nil {
|
||||
if val, ok := checkDeprecatedEnvVar("REPLICA_WEBURL", "REPLICA_WEB_URL"); ok {
|
||||
cfg.Replica.WebURL = val
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("REPLICA_AUTOSETUP", "REPLICA_AUTO_SETUP"); ok {
|
||||
cfg.Replica.AutoSetup, _ = strconv.ParseBool(val)
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("REPLICA_INTERFACENAME", "REPLICA_INTERFACE_NAME"); ok {
|
||||
cfg.Replica.InterfaceName = val
|
||||
}
|
||||
if val, ok := checkDeprecatedEnvVar("REPLICA_DHCPSERVERENABLED", "REPLICA_DHCP_SERVER_ENABLED"); ok {
|
||||
if b, err := strconv.ParseBool(val); err != nil {
|
||||
cfg.Replica.DHCPServerEnabled = utils.Ptr(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
newVal, newOK := os.LookupEnv(newName)
|
||||
if newOK {
|
||||
return newVal, true
|
||||
}
|
||||
return old, oldOK
|
||||
}
|
||||
|
||||
func checkDeprecatedReplicaEnvVar(oldPattern, newPattern string, replicaID int) (string, bool) {
|
||||
return checkDeprecatedEnvVar(fmt.Sprintf(oldPattern, replicaID), fmt.Sprintf(newPattern, replicaID))
|
||||
}
|
||||
|
||||
// Manually collect replicas from env.
|
||||
func enrichReplicasFromEnv(initialReplicas []types.AdGuardInstance) ([]types.AdGuardInstance, error) {
|
||||
var replicas []types.AdGuardInstance
|
||||
for _, v := range os.Environ() {
|
||||
if envReplicasURLPattern.MatchString(v) {
|
||||
sm := envReplicasURLPattern.FindStringSubmatch(v)
|
||||
id, _ := strconv.Atoi(sm[1])
|
||||
|
||||
if id <= 0 {
|
||||
return nil, fmt.Errorf("numbered replica env variables must have a number id >= 1, got %q", v)
|
||||
}
|
||||
|
||||
if id > len(initialReplicas) {
|
||||
replicas = append(replicas, types.AdGuardInstance{URL: sm[2]})
|
||||
} else {
|
||||
re := initialReplicas[id-1]
|
||||
re.URL = sm[2]
|
||||
replicas = append(replicas, re)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(replicas) == 0 {
|
||||
replicas = initialReplicas
|
||||
}
|
||||
|
||||
for i := range replicas {
|
||||
reID := i + 1
|
||||
|
||||
// keep previously set value
|
||||
replicaDhcpServer := replicas[i].DHCPServerEnabled
|
||||
replicas[i].DHCPServerEnabled = nil
|
||||
if err := env.ParseWithOptions(&replicas[i], env.Options{Prefix: fmt.Sprintf("REPLICA%d_", reID)}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if replicas[i].DHCPServerEnabled == nil {
|
||||
replicas[i].DHCPServerEnabled = replicaDhcpServer
|
||||
}
|
||||
if val, ok := checkDeprecatedReplicaEnvVar("REPLICA%d_APIPATH", "REPLICA%d_API_PATH", reID); ok {
|
||||
replicas[i].APIPath = val
|
||||
}
|
||||
if val, ok := checkDeprecatedReplicaEnvVar("REPLICA%d_INSECURESKIPVERIFY", "REPLICA%d_INSECURE_SKIP_VERIFY", reID); ok {
|
||||
replicas[i].InsecureSkipVerify = strings.EqualFold(val, "true")
|
||||
}
|
||||
if val, ok := checkDeprecatedReplicaEnvVar("REPLICA%d_AUTOSETUP", "REPLICA%d_AUTO_SETUP", reID); ok {
|
||||
replicas[i].AutoSetup = strings.EqualFold(val, "true")
|
||||
}
|
||||
if val, ok := checkDeprecatedReplicaEnvVar("REPLICA%d_INTERFACENAME", "REPLICA%d_INTERFACE_NAME", reID); ok {
|
||||
replicas[i].InterfaceName = val
|
||||
}
|
||||
|
||||
if dhcpEnabled, ok := checkDeprecatedReplicaEnvVar("REPLICA%d_DHCPSERVERENABLED", "REPLICA%d_DHCP_SERVER_ENABLED", reID); ok {
|
||||
if strings.EqualFold(dhcpEnabled, "true") {
|
||||
replicas[i].DHCPServerEnabled = utils.Ptr(true)
|
||||
} else if strings.EqualFold(dhcpEnabled, "false") {
|
||||
replicas[i].DHCPServerEnabled = utils.Ptr(false)
|
||||
}
|
||||
}
|
||||
if replicas[i].APIPath == "" {
|
||||
replicas[i].APIPath = "/control"
|
||||
}
|
||||
}
|
||||
|
||||
return replicas, nil
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.2"
|
||||
viewBox="0 0 1000 1000"
|
||||
id="svg3"
|
||||
sodipodi:docname="adguardhome-sync.svg"
|
||||
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3">
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect18"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,54.646215,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 | F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,54.646212,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="skeletal"
|
||||
id="path-effect13"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
pattern="m 78.30448,0.02132 c -1.76356,0.0996 -3.48821,0.55822 -5.06836,1.34765 L 5.80252,35.08773 c -18.554321,9.281429 -18.766576,9.393634 0,18.78124 l 67.4336,33.71876 c 8.62996,4.31519 18.78393,-1.9607 18.7832,-11.60938 v -11.5 h 213 c 6.62742,0 12,-5.372583 12,-12 v -16 c 0,-6.627417 -5.37258,-12 -12,-12 h -213 v -11.5 C 92.01887,5.52137 85.74946,-0.40162 78.30448,0.02132 Z"
|
||||
copytype="repeated_stretched"
|
||||
prop_scale="1"
|
||||
scale_y_rel="false"
|
||||
spacing="100"
|
||||
normal_offset="0"
|
||||
tang_offset="0"
|
||||
prop_units="false"
|
||||
vertical_pattern="false"
|
||||
hide_knot="false"
|
||||
fuse_tolerance="0"
|
||||
pattern-nodetypes="cccccccssssccc" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect11"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,12,0,1 @ F,0,1,1,0,12,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<inkscape:path-effect
|
||||
effect="fillet_chamfer"
|
||||
id="path-effect33"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
nodesatellites_param=""
|
||||
radius="0"
|
||||
unit="px"
|
||||
method="auto"
|
||||
mode="F"
|
||||
chamfer_steps="1"
|
||||
flexible="false"
|
||||
use_knot_distance="true"
|
||||
apply_no_radius="true"
|
||||
apply_with_radius="true"
|
||||
only_selected="false"
|
||||
hide_knots="false" />
|
||||
<linearGradient
|
||||
id="swatch26"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop26" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="swatch25"
|
||||
inkscape:swatch="solid">
|
||||
<stop
|
||||
style="stop-color:#407b28;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop25" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 500 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="1000 : 500 : 1"
|
||||
inkscape:persp3d-origin="500 : 333.33333 : 1"
|
||||
id="perspective6" />
|
||||
<inkscape:path-effect
|
||||
effect="skeletal"
|
||||
id="path-effect13-9"
|
||||
is_visible="true"
|
||||
lpeversion="1"
|
||||
pattern="m -435.41689,700.31394 -82.73956,27.87776 82.73956,31.49534 v -23.8092 l 434.54687,9.11337 v -33.59902 l -434.54687,9.11337 z"
|
||||
copytype="repeated_stretched"
|
||||
prop_scale="2"
|
||||
scale_y_rel="false"
|
||||
spacing="100"
|
||||
normal_offset="0"
|
||||
tang_offset="0"
|
||||
prop_units="false"
|
||||
vertical_pattern="false"
|
||||
hide_knot="false"
|
||||
fuse_tolerance="0"
|
||||
pattern-nodetypes="sccccccs" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="namedview3"
|
||||
pagecolor="#505050"
|
||||
bordercolor="#eeeeee"
|
||||
borderopacity="1"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#505050"
|
||||
inkscape:zoom="0.70710678"
|
||||
inkscape:cx="540.93669"
|
||||
inkscape:cy="502.04582"
|
||||
inkscape:window-width="1556"
|
||||
inkscape:window-height="1360"
|
||||
inkscape:window-x="1868"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg3" />
|
||||
<path
|
||||
fill="#68bc71"
|
||||
d="m 993.75002,114.1 c 0,171.8 3.1,595.3 -493.8,885.9 C 3.0500233,709.4 6.2500233,285.9 6.2500233,114.1 159.35002,35.9 345.25002,0 499.95002,0 c 154.7,0 340.6,35.9 493.8,114.1 z"
|
||||
id="path1"
|
||||
inkscape:label="shield" />
|
||||
<path
|
||||
fill="#67b279"
|
||||
d="M500 1000C3.1 709.4 6.2 285.9 6.2 114.1 159.4 35.9 345.3 0 500 0z"
|
||||
id="path2"
|
||||
inkscape:label="half-shield" />
|
||||
<path
|
||||
fill="#ffffff"
|
||||
d="m 225,449.6 c 15,-11.7 80,-53.4 128.3,1.6 L 453.3,569.6 720,297.9 c 11.7,-10 31.7,-23.3 55,-5 L 455,716.2 Z"
|
||||
id="path3"
|
||||
inkscape:label="checkmark"
|
||||
style="display:none" />
|
||||
<circle
|
||||
style="display:none;fill:#ffffff;fill-opacity:0.5;stroke:#ffffff;stroke-width:8e-08;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:0.502604"
|
||||
id="path18"
|
||||
cx="-500"
|
||||
cy="426"
|
||||
r="400"
|
||||
inkscape:label="badge"
|
||||
transform="scale(-1,1)" />
|
||||
<path
|
||||
id="path12-8"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:4.00001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:100;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -75.867249,555.75073 c -1.469322,-39.92741 -12.296964,-76.43624 -30.823861,-104.61661 -21.05517,28.18037 -47.89663,45.38022 -75.18829,53.68483 l 42.51192,20.42415 c -33.35434,61.94297 -101.60764,105.3289 -167.51689,101.23666 -42.42317,-1.43193 -82.3318,-22.18867 -112.01355,-52.33871 -21.09944,-21.43232 -53.37423,-31.44115 -79.38397,-16.1329 l -10.3958,6.11853 c 43.49744,68.86447 120.54256,113.80911 201.79332,112.04834 87.97224,-4.41047 162.60077,-62.73987 194.96448,-137.74518 z M -537.90127,346.51705 c 1.46924,39.92741 12.29681,76.43626 30.82364,104.61667 21.05523,-28.18031 47.89674,-45.38011 75.18842,-53.68467 l -42.51189,-20.42423 c 33.35441,-61.94281 101.60759,-105.32857 167.51673,-101.23635 42.4233,1.43194 82.33203,22.18879 112.01381,52.33897 21.0994,21.43235 53.37417,31.44124 79.38393,16.13305 l 10.39581,-6.11852 c -43.49739,-68.86468 -120.54264,-113.8095 -201.79355,-112.04872 -87.97208,4.41046 -162.60049,62.73965 -194.96429,137.74477 z"
|
||||
transform="matrix(0,-1.3167476,1.3167476,0,-94.029776,21.910887)"
|
||||
inkscape:label="double-arrow"
|
||||
inkscape:path-effect="#path-effect1"
|
||||
inkscape:original-d="m -75.867249,555.75073 c -1.469322,-39.92741 -12.296964,-76.43624 -30.823861,-104.61661 -21.05517,28.18037 -47.89663,45.38022 -75.18829,53.68483 l 42.51192,20.42415 c -33.35434,61.94297 -101.60764,105.3289 -167.51689,101.23666 -42.42317,-1.43193 -82.3318,-22.18867 -112.01355,-52.33871 -21.09944,-21.43232 -53.37423,-31.44115 -79.38397,-16.1329 l -10.3958,6.11853 c 43.49744,68.86447 120.54256,113.80911 201.79332,112.04834 87.97224,-4.41047 162.60077,-62.73987 194.96448,-137.74518 z M -537.90127,346.51705 c 1.46924,39.92741 12.29681,76.43626 30.82364,104.61667 21.05523,-28.18031 47.89674,-45.38011 75.18842,-53.68467 l -42.51189,-20.42423 c 33.35441,-61.94281 101.60759,-105.32857 167.51673,-101.23635 42.4233,1.43194 82.33203,22.18879 112.01381,52.33897 21.0994,21.43235 53.37417,31.44124 79.38393,16.13305 l 10.39581,-6.11852 c -43.49739,-68.86468 -120.54264,-113.8095 -201.79355,-112.04872 -87.97208,4.41046 -162.60049,62.73965 -194.96429,137.74477 z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 8.8 KiB |
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
echo "## AdGuardHome.yaml of latest replica" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
kubectl exec adguardhome-replica-latest -- cat /opt/adguardhome/conf/AdGuardHome.yaml >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
echo "## AdGuardHome.yaml of latest replica" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
kubectl exec adguardhome-replica-latest -- cat /opt/adguardhome/conf/AdGuardHome.yaml >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
2
testdata/e2e/bin/wait-for-start.sh
vendored
2
testdata/e2e/bin/wait-for-start.sh
vendored
@@ -1,3 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
kubectl wait --for=jsonpath='{.status.phase}'=Running pod/adguardhome-sync --timeout=1m
|
||||
kubectl describe pod/adguardhome-sync
|
||||
kubectl logs pod/adguardhome-sync
|
||||
|
||||
8
testdata/e2e/values.yaml
vendored
8
testdata/e2e/values.yaml
vendored
@@ -1,12 +1,12 @@
|
||||
replica:
|
||||
versions:
|
||||
- v0.107.40
|
||||
- v0.107.43
|
||||
- v0.107.63
|
||||
- v0.107.67
|
||||
- v0.107.68
|
||||
- latest
|
||||
|
||||
mode: env
|
||||
|
||||
kubectl:
|
||||
repository: bitnami/kubectl
|
||||
tag: "1.30"
|
||||
repository: bitnamisecure/kubectl
|
||||
tag: "latest"
|
||||
|
||||
Reference in New Issue
Block a user