mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Add DurationOperator to handle duration comparison operations (#2214)
Signed-off-by: Trey Dockendorf <tdockendorf@osc.edu>
This commit is contained in:
parent
922840b344
commit
8204028009
4 changed files with 729 additions and 0 deletions
|
@ -215,6 +215,14 @@ const (
|
|||
LessThanOrEquals ConditionOperator = "LessThanOrEquals"
|
||||
// LessThan evaluates if the key (numeric) is less than the value (numeric).
|
||||
LessThan ConditionOperator = "LessThan"
|
||||
// DurationGreaterThanOrEquals evaluates if the key (duration) is greater than or equal to the value (duration)
|
||||
DurationGreaterThanOrEquals ConditionOperator = "DurationGreaterThanOrEquals"
|
||||
// DurationGreaterThan evaluates if the key (duration) is greater than the value (duration)
|
||||
DurationGreaterThan ConditionOperator = "DurationGreaterThan"
|
||||
// DurationLessThanOrEquals evaluates if the key (duration) is less than or equal to the value (duration)
|
||||
DurationLessThanOrEquals ConditionOperator = "DurationLessThanOrEquals"
|
||||
// DurationLessThan evaluates if the key (duration) is greater than the value (duration)
|
||||
DurationLessThan ConditionOperator = "DurationLessThan"
|
||||
)
|
||||
|
||||
// MatchResources is used to specify resource and admission review request data for
|
||||
|
|
|
@ -211,6 +211,150 @@ func Test_Eval_LessThan_Const_string_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_string_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_string_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_string_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: "2h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_string_Equal_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: "2h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_string_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_string_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: "2h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_string_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_string_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_string_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_string_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "1h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_string_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_string_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "1h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
//Bool
|
||||
|
||||
func Test_Eval_Equal_Const_Bool_Pass(t *testing.T) {
|
||||
|
@ -470,6 +614,150 @@ func Test_Eval_LessThan_Const_int_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_int_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: 3600,
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_int_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: 3600,
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_int_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: 7200,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_int_Equal_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600,
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: 7200,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_int_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: 3600,
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_int_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600,
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: 7200,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_int_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "2h",
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: 7200,
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_int_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: 7200,
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_int_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 7200,
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: 3600,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_int_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600,
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "1h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_int_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600,
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_int_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 7200,
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: 3600,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
// int64
|
||||
func Test_Eval_Equal_Const_int64_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
|
@ -527,6 +815,150 @@ func Test_Eval_NoEqual_Const_int64_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_int64_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(3600),
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_int64_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(7200),
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_int64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(3600),
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: int64(7200),
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_int64_Equal_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(3600),
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: int64(7200),
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_int64_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(7200),
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: int64(3600),
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_int64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(3600),
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: int64(7200),
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_int64_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(7200),
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_int64_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(3600),
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_int64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(7200),
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: int64(3600),
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_int64_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(3600),
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "1h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_int64_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(3600),
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_int64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: int64(7200),
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: int64(3600),
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
//float64
|
||||
|
||||
func Test_Eval_Equal_Const_float64_Pass(t *testing.T) {
|
||||
|
@ -729,6 +1161,150 @@ func Test_Eval_LessThan_Const_float64_Fail(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_float64_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600.0,
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_float64_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 7200.0,
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThanOrEquals_Const_float64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600.0,
|
||||
Operator: kyverno.DurationGreaterThanOrEquals,
|
||||
Value: 7200.0,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_float64_Equal_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600.0,
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: 7200.0,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_float64_Greater_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 7200.0,
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: "1h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationGreaterThan_Const_float64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600.0,
|
||||
Operator: kyverno.DurationGreaterThan,
|
||||
Value: 7200.0,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_float64_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 7200.0,
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_float64_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600.0,
|
||||
Operator: kyverno.DurationLessThanOrEquals,
|
||||
Value: "2h",
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThanOrEquals_Const_float64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 7200.0,
|
||||
Operator: kyverno.LessThanOrEquals,
|
||||
Value: "1h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_float64_Equal_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 3600.0,
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: "1h",
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_float64_Less_Pass(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: "1h",
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: 7200.0,
|
||||
}
|
||||
if !Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to pass")
|
||||
}
|
||||
}
|
||||
|
||||
func Test_Eval_DurationLessThan_Const_float64_Fail(t *testing.T) {
|
||||
ctx := context.NewContext()
|
||||
condition := kyverno.Condition{
|
||||
Key: 7200.0,
|
||||
Operator: kyverno.DurationLessThan,
|
||||
Value: 3600.0,
|
||||
}
|
||||
if Evaluate(log.Log, ctx, condition) {
|
||||
t.Error("expected to fail")
|
||||
}
|
||||
}
|
||||
|
||||
//object/map[string]interface
|
||||
|
||||
func Test_Eval_Equal_Const_object_Pass(t *testing.T) {
|
||||
|
|
139
pkg/engine/variables/operator/duration.go
Normal file
139
pkg/engine/variables/operator/duration.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
package operator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
kyverno "github.com/kyverno/kyverno/pkg/api/kyverno/v1"
|
||||
"github.com/kyverno/kyverno/pkg/engine/context"
|
||||
)
|
||||
|
||||
//NewDurationOperatorHandler returns handler to manage the provided duration operations (>, >=, <=, <)
|
||||
func NewDurationOperatorHandler(log logr.Logger, ctx context.EvalInterface, op kyverno.ConditionOperator) OperatorHandler {
|
||||
return DurationOperatorHandler{
|
||||
ctx: ctx,
|
||||
log: log,
|
||||
condition: op,
|
||||
}
|
||||
}
|
||||
|
||||
//DurationOperatorHandler provides implementation to handle Duration Operations associated with policies
|
||||
type DurationOperatorHandler struct {
|
||||
ctx context.EvalInterface
|
||||
log logr.Logger
|
||||
condition kyverno.ConditionOperator
|
||||
}
|
||||
|
||||
// durationCompareByCondition compares a time.Duration key with a time.Duration value on the basis of the provided operator
|
||||
func durationCompareByCondition(key time.Duration, value time.Duration, op kyverno.ConditionOperator, log *logr.Logger) bool {
|
||||
switch op {
|
||||
case kyverno.DurationGreaterThanOrEquals:
|
||||
return key >= value
|
||||
case kyverno.DurationGreaterThan:
|
||||
return key > value
|
||||
case kyverno.DurationLessThanOrEquals:
|
||||
return key <= value
|
||||
case kyverno.DurationLessThan:
|
||||
return key < value
|
||||
default:
|
||||
(*log).Info(fmt.Sprintf("Expected operator, one of [DurationGreaterThanOrEquals, DurationGreaterThan, DurationLessThanOrEquals, DurationLessThan], found %s", op))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (doh DurationOperatorHandler) Evaluate(key, value interface{}) bool {
|
||||
switch typedKey := key.(type) {
|
||||
case int:
|
||||
return doh.validateValueWithIntPattern(int64(typedKey), value)
|
||||
case int64:
|
||||
return doh.validateValueWithIntPattern(typedKey, value)
|
||||
case float64:
|
||||
return doh.validateValueWithFloatPattern(typedKey, value)
|
||||
case string:
|
||||
return doh.validateValueWithStringPattern(typedKey, value)
|
||||
default:
|
||||
doh.log.Info("Unsupported type", "value", typedKey, "type", fmt.Sprintf("%T", typedKey))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (doh DurationOperatorHandler) validateValueWithIntPattern(key int64, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case int:
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case int64:
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case float64:
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case string:
|
||||
duration, err := time.ParseDuration(typedValue)
|
||||
if err == nil {
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, duration, doh.condition, &doh.log)
|
||||
}
|
||||
doh.log.Error(fmt.Errorf("Parse Error: "), "Failed to parse time duration from the string value")
|
||||
return false
|
||||
default:
|
||||
doh.log.Info("Unexpected type", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (doh DurationOperatorHandler) validateValueWithFloatPattern(key float64, value interface{}) bool {
|
||||
switch typedValue := value.(type) {
|
||||
case int:
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case int64:
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case float64:
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case string:
|
||||
duration, err := time.ParseDuration(typedValue)
|
||||
if err == nil {
|
||||
return durationCompareByCondition(time.Duration(key)*time.Second, duration, doh.condition, &doh.log)
|
||||
}
|
||||
doh.log.Error(fmt.Errorf("Parse Error: "), "Failed to parse time duration from the string value")
|
||||
return false
|
||||
default:
|
||||
doh.log.Info("Unexpected type", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (doh DurationOperatorHandler) validateValueWithStringPattern(key string, value interface{}) bool {
|
||||
duration, err := time.ParseDuration(key)
|
||||
if err != nil {
|
||||
doh.log.Error(err, "Failed to parse time duration from the string key")
|
||||
return false
|
||||
}
|
||||
switch typedValue := value.(type) {
|
||||
case int:
|
||||
return durationCompareByCondition(duration, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case int64:
|
||||
return durationCompareByCondition(duration, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case float64:
|
||||
return durationCompareByCondition(duration, time.Duration(typedValue)*time.Second, doh.condition, &doh.log)
|
||||
case string:
|
||||
durationValue, err := time.ParseDuration(typedValue)
|
||||
if err == nil {
|
||||
return durationCompareByCondition(duration, durationValue, doh.condition, &doh.log)
|
||||
}
|
||||
doh.log.Error(fmt.Errorf("Parse Error: "), "Failed to parse time duration from the string value")
|
||||
return false
|
||||
default:
|
||||
doh.log.Info("Unexpected type", "value", value, "type", fmt.Sprintf("%T", value))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// the following functions are unreachable because the key is strictly supposed to be a duration
|
||||
// still the following functions are just created to make DurationOperatorHandler struct implement OperatorHandler interface
|
||||
func (doh DurationOperatorHandler) validateValueWithBoolPattern(key bool, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
func (doh DurationOperatorHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
||||
func (doh DurationOperatorHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
|
||||
return false
|
||||
}
|
|
@ -51,6 +51,12 @@ func CreateOperatorHandler(log logr.Logger, ctx context.EvalInterface, op kyvern
|
|||
strings.ToLower(string(kyverno.LessThan)):
|
||||
return NewNumericOperatorHandler(log, ctx, op)
|
||||
|
||||
case strings.ToLower(string(kyverno.DurationGreaterThanOrEquals)),
|
||||
strings.ToLower(string(kyverno.DurationGreaterThan)),
|
||||
strings.ToLower(string(kyverno.DurationLessThanOrEquals)),
|
||||
strings.ToLower(string(kyverno.DurationLessThan)):
|
||||
return NewDurationOperatorHandler(log, ctx, op)
|
||||
|
||||
default:
|
||||
log.Info("operator not supported", "operator", str)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue