forked from kyverno/kyverno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
notequal.go
139 lines (128 loc) · 3.87 KB
/
notequal.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package operator
import (
"math"
"reflect"
"strconv"
"github.com/golang/glog"
"github.com/nirmata/kyverno/pkg/engine/context"
)
func NewNotEqualHandler(ctx context.EvalInterface, subHandler VariableSubstitutionHandler) OperatorHandler {
return NotEqualHandler{
ctx: ctx,
subHandler: subHandler,
}
}
type NotEqualHandler struct {
ctx context.EvalInterface
subHandler VariableSubstitutionHandler
}
func (neh NotEqualHandler) Evaluate(key, value interface{}) bool {
// substitute the variables
nKey := neh.subHandler(neh.ctx, key)
nValue := neh.subHandler(neh.ctx, value)
// key and value need to be of same type
switch typedKey := nKey.(type) {
case bool:
return neh.validateValuewithBoolPattern(typedKey, nValue)
case int:
return neh.validateValuewithIntPattern(int64(typedKey), nValue)
case int64:
return neh.validateValuewithIntPattern(typedKey, nValue)
case float64:
return neh.validateValuewithFloatPattern(typedKey, nValue)
case string:
return neh.validateValuewithStringPattern(typedKey, nValue)
case map[string]interface{}:
return neh.validateValueWithMapPattern(typedKey, nValue)
case []interface{}:
return neh.validateValueWithSlicePattern(typedKey, nValue)
default:
glog.Error("Unsupported type %V", typedKey)
return false
}
}
func (neh NotEqualHandler) validateValueWithSlicePattern(key []interface{}, value interface{}) bool {
if val, ok := value.([]interface{}); ok {
return !reflect.DeepEqual(key, val)
}
glog.Warningf("Expected []interface{}, %v is of type %T", value, value)
return false
}
func (neh NotEqualHandler) validateValueWithMapPattern(key map[string]interface{}, value interface{}) bool {
if val, ok := value.(map[string]interface{}); ok {
return !reflect.DeepEqual(key, val)
}
glog.Warningf("Expected map[string]interface{}, %v is of type %T", value, value)
return false
}
func (neh NotEqualHandler) validateValuewithStringPattern(key string, value interface{}) bool {
if val, ok := value.(string); ok {
return key != val
}
glog.Warningf("Expected string, %v is of type %T", value, value)
return false
}
func (neh NotEqualHandler) validateValuewithFloatPattern(key float64, value interface{}) bool {
switch typedValue := value.(type) {
case int:
// check that float has not fraction
if key == math.Trunc(key) {
return int(key) != typedValue
}
glog.Warningf("Expected float, found int: %d\n", typedValue)
case int64:
// check that float has not fraction
if key == math.Trunc(key) {
return int64(key) != typedValue
}
glog.Warningf("Expected float, found int: %d\n", typedValue)
case float64:
return typedValue != key
case string:
// extract float from string
float64Num, err := strconv.ParseFloat(typedValue, 64)
if err != nil {
glog.Warningf("Failed to parse float64 from string: %v", err)
return false
}
return float64Num != key
default:
glog.Warningf("Expected float, found: %T\n", value)
return false
}
return false
}
func (neh NotEqualHandler) validateValuewithBoolPattern(key bool, value interface{}) bool {
typedValue, ok := value.(bool)
if !ok {
glog.Error("Expected bool, found %V", value)
return false
}
return key != typedValue
}
func (neh NotEqualHandler) validateValuewithIntPattern(key int64, value interface{}) bool {
switch typedValue := value.(type) {
case int:
return int64(typedValue) != key
case int64:
return typedValue != key
case float64:
// check that float has no fraction
if typedValue == math.Trunc(typedValue) {
return int64(typedValue) != key
}
glog.Warningf("Expected int, found float: %f\n", typedValue)
return false
case string:
// extract in64 from string
int64Num, err := strconv.ParseInt(typedValue, 10, 64)
if err != nil {
glog.Warningf("Failed to parse int64 from string: %v", err)
return false
}
return int64Num != key
default:
glog.Warningf("Expected int, %v is of type %T", value, value)
return false
}
}