convert interval to double, fixes #49

Requires min AdGuard Home v0.107.0
This commit is contained in:
bakito 2022-01-09 18:15:54 +01:00
parent bd799912f6
commit 5cd27f4684
No known key found for this signature in database
GPG key ID: FAF93C1C384DD6B4
10 changed files with 88 additions and 22 deletions

View file

@ -25,7 +25,7 @@ jobs:
- name: Set up Go 1.x - name: Set up Go 1.x
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: ^1.16 go-version: ^1.17
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -46,7 +46,7 @@ jobs:
- name: Set up Go 1.x - name: Set up Go 1.x
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: ^1.16 go-version: ^1.17
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
uses: actions/checkout@v2 uses: actions/checkout@v2

View file

@ -1,4 +1,4 @@
FROM docker.io/library/golang:1.16 as builder FROM docker.io/library/golang:1.17 as builder
WORKDIR /go/src/app WORKDIR /go/src/app

24
go.mod
View file

@ -1,6 +1,6 @@
module github.com/bakito/adguardhome-sync module github.com/bakito/adguardhome-sync
go 1.16 go 1.17
require ( require (
github.com/go-resty/resty/v2 v2.7.0 github.com/go-resty/resty/v2 v2.7.0
@ -13,4 +13,26 @@ require (
github.com/spf13/cobra v1.3.0 github.com/spf13/cobra v1.3.0
github.com/spf13/viper v1.10.1 github.com/spf13/viper v1.10.1
go.uber.org/zap v1.19.1 go.uber.org/zap v1.19.1
golang.org/x/mod v0.5.0
)
require (
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect
golang.org/x/sys v0.0.0-20211210111614-af8b64212486 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
) )

1
go.sum
View file

@ -436,6 +436,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View file

@ -65,7 +65,7 @@ type Client interface {
DeleteRewriteEntries(e ...types.RewriteEntry) error DeleteRewriteEntries(e ...types.RewriteEntry) error
Filtering() (*types.FilteringStatus, error) Filtering() (*types.FilteringStatus, error)
ToggleFiltering(enabled bool, interval int) error ToggleFiltering(enabled bool, interval float64) error
AddFilters(whitelist bool, e ...types.Filter) error AddFilters(whitelist bool, e ...types.Filter) error
DeleteFilters(whitelist bool, e ...types.Filter) error DeleteFilters(whitelist bool, e ...types.Filter) error
UpdateFilters(whitelist bool, e ...types.Filter) error UpdateFilters(whitelist bool, e ...types.Filter) error
@ -88,9 +88,9 @@ type Client interface {
DeleteClients(client ...types.Client) error DeleteClients(client ...types.Client) error
QueryLogConfig() (*types.QueryLogConfig, error) QueryLogConfig() (*types.QueryLogConfig, error)
SetQueryLogConfig(enabled bool, interval int, anonymizeClientIP bool) error SetQueryLogConfig(enabled bool, interval float64, anonymizeClientIP bool) error
StatsConfig() (*types.IntervalConfig, error) StatsConfig() (*types.IntervalConfig, error)
SetStatsConfig(interval int) error SetStatsConfig(interval float64) error
Setup() error Setup() error
AccessList() (*types.AccessList, error) AccessList() (*types.AccessList, error)
@ -291,7 +291,7 @@ func (cl *client) SetCustomRules(rules types.UserRules) error {
return cl.doPost(cl.client.R().EnableTrace().SetBody(rules.String()), "/filtering/set_rules") return cl.doPost(cl.client.R().EnableTrace().SetBody(rules.String()), "/filtering/set_rules")
} }
func (cl *client) ToggleFiltering(enabled bool, interval int) error { func (cl *client) ToggleFiltering(enabled bool, interval float64) error {
cl.log.With("enabled", enabled, "interval", interval).Info("Toggle filtering") cl.log.With("enabled", enabled, "interval", interval).Info("Toggle filtering")
return cl.doPost(cl.client.R().EnableTrace().SetBody(&types.FilteringConfig{ return cl.doPost(cl.client.R().EnableTrace().SetBody(&types.FilteringConfig{
EnableConfig: types.EnableConfig{Enabled: enabled}, EnableConfig: types.EnableConfig{Enabled: enabled},
@ -357,7 +357,7 @@ func (cl *client) QueryLogConfig() (*types.QueryLogConfig, error) {
return qlc, err return qlc, err
} }
func (cl *client) SetQueryLogConfig(enabled bool, interval int, anonymizeClientIP bool) error { func (cl *client) SetQueryLogConfig(enabled bool, interval float64, anonymizeClientIP bool) error {
cl.log.With("enabled", enabled, "interval", interval, "anonymizeClientIP", anonymizeClientIP).Info("Set query log config") cl.log.With("enabled", enabled, "interval", interval, "anonymizeClientIP", anonymizeClientIP).Info("Set query log config")
return cl.doPost(cl.client.R().EnableTrace().SetBody(&types.QueryLogConfig{ return cl.doPost(cl.client.R().EnableTrace().SetBody(&types.QueryLogConfig{
EnableConfig: types.EnableConfig{Enabled: enabled}, EnableConfig: types.EnableConfig{Enabled: enabled},
@ -372,7 +372,7 @@ func (cl *client) StatsConfig() (*types.IntervalConfig, error) {
return stats, err return stats, err
} }
func (cl *client) SetStatsConfig(interval int) error { func (cl *client) SetStatsConfig(interval float64) error {
cl.log.With("interval", interval).Info("Set stats config") cl.log.With("interval", interval).Info("Set stats config")
return cl.doPost(cl.client.R().EnableTrace().SetBody(&types.IntervalConfig{Interval: interval}), "/stats_config") return cl.doPost(cl.client.R().EnableTrace().SetBody(&types.IntervalConfig{Interval: interval}), "/stats_config")
} }

View file

@ -265,7 +265,7 @@ bar`)
qlc, err := cl.QueryLogConfig() qlc, err := cl.QueryLogConfig()
Ω(err).ShouldNot(HaveOccurred()) Ω(err).ShouldNot(HaveOccurred())
Ω(qlc.Enabled).Should(BeTrue()) Ω(qlc.Enabled).Should(BeTrue())
Ω(qlc.Interval).Should(Equal(90)) Ω(qlc.Interval).Should(Equal(90.0))
}) })
It("should set QueryLogConfig", func() { It("should set QueryLogConfig", func() {
ts, cl = ClientPost("/querylog_config", `{"enabled":true,"interval":123,"anonymize_client_ip":true}`) ts, cl = ClientPost("/querylog_config", `{"enabled":true,"interval":123,"anonymize_client_ip":true}`)
@ -278,11 +278,11 @@ bar`)
ts, cl = ClientGet("stats_info.json", "/stats_info") ts, cl = ClientGet("stats_info.json", "/stats_info")
sc, err := cl.StatsConfig() sc, err := cl.StatsConfig()
Ω(err).ShouldNot(HaveOccurred()) Ω(err).ShouldNot(HaveOccurred())
Ω(sc.Interval).Should(Equal(1)) Ω(sc.Interval).Should(Equal(1.0))
}) })
It("should set StatsConfig", func() { It("should set StatsConfig", func() {
ts, cl = ClientPost("/stats_config", `{"interval":123}`) ts, cl = ClientPost("/stats_config", `{"interval":123}`)
err := cl.SetStatsConfig(123) err := cl.SetStatsConfig(123.0)
Ω(err).ShouldNot(HaveOccurred()) Ω(err).ShouldNot(HaveOccurred())
}) })
}) })

View file

@ -430,7 +430,7 @@ func (mr *MockClientMockRecorder) SetDNSConfig(arg0 interface{}) *gomock.Call {
} }
// SetQueryLogConfig mocks base method. // SetQueryLogConfig mocks base method.
func (m *MockClient) SetQueryLogConfig(arg0 bool, arg1 int, arg2 bool) error { func (m *MockClient) SetQueryLogConfig(arg0 bool, arg1 float64, arg2 bool) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetQueryLogConfig", arg0, arg1, arg2) ret := m.ctrl.Call(m, "SetQueryLogConfig", arg0, arg1, arg2)
ret0, _ := ret[0].(error) ret0, _ := ret[0].(error)
@ -458,7 +458,7 @@ func (mr *MockClientMockRecorder) SetServices(arg0 interface{}) *gomock.Call {
} }
// SetStatsConfig mocks base method. // SetStatsConfig mocks base method.
func (m *MockClient) SetStatsConfig(arg0 int) error { func (m *MockClient) SetStatsConfig(arg0 float64) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetStatsConfig", arg0) ret := m.ctrl.Call(m, "SetStatsConfig", arg0)
ret0, _ := ret[0].(error) ret0, _ := ret[0].(error)
@ -516,7 +516,7 @@ func (mr *MockClientMockRecorder) Status() *gomock.Call {
} }
// ToggleFiltering mocks base method. // ToggleFiltering mocks base method.
func (m *MockClient) ToggleFiltering(arg0 bool, arg1 int) error { func (m *MockClient) ToggleFiltering(arg0 bool, arg1 float64) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ToggleFiltering", arg0, arg1) ret := m.ctrl.Call(m, "ToggleFiltering", arg0, arg1)
ret0, _ := ret[0].(error) ret0, _ := ret[0].(error)

View file

@ -10,8 +10,11 @@ import (
"github.com/bakito/adguardhome-sync/version" "github.com/bakito/adguardhome-sync/version"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/mod/semver"
) )
const minAghVersion = "v0.107.0"
var l = log.GetLogger("sync") var l = log.GetLogger("sync")
// Sync config from origin to replica // Sync config from origin to replica
@ -97,6 +100,11 @@ func (w *worker) sync() {
return return
} }
if semver.Compare(o.status.Version, minAghVersion) == -1 {
sl.With("error", err, "version", o.status.Version).Errorf("Origin AdGuard Home version must be >= %s", minAghVersion)
return
}
o.parental, err = oc.Parental() o.parental, err = oc.Parental()
if err != nil { if err != nil {
sl.With("error", err).Error("Error getting parental status") sl.With("error", err).Error("Error getting parental status")
@ -186,6 +194,11 @@ func (w *worker) syncTo(l *zap.SugaredLogger, o *origin, replica types.AdGuardIn
return return
} }
if semver.Compare(rs.Version, minAghVersion) == -1 {
rl.With("error", err, "version", rs.Version).Errorf("Replica AdGuard Home version must be >= %s", minAghVersion)
return
}
if o.status.Version != rs.Version { if o.status.Version != rs.Version {
rl.With("originVersion", o.status.Version, "replicaVersion", rs.Version).Warn("Versions do not match") rl.With("originVersion", o.status.Version, "replicaVersion", rs.Version).Warn("Versions do not match")
} }

View file

@ -269,7 +269,7 @@ var _ = Describe("Sync", func() {
It("should have QueryLogConfig changes", func() { It("should have QueryLogConfig changes", func() {
o.queryLogConfig.Interval = 123 o.queryLogConfig.Interval = 123
cl.EXPECT().QueryLogConfig().Return(qlc, nil) cl.EXPECT().QueryLogConfig().Return(qlc, nil)
cl.EXPECT().SetQueryLogConfig(false, 123, false) cl.EXPECT().SetQueryLogConfig(false, 123.0, false)
cl.EXPECT().StatsConfig().Return(sc, nil) cl.EXPECT().StatsConfig().Return(sc, nil)
err := w.syncConfigs(o, cl) err := w.syncConfigs(o, cl)
Ω(err).ShouldNot(HaveOccurred()) Ω(err).ShouldNot(HaveOccurred())
@ -278,7 +278,7 @@ var _ = Describe("Sync", func() {
o.statsConfig.Interval = 123 o.statsConfig.Interval = 123
cl.EXPECT().QueryLogConfig().Return(qlc, nil) cl.EXPECT().QueryLogConfig().Return(qlc, nil)
cl.EXPECT().StatsConfig().Return(sc, nil) cl.EXPECT().StatsConfig().Return(sc, nil)
cl.EXPECT().SetStatsConfig(123) cl.EXPECT().SetStatsConfig(123.0)
err := w.syncConfigs(o, cl) err := w.syncConfigs(o, cl)
Ω(err).ShouldNot(HaveOccurred()) Ω(err).ShouldNot(HaveOccurred())
}) })
@ -425,7 +425,7 @@ var _ = Describe("Sync", func() {
}) })
Context("sync", func() { Context("sync", func() {
It("should have no changes", func() { BeforeEach(func() {
w.cfg = &types.Config{ w.cfg = &types.Config{
Origin: types.AdGuardInstance{}, Origin: types.AdGuardInstance{},
Replica: types.AdGuardInstance{URL: "foo"}, Replica: types.AdGuardInstance{URL: "foo"},
@ -447,9 +447,11 @@ var _ = Describe("Sync", func() {
QueryLogConfig: true, QueryLogConfig: true,
}, },
} }
})
It("should have no changes", func() {
// origin // origin
cl.EXPECT().Host() cl.EXPECT().Host()
cl.EXPECT().Status().Return(&types.Status{}, nil) cl.EXPECT().Status().Return(&types.Status{Version: minAghVersion}, nil)
cl.EXPECT().Parental() cl.EXPECT().Parental()
cl.EXPECT().SafeSearch() cl.EXPECT().SafeSearch()
cl.EXPECT().SafeBrowsing() cl.EXPECT().SafeBrowsing()
@ -465,7 +467,7 @@ var _ = Describe("Sync", func() {
// replica // replica
cl.EXPECT().Host() cl.EXPECT().Host()
cl.EXPECT().Status().Return(&types.Status{}, nil) cl.EXPECT().Status().Return(&types.Status{Version: minAghVersion}, nil)
cl.EXPECT().Parental() cl.EXPECT().Parental()
cl.EXPECT().SafeSearch() cl.EXPECT().SafeSearch()
cl.EXPECT().SafeBrowsing() cl.EXPECT().SafeBrowsing()
@ -493,6 +495,34 @@ var _ = Describe("Sync", func() {
cl.EXPECT().DeleteDHCPStaticLeases().Return(nil) cl.EXPECT().DeleteDHCPStaticLeases().Return(nil)
w.sync() w.sync()
}) })
It("origin version is too small", func() {
// origin
cl.EXPECT().Host()
cl.EXPECT().Status().Return(&types.Status{Version: "v0.106.9"}, nil)
w.sync()
})
It("replica version is too small", func() {
// origin
cl.EXPECT().Host()
cl.EXPECT().Status().Return(&types.Status{Version: minAghVersion}, nil)
cl.EXPECT().Parental()
cl.EXPECT().SafeSearch()
cl.EXPECT().SafeBrowsing()
cl.EXPECT().RewriteList().Return(&types.RewriteEntries{}, nil)
cl.EXPECT().Services()
cl.EXPECT().Filtering().Return(&types.FilteringStatus{}, nil)
cl.EXPECT().Clients().Return(&types.Clients{}, nil)
cl.EXPECT().QueryLogConfig().Return(&types.QueryLogConfig{}, nil)
cl.EXPECT().StatsConfig().Return(&types.IntervalConfig{}, nil)
cl.EXPECT().AccessList().Return(&types.AccessList{}, nil)
cl.EXPECT().DNSConfig().Return(&types.DNSConfig{}, nil)
cl.EXPECT().DHCPServerConfig().Return(&types.DHCPServerConfig{}, nil)
// replica
cl.EXPECT().Host()
cl.EXPECT().Status().Return(&types.Status{Version: "v0.106.9"}, nil)
w.sync()
})
}) })
}) })
}) })

View file

@ -215,7 +215,7 @@ type EnableConfig struct {
// IntervalConfig API struct // IntervalConfig API struct
type IntervalConfig struct { type IntervalConfig struct {
Interval int `json:"interval"` Interval float64 `json:"interval"`
} }
// FilteringConfig API struct // FilteringConfig API struct