diff --git a/examples/resources/coder_parameter/resource.tf b/examples/resources/coder_parameter/resource.tf index 987318b3..d23afc5f 100644 --- a/examples/resources/coder_parameter/resource.tf +++ b/examples/resources/coder_parameter/resource.tf @@ -40,10 +40,23 @@ data "coder_parameter" "cores" { data "coder_parameter" "disk_size" { name = "Disk Size" type = "number" + default = "5" + validation { + # This can apply to number. + min = 0 + max = 10 + monotonic = "increasing" + } +} + +data "coder_parameter" "cat_lives" { + name = "Cat Live" + type = "number" default = "9" validation { - # This can apply to number and string types. + # This can apply to number. min = 0 max = 10 + monotonic = "decreasing" } } diff --git a/provider/parameter.go b/provider/parameter.go index e47e7ab5..615a3da3 100644 --- a/provider/parameter.go +++ b/provider/parameter.go @@ -25,12 +25,19 @@ type Option struct { } type Validation struct { - Min int - Max int + Min int + Max int + Monotonic string + Regex string Error string } +const ( + ValidationMonotonicIncreasing = "increasing" + ValidationMonotonicDecreasing = "decreasing" +) + type Parameter struct { Value string Name string @@ -235,9 +242,14 @@ func parameterDataSource() *schema.Resource { Description: "The maximum of a number parameter.", RequiredWith: []string{"validation.0.min"}, }, + "monotonic": { + Type: schema.TypeString, + Optional: true, + Description: "Number monotonicity, either increasing or decreasing.", + }, "regex": { Type: schema.TypeString, - ConflictsWith: []string{"validation.0.min", "validation.0.max"}, + ConflictsWith: []string{"validation.0.min", "validation.0.max", "validation.0.monotonic"}, Description: "A regex for the input parameter to match against.", Optional: true, }, @@ -318,6 +330,9 @@ func (v *Validation) Valid(typ, value string) error { if num > v.Max { return fmt.Errorf("value %d is more than the maximum %d", num, v.Max) } + if v.Monotonic != "" && v.Monotonic != ValidationMonotonicIncreasing && v.Monotonic != ValidationMonotonicDecreasing { + return fmt.Errorf("number monotonicity can be either %q or %q", ValidationMonotonicIncreasing, ValidationMonotonicDecreasing) + } } return nil } diff --git a/provider/parameter_test.go b/provider/parameter_test.go index c99edd3c..f4a7ae4e 100644 --- a/provider/parameter_test.go +++ b/provider/parameter_test.go @@ -271,7 +271,8 @@ func TestValueValidatesType(t *testing.T) { RegexError string Min, Max int - Error *regexp.Regexp + Monotonic string + Error *regexp.Regexp }{{ Name: "StringWithMin", Type: "string", @@ -320,18 +321,42 @@ func TestValueValidatesType(t *testing.T) { RegexError: "bad fruit", Value: "apple", Error: regexp.MustCompile(`bad fruit`), + }, { + Name: "InvalidMonotonicity", + Type: "number", + Value: "1", + Min: 0, + Max: 2, + Monotonic: "foobar", + Error: regexp.MustCompile(`number monotonicity can be either "increasing" or "decreasing"`), + }, { + Name: "IncreasingMonotonicity", + Type: "number", + Value: "1", + Min: 0, + Max: 2, + Monotonic: "increasing", + }, { + Name: "DecreasingMonotonicity", + Type: "number", + Value: "1", + Min: 0, + Max: 2, + Monotonic: "decreasing", }} { tc := tc t.Run(tc.Name, func(t *testing.T) { t.Parallel() v := &provider.Validation{ - Min: tc.Min, - Max: tc.Max, - Regex: tc.Regex, - Error: tc.RegexError, + Min: tc.Min, + Max: tc.Max, + Monotonic: tc.Monotonic, + Regex: tc.Regex, + Error: tc.RegexError, } err := v.Valid(tc.Type, tc.Value) if tc.Error != nil { + require.Error(t, err) require.True(t, tc.Error.MatchString(err.Error()), "got: %s", err.Error()) } })