diff --git a/cmd/kured/main.go b/cmd/kured/main.go index 0597731..58df41e 100644 --- a/cmd/kured/main.go +++ b/cmd/kured/main.go @@ -193,7 +193,10 @@ func flagCheck(cmd *cobra.Command, args []string) { if slackHookURL != "" && notifyURL != "" { log.Warnf("Cannot use both --notify-url and --slack-hook-url flags. Kured will use --notify-url flag only...") } - if slackHookURL != "" { + if notifyURL != "" { + notifyURL = stripQuotes(notifyURL) + } else if slackHookURL != "" { + slackHookURL = stripQuotes(slackHookURL) log.Warnf("Deprecated flag(s). Please use --notify-url flag instead.") trataURL, err := url.Parse(slackHookURL) if err != nil { @@ -207,6 +210,19 @@ func flagCheck(cmd *cobra.Command, args []string) { } } +// stripQuotes removes any literal single or double quote chars that surround a string +func stripQuotes(str string) string { + if len(str) > 2 { + firstChar := str[0] + lastChar := str[len(str)-1] + if firstChar == lastChar && (firstChar == '"' || firstChar == '\'') { + return str[1 : len(str)-1] + } + } + // return the original string if it has a length of zero or one + return str +} + // bindViper initializes viper and binds command flags with environment variables func bindViper(cmd *cobra.Command, args []string) error { v := viper.New() diff --git a/cmd/kured/main_test.go b/cmd/kured/main_test.go index 24e8efb..d6849c2 100644 --- a/cmd/kured/main_test.go +++ b/cmd/kured/main_test.go @@ -27,11 +27,86 @@ func Test_flagCheck(t *testing.T) { var cmd *cobra.Command var args []string slackHookURL = "https://hooks.slack.com/services/BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET" + expected := "slack://BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET" flagCheck(cmd, args) - if notifyURL != "slack://BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET" { - t.Errorf("Slack URL Parsing is wrong: expecting %s but got %s\n", "slack://BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET", notifyURL) + if notifyURL != expected { + t.Errorf("Slack URL Parsing is wrong: expecting %s but got %s\n", expected, notifyURL) + } + + // validate that surrounding quotes are stripped + slackHookURL = "\"https://hooks.slack.com/services/BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET\"" + expected = "slack://BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET" + flagCheck(cmd, args) + if notifyURL != expected { + t.Errorf("Slack URL Parsing is wrong: expecting %s but got %s\n", expected, notifyURL) + } + slackHookURL = "'https://hooks.slack.com/services/BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET'" + expected = "slack://BLABLABA12345/IAM931A0VERY/COMPLICATED711854TOKEN1SET" + flagCheck(cmd, args) + if notifyURL != expected { + t.Errorf("Slack URL Parsing is wrong: expecting %s but got %s\n", expected, notifyURL) + } + slackHookURL = "" + notifyURL = "\"teams://79b4XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX@acd8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/204cXXXXXXXXXXXXXXXXXXXXXXXXXXXX/a1f8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX?host=XXXX.webhook.office.com\"" + expected = "teams://79b4XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX@acd8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/204cXXXXXXXXXXXXXXXXXXXXXXXXXXXX/a1f8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX?host=XXXX.webhook.office.com" + flagCheck(cmd, args) + if notifyURL != expected { + t.Errorf("notifyURL Parsing is wrong: expecting %s but got %s\n", expected, notifyURL) + } + notifyURL = "'teams://79b4XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX@acd8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/204cXXXXXXXXXXXXXXXXXXXXXXXXXXXX/a1f8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX?host=XXXX.webhook.office.com'" + expected = "teams://79b4XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX@acd8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/204cXXXXXXXXXXXXXXXXXXXXXXXXXXXX/a1f8XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX?host=XXXX.webhook.office.com" + flagCheck(cmd, args) + if notifyURL != expected { + t.Errorf("notifyURL Parsing is wrong: expecting %s but got %s\n", expected, notifyURL) } } + +func Test_stripQuotes(t *testing.T) { + tests := []struct { + name string + input string + expected string + }{ + { + name: "string with no surrounding quotes is unchanged", + input: "Hello, world!", + expected: "Hello, world!", + }, + { + name: "string with surrounding double quotes should strip quotes", + input: "\"Hello, world!\"", + expected: "Hello, world!", + }, + { + name: "string with surrounding single quotes should strip quotes", + input: "'Hello, world!'", + expected: "Hello, world!", + }, + { + name: "string with unbalanced surrounding quotes is unchanged", + input: "'Hello, world!\"", + expected: "'Hello, world!\"", + }, + { + name: "string with length of one is unchanged", + input: "'", + expected: "'", + }, + { + name: "string with length of zero is unchanged", + input: "", + expected: "", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := stripQuotes(tt.input); !reflect.DeepEqual(got, tt.expected) { + t.Errorf("stripQuotes() = %v, expected %v", got, tt.expected) + } + }) + } +} + func Test_rebootBlocked(t *testing.T) { noCheckers := []RebootBlocker{} nonblockingChecker := BlockingChecker{blocking: false}