1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

Added time_since() custom JMESPath function ()

* Added time_since() custom JMESPath function

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>

* Remove time.Layout (not supported in Go 1.16)

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>

* Modify time_since() for 3 arguments

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>

* Add tests for functions_test.go

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>

* Timestamp literals and tabulated tests

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>

* Remove layout map and default to RFC3339

Signed-off-by: Kumar Mallikarjuna <kumarmallikarjuna1@gmail.com>
This commit is contained in:
Kumar Mallikarjuna 2021-11-18 01:47:17 +05:30 committed by GitHub
parent 1ff16ba5d4
commit 7f95bee23c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 0 deletions

View file

@ -8,6 +8,7 @@ import (
"regexp"
"strconv"
"strings"
"time"
gojmespath "github.com/jmespath/go-jmespath"
)
@ -46,6 +47,7 @@ var (
modulo = "modulo"
base64Decode = "base64_decode"
base64Encode = "base64_encode"
timeSince = "time_since"
)
const errorPrefix = "JMESPath function '%s': "
@ -210,6 +212,15 @@ func getFunctions() []*gojmespath.FunctionEntry {
},
Handler: jpBase64Encode,
},
{
Name: timeSince,
Arguments: []ArgSpec{
{Types: []JpType{JpString}},
{Types: []JpType{JpString}},
{Types: []JpType{JpString}},
},
Handler: jpTimeSince,
},
}
}
@ -550,6 +561,49 @@ func jpBase64Encode(arguments []interface{}) (interface{}, error) {
return base64.StdEncoding.EncodeToString([]byte(str.String())), nil
}
func jpTimeSince(arguments []interface{}) (interface{}, error) {
var err error
layout, err := validateArg("", arguments, 0, reflect.String)
if err != nil {
return nil, err
}
ts1, err := validateArg("", arguments, 1, reflect.String)
if err != nil {
return nil, err
}
ts2, err := validateArg("", arguments, 2, reflect.String)
if err != nil {
return nil, err
}
var t1, t2 time.Time
if layout.String() != "" {
t1, err = time.Parse(layout.String(), ts1.String())
} else {
t1, err = time.Parse(time.RFC3339, ts1.String())
}
if err != nil {
return nil, err
}
t2 = time.Now()
if ts2.String() != "" {
if layout.String() != "" {
t2, err = time.Parse(layout.String(), ts2.String())
} else {
t2, err = time.Parse(time.RFC3339, ts2.String())
}
if err != nil {
return nil, err
}
}
return t2.Sub(t1).String(), nil
}
// InterfaceToString casts an interface to a string type
func ifaceToString(iface interface{}) (string, error) {
switch i := iface.(type) {

View file

@ -504,3 +504,34 @@ func Test_Base64Decode_Secret(t *testing.T) {
assert.Assert(t, ok)
assert.Equal(t, string(result), "Hello, world!")
}
func Test_TimeSince(t *testing.T) {
testCases := []struct {
test string
expectedResult string
}{
{
test: "time_since('', '2021-01-02T15:04:05-07:00', '2021-01-10T03:14:05-07:00')",
expectedResult: "180h10m0s",
},
{
test: "time_since('Mon Jan _2 15:04:05 MST 2006', 'Mon Jan 02 15:04:05 MST 2021', 'Mon Jan 10 03:14:16 MST 2021')",
expectedResult: "180h10m11s",
},
}
for i, tc := range testCases {
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
query, err := New(tc.test)
assert.NilError(t, err)
res, err := query.Search("")
assert.NilError(t, err)
result, ok := res.(string)
assert.Assert(t, ok)
assert.Equal(t, result, tc.expectedResult)
})
}
}