diff --git a/kapacitor/vars.go b/kapacitor/vars.go index 4ef867a2d7..1821508727 100644 --- a/kapacitor/vars.go +++ b/kapacitor/vars.go @@ -76,10 +76,12 @@ func Vars(rule chronograf.AlertRule) (string, error) { } } +// NotEmpty is an error collector checking if strings are empty values type NotEmpty struct { Err error } +// Valid checks if string s is empty and if so reports an error using name func (n *NotEmpty) Valid(name, s string) error { if n.Err != nil { return n.Err @@ -91,6 +93,7 @@ func (n *NotEmpty) Valid(name, s string) error { return n.Err } +// Escape sanitizes strings with single quotes for kapacitor func Escape(str string) string { return strings.Replace(str, "'", `\'`, -1) } @@ -251,5 +254,10 @@ func formatValue(value string) string { if _, err := strconv.ParseFloat(value, 64); err == nil { return value } - return "'" + value + "'" + + // If the value is a kapacitor boolean value perform no formatting + if value == "TRUE" || value == "FALSE" { + return value + } + return "'" + Escape(value) + "'" } diff --git a/kapacitor/vars_test.go b/kapacitor/vars_test.go index 90d79390a8..305685ad77 100644 --- a/kapacitor/vars_test.go +++ b/kapacitor/vars_test.go @@ -49,3 +49,39 @@ func TestVarsCritStringEqual(t *testing.T) { t.Errorf("Error validating alert: %v %s", err, tick) } } + +func Test_formatValue(t *testing.T) { + tests := []struct { + name string + value string + want string + }{ + { + name: "parses floats", + value: "3.14", + want: "3.14", + }, + { + name: "parses booleans", + value: "TRUE", + want: "TRUE", + }, + { + name: "single quotes for strings", + value: "up", + want: "'up'", + }, + { + name: "handles escaping of single quotes", + value: "down's", + want: "'down\\'s'", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := formatValue(tt.value); got != tt.want { + t.Errorf("formatValue() = %v, want %v", got, tt.want) + } + }) + } +}