Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fca3b1002 | ||
|
|
1edf5ae52a | ||
|
|
39f7f41e6d |
30
README.md
30
README.md
@@ -146,7 +146,7 @@ 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_WEB_URL: "https://some-other.url" # used in the web interface (default: <origin-url>
|
||||
|
||||
ORIGIN_USERNAME: "username"
|
||||
ORIGIN_PASSWORD: "password"
|
||||
@@ -156,29 +156,29 @@ services:
|
||||
REPLICA1_URL: "http://192.168.1.4"
|
||||
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
|
||||
REPLICA1_API_PATH: "/some/path/control"
|
||||
# REPLICA1_WEB_URL: "https://some-other.url" # used in the web interface (default: <replica-url>
|
||||
# REPLICA1_AUTO_SETUP: true # if true, AdGuardHome is automatically initialized.
|
||||
# REPLICA1_INTERFACE_NAME: 'ens18' # use custom dhcp interface name
|
||||
# REPLICA1_DHCP_SERVER_ENABLED: true/false (optional) enables/disables the dhcp server on the replica
|
||||
CRON: "*/10 * * * *" # run every 10 minutes
|
||||
RUNONSTART: true
|
||||
# CONTINUEONERROR: false # If enabled, the synchronisation task will not fail on single errors, but will log the errors and continue
|
||||
# CONTINUE_ON_ERROR: false # If enabled, the synchronisation task will not fail on single errors, but will log the errors and continue
|
||||
|
||||
# Configure the sync API server, disabled if api port is 0
|
||||
API_PORT: 8080
|
||||
|
||||
# Configure sync features; by default all features are enabled.
|
||||
# FEATURES_GENERALSETTINGS: true
|
||||
# FEATURES_QUERYLOGCONFIG: true
|
||||
# FEATURES_STATSCONFIG: true
|
||||
# FEATURES_CLIENTSETTINGS: true
|
||||
# FEATURES_GENERAL_SETTINGS: true
|
||||
# FEATURES_QUERY_LOG_CONFIG: true
|
||||
# FEATURES_STATS_CONFIG: true
|
||||
# FEATURES_CLIENT_SETTINGS: true
|
||||
# FEATURES_SERVICES: true
|
||||
# FEATURES_FILTERS: true
|
||||
# FEATURES_DHCP_SERVERCONFIG: true
|
||||
# FEATURES_DHCP_STATICLEASES: true
|
||||
# FEATURES_DNS_SERVERCONFIG: true
|
||||
# FEATURES_DNS_ACCESSLISTS: true
|
||||
# FEATURES_DHCP_SERVER_CONFIG: true
|
||||
# FEATURES_DHCP_STATIC_LEASES: true
|
||||
# FEATURES_DNS_SERVER_CONFIG: true
|
||||
# FEATURES_DNS_ACCESS_LISTS: true
|
||||
# FEATURES_DNS_REWRITES: true
|
||||
ports:
|
||||
- 8080:8080
|
||||
|
||||
194
cmd/root.go
194
cmd/root.go
@@ -4,10 +4,12 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"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/version"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -15,56 +17,45 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
configCron = "cron"
|
||||
configRunOnStart = "runOnStart"
|
||||
configCron = "CRON"
|
||||
configRunOnStart = "RUN_ON_START"
|
||||
configPrintConfigOnly = "PRINT_CONFIG_ONLY"
|
||||
configContinueOnError = "CONTINUE_ON_ERROR"
|
||||
configLogLevel = "LOG_LEVEL"
|
||||
|
||||
configAPIPort = "api.port"
|
||||
configAPIUsername = "api.username"
|
||||
configAPIPassword = "api.password"
|
||||
configAPIDarkMode = "api.darkMode"
|
||||
configAPIPort = "API.PORT"
|
||||
configAPIUsername = "API.USERNAME"
|
||||
configAPIPassword = "API.PASSWORD"
|
||||
configAPIDarkMode = "API.DARK_MODE"
|
||||
|
||||
configFeatureDHCPServerConfig = "features.dhcp.serverConfig"
|
||||
configFeatureDHCPStaticLeases = "features.dhcp.staticLeases"
|
||||
configFeatureDNServerConfig = "features.dns.serverConfig"
|
||||
configFeatureDNSPAccessLists = "features.dns.accessLists"
|
||||
configFeatureDNSRewrites = "features.dns.rewrites"
|
||||
configFeatureGeneralSettings = "features.generalSettings"
|
||||
configFeatureQueryLogConfig = "features.queryLogConfig"
|
||||
configFeatureStatsConfig = "features.statsConfig"
|
||||
configFeatureClientSettings = "features.clientSettings"
|
||||
configFeatureServices = "features.services"
|
||||
configFeatureFilters = "features.filters"
|
||||
configFeatureDHCPServerConfig = "FEATURES.DHCP.SERVER_CONFIG"
|
||||
configFeatureDHCPStaticLeases = "FEATURES.DHCP.STATIC_LEASES"
|
||||
configFeatureDNServerConfig = "FEATURES.DNS.SERVER_CONFIG"
|
||||
configFeatureDNSPAccessLists = "FEATURES.DNS.ACCESS_LISTS"
|
||||
configFeatureDNSRewrites = "FEATURES.DNS.rewrites"
|
||||
configFeatureGeneralSettings = "FEATURES.GENERAL_SETTINGS"
|
||||
configFeatureQueryLogConfig = "FEATURES.QUERY_LOG_CONFIG"
|
||||
configFeatureStatsConfig = "FEATURES.STATS_CONFIG"
|
||||
configFeatureClientSettings = "FEATURES.CLIENT_SETTINGS"
|
||||
configFeatureServices = "FEATURES.SERVICES"
|
||||
configFeatureFilters = "FEATURES.FILTERS"
|
||||
|
||||
configOriginURL = "origin.url"
|
||||
configOriginWebURL = "origin.webURL"
|
||||
configOriginAPIPath = "origin.apiPath"
|
||||
configOriginUsername = "origin.username"
|
||||
configOriginPassword = "origin.password"
|
||||
configOriginCookie = "origin.cookie"
|
||||
configOriginInsecureSkipVerify = "origin.insecureSkipVerify"
|
||||
configOriginURL = "ORIGIN.URL"
|
||||
configOriginWebURL = "ORIGIN.WEB_URL"
|
||||
configOriginAPIPath = "ORIGIN.API_PATH"
|
||||
configOriginUsername = "ORIGIN.USERNAME"
|
||||
configOriginPassword = "ORIGIN.PASSWORD"
|
||||
configOriginCookie = "ORIGIN.COOKIE"
|
||||
configOriginInsecureSkipVerify = "ORIGIN.INSECURE_SKIP_VERIFY"
|
||||
|
||||
configReplicaURL = "replica.url"
|
||||
configReplicaWebURL = "replica.webURL"
|
||||
configReplicaAPIPath = "replica.apiPath"
|
||||
configReplicaUsername = "replica.username"
|
||||
configReplicaPassword = "replica.password"
|
||||
configReplicaCookie = "replica.cookie"
|
||||
configReplicaInsecureSkipVerify = "replica.insecureSkipVerify"
|
||||
configReplicaAutoSetup = "replica.autoSetup"
|
||||
configReplicaInterfaceName = "replica.interfaceName"
|
||||
|
||||
envReplicasUsernameFormat = "REPLICA%s_USERNAME" // #nosec G101
|
||||
envReplicasPasswordFormat = "REPLICA%s_PASSWORD" // #nosec G101
|
||||
envReplicasCookieFormat = "REPLICA%s_COOKIE" // #nosec G101
|
||||
envReplicasAPIPathFormat = "REPLICA%s_APIPATH"
|
||||
envReplicasInsecureSkipVerifyFormat = "REPLICA%s_INSECURESKIPVERIFY"
|
||||
envReplicasAutoSetup = "REPLICA%s_AUTOSETUP"
|
||||
envReplicasInterfaceName = "REPLICA%s_INTERFACENAME"
|
||||
envDHCPServerEnabled = "REPLICA%s_DHCPSERVERENABLED"
|
||||
envWebURL = "REPLICA%s_WEBURL"
|
||||
configReplicaURL = "REPLICA.URL"
|
||||
configReplicaWebURL = "REPLICA.WEB_URL"
|
||||
configReplicaAPIPath = "REPLICA.API_PATH"
|
||||
configReplicaUsername = "REPLICA.USERNAME"
|
||||
configReplicaPassword = "REPLICA.PASSWORD"
|
||||
configReplicaCookie = "REPLICA.COOKIE"
|
||||
configReplicaInsecureSkipVerify = "REPLICA.INSECURE_SKIP_VERIFY"
|
||||
configReplicaAutoSetup = "REPLICA.AUTO_SETUP"
|
||||
configReplicaInterfaceName = "REPLICA.INTERFACE_NAME"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -147,33 +138,116 @@ func getConfig() (*types.Config, error) {
|
||||
cfg.Replicas = append(cfg.Replicas, collectEnvReplicas()...)
|
||||
}
|
||||
|
||||
handleDeprecatedEnvVars(cfg)
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func handleDeprecatedEnvVars(cfg *types.Config) {
|
||||
value := checkDeprecatedEnvVar("RUNONSTART", "RUN_ON_START")
|
||||
if value != "" {
|
||||
cfg.RunOnStart, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("API_DARKMODE", "API_DARK_MODE")
|
||||
if value != "" {
|
||||
cfg.API.DarkMode, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_GENERALSETTINGS", "FEATURES_GENERAL_SETTINGS")
|
||||
if value != "" {
|
||||
cfg.Features.GeneralSettings, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_QUERYLOGCONFIG", "FEATURES_QUERY_LOG_CONFIG")
|
||||
if value != "" {
|
||||
cfg.Features.QueryLogConfig, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_STATSCONFIG", "FEATURES_STATS_CONFIG")
|
||||
if value != "" {
|
||||
cfg.Features.StatsConfig, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_CLIENTSETTINGS", "FEATURES_CLIENT_SETTINGS")
|
||||
if value != "" {
|
||||
cfg.Features.ClientSettings, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_DHCP_SERVERCONFIG", "FEATURES_DHCP_SERVER_CONFIG")
|
||||
if value != "" {
|
||||
cfg.Features.DHCP.ServerConfig, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_DHCP_STATICLEASES", "FEATURES_DHCP_STATIC_LEASES")
|
||||
if value != "" {
|
||||
cfg.Features.DHCP.StaticLeases, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_DNS_ACCESSLISTS", "FEATURES_DNS_ACCESS_LISTS")
|
||||
if value != "" {
|
||||
cfg.Features.DNS.AccessLists, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("FEATURES_DNS_SERVERCONFIG", "FEATURES_DNS_SERVER_CONFIG")
|
||||
if value != "" {
|
||||
cfg.Features.DNS.ServerConfig, _ = strconv.ParseBool(value)
|
||||
}
|
||||
|
||||
if cfg.Replica != nil {
|
||||
value = checkDeprecatedEnvVar("REPLICA_WEBURL", "REPLICA_WEB_URL")
|
||||
if value != "" {
|
||||
cfg.Replica.WebURL = value
|
||||
}
|
||||
value = checkDeprecatedEnvVar("REPLICA_AUTOSETUP", "REPLICA_AUTO_SETUP")
|
||||
if value != "" {
|
||||
cfg.Replica.AutoSetup, _ = strconv.ParseBool(value)
|
||||
}
|
||||
value = checkDeprecatedEnvVar("REPLICA_INTERFACENAME", "REPLICA_INTERFACE_NAME")
|
||||
if value != "" {
|
||||
cfg.Replica.InterfaceName = value
|
||||
}
|
||||
value = checkDeprecatedEnvVar("REPLICA_DHCPSERVERENABLED", "REPLICA_DHCP_SERVER_ENABLED")
|
||||
if value != "" {
|
||||
if b, err := strconv.ParseBool(value); err != nil {
|
||||
cfg.Replica.DHCPServerEnabled = utils.Ptr(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkDeprecatedEnvVar(oldName string, newName string) string {
|
||||
old, oldOK := os.LookupEnv(oldName)
|
||||
if oldOK {
|
||||
logger.With("deprecated", oldName, "replacement", newName).
|
||||
Warn("Deprecated env variable is used, please use the correct one")
|
||||
}
|
||||
new, newOK := os.LookupEnv(newName)
|
||||
if newOK {
|
||||
return new
|
||||
}
|
||||
return old
|
||||
}
|
||||
|
||||
func checkDeprecatedReplicaEnvVar(oldPattern, newPattern, replicaID string) string {
|
||||
return checkDeprecatedEnvVar(fmt.Sprintf(oldPattern, replicaID), fmt.Sprintf(newPattern, replicaID))
|
||||
}
|
||||
|
||||
// Manually collect replicas from env.
|
||||
func collectEnvReplicas() []types.AdGuardInstance {
|
||||
var replicas []types.AdGuardInstance
|
||||
for _, v := range os.Environ() {
|
||||
if envReplicasURLPattern.MatchString(v) {
|
||||
sm := envReplicasURLPattern.FindStringSubmatch(v)
|
||||
index := sm[1]
|
||||
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])),
|
||||
APIPath: os.Getenv(fmt.Sprintf(envReplicasAPIPathFormat, sm[1])),
|
||||
InsecureSkipVerify: strings.EqualFold(os.Getenv(fmt.Sprintf(envReplicasInsecureSkipVerifyFormat, sm[1])), "true"),
|
||||
AutoSetup: strings.EqualFold(os.Getenv(fmt.Sprintf(envReplicasAutoSetup, sm[1])), "true"),
|
||||
InterfaceName: os.Getenv(fmt.Sprintf(envReplicasInterfaceName, sm[1])),
|
||||
WebURL: os.Getenv(fmt.Sprintf("REPLICA%s_WEB_URL", index)),
|
||||
APIPath: checkDeprecatedReplicaEnvVar("REPLICA%s_APIPATH", "REPLICA%s_API_PATH", index),
|
||||
Username: os.Getenv(fmt.Sprintf("REPLICA%s_USERNAME", index)),
|
||||
Password: os.Getenv(fmt.Sprintf("REPLICA%s_PASSWORD", index)),
|
||||
Cookie: os.Getenv(fmt.Sprintf("REPLICA%s_COOKIE", index)),
|
||||
InsecureSkipVerify: strings.EqualFold(checkDeprecatedReplicaEnvVar("REPLICA%s_INSECURESKIPVERIFY", "REPLICA%s_INSECURE_SKIP_VERIFY", index), "true"),
|
||||
AutoSetup: strings.EqualFold(checkDeprecatedReplicaEnvVar("REPLICA%s_AUTOSETUP", "REPLICA%s_AUTO_SETUP", index), "true"),
|
||||
InterfaceName: checkDeprecatedReplicaEnvVar("REPLICA%s_INTERFACENAME", "REPLICA%s_INTERFACE_NAME", index),
|
||||
}
|
||||
|
||||
if dhcpEnabled, ok := os.LookupEnv(fmt.Sprintf(envDHCPServerEnabled, sm[1])); ok {
|
||||
if strings.EqualFold(dhcpEnabled, "true") {
|
||||
re.DHCPServerEnabled = boolPtr(true)
|
||||
} else if strings.EqualFold(dhcpEnabled, "false") {
|
||||
re.DHCPServerEnabled = boolPtr(false)
|
||||
}
|
||||
dhcpEnabled := checkDeprecatedReplicaEnvVar("REPLICA%s_DHCPSERVERENABLED", "REPLICA%s_DHCP_SERVER_ENABLED", index)
|
||||
if strings.EqualFold(dhcpEnabled, "true") {
|
||||
re.DHCPServerEnabled = utils.Ptr(true)
|
||||
} else if strings.EqualFold(dhcpEnabled, "false") {
|
||||
re.DHCPServerEnabled = utils.Ptr(false)
|
||||
}
|
||||
if re.APIPath == "" {
|
||||
re.APIPath = "/control"
|
||||
@@ -184,7 +258,3 @@ func collectEnvReplicas() []types.AdGuardInstance {
|
||||
|
||||
return replicas
|
||||
}
|
||||
|
||||
func boolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
119
cmd/root_test.go
119
cmd/root_test.go
@@ -10,6 +10,22 @@ import (
|
||||
)
|
||||
|
||||
var envVars = []string{
|
||||
"FEATURES_GENERAL_SETTINGS",
|
||||
"FEATURES_QUERY_LOG_CONFIG",
|
||||
"FEATURES_STATS_CONFIG",
|
||||
"FEATURES_CLIENT_SETTINGS",
|
||||
"FEATURES_SERVICES",
|
||||
"FEATURES_FILTERS",
|
||||
"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",
|
||||
@@ -26,56 +42,83 @@ var envVars = []string{
|
||||
}
|
||||
|
||||
var _ = Describe("Run", func() {
|
||||
BeforeEach(func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
initConfig()
|
||||
})
|
||||
AfterEach(func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
})
|
||||
Context("getConfig", func() {
|
||||
It("features should be true by default", func() {
|
||||
cfg, err := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, true)
|
||||
})
|
||||
It("features should be false", func() {
|
||||
for _, envVar := range envVars {
|
||||
Context("deprecated", func() {
|
||||
BeforeEach(func() {
|
||||
for _, envVar := range deprecatedEnvVars {
|
||||
Ω(os.Setenv(envVar, "false")).ShouldNot(HaveOccurred())
|
||||
}
|
||||
cfg, err := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
verifyFeatures(cfg, false)
|
||||
initConfig()
|
||||
})
|
||||
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(envReplicasInterfaceName, "1"), "eth0")).ShouldNot(HaveOccurred())
|
||||
AfterEach(func() {
|
||||
for _, envVar := range deprecatedEnvVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
})
|
||||
Context("getConfig", func() {
|
||||
It("features should be false", func() {
|
||||
cfg, err := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].InterfaceName).Should(Equal("eth0"))
|
||||
verifyFeatures(cfg, false)
|
||||
})
|
||||
})
|
||||
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(envDHCPServerEnabled, "1"), "true")).ShouldNot(HaveOccurred())
|
||||
})
|
||||
Context("current", func() {
|
||||
BeforeEach(func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
initConfig()
|
||||
})
|
||||
AfterEach(func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Unsetenv(envVar)).ShouldNot(HaveOccurred())
|
||||
}
|
||||
})
|
||||
Context("getConfig", func() {
|
||||
It("features should be true by default", func() {
|
||||
cfg, err := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Replicas[0].DHCPServerEnabled).Should(BeTrue())
|
||||
verifyFeatures(cfg, true)
|
||||
})
|
||||
It("should disable the dhcp server of replica 1", func() {
|
||||
Ω(os.Setenv("REPLICA1_URL", "https://foo.bar")).ShouldNot(HaveOccurred())
|
||||
Ω(os.Setenv(fmt.Sprintf(envDHCPServerEnabled, "1"), "false")).ShouldNot(HaveOccurred())
|
||||
It("features should be true by default", func() {
|
||||
cfg, err := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
verifyFeatures(cfg, true)
|
||||
})
|
||||
It("features should be false", func() {
|
||||
for _, envVar := range envVars {
|
||||
Ω(os.Setenv(envVar, "false")).ShouldNot(HaveOccurred())
|
||||
}
|
||||
cfg, err := getConfig()
|
||||
Ω(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 := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.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 := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.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 := getConfig()
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
Ω(cfg.Replicas[0].DHCPServerEnabled).ShouldNot(BeNil())
|
||||
Ω(*cfg.Replicas[0].DHCPServerEnabled).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
11
cmd/run.go
11
cmd/run.go
@@ -54,9 +54,6 @@ func init() {
|
||||
"will not fail on single errors, but will log the errors and continue.")
|
||||
_ = viper.BindPFlag(configContinueOnError, doCmd.PersistentFlags().Lookup("continueOnError"))
|
||||
|
||||
doCmd.PersistentFlags().String("logLevel", "info", "The log level to set. One of (debug, info, warn and error)")
|
||||
_ = viper.BindPFlag(configLogLevel, doCmd.PersistentFlags().Lookup("logLevel"))
|
||||
|
||||
doCmd.PersistentFlags().Int("api-port", 8080, "Sync API Port, the API endpoint will be started to enable remote triggering; if 0 port API is disabled.")
|
||||
_ = viper.BindPFlag(configAPIPort, doCmd.PersistentFlags().Lookup("api-port"))
|
||||
doCmd.PersistentFlags().String("api-username", "", "Sync API username")
|
||||
@@ -93,8 +90,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-web-url", "", "Origin instance web url used in the web interface (default: <origin-url>)")
|
||||
_ = viper.BindPFlag(configOriginWebURL, doCmd.PersistentFlags().Lookup("origin-web-url"))
|
||||
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")
|
||||
@@ -108,8 +105,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-web-url", "", "Replica instance web url used in the web interface (default: <replica-url>)")
|
||||
_ = viper.BindPFlag(configReplicaWebURL, doCmd.PersistentFlags().Lookup("replica-web-url"))
|
||||
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")
|
||||
|
||||
2
go.mod
2
go.mod
@@ -62,7 +62,7 @@ require (
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.7.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
golang.org/x/crypto v0.18.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -171,8 +171,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
|
||||
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
|
||||
@@ -425,6 +425,50 @@ var _ = Describe("Sync", func() {
|
||||
err := actionFilters(ac)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
It("should add a filter", func() {
|
||||
ac.origin.filters.Filters = utils.Ptr([]model.Filter{{Name: "foo", Url: "https://foo.bar"}})
|
||||
cl.EXPECT().Filtering().Return(rf, nil)
|
||||
cl.EXPECT().AddFilter(false, model.Filter{Name: "foo", Url: "https://foo.bar"})
|
||||
cl.EXPECT().RefreshFilters(gm.Any())
|
||||
err := actionFilters(ac)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
It("should delete a filter", func() {
|
||||
rf.Filters = utils.Ptr([]model.Filter{{Name: "foo", Url: "https://foo.bar"}})
|
||||
cl.EXPECT().Filtering().Return(rf, nil)
|
||||
cl.EXPECT().DeleteFilter(false, model.Filter{Name: "foo", Url: "https://foo.bar"})
|
||||
err := actionFilters(ac)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
It("should update a filter", func() {
|
||||
ac.origin.filters.Filters = utils.Ptr([]model.Filter{{Name: "foo", Url: "https://foo.bar", Enabled: true}})
|
||||
rf.Filters = utils.Ptr([]model.Filter{{Name: "foo", Url: "https://foo.bar"}})
|
||||
cl.EXPECT().Filtering().Return(rf, nil)
|
||||
cl.EXPECT().UpdateFilter(false, model.Filter{Name: "foo", Url: "https://foo.bar", Enabled: true})
|
||||
cl.EXPECT().RefreshFilters(gm.Any())
|
||||
err := actionFilters(ac)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should abort after failed added filter", func() {
|
||||
ac.continueOnError = false
|
||||
ac.origin.filters.Filters = utils.Ptr([]model.Filter{{Name: "foo", Url: "https://foo.bar"}})
|
||||
cl.EXPECT().Filtering().Return(rf, nil)
|
||||
cl.EXPECT().AddFilter(false, model.Filter{Name: "foo", Url: "https://foo.bar"}).Return(errors.New("test failure"))
|
||||
err := actionFilters(ac)
|
||||
Ω(err).Should(HaveOccurred())
|
||||
})
|
||||
|
||||
It("should continue after failed added filter", func() {
|
||||
ac.continueOnError = true
|
||||
ac.origin.filters.Filters = utils.Ptr([]model.Filter{{Name: "foo", Url: "https://foo.bar"}, {Name: "bar", Url: "https://bar.foo"}})
|
||||
cl.EXPECT().Filtering().Return(rf, nil)
|
||||
cl.EXPECT().AddFilter(false, model.Filter{Name: "foo", Url: "https://foo.bar"}).Return(errors.New("test failure"))
|
||||
cl.EXPECT().AddFilter(false, model.Filter{Name: "bar", Url: "https://bar.foo"})
|
||||
cl.EXPECT().RefreshFilters(gm.Any())
|
||||
err := actionFilters(ac)
|
||||
Ω(err).ShouldNot(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("actionDNSAccessLists", func() {
|
||||
|
||||
@@ -6,26 +6,26 @@ import (
|
||||
|
||||
// Features feature flags
|
||||
type Features struct {
|
||||
DNS DNS `json:"dns" yaml:"dns"`
|
||||
DHCP DHCP `json:"dhcp" yaml:"dhcp"`
|
||||
GeneralSettings bool `json:"generalSettings" yaml:"generalSettings"`
|
||||
QueryLogConfig bool `json:"queryLogConfig" yaml:"queryLogConfig"`
|
||||
StatsConfig bool `json:"statsConfig" yaml:"statsConfig"`
|
||||
ClientSettings bool `json:"clientSettings" yaml:"clientSettings"`
|
||||
Services bool `json:"services" yaml:"services"`
|
||||
Filters bool `json:"filters" yaml:"filters"`
|
||||
DNS DNS `json:"dns" yaml:"dns" mapstructure:"DNS"`
|
||||
DHCP DHCP `json:"dhcp" yaml:"dhcp" mapstructure:"DHCP"`
|
||||
GeneralSettings bool `json:"generalSettings" yaml:"generalSettings" mapstructure:"GENERAL_SETTINGS"`
|
||||
QueryLogConfig bool `json:"queryLogConfig" yaml:"queryLogConfig" mapstructure:"QUERY_LOG_CONFIG"`
|
||||
StatsConfig bool `json:"statsConfig" yaml:"statsConfig" mapstructure:"STATS_CONFIG"`
|
||||
ClientSettings bool `json:"clientSettings" yaml:"clientSettings" mapstructure:"CLIENT_SETTINGS"`
|
||||
Services bool `json:"services" yaml:"services" mapstructure:"SERVICES"`
|
||||
Filters bool `json:"filters" yaml:"filters" mapstructure:"FILTERS"`
|
||||
}
|
||||
|
||||
// DHCP features
|
||||
type DHCP struct {
|
||||
ServerConfig bool `json:"serverConfig" yaml:"serverConfig"`
|
||||
StaticLeases bool `json:"staticLeases" yaml:"staticLeases"`
|
||||
ServerConfig bool `json:"serverConfig" yaml:"serverConfig" mapstructure:"SERVER_CONFIG"`
|
||||
StaticLeases bool `json:"staticLeases" yaml:"staticLeases" mapstructure:"STATIC_LEASES"`
|
||||
}
|
||||
|
||||
// DNS features
|
||||
type DNS struct {
|
||||
AccessLists bool `json:"accessLists" yaml:"accessLists"`
|
||||
ServerConfig bool `json:"serverConfig" yaml:"serverConfig"`
|
||||
AccessLists bool `json:"accessLists" yaml:"accessLists" mapstructure:"ACCESS_LISTS"`
|
||||
ServerConfig bool `json:"serverConfig" yaml:"serverConfig" mapstructure:"SERVER_CONFIG"`
|
||||
Rewrites bool `json:"rewrites" yaml:"rewrites"`
|
||||
}
|
||||
|
||||
|
||||
@@ -15,24 +15,23 @@ const (
|
||||
// Config application configuration struct
|
||||
// +k8s:deepcopy-gen=true
|
||||
type Config struct {
|
||||
Origin AdGuardInstance `json:"origin" yaml:"origin"`
|
||||
Replica *AdGuardInstance `json:"replica,omitempty" yaml:"replica,omitempty"`
|
||||
Origin AdGuardInstance `json:"origin" yaml:"origin" mapstructure:"ORIGIN"`
|
||||
Replica *AdGuardInstance `json:"replica,omitempty" yaml:"replica,omitempty" mapstructure:"REPLICA"`
|
||||
Replicas []AdGuardInstance `json:"replicas,omitempty" yaml:"replicas,omitempty"`
|
||||
Cron string `json:"cron,omitempty" yaml:"cron,omitempty"`
|
||||
RunOnStart bool `json:"runOnStart,omitempty" yaml:"runOnStart,omitempty"`
|
||||
Cron string `json:"cron,omitempty" yaml:"cron,omitempty" mapstructure:"CRON"`
|
||||
RunOnStart bool `json:"runOnStart,omitempty" yaml:"runOnStart,omitempty" mapstructure:"RUN_ON_START"`
|
||||
PrintConfigOnly bool `json:"printConfigOnly,omitempty" yaml:"printConfigOnly,omitempty" mapstructure:"PRINT_CONFIG_ONLY"`
|
||||
ContinueOnError bool `json:"continueOnError,omitempty" yaml:"continueOnError,omitempty" mapstructure:"CONTINUE_ON_ERROR"`
|
||||
API API `json:"api,omitempty" yaml:"api,omitempty"`
|
||||
Features Features `json:"features,omitempty" yaml:"features,omitempty"`
|
||||
LogLevel string `json:"logLevel,omitempty" yaml:"logLevel,omitempty" mapstructure:"LOG_LEVEL"`
|
||||
API API `json:"api,omitempty" yaml:"api,omitempty" mapstructure:"API"`
|
||||
Features Features `json:"features,omitempty" yaml:"features,omitempty" mapstructure:"FEATURES"`
|
||||
}
|
||||
|
||||
// API configuration
|
||||
type API struct {
|
||||
Port int `json:"port,omitempty" yaml:"port,omitempty"`
|
||||
Username string `json:"username,omitempty" yaml:"username,omitempty"`
|
||||
Password string `json:"password,omitempty" yaml:"password,omitempty"`
|
||||
DarkMode bool `json:"darkMode,omitempty" yaml:"darkMode,omitempty"`
|
||||
Port int `json:"port,omitempty" yaml:"port,omitempty" mapstructure:"PORT"`
|
||||
Username string `json:"username,omitempty" yaml:"username,omitempty" mapstructure:"USERNAME"`
|
||||
Password string `json:"password,omitempty" yaml:"password,omitempty" mapstructure:"PASSWORD"`
|
||||
DarkMode bool `json:"darkMode,omitempty" yaml:"darkMode,omitempty" mapstructure:"DARK_MODE"`
|
||||
}
|
||||
|
||||
// UniqueReplicas get unique replication instances
|
||||
@@ -90,16 +89,16 @@ func (cfg *Config) Init() error {
|
||||
// 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"`
|
||||
Cookie string `json:"cookie,omitempty" yaml:"cookie,omitempty"`
|
||||
InsecureSkipVerify bool `json:"insecureSkipVerify" yaml:"insecureSkipVerify"`
|
||||
AutoSetup bool `json:"autoSetup" yaml:"autoSetup"`
|
||||
InterfaceName string `json:"interfaceName,omitempty" yaml:"interfaceName,omitempty"`
|
||||
DHCPServerEnabled *bool `json:"dhcpServerEnabled,omitempty" yaml:"dhcpServerEnabled,omitempty"`
|
||||
URL string `json:"url" yaml:"url" mapstructure:"URL"`
|
||||
WebURL string `json:"webURL" yaml:"webURL" mapstructure:"WEB_URL"`
|
||||
APIPath string `json:"apiPath,omitempty" yaml:"apiPath,omitempty" mapstructure:"API_PATH"`
|
||||
Username string `json:"username,omitempty" yaml:"username,omitempty" mapstructure:"USERNAME"`
|
||||
Password string `json:"password,omitempty" yaml:"password,omitempty" mapstructure:"PASSWORD"`
|
||||
Cookie string `json:"cookie,omitempty" yaml:"cookie,omitempty" mapstructure:"COOKIE"`
|
||||
InsecureSkipVerify bool `json:"insecureSkipVerify" yaml:"insecureSkipVerify" mapstructure:"INSECURE_SKIP_VERIFY"`
|
||||
AutoSetup bool `json:"autoSetup" yaml:"autoSetup" mapstructure:"AUTO_SETUP"`
|
||||
InterfaceName string `json:"interfaceName,omitempty" yaml:"interfaceName,omitempty" mapstructure:"INTERFACE_NAME"`
|
||||
DHCPServerEnabled *bool `json:"dhcpServerEnabled,omitempty" yaml:"dhcpServerEnabled,omitempty" mapstructure:"DHCP_SERVER_ENABLED"`
|
||||
|
||||
Host string `json:"-" yaml:"-"`
|
||||
WebHost string `json:"-" yaml:"-"`
|
||||
|
||||
Reference in New Issue
Block a user