Skip to content

Commit bd2adf6

Browse files
jlaskapiksel
andauthored
Support secrets for notification_url (#1300)
Co-authored-by: nils måsén <[email protected]>
1 parent 489356a commit bd2adf6

File tree

3 files changed

+57
-7
lines changed

3 files changed

+57
-7
lines changed

docs/notifications.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ If you want to disable TLS verification for the Gotify instance, you can use eit
181181

182182
To send notifications via shoutrrr, the following command-line options, or their corresponding environment variables, can be set:
183183

184-
- `--notification-url` (env. `WATCHTOWER_NOTIFICATION_URL`): The shoutrrr service URL to be used.
184+
- `--notification-url` (env. `WATCHTOWER_NOTIFICATION_URL`): The shoutrrr service URL to be used. This option can also reference a file, in which case the contents of the file are used.
185+
185186

186187
Go to [containrrr.dev/shoutrrr/v0.6/services/overview](https://containrrr.dev/shoutrrr/v0.6/services/overview) to
187188
learn more about the different service URLs you can use. You can define multiple services by space separating the

internal/flags/flags.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package flags
22

33
import (
4+
"bufio"
45
"errors"
56
"io/ioutil"
67
"os"
@@ -444,6 +445,7 @@ func GetSecretsFromFiles(rootCmd *cobra.Command) {
444445
"notification-slack-hook-url",
445446
"notification-msteams-hook",
446447
"notification-gotify-token",
448+
"notification-url",
447449
}
448450
for _, secret := range secrets {
449451
getSecretFromFile(flags, secret)
@@ -452,10 +454,33 @@ func GetSecretsFromFiles(rootCmd *cobra.Command) {
452454

453455
// getSecretFromFile will check if the flag contains a reference to a file; if it does, replaces the value of the flag with the contents of the file.
454456
func getSecretFromFile(flags *pflag.FlagSet, secret string) {
455-
value, err := flags.GetString(secret)
456-
if err != nil {
457-
log.Error(err)
457+
flag := flags.Lookup(secret)
458+
if sliceValue, ok := flag.Value.(pflag.SliceValue); ok {
459+
oldValues := sliceValue.GetSlice()
460+
values := make([]string, 0, len(oldValues))
461+
for _, value := range oldValues {
462+
if value != "" && isFile(value) {
463+
file, err := os.Open(value)
464+
if err != nil {
465+
log.Fatal(err)
466+
}
467+
scanner := bufio.NewScanner(file)
468+
for scanner.Scan() {
469+
line := scanner.Text()
470+
if line == "" {
471+
continue
472+
}
473+
values = append(values, line)
474+
}
475+
} else {
476+
values = append(values, value)
477+
}
478+
}
479+
sliceValue.Replace(values)
480+
return
458481
}
482+
483+
value := flag.Value.String()
459484
if value != "" && isFile(value) {
460485
file, err := ioutil.ReadFile(value)
461486
if err != nil {

internal/flags/flags_test.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func TestGetSecretsFromFilesWithString(t *testing.T) {
5050

5151
err := os.Setenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD", value)
5252
require.NoError(t, err)
53+
defer os.Unsetenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD")
5354

5455
testGetSecretsFromFiles(t, "notification-email-server-password", value)
5556
}
@@ -69,17 +70,40 @@ func TestGetSecretsFromFilesWithFile(t *testing.T) {
6970

7071
err = os.Setenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD", file.Name())
7172
require.NoError(t, err)
73+
defer os.Unsetenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD")
7274

7375
testGetSecretsFromFiles(t, "notification-email-server-password", value)
7476
}
7577

76-
func testGetSecretsFromFiles(t *testing.T, flagName string, expected string) {
78+
func TestGetSliceSecretsFromFiles(t *testing.T) {
79+
values := []string{"entry2", "", "entry3"}
80+
81+
// Create the temporary file which will contain a secret.
82+
file, err := ioutil.TempFile(os.TempDir(), "watchtower-")
83+
require.NoError(t, err)
84+
defer os.Remove(file.Name()) // Make sure to remove the temporary file later.
85+
86+
// Write the secret to the temporary file.
87+
for _, value := range values {
88+
_, err = file.WriteString("\n" + value)
89+
require.NoError(t, err)
90+
}
91+
file.Close()
92+
93+
testGetSecretsFromFiles(t, "notification-url", `[entry1,entry2,entry3]`,
94+
`--notification-url`, "entry1",
95+
`--notification-url`, file.Name())
96+
}
97+
98+
func testGetSecretsFromFiles(t *testing.T, flagName string, expected string, args ...string) {
7799
cmd := new(cobra.Command)
78100
SetDefaults()
79101
RegisterNotificationFlags(cmd)
102+
require.NoError(t, cmd.ParseFlags(args))
80103
GetSecretsFromFiles(cmd)
81-
value, err := cmd.PersistentFlags().GetString(flagName)
82-
require.NoError(t, err)
104+
flag := cmd.PersistentFlags().Lookup(flagName)
105+
require.NotNil(t, flag)
106+
value := flag.Value.String()
83107

84108
assert.Equal(t, expected, value)
85109
}

0 commit comments

Comments
 (0)