From ea64b24cd97309dfc337ac7902d88b4940030379 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 1 Mar 2018 23:19:07 -0500 Subject: [PATCH 1/2] validation: Add ValidateRFC3339TimeString --- helper/validation/validation.go | 10 ++++++ helper/validation/validation_test.go | 52 ++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/helper/validation/validation.go b/helper/validation/validation.go index b92916315..6c3b29a45 100644 --- a/helper/validation/validation.go +++ b/helper/validation/validation.go @@ -6,6 +6,7 @@ import ( "reflect" "regexp" "strings" + "time" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/structure" @@ -210,3 +211,12 @@ func ValidateRegexp(v interface{}, k string) (ws []string, errors []error) { } return } + +// ValidateRFC3339TimeString is a ValidateFunc that ensures a string parses +// as time.RFC3339 format +func ValidateRFC3339TimeString(v interface{}, k string) (ws []string, errors []error) { + if _, err := time.Parse(time.RFC3339, v.(string)); err != nil { + errors = append(errors, fmt.Errorf("%q: %s", k, err)) + } + return +} diff --git a/helper/validation/validation_test.go b/helper/validation/validation_test.go index cd68fa18d..82932ba51 100644 --- a/helper/validation/validation_test.go +++ b/helper/validation/validation_test.go @@ -144,6 +144,58 @@ func TestValidationRegexp(t *testing.T) { }) } +func TestValidateRFC3339TimeString(t *testing.T) { + runTestCases(t, []testCase{ + { + val: "2018-03-01T00:00:00Z", + f: ValidateRFC3339TimeString, + }, + { + val: "2018-03-01T00:00:00-05:00", + f: ValidateRFC3339TimeString, + }, + { + val: "2018-03-01T00:00:00+05:00", + f: ValidateRFC3339TimeString, + }, + { + val: "03/01/2018", + f: ValidateRFC3339TimeString, + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "1/2018" as "2006"`)), + }, + { + val: "03-01-2018", + f: ValidateRFC3339TimeString, + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "1-2018" as "2006"`)), + }, + { + val: "2018-03-01", + f: ValidateRFC3339TimeString, + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "" as "T"`)), + }, + { + val: "2018-03-01T", + f: ValidateRFC3339TimeString, + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "" as "15"`)), + }, + { + val: "2018-03-01T00:00:00", + f: ValidateRFC3339TimeString, + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "" as "Z07:00"`)), + }, + { + val: "2018-03-01T00:00:00Z05:00", + f: ValidateRFC3339TimeString, + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`extra text: 05:00`)), + }, + { + val: "2018-03-01T00:00:00Z-05:00", + f: ValidateRFC3339TimeString, + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`extra text: -05:00`)), + }, + }) +} + func TestValidateJsonString(t *testing.T) { type testCases struct { Value string From 994a78dbc77334a4422f41146adde29d73c203b9 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 15 Mar 2018 12:31:31 -0400 Subject: [PATCH 2/2] validation: Return "invalid RFC3339 timestamp" in ValidateRFC3339TimeString --- helper/validation/validation.go | 2 +- helper/validation/validation_test.go | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/helper/validation/validation.go b/helper/validation/validation.go index 6c3b29a45..1fc3a6c09 100644 --- a/helper/validation/validation.go +++ b/helper/validation/validation.go @@ -216,7 +216,7 @@ func ValidateRegexp(v interface{}, k string) (ws []string, errors []error) { // as time.RFC3339 format func ValidateRFC3339TimeString(v interface{}, k string) (ws []string, errors []error) { if _, err := time.Parse(time.RFC3339, v.(string)); err != nil { - errors = append(errors, fmt.Errorf("%q: %s", k, err)) + errors = append(errors, fmt.Errorf("%q: invalid RFC3339 timestamp", k)) } return } diff --git a/helper/validation/validation_test.go b/helper/validation/validation_test.go index 82932ba51..0e77006d4 100644 --- a/helper/validation/validation_test.go +++ b/helper/validation/validation_test.go @@ -161,37 +161,37 @@ func TestValidateRFC3339TimeString(t *testing.T) { { val: "03/01/2018", f: ValidateRFC3339TimeString, - expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "1/2018" as "2006"`)), + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`invalid RFC3339 timestamp`)), }, { val: "03-01-2018", f: ValidateRFC3339TimeString, - expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "1-2018" as "2006"`)), + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`invalid RFC3339 timestamp`)), }, { val: "2018-03-01", f: ValidateRFC3339TimeString, - expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "" as "T"`)), + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`invalid RFC3339 timestamp`)), }, { val: "2018-03-01T", f: ValidateRFC3339TimeString, - expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "" as "15"`)), + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`invalid RFC3339 timestamp`)), }, { val: "2018-03-01T00:00:00", f: ValidateRFC3339TimeString, - expectedErr: regexp.MustCompile(regexp.QuoteMeta(`cannot parse "" as "Z07:00"`)), + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`invalid RFC3339 timestamp`)), }, { val: "2018-03-01T00:00:00Z05:00", f: ValidateRFC3339TimeString, - expectedErr: regexp.MustCompile(regexp.QuoteMeta(`extra text: 05:00`)), + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`invalid RFC3339 timestamp`)), }, { val: "2018-03-01T00:00:00Z-05:00", f: ValidateRFC3339TimeString, - expectedErr: regexp.MustCompile(regexp.QuoteMeta(`extra text: -05:00`)), + expectedErr: regexp.MustCompile(regexp.QuoteMeta(`invalid RFC3339 timestamp`)), }, }) }