Skip to content

Commit

Permalink
Support secrets for notification_url (#1300)
Browse files Browse the repository at this point in the history
Co-authored-by: nils måsén <nils@piksel.se>
  • Loading branch information
jlaska and piksel committed Aug 1, 2022
1 parent 489356a commit bd2adf6
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
3 changes: 2 additions & 1 deletion docs/notifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ If you want to disable TLS verification for the Gotify instance, you can use eit

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

- `--notification-url` (env. `WATCHTOWER_NOTIFICATION_URL`): The shoutrrr service URL to be used.
- `--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.


Go to [containrrr.dev/shoutrrr/v0.6/services/overview](https://containrrr.dev/shoutrrr/v0.6/services/overview) to
learn more about the different service URLs you can use. You can define multiple services by space separating the
Expand Down
31 changes: 28 additions & 3 deletions internal/flags/flags.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package flags

import (
"bufio"
"errors"
"io/ioutil"
"os"
Expand Down Expand Up @@ -444,6 +445,7 @@ func GetSecretsFromFiles(rootCmd *cobra.Command) {
"notification-slack-hook-url",
"notification-msteams-hook",
"notification-gotify-token",
"notification-url",
}
for _, secret := range secrets {
getSecretFromFile(flags, secret)
Expand All @@ -452,10 +454,33 @@ func GetSecretsFromFiles(rootCmd *cobra.Command) {

// 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.
func getSecretFromFile(flags *pflag.FlagSet, secret string) {
value, err := flags.GetString(secret)
if err != nil {
log.Error(err)
flag := flags.Lookup(secret)
if sliceValue, ok := flag.Value.(pflag.SliceValue); ok {
oldValues := sliceValue.GetSlice()
values := make([]string, 0, len(oldValues))
for _, value := range oldValues {
if value != "" && isFile(value) {
file, err := os.Open(value)
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if line == "" {
continue
}
values = append(values, line)
}
} else {
values = append(values, value)
}
}
sliceValue.Replace(values)
return
}

value := flag.Value.String()
if value != "" && isFile(value) {
file, err := ioutil.ReadFile(value)
if err != nil {
Expand Down
30 changes: 27 additions & 3 deletions internal/flags/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func TestGetSecretsFromFilesWithString(t *testing.T) {

err := os.Setenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD", value)
require.NoError(t, err)
defer os.Unsetenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD")

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

err = os.Setenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD", file.Name())
require.NoError(t, err)
defer os.Unsetenv("WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD")

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

func testGetSecretsFromFiles(t *testing.T, flagName string, expected string) {
func TestGetSliceSecretsFromFiles(t *testing.T) {
values := []string{"entry2", "", "entry3"}

// Create the temporary file which will contain a secret.
file, err := ioutil.TempFile(os.TempDir(), "watchtower-")
require.NoError(t, err)
defer os.Remove(file.Name()) // Make sure to remove the temporary file later.

// Write the secret to the temporary file.
for _, value := range values {
_, err = file.WriteString("\n" + value)
require.NoError(t, err)
}
file.Close()

testGetSecretsFromFiles(t, "notification-url", `[entry1,entry2,entry3]`,
`--notification-url`, "entry1",
`--notification-url`, file.Name())
}

func testGetSecretsFromFiles(t *testing.T, flagName string, expected string, args ...string) {
cmd := new(cobra.Command)
SetDefaults()
RegisterNotificationFlags(cmd)
require.NoError(t, cmd.ParseFlags(args))
GetSecretsFromFiles(cmd)
value, err := cmd.PersistentFlags().GetString(flagName)
require.NoError(t, err)
flag := cmd.PersistentFlags().Lookup(flagName)
require.NotNil(t, flag)
value := flag.Value.String()

assert.Equal(t, expected, value)
}
Expand Down

0 comments on commit bd2adf6

Please sign in to comment.