mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
* Added validation for Condition Operators Signed-off-by: Abhinav Sinha <zeborg3@gmail.com> * Updated description of `Condition.Operator` with all current valid condition operators` Signed-off-by: Abhinav Sinha <zeborg3@gmail.com> * Added `ConditionOperators` map and updated existing `ConditionOperator` type references Signed-off-by: Abhinav Sinha <zeborg3@gmail.com>
139 lines
5.6 KiB
Go
139 lines
5.6 KiB
Go
package operator
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
kyverno "github.com/kyverno/kyverno/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.ConditionOperators["DurationGreaterThanOrEquals"]:
|
|
return key >= value
|
|
case kyverno.ConditionOperators["DurationGreaterThan"]:
|
|
return key > value
|
|
case kyverno.ConditionOperators["DurationLessThanOrEquals"]:
|
|
return key <= value
|
|
case kyverno.ConditionOperators["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
|
|
}
|