add multi replica env support #4
This commit is contained in:
@@ -52,6 +52,8 @@ docker run -d \
|
||||
```
|
||||
|
||||
## docker compose
|
||||
|
||||
### config file
|
||||
```yaml
|
||||
---
|
||||
version: "2.1"
|
||||
@@ -66,6 +68,32 @@ services:
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### env
|
||||
|
||||
```yaml
|
||||
---
|
||||
version: "2.1"
|
||||
services:
|
||||
adguardhome-sync:
|
||||
image: quay.io/bakito/adguardhome-sync
|
||||
container_name: adguardhome-sync
|
||||
environment:
|
||||
- ORIGIN_URL=https://192.168.1.2:3000
|
||||
- ORIGIN_USERNAME=username
|
||||
- ORIGIN_PASSWORD=password
|
||||
- REPLICA_URL=http://192.168.1.3
|
||||
- REPLICA_USERNAME=username
|
||||
- REPLICA_PASSWORD=password
|
||||
- REPLICA1_URL=http://192.168.1.4
|
||||
- REPLICA1_USERNAME=username
|
||||
- REPLICA1_PASSWORD=password
|
||||
- REPLICA1_APIPATH=/some/path/control
|
||||
- CRON=*/10 * * * * # run every 10 minutes
|
||||
ports:
|
||||
- 8080:8080
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### Config file
|
||||
|
||||
location: $HOME/.adguardhome-sync.yaml
|
||||
|
||||
+43
-5
@@ -3,13 +3,13 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
@@ -31,11 +31,17 @@ const (
|
||||
configReplicaUsername = "replica.username"
|
||||
configReplicaPassword = "replica.password"
|
||||
configReplicaInsecureSkipVerify = "replica.insecureSkipVerify"
|
||||
|
||||
envReplicasUsernameFormat = "REPLICA%s_USERNAME"
|
||||
envReplicasPasswordFormat = "REPLICA%s_PASSWORD"
|
||||
envReplicasAPIPathFormat = "REPLICA%s_APIPATH"
|
||||
envReplicasInsecureSkipVerifyFormat = "REPLICA%s_INSECURESKIPVERIFY"
|
||||
)
|
||||
|
||||
var (
|
||||
cfgFile string
|
||||
logger = log.GetLogger("root")
|
||||
cfgFile string
|
||||
logger = log.GetLogger("root")
|
||||
envReplicasURLPattern = regexp.MustCompile(`^REPLICA(\d+)_URL=(.*)`)
|
||||
)
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
@@ -95,3 +101,35 @@ func initConfig() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func getConfig() (*types.Config, error) {
|
||||
cfg := &types.Config{}
|
||||
if err := viper.Unmarshal(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(cfg.Replicas) == 0 {
|
||||
cfg.Replicas = append(cfg.Replicas, collectEnvReplicas()...)
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// 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)
|
||||
re := types.AdGuardInstance{
|
||||
URL: sm[2],
|
||||
Username: os.Getenv(fmt.Sprintf(envReplicasUsernameFormat, sm[1])),
|
||||
Password: os.Getenv(fmt.Sprintf(envReplicasPasswordFormat, sm[1])),
|
||||
APIPath: os.Getenv(fmt.Sprintf(envReplicasAPIPathFormat, sm[1])),
|
||||
InsecureSkipVerify: strings.EqualFold(os.Getenv(fmt.Sprintf(envReplicasInsecureSkipVerifyFormat, sm[1])), "true"),
|
||||
}
|
||||
replicas = append(replicas, re)
|
||||
}
|
||||
}
|
||||
|
||||
return replicas
|
||||
}
|
||||
|
||||
+3
-5
@@ -3,10 +3,8 @@ package cmd
|
||||
import (
|
||||
"github.com/bakito/adguardhome-sync/pkg/log"
|
||||
"github.com/bakito/adguardhome-sync/pkg/sync"
|
||||
"github.com/bakito/adguardhome-sync/pkg/types"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// runCmd represents the run command
|
||||
@@ -16,8 +14,8 @@ var doCmd = &cobra.Command{
|
||||
Long: `Synchronizes the configuration form an origin instance to a replica`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
logger = log.GetLogger("run")
|
||||
cfg := &types.Config{}
|
||||
if err := viper.Unmarshal(cfg); err != nil {
|
||||
cfg, err := getConfig()
|
||||
if err != nil {
|
||||
logger.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
+9
-4
@@ -10,7 +10,7 @@ import (
|
||||
// Config application configuration struct
|
||||
type Config struct {
|
||||
Origin AdGuardInstance `json:"origin" yaml:"origin"`
|
||||
Replica *AdGuardInstance `json:"replica,omitempty" yaml:"replica,omitempty"`
|
||||
Replica AdGuardInstance `json:"replica,omitempty" yaml:"replica,omitempty"`
|
||||
Replicas []AdGuardInstance `json:"replicas,omitempty" yaml:"replicas,omitempty"`
|
||||
Cron string `json:"cron,omitempty" yaml:"cron,omitempty"`
|
||||
API API `json:"api,omitempty" yaml:"api,omitempty"`
|
||||
@@ -26,15 +26,20 @@ type API struct {
|
||||
// UniqueReplicas get unique replication instances
|
||||
func (cfg *Config) UniqueReplicas() []AdGuardInstance {
|
||||
dedup := make(map[string]AdGuardInstance)
|
||||
if cfg.Replica != nil {
|
||||
dedup[cfg.Replica.Key()] = *cfg.Replica
|
||||
if cfg.Replica.URL != "" {
|
||||
dedup[cfg.Replica.Key()] = cfg.Replica
|
||||
}
|
||||
for _, replica := range cfg.Replicas {
|
||||
dedup[replica.Key()] = replica
|
||||
if replica.URL != "" {
|
||||
dedup[replica.Key()] = replica
|
||||
}
|
||||
}
|
||||
|
||||
var r []AdGuardInstance
|
||||
for _, replica := range dedup {
|
||||
if replica.APIPath == "" {
|
||||
replica.APIPath = "/control"
|
||||
}
|
||||
r = append(r, replica)
|
||||
}
|
||||
return r
|
||||
|
||||
Reference in New Issue
Block a user