mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Added time_since() custom JMESPath function (#2680)
* 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:
parent
1ff16ba5d4
commit
7f95bee23c
2 changed files with 85 additions and 0 deletions
pkg/engine/jmespath
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue