Skip to content

Commit f698276

Browse files
truncate custom jmespath function (kyverno#2836)
* [feature] custom jmespath truncate function Signed-off-by: Danny Kulchinsky <[email protected]> * formatting Signed-off-by: Danny Kulchinsky <[email protected]> * simplify naming a bit Signed-off-by: Danny Kulchinsky <[email protected]> Co-authored-by: shuting <[email protected]>
1 parent bbdfc21 commit f698276

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ require (
5454
)
5555

5656
require (
57+
github.com/aquilax/truncate v1.0.0 // indirect
5758
github.com/opencontainers/image-spec v1.0.2 // indirect
5859
gopkg.in/inf.v0 v0.9.1
5960
)

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDw
222222
github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE=
223223
github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
224224
github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30/go.mod h1:4AJxUpXUhv4N+ziTvIcWWXgeorXpxPZOfk9HdEVr96M=
225+
github.com/aquilax/truncate v1.0.0 h1:UgIGS8U/aZ4JyOJ2h3xcF5cSQ06+gGBnjxH2RUHJe0U=
226+
github.com/aquilax/truncate v1.0.0/go.mod h1:BeMESIDMlvlS3bmg4BVvBbbZUNwWtS8uzYPAKXwwhLw=
225227
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
226228
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
227229
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=

pkg/engine/jmespath/functions.go

+24
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strings"
1212
"time"
1313

14+
trunc "github.com/aquilax/truncate"
1415
gojmespath "github.com/jmespath/go-jmespath"
1516
"github.com/minio/pkg/wildcard"
1617
)
@@ -53,6 +54,7 @@ var (
5354
base64Encode = "base64_encode"
5455
timeSince = "time_since"
5556
pathCanonicalize = "path_canonicalize"
57+
truncate = "truncate"
5658
)
5759

5860
const errorPrefix = "JMESPath function '%s': "
@@ -242,6 +244,14 @@ func getFunctions() []*gojmespath.FunctionEntry {
242244
},
243245
Handler: jpPathCanonicalize,
244246
},
247+
{
248+
Name: truncate,
249+
Arguments: []ArgSpec{
250+
{Types: []JpType{JpString}},
251+
{Types: []JpType{JpNumber}},
252+
},
253+
Handler: jpTruncate,
254+
},
245255
}
246256

247257
}
@@ -600,6 +610,20 @@ func jpPathCanonicalize(arguments []interface{}) (interface{}, error) {
600610
return filepath.Join(str.String()), nil
601611
}
602612

613+
func jpTruncate(arguments []interface{}) (interface{}, error) {
614+
var err error
615+
str, err := validateArg(truncate, arguments, 0, reflect.String)
616+
if err != nil {
617+
return nil, err
618+
}
619+
length, err := validateArg(truncate, arguments, 1, reflect.Float64)
620+
if err != nil {
621+
return nil, err
622+
}
623+
624+
return trunc.Truncator(str.String(), int(length.Float()), trunc.CutStrategy{}), nil
625+
}
626+
603627
// InterfaceToString casts an interface to a string type
604628
func ifaceToString(iface interface{}) (string, error) {
605629
switch i := iface.(type) {

pkg/engine/jmespath/functions_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -972,3 +972,42 @@ func Test_PathCanonicalize(t *testing.T) {
972972
})
973973
}
974974
}
975+
976+
func Test_Truncate(t *testing.T) {
977+
// Can't use integer literals due to
978+
// https://github.com/jmespath/go-jmespath/issues/27
979+
//
980+
// TODO: fix this in https://github.com/kyverno/go-jmespath
981+
982+
testCases := []struct {
983+
jmesPath string
984+
expectedResult string
985+
}{
986+
{
987+
jmesPath: "truncate('Lorem ipsum dolor sit amet', `5`)",
988+
expectedResult: "Lorem",
989+
},
990+
{
991+
jmesPath: "truncate('Lorem ipsum ipsum ipsum dolor sit amet', `11`)",
992+
expectedResult: "Lorem ipsum",
993+
},
994+
{
995+
jmesPath: "truncate('Lorem ipsum ipsum ipsum dolor sit amet', `40`)",
996+
expectedResult: "Lorem ipsum ipsum ipsum dolor sit amet",
997+
},
998+
}
999+
1000+
for _, tc := range testCases {
1001+
t.Run(tc.jmesPath, func(t *testing.T) {
1002+
jp, err := New(tc.jmesPath)
1003+
assert.NilError(t, err)
1004+
1005+
result, err := jp.Search("")
1006+
assert.NilError(t, err)
1007+
1008+
res, ok := result.(string)
1009+
assert.Assert(t, ok)
1010+
assert.Equal(t, res, tc.expectedResult)
1011+
})
1012+
}
1013+
}

0 commit comments

Comments
 (0)