mirror of
https://github.com/bakito/adguardhome-sync.git
synced 2024-11-10 09:12:29 +08:00
allow definig web URL (#267)
This commit is contained in:
parent
749c5f178c
commit
4a8e2aab51
9 changed files with 133 additions and 15 deletions
|
@ -146,6 +146,8 @@ services:
|
|||
environment:
|
||||
LOG_LEVEL: "info"
|
||||
ORIGIN_URL: "https://192.168.1.2:3000"
|
||||
# ORIGIN_WEBURL: "https://some-other.url" # used in the web interface (default: <origin-url>
|
||||
|
||||
ORIGIN_USERNAME: "username"
|
||||
ORIGIN_PASSWORD: "password"
|
||||
REPLICA_URL: "http://192.168.1.3"
|
||||
|
@ -155,6 +157,7 @@ services:
|
|||
REPLICA1_USERNAME: "username"
|
||||
REPLICA1_PASSWORD: "password"
|
||||
REPLICA1_APIPATH: "/some/path/control"
|
||||
# REPLICA1_WEBURL: "https://some-other.url" # used in the web interface (default: <replica-url>
|
||||
# REPLICA1_AUTOSETUP: true # if true, AdGuardHome is automatically initialized.
|
||||
# REPLICA1_INTERFACENAME: 'ens18' # use custom dhcp interface name
|
||||
# REPLICA1_DHCPSERVERENABLED: true/false (optional) enables/disables the dhcp server on the replica
|
||||
|
@ -208,6 +211,7 @@ replica:
|
|||
username: username
|
||||
password: password
|
||||
# cookie: Replica-Cookie-Name=CCCOOOKKKIIIEEE
|
||||
# webURL: "https://some-other.url" # used in the web interface (default: <origin-url>
|
||||
|
||||
# replicas instances (optional, if more than one)
|
||||
replicas:
|
||||
|
@ -221,6 +225,7 @@ replicas:
|
|||
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>
|
||||
|
||||
# Configure the sync API server, disabled if api port is 0
|
||||
api:
|
||||
|
@ -229,6 +234,8 @@ api:
|
|||
# if username and password are defined, basic auth is applied to the sync API
|
||||
username: username
|
||||
password: password
|
||||
# enable api dark mode
|
||||
darkMode: true
|
||||
|
||||
# Configure sync features; by default all features are enabled.
|
||||
features:
|
||||
|
|
|
@ -38,6 +38,7 @@ const (
|
|||
configFeatureFilters = "features.filters"
|
||||
|
||||
configOriginURL = "origin.url"
|
||||
configOriginWebURL = "origin.webURL"
|
||||
configOriginAPIPath = "origin.apiPath"
|
||||
configOriginUsername = "origin.username"
|
||||
configOriginPassword = "origin.password"
|
||||
|
@ -45,6 +46,7 @@ const (
|
|||
configOriginInsecureSkipVerify = "origin.insecureSkipVerify"
|
||||
|
||||
configReplicaURL = "replica.url"
|
||||
configReplicaWebURL = "replica.webURL"
|
||||
configReplicaAPIPath = "replica.apiPath"
|
||||
configReplicaUsername = "replica.username"
|
||||
configReplicaPassword = "replica.password"
|
||||
|
@ -63,6 +65,7 @@ const (
|
|||
// Deprecated: use envReplicasInterfaceName instead
|
||||
envReplicasInterfaceNameDeprecated = "REPLICA%s_INTERFACWENAME"
|
||||
envDHCPServerEnabled = "REPLICA%s_DHCPSERVERENABLED"
|
||||
envWebURL = "REPLICA%s_WEBURL"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -144,6 +147,7 @@ func getConfig(logger *zap.SugaredLogger) (*types.Config, error) {
|
|||
if len(cfg.Replicas) == 0 {
|
||||
cfg.Replicas = append(cfg.Replicas, collectEnvReplicas(logger)...)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
|
@ -155,6 +159,7 @@ func collectEnvReplicas(logger *zap.SugaredLogger) []types.AdGuardInstance {
|
|||
sm := envReplicasURLPattern.FindStringSubmatch(v)
|
||||
re := types.AdGuardInstance{
|
||||
URL: sm[2],
|
||||
WebURL: os.Getenv(fmt.Sprintf(envWebURL, sm[1])),
|
||||
Username: os.Getenv(fmt.Sprintf(envReplicasUsernameFormat, sm[1])),
|
||||
Password: os.Getenv(fmt.Sprintf(envReplicasPasswordFormat, sm[1])),
|
||||
Cookie: os.Getenv(fmt.Sprintf(envReplicasCookieFormat, sm[1])),
|
||||
|
|
|
@ -21,6 +21,11 @@ var doCmd = &cobra.Command{
|
|||
return err
|
||||
}
|
||||
|
||||
if err := cfg.Init(); err != nil {
|
||||
logger.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if cfg.PrintConfigOnly {
|
||||
config, err := yaml.Marshal(cfg)
|
||||
if err != nil {
|
||||
|
@ -81,6 +86,8 @@ func init() {
|
|||
|
||||
doCmd.PersistentFlags().String("origin-url", "", "Origin instance url")
|
||||
_ = viper.BindPFlag(configOriginURL, doCmd.PersistentFlags().Lookup("origin-url"))
|
||||
doCmd.PersistentFlags().String("origin-weburl", "", "Origin instance web url used in the web interface (default: <origin-url>)")
|
||||
_ = viper.BindPFlag(configOriginWebURL, doCmd.PersistentFlags().Lookup("origin-weburl"))
|
||||
doCmd.PersistentFlags().String("origin-api-path", "/control", "Origin instance API path")
|
||||
_ = viper.BindPFlag(configOriginAPIPath, doCmd.PersistentFlags().Lookup("origin-api-path"))
|
||||
doCmd.PersistentFlags().String("origin-username", "", "Origin instance username")
|
||||
|
@ -94,6 +101,8 @@ func init() {
|
|||
|
||||
doCmd.PersistentFlags().String("replica-url", "", "Replica instance url")
|
||||
_ = viper.BindPFlag(configReplicaURL, doCmd.PersistentFlags().Lookup("replica-url"))
|
||||
doCmd.PersistentFlags().String("replica-weburl", "", "Replica instance web url used in the web interface (default: <replica-url>)")
|
||||
_ = viper.BindPFlag(configOriginWebURL, doCmd.PersistentFlags().Lookup("replica-weburl"))
|
||||
doCmd.PersistentFlags().String("replica-api-path", "/control", "Replica instance API path")
|
||||
_ = viper.BindPFlag(configReplicaAPIPath, doCmd.PersistentFlags().Lookup("replica-api-path"))
|
||||
doCmd.PersistentFlags().String("replica-username", "", "Replica instance username")
|
||||
|
|
|
@ -80,9 +80,9 @@ func New(config types.AdGuardInstance) (Client, error) {
|
|||
}
|
||||
|
||||
return &client{
|
||||
host: u.Host,
|
||||
host: config.Host,
|
||||
client: cl,
|
||||
log: l.With("host", u.Host),
|
||||
log: l.With("host", config.Host),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,10 @@ var _ = Describe("Client", func() {
|
|||
|
||||
Context("Host", func() {
|
||||
It("should read the current host", func() {
|
||||
cl, _ := client.New(types.AdGuardInstance{URL: "https://foo.bar:3000"})
|
||||
inst := types.AdGuardInstance{URL: "https://foo.bar:3000"}
|
||||
err := inst.Init()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
cl, _ := client.New(inst)
|
||||
host := cl.Host()
|
||||
Ω(host).Should(Equal("foo.bar:3000"))
|
||||
})
|
||||
|
|
|
@ -112,27 +112,32 @@ func (w *worker) status() *syncStatus {
|
|||
return syncStatus
|
||||
}
|
||||
|
||||
func (w *worker) getStatus(inst types.AdGuardInstance) replicaStatus {
|
||||
func (w *worker) getStatus(inst types.AdGuardInstance) (st replicaStatus) {
|
||||
st = replicaStatus{Host: inst.WebHost, URL: inst.WebURL}
|
||||
|
||||
oc, err := w.createClient(inst)
|
||||
if err != nil {
|
||||
l.With("error", err, "url", w.cfg.Origin.URL).Error("Error creating origin client")
|
||||
return replicaStatus{Host: oc.Host(), URL: inst.URL, Error: err.Error(), Status: "danger"}
|
||||
st.Status = "danger"
|
||||
st.Error = err.Error()
|
||||
return
|
||||
}
|
||||
sl := l.With("from", oc.Host())
|
||||
st, err := oc.Status()
|
||||
sl := l.With("from", inst.WebHost)
|
||||
status, err := oc.Status()
|
||||
if err != nil {
|
||||
if errors.Is(err, client.ErrSetupNeeded) {
|
||||
return replicaStatus{Host: oc.Host(), URL: inst.URL, Error: err.Error(), Status: "warning"}
|
||||
st.Status = "warning"
|
||||
st.Error = err.Error()
|
||||
return
|
||||
}
|
||||
sl.With("error", err).Error("Error getting origin status")
|
||||
return replicaStatus{Host: oc.Host(), URL: inst.URL, Error: err.Error(), Status: "danger"}
|
||||
}
|
||||
return replicaStatus{
|
||||
Host: oc.Host(),
|
||||
URL: inst.URL,
|
||||
Status: "success",
|
||||
ProtectionEnabled: utils.Ptr(st.ProtectionEnabled),
|
||||
st.Status = "danger"
|
||||
st.Error = err.Error()
|
||||
return
|
||||
}
|
||||
st.Status = "success"
|
||||
st.ProtectionEnabled = utils.Ptr(status.ProtectionEnabled)
|
||||
return
|
||||
}
|
||||
|
||||
func (w *worker) sync() {
|
||||
|
|
|
@ -2,6 +2,7 @@ package types
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -71,10 +72,24 @@ func (cfg *Config) Log(l *zap.SugaredLogger) {
|
|||
l.With("config", c).Debug("Using config")
|
||||
}
|
||||
|
||||
func (cfg *Config) Init() error {
|
||||
if err := cfg.Origin.Init(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range cfg.Replicas {
|
||||
replica := &cfg.Replicas[i]
|
||||
if err := replica.Init(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AdGuardInstance AdguardHome config instance
|
||||
// +k8s:deepcopy-gen=true
|
||||
type AdGuardInstance struct {
|
||||
URL string `json:"url" yaml:"url"`
|
||||
WebURL string `json:"webURL" yaml:"webURL"`
|
||||
APIPath string `json:"apiPath,omitempty" yaml:"apiPath,omitempty"`
|
||||
Username string `json:"username,omitempty" yaml:"username,omitempty"`
|
||||
Password string `json:"password,omitempty" yaml:"password,omitempty"`
|
||||
|
@ -83,6 +98,9 @@ type AdGuardInstance struct {
|
|||
AutoSetup bool `json:"autoSetup" yaml:"autoSetup"`
|
||||
InterfaceName string `json:"interfaceName,omitempty" yaml:"interfaceName,omitempty"`
|
||||
DHCPServerEnabled *bool `json:"dhcpServerEnabled,omitempty" yaml:"dhcpServerEnabled,omitempty"`
|
||||
|
||||
Host string `json:"-" yaml:"-"`
|
||||
WebHost string `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
// Key AdGuardInstance key
|
||||
|
@ -96,6 +114,26 @@ func (i *AdGuardInstance) Mask() {
|
|||
i.Password = mask(i.Password)
|
||||
}
|
||||
|
||||
func (i *AdGuardInstance) Init() error {
|
||||
u, err := url.Parse(i.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Host = u.Host
|
||||
|
||||
if i.WebURL == "" {
|
||||
i.WebHost = i.Host
|
||||
i.WebURL = i.URL
|
||||
} else {
|
||||
u, err := url.Parse(i.WebURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.WebHost = u.Host
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func mask(s string) string {
|
||||
if s == "" {
|
||||
return "***"
|
||||
|
|
13
pkg/types/types_suite_test.go
Normal file
13
pkg/types/types_suite_test.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestSync(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Types Suite")
|
||||
}
|
38
pkg/types/types_test.go
Normal file
38
pkg/types/types_test.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package types_test
|
||||
|
||||
import (
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("AdGuardInstance", func() {
|
||||
var inst types.AdGuardInstance
|
||||
|
||||
BeforeEach(func() {
|
||||
inst = types.AdGuardInstance{}
|
||||
})
|
||||
Context("Init", func() {
|
||||
BeforeEach(func() {
|
||||
inst.URL = "https://localhost:3000"
|
||||
})
|
||||
It("should correctly set Host and WebHost if only URL is set", func() {
|
||||
err := inst.Init()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(inst.Host).Should(Equal("localhost:3000"))
|
||||
Ω(inst.WebHost).Should(Equal("localhost:3000"))
|
||||
Ω(inst.URL).Should(Equal("https://localhost:3000"))
|
||||
Ω(inst.WebURL).Should(Equal("https://localhost:3000"))
|
||||
})
|
||||
It("should correctly set Host and WebHost if URL and WebURL are set", func() {
|
||||
inst.WebURL = "https://127.0.0.1:4000"
|
||||
err := inst.Init()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(inst.Host).Should(Equal("localhost:3000"))
|
||||
Ω(inst.WebHost).Should(Equal("127.0.0.1:4000"))
|
||||
Ω(inst.WebURL).Should(Equal(inst.WebURL))
|
||||
Ω(inst.URL).Should(Equal("https://localhost:3000"))
|
||||
Ω(inst.WebURL).Should(Equal("https://127.0.0.1:4000"))
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue