Skip to content

Commit

Permalink
feat: link shoutrrr and initialize services (part 1 of shoutrrr suppo…
Browse files Browse the repository at this point in the history
…rt) (#633)
  • Loading branch information
favonia committed Nov 6, 2023
1 parent fb368ac commit 61f42a0
Show file tree
Hide file tree
Showing 24 changed files with 627 additions and 40 deletions.
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ linters:
- varcheck # deprecated

- cyclop # can detect complicated code, but never leads to actual code changes
- funlen # can detect complicated code, but never leads to actual code changes
- gocognit # can detect complicated code, but never leads to actual code changes
- maintidx # can detect complicated code, but never leads to actual code changes

Expand Down
2 changes: 1 addition & 1 deletion README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A feature-rich and robust Cloudflare DDNS updater with a small footprint. The pr

### ⚡ Efficiency

- 🤏 The Docker image takes less than 3 MB (after compression).
- 🤏 The Docker image takes less than 5 MB after compression.
- 🔁 The Go runtime re-uses existing HTTP connections.
- 🗃️ Cloudflare API responses are cached to reduce the API usage.

Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.21

require (
github.com/cloudflare/cloudflare-go v0.80.0
github.com/containrrr/shoutrrr v0.8.0
github.com/google/go-querystring v1.1.0
github.com/hashicorp/go-retryablehttp v0.7.4
github.com/jellydator/ttlcache/v3 v3.1.0
Expand All @@ -16,10 +17,14 @@ require (

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
43 changes: 33 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,33 +1,50 @@
github.com/cloudflare/cloudflare-go v0.80.0 h1:BfCFK9gy+2H/R3yjZWzFvWsVXwr2zICCfmAW3brbHpE=
github.com/cloudflare/cloudflare-go v0.80.0/go.mod h1:gkHQf9xEubaQPEuerBuoinR9P8bf8a05Lq0X6WKy1Oc=
github.com/containrrr/shoutrrr v0.8.0 h1:mfG2ATzIS7NR2Ec6XL+xyoHzN97H8WPjir8aYzJUSec=
github.com/containrrr/shoutrrr v0.8.0/go.mod h1:ioyQAyu1LJY6sILuNyKaQaw+9Ttik5QePU8atnAdO2o=
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/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc=
github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/jellydator/ttlcache/v3 v3.1.0 h1:0gPFG0IHHP6xyUyXq+JaD8fwkDCqgqwohXNJBcYE71g=
github.com/jellydator/ttlcache/v3 v3.1.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
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/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU=
github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
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/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
Expand All @@ -45,13 +62,19 @@ golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY=
golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
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=
Expand Down
3 changes: 3 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/favonia/cloudflare-ddns/internal/domain"
"github.com/favonia/cloudflare-ddns/internal/ipnet"
"github.com/favonia/cloudflare-ddns/internal/monitor"
"github.com/favonia/cloudflare-ddns/internal/notifier"
"github.com/favonia/cloudflare-ddns/internal/provider"
)

Expand All @@ -29,6 +30,7 @@ type Config struct {
DetectionTimeout time.Duration
UpdateTimeout time.Duration
Monitors []monitor.Monitor
Notifiers []notifier.Notifier
}

// Default gives the default configuration.
Expand All @@ -54,5 +56,6 @@ func Default() *Config {
UpdateTimeout: time.Second * 30, //nolint:gomnd
DetectionTimeout: time.Second * 5, //nolint:gomnd
Monitors: nil,
Notifiers: nil,
}
}
8 changes: 8 additions & 0 deletions internal/config/config_print.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/favonia/cloudflare-ddns/internal/domain"
"github.com/favonia/cloudflare-ddns/internal/ipnet"
"github.com/favonia/cloudflare-ddns/internal/monitor"
"github.com/favonia/cloudflare-ddns/internal/notifier"
"github.com/favonia/cloudflare-ddns/internal/pp"
"github.com/favonia/cloudflare-ddns/internal/provider"
)
Expand Down Expand Up @@ -94,4 +95,11 @@ func (c *Config) Print(ppfmt pp.PP) {
item(service+":", "%s", params)
}, c.Monitors)
}

if len(c.Notifiers) > 0 {
section("Notifiers (via shoutrrr):")
notifier.DescribeAll(func(service, params string) {
item(service+":", "%s", params)
}, c.Notifiers)
}
}
20 changes: 16 additions & 4 deletions internal/config/config_print_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import (
"strings"
"testing"

"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"

"github.com/favonia/cloudflare-ddns/internal/config"
"github.com/favonia/cloudflare-ddns/internal/domain"
"github.com/favonia/cloudflare-ddns/internal/ipnet"
"github.com/favonia/cloudflare-ddns/internal/mocks"
"github.com/favonia/cloudflare-ddns/internal/monitor"
"github.com/favonia/cloudflare-ddns/internal/notifier"
"github.com/favonia/cloudflare-ddns/internal/pp"
)

Expand Down Expand Up @@ -117,7 +117,9 @@ func TestPrintMaps(t *testing.T) {
printItem(innerMockPP, "IP detection:", "5s"),
printItem(innerMockPP, "Record updating:", "30s"),
mockPP.EXPECT().Infof(pp.EmojiConfig, "Monitors:"),
printItem(innerMockPP, "Healthchecks:", "(URL redacted)"),
printItem(innerMockPP, "Meow:", "purrrr"),
mockPP.EXPECT().Infof(pp.EmojiConfig, "Notifiers (via shoutrrr):"),
printItem(innerMockPP, "Snake:", "hissss"),
)

c := config.Default()
Expand All @@ -133,10 +135,20 @@ func TestPrintMaps(t *testing.T) {
c.Proxied[domain.FQDN("c")] = false
c.Proxied[domain.FQDN("d")] = false

m, ok := monitor.NewHealthchecks(mockPP, "https://user:pass@host/path")
require.True(t, ok)
m := mocks.NewMockMonitor(mockCtrl)
m.EXPECT().Describe(gomock.Any()).
DoAndReturn(func(f func(string, string)) {
f("Meow", "purrrr")
}).AnyTimes()
c.Monitors = []monitor.Monitor{m}

n := mocks.NewMockNotifier(mockCtrl)
n.EXPECT().Describe(gomock.Any()).
DoAndReturn(func(f func(string, string)) {
f("Snake", "hissss")
}).AnyTimes()
c.Notifiers = []notifier.Notifier{n}

c.Print(mockPP)
}

Expand Down
3 changes: 2 additions & 1 deletion internal/config/config_read.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ func (c *Config) ReadEnv(ppfmt pp.PP) bool {
!ReadNonnegDuration(ppfmt, "DETECTION_TIMEOUT", &c.DetectionTimeout) ||
!ReadNonnegDuration(ppfmt, "UPDATE_TIMEOUT", &c.UpdateTimeout) ||
!ReadAndAppendHealthchecksURL(ppfmt, "HEALTHCHECKS", &c.Monitors) ||
!ReadAndAppendUptimeKumaURL(ppfmt, "UPTIMEKUMA", &c.Monitors) {
!ReadAndAppendUptimeKumaURL(ppfmt, "UPTIMEKUMA", &c.Monitors) ||
!ReadAndAppendShoutrrrURL(ppfmt, "SHOUTRRR", &c.Notifiers) {
return false
}

Expand Down
32 changes: 21 additions & 11 deletions internal/config/config_read_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,31 @@ import (
"github.com/favonia/cloudflare-ddns/internal/provider"
)

//nolint:paralleltest // environment variables are global
func TestReadEnvWithOnlyToken(t *testing.T) {
mockCtrl := gomock.NewController(t)

func unsetAll(t *testing.T) {
t.Helper()
unset(t,
"CF_API_TOKEN", "CF_API_TOKEN_FILE", "CF_ACCOUNT_ID",
"IP4_PROVIDER", "IP6_PROVIDER",
"DOMAINS", "IP4_DOMAINS", "IP6_DOMAINS",
"UPDATE_CRON", "UPDATE_ON_START", "DELETE_ON_STOP", "CACHE_EXPIRATION", "TTL", "PROXIED", "DETECTION_TIMEOUT")
"UPDATE_CRON",
"UPDATE_ON_START",
"DELETE_ON_STOP",
"CACHE_EXPIRATION",
"TTL",
"PROXIED",
"DETECTION_TIMEOUT",
"UPDATE_TIMEOUT",
"HEALTHCHECKS",
"UPTIMEKUMA",
"SHOUTRRR",
)
}

//nolint:paralleltest // environment variables are global
func TestReadEnvWithOnlyToken(t *testing.T) {
mockCtrl := gomock.NewController(t)

unsetAll(t)
store(t, "CF_API_TOKEN", "deadbeaf")

var cfg config.Config
Expand Down Expand Up @@ -55,12 +70,7 @@ func TestReadEnvWithOnlyToken(t *testing.T) {
func TestReadEnvEmpty(t *testing.T) {
mockCtrl := gomock.NewController(t)

unset(t,
"CF_API_TOKEN", "CF_API_TOKEN_FILE", "CF_ACCOUNT_ID",
"IP4_PROVIDER", "IP6_PROVIDER",
"IP4_POLICY", "IP6_POLICY",
"DOMAINS", "IP4_DOMAINS", "IP6_DOMAINS",
"UPDATE_CRON", "UPDATE_ON_START", "DELETE_ON_STOP", "CACHE_EXPIRATION", "TTL", "PROXIED", "DETECTION_TIMEOUT")
unsetAll(t)

var cfg config.Config
mockPP := mocks.NewMockPP(mockCtrl)
Expand Down
13 changes: 13 additions & 0 deletions internal/config/env_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ func Getenv(key string) string {
return strings.TrimSpace(os.Getenv(key))
}

// Getenvs reads an environment variable, split it by '\n', and trim the space.
func Getenvs(key string) []string {
rawVals := strings.Split(os.Getenv(key), "\n")
vals := make([]string, 0, len(rawVals))
for _, v := range rawVals {
v = strings.TrimSpace(v)
if len(v) > 0 {
vals = append(vals, v)
}
}
return vals
}

// ReadString reads an environment variable as a plain string.
func ReadString(ppfmt pp.PP, key string, field *string) bool {
val := Getenv(key)
Expand Down
23 changes: 23 additions & 0 deletions internal/config/env_base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ func TestGetenv(t *testing.T) {
}
}

//nolint:paralleltest // environment vars are global
func TestGetenvs(t *testing.T) {
key := keyPrefix + "VAR"
for name, tc := range map[string]struct {
set bool
val string
expected []string
}{
"nil": {false, "", []string{}},
"empty": {true, "", []string{}},
"only-spaces": {true, "\n \n \n \t", []string{}},
"simple": {true, "VAL", []string{"VAL"}},
"space1": {true, " VAL1 \nVAL2 ", []string{"VAL1", "VAL2"}},
"space2": {true, " VAL1 \n VAL2 ", []string{"VAL1", "VAL2"}},
} {
tc := tc
t.Run(name, func(t *testing.T) {
set(t, key, tc.set, tc.val)
require.Equal(t, tc.expected, config.Getenvs(key))
})
}
}

//nolint:paralleltest // environment vars are global
func TestReadString(t *testing.T) {
key := keyPrefix + "STRING"
Expand Down
24 changes: 24 additions & 0 deletions internal/config/env_notifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package config

import (
"github.com/favonia/cloudflare-ddns/internal/notifier"
"github.com/favonia/cloudflare-ddns/internal/pp"
)

// ReadAndAppendShoutrrrURL reads the URLs separated by the newline.
func ReadAndAppendShoutrrrURL(ppfmt pp.PP, key string, field *[]notifier.Notifier) bool {
vals := Getenvs(key)

if len(vals) == 0 {
return true
}

s, ok := notifier.NewShoutrrr(ppfmt, vals)
if !ok {
return false
}

// Append the new monitor to the existing list
*field = append(*field, s)
return true
}
Loading

0 comments on commit 61f42a0

Please sign in to comment.