Repository: kyverno/kyverno
Pull request #5905 (2023-01-06 07:28:06)

Adds JMESPath filter for returning cron expression for absolute time (cherry-pick #5814)


Cherry-picked Adds JMESPath filter for returning cron expression for absolute time (#5814)

* time_to_cron

Signed-off-by: Vishal Choudhary <contactvishaltech@gmail.com>

* tests

Signed-off-by: Vishal Choudhary <contactvishaltech@gmail.com>

* Update pkg/engine/jmespath/functions.go

Signed-off-by: shuting <shutting06@gmail.com>

* fix linter

Signed-off-by: ShutingZhao <shuting@nirmata.com>

Signed-off-by: Vishal Choudhary <contactvishaltech@gmail.com>
Signed-off-by: shuting <shutting06@gmail.com>
Signed-off-by: ShutingZhao <shuting@nirmata.com>
Co-authored-by: shuting <shuting@nirmata.com>
Co-authored-by: shuting <shutting06@gmail.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/kyverno/kyverno/pull/5905?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno) Report
> Merging [#5905](https://codecov.io/gh/kyverno/kyverno/pull/5905?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno) (ee4f4de) into [release-1.9](https://codecov.io/gh/kyverno/kyverno/commit/fbeb33b49a76fb05f132da051366b32d423b9832?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno) (fbeb33b) will **increase** coverage by `0.07%`.
> The diff coverage is `81.81%`.

```diff
@@               Coverage Diff               @@
##           release-1.9    #5905      +/-   ##
===============================================
+ Coverage        35.50%   35.57%   +0.07%     
===============================================
  Files              187      187              
  Lines            20638    20671      +33     
===============================================
+ Hits              7327     7354      +27     
- Misses           12506    12510       +4     
- Partials           805      807       +2     
```


| [Impacted Files](https://codecov.io/gh/kyverno/kyverno/pull/5905?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno) | Coverage Δ | |
|---|---|---|
| [pkg/engine/jmespath/functions.go](https://codecov.io/gh/kyverno/kyverno/pull/5905?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno#diff-cGtnL2VuZ2luZS9qbWVzcGF0aC9mdW5jdGlvbnMuZ28=) | `72.29% <81.81%> (+0.36%)` | :arrow_up: |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kyverno)


Patch:
diff --git a/pkg/engine/jmespath/functions.go b/pkg/engine/jmespath/functions.go
index 82783e87b..f513aaf76 100644
--- a/pkg/engine/jmespath/functions.go
+++ b/pkg/engine/jmespath/functions.go
@@ -81,6 +81,7 @@ var (
 	objectFromLists        = "object_from_lists"
 	random                 = "random"
 	x509_decode            = "x509_decode"
+	timeToCron             = "time_to_cron"
 )
 
 const (
@@ -490,6 +491,17 @@ func GetFunctions() []*FunctionEntry {
 			ReturnType: []JpType{JpObject},
 			Note:       "decodes an x.509 certificate to an object. you may also use this in conjunction with `base64_decode` jmespath function to decode a base64-encoded certificate",
 		},
+		{
+			Entry: &gojmespath.FunctionEntry{
+				Name: timeToCron,
+				Arguments: []ArgSpec{
+					{Types: []JpType{JpString}},
+				},
+				Handler: jpTimeToCron,
+			},
+			ReturnType: []JpType{JpString},
+			Note:       "converts an absolute time (RFC 3339) to a cron expression (string).",
+		},
 	}
 }
 
@@ -1094,3 +1106,28 @@ func jpX509Decode(arguments []interface{}) (interface{}, error) {
 
 	return res, nil
 }
+
+func jpTimeToCron(arguments []interface{}) (interface{}, error) {
+	var err error
+
+	ts, err := validateArg("", arguments, 0, reflect.String)
+	if err != nil {
+		return nil, err
+	}
+
+	var t time.Time
+	t, err = time.Parse(time.RFC3339, ts.String())
+	if err != nil {
+		return nil, err
+	}
+	t = t.UTC()
+
+	var cron string = ""
+	cron += strconv.Itoa(t.Minute()) + " "
+	cron += strconv.Itoa(t.Hour()) + " "
+	cron += strconv.Itoa(t.Day()) + " "
+	cron += strconv.Itoa(int(t.Month())) + " "
+	cron += strconv.Itoa(int(t.Weekday()))
+
+	return cron, nil
+}


Test patch:
diff --git a/pkg/engine/jmespath/functions_test.go b/pkg/engine/jmespath/functions_test.go
index 2c70977bf..cfbd73687 100644
--- a/pkg/engine/jmespath/functions_test.go
+++ b/pkg/engine/jmespath/functions_test.go
@@ -1549,3 +1549,33 @@ UFOZZVoELaasWS559wy8og39Eq21dDMynb8Bndn/
 		})
 	}
 }
+
+func Test_TimeToCron(t *testing.T) {
+	testCases := []struct {
+		test           string
+		expectedResult string
+	}{
+		{
+			test:           "time_to_cron('2023-02-02T15:04:05Z')",
+			expectedResult: "4 15 2 2 4",
+		},
+		{
+			test:           "time_to_cron('2023-02-02T15:04:05-07:00')",
+			expectedResult: "4 22 2 2 4",
+		},
+	}
+	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)
+		})
+	}
+}