diff --git a/sdk/helper/template/funcs.go b/sdk/helper/template/funcs.go index 8adb5109c..bbfceaece 100644 --- a/sdk/helper/template/funcs.go +++ b/sdk/helper/template/funcs.go @@ -10,12 +10,16 @@ import ( UUID "github.com/hashicorp/go-uuid" ) -func nowSeconds() string { +func unixTime() string { return strconv.FormatInt(time.Now().Unix(), 10) } -func nowNano() string { - return strconv.FormatInt(time.Now().UnixNano(), 10) +func unixTimeMillis() string { + return strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) +} + +func timestamp(format string) string { + return time.Now().Format(format) } func truncate(maxLen int, str string) (string, error) { diff --git a/sdk/helper/template/funcs_test.go b/sdk/helper/template/funcs_test.go index c6c87b444..d7c3021ae 100644 --- a/sdk/helper/template/funcs_test.go +++ b/sdk/helper/template/funcs_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/require" ) -func TestNowSeconds(t *testing.T) { +func TestUnixTimestamp(t *testing.T) { now := time.Now().Unix() for i := 0; i < 100; i++ { - str := nowSeconds() + str := unixTime() actual, err := strconv.Atoi(str) require.NoError(t, err) // Make sure the value generated is from now (or later if the clock ticked over) @@ -20,9 +20,9 @@ func TestNowSeconds(t *testing.T) { } func TestNowNano(t *testing.T) { - now := time.Now().UnixNano() + now := time.Now().UnixNano() / int64(time.Millisecond) for i := 0; i < 100; i++ { - str := nowNano() + str := unixTimeMillis() actual, err := strconv.Atoi(str) require.NoError(t, err) // Make sure the value generated is from now (or later if the clock ticked over) diff --git a/sdk/helper/template/template.go b/sdk/helper/template/template.go index 181332ec3..44c5a0e2f 100644 --- a/sdk/helper/template/template.go +++ b/sdk/helper/template/template.go @@ -36,21 +36,21 @@ func Function(name string, f interface{}) Opt { // StringTemplate creates strings based on the provided template. // This uses the go templating language, so anything that adheres to that language will function in this struct. // There are several custom functions available for use in the template: -// - random (rand) +// - random // - Randomly generated characters. This uses the charset specified in RandomCharset. Must include a length. // Example: {{ rand 20 }} -// - truncate (trunc) +// - truncate // - Truncates the previous value to the specified length. Must include a maximum length. // Example: {{ .DisplayName | truncate 10 }} -// - truncate_sha256 (trunc_sha256) +// - truncate_sha256 // - Truncates the previous value to the specified length. If the original length is greater than the length // specified, the remaining characters will be sha256 hashed and appended to the end. The hash will be only the first 8 characters The maximum length will // be no longer than the length specified. // Example: {{ .DisplayName | truncate_sha256 30 }} -// - uppercase (upper) +// - uppercase // - Uppercases the previous value. // Example: {{ .RoleName | uppercase }} -// - lowercase (lower) +// - lowercase // - Lowercases the previous value. // Example: {{ .DisplayName | lowercase }} // - replace @@ -59,12 +59,14 @@ func Function(name string, f interface{}) Opt { // - sha256 // - SHA256 hashes the previous value. // Example: {{ .DisplayName | sha256 }} -// - timestamp (now_seconds) +// - unix_time // - Provides the current unix time in seconds. -// Example: {{ now_seconds}} -// - now_nano -// - Provides the current unix time in nanoseconds. -// Example: {{ now_nano}} +// Example: {{ unix_time }} +// - unix_time_millis +// - Provides the current unix time in milliseconds. +// Example: {{ unix_time_millis }} +// - timestamp +// - Provides the current time. Must include a standard Go format string // - uuid // - Generates a UUID // Example: {{ uuid }} @@ -81,22 +83,17 @@ func NewTemplate(opts ...Opt) (up StringTemplate, err error) { up = StringTemplate{ funcMap: map[string]interface{}{ "random": base62.Random, - "rand": base62.Random, "truncate": truncate, - "trunc": truncate, "truncate_sha256": truncateSHA256, - "trunc_sha256": truncateSHA256, "uppercase": uppercase, - "upper": uppercase, "lowercase": lowercase, - "lower": lowercase, "replace": replace, "sha256": hashSHA256, - "timestamp": nowSeconds, - "now_seconds": nowSeconds, - "now_nano": nowNano, - "uuid": uuid, + "unix_time": unixTime, + "unix_time_millis": unixTimeMillis, + "timestamp": timestamp, + "uuid": uuid, }, } diff --git a/sdk/helper/template/template_test.go b/sdk/helper/template/template_test.go index 460c6befd..1095746ff 100644 --- a/sdk/helper/template/template_test.go +++ b/sdk/helper/template/template_test.go @@ -42,30 +42,22 @@ func TestGenerate(t *testing.T) { }, "template with builtin functions": { template: `{{.String | truncate 10}} -{{.String | trunc 8}} {{.String | uppercase}} -{{.String | upper}} {{.String | lowercase}} -{{.String | lower}} {{.String | replace " " "."}} {{.String | sha256}} -{{.String | truncate_sha256 20}} -{{.String | trunc_sha256 25}}`, +{{.String | truncate_sha256 20}}`, data: struct { String string }{ String: "Some string with Multiple Capitals LETTERS", }, expected: `Some strin -Some str SOME STRING WITH MULTIPLE CAPITALS LETTERS -SOME STRING WITH MULTIPLE CAPITALS LETTERS -some string with multiple capitals letters some string with multiple capitals letters Some.string.with.Multiple.Capitals.LETTERS da9872dd96609c72897defa11fe81017a62c3f44339d9d3b43fe37540ede3601 -Some string 6841cf80 -Some string with 058f6eeb`, +Some string 6841cf80`, expectErr: false, }, "custom function": { @@ -112,59 +104,45 @@ Some string with 058f6eeb`, } }) - t.Run("rand", func(t *testing.T) { - for i := 1; i < 100; i++ { + t.Run("unix_time", func(t *testing.T) { + for i := 0; i < 100; i++ { st, err := NewTemplate( - Template(fmt.Sprintf("{{random %d}}", i)), + Template("{{unix_time}}"), ) require.NoError(t, err) actual, err := st.Generate(nil) require.NoError(t, err) - require.Regexp(t, fmt.Sprintf("^[a-zA-Z0-9]{%d}$", i), actual) + require.Regexp(t, "^[0-9]+$", actual) + } + }) + + t.Run("unix_time_millis", func(t *testing.T) { + for i := 0; i < 100; i++ { + st, err := NewTemplate( + Template("{{unix_time_millis}}"), + ) + require.NoError(t, err) + + actual, err := st.Generate(nil) + require.NoError(t, err) + + require.Regexp(t, "^[0-9]+$", actual) } }) t.Run("timestamp", func(t *testing.T) { for i := 0; i < 100; i++ { st, err := NewTemplate( - Template("{{timestamp}}"), + Template(`{{timestamp "2006-01-02T15:04:05.000Z"}}`), ) require.NoError(t, err) actual, err := st.Generate(nil) require.NoError(t, err) - require.Regexp(t, "^[0-9]+$", actual) - } - }) - - t.Run("now_seconds", func(t *testing.T) { - for i := 0; i < 100; i++ { - st, err := NewTemplate( - Template("{{now_seconds}}"), - ) - require.NoError(t, err) - - actual, err := st.Generate(nil) - require.NoError(t, err) - - require.Regexp(t, "^[0-9]+$", actual) - } - }) - - t.Run("now_nano", func(t *testing.T) { - for i := 0; i < 100; i++ { - st, err := NewTemplate( - Template("{{now_nano}}"), - ) - require.NoError(t, err) - - actual, err := st.Generate(nil) - require.NoError(t, err) - - require.Regexp(t, "^[0-9]+$", actual) + require.Regexp(t, `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$`, actual) } }) }