mirror of
https://github.com/rancher/norman.git
synced 2025-04-28 11:24:47 +00:00
This change gives norman the ability to filter api requests based on the default value of fields. Before, it would filter on the actual data in the resource, and then apply default values to the resource before returning. Issue: https://github.com/rancher/rancher/issues/13418
122 lines
2.9 KiB
Go
122 lines
2.9 KiB
Go
package types
|
|
|
|
import (
|
|
"github.com/rancher/norman/types/convert"
|
|
)
|
|
|
|
var (
|
|
CondEQ = QueryConditionType{ModifierEQ, 1}
|
|
CondNE = QueryConditionType{ModifierNE, 1}
|
|
CondNull = QueryConditionType{ModifierNull, 0}
|
|
CondNotNull = QueryConditionType{ModifierNotNull, 0}
|
|
CondIn = QueryConditionType{ModifierIn, -1}
|
|
CondNotIn = QueryConditionType{ModifierNotIn, -1}
|
|
CondOr = QueryConditionType{ModifierType("or"), 1}
|
|
CondAnd = QueryConditionType{ModifierType("and"), 1}
|
|
|
|
mods = map[ModifierType]QueryConditionType{
|
|
CondEQ.Name: CondEQ,
|
|
CondNE.Name: CondNE,
|
|
CondNull.Name: CondNull,
|
|
CondNotNull.Name: CondNotNull,
|
|
CondIn.Name: CondIn,
|
|
CondNotIn.Name: CondNotIn,
|
|
CondOr.Name: CondOr,
|
|
CondAnd.Name: CondAnd,
|
|
}
|
|
)
|
|
|
|
type QueryConditionType struct {
|
|
Name ModifierType
|
|
Args int
|
|
}
|
|
|
|
type QueryCondition struct {
|
|
Field string
|
|
Value string
|
|
Values map[string]bool
|
|
conditionType QueryConditionType
|
|
left, right *QueryCondition
|
|
}
|
|
|
|
func (q *QueryCondition) Valid(schema *Schema, data map[string]interface{}) bool {
|
|
switch q.conditionType {
|
|
case CondAnd:
|
|
if q.left == nil || q.right == nil {
|
|
return false
|
|
}
|
|
return q.left.Valid(schema, data) && q.right.Valid(schema, data)
|
|
case CondOr:
|
|
if q.left == nil || q.right == nil {
|
|
return false
|
|
}
|
|
return q.left.Valid(schema, data) || q.right.Valid(schema, data)
|
|
case CondEQ:
|
|
return q.Value == convert.ToString(valueOrDefault(schema, data, q))
|
|
case CondNE:
|
|
return q.Value != convert.ToString(valueOrDefault(schema, data, q))
|
|
case CondIn:
|
|
return q.Values[convert.ToString(valueOrDefault(schema, data, q))]
|
|
case CondNotIn:
|
|
return !q.Values[convert.ToString(valueOrDefault(schema, data, q))]
|
|
case CondNotNull:
|
|
return convert.ToString(valueOrDefault(schema, data, q)) != ""
|
|
case CondNull:
|
|
return convert.ToString(valueOrDefault(schema, data, q)) == ""
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func valueOrDefault(schema *Schema, data map[string]interface{}, q *QueryCondition) interface{} {
|
|
value := data[q.Field]
|
|
if value == nil {
|
|
value = schema.ResourceFields[q.Field].Default
|
|
}
|
|
|
|
return value
|
|
}
|
|
|
|
func (q *QueryCondition) ToCondition() Condition {
|
|
cond := Condition{
|
|
Modifier: q.conditionType.Name,
|
|
}
|
|
if q.conditionType.Args == 1 {
|
|
cond.Value = q.Value
|
|
} else if q.conditionType.Args == -1 {
|
|
stringValues := []string{}
|
|
for val := range q.Values {
|
|
stringValues = append(stringValues, val)
|
|
}
|
|
cond.Value = stringValues
|
|
}
|
|
|
|
return cond
|
|
}
|
|
|
|
func ValidMod(mod ModifierType) bool {
|
|
_, ok := mods[mod]
|
|
return ok
|
|
}
|
|
|
|
func EQ(key, value string) *QueryCondition {
|
|
return NewConditionFromString(key, ModifierEQ, value)
|
|
}
|
|
|
|
func NewConditionFromString(field string, mod ModifierType, values ...string) *QueryCondition {
|
|
q := &QueryCondition{
|
|
Field: field,
|
|
conditionType: mods[mod],
|
|
Values: map[string]bool{},
|
|
}
|
|
|
|
for i, value := range values {
|
|
if i == 0 {
|
|
q.Value = value
|
|
}
|
|
q.Values[value] = true
|
|
}
|
|
|
|
return q
|
|
}
|