traefik/pkg/provider/constraints/constraints_labels.go

81 lines
1.7 KiB
Go
Raw Permalink Normal View History

package constraints
import (
"errors"
"regexp"
"github.com/vulcand/predicate"
)
2019-11-29 16:16:05 +00:00
type constraintLabelFunc func(map[string]string) bool
2019-11-29 16:16:05 +00:00
// MatchLabels reports whether the expression matches with the given labels.
// The expression must match any logical boolean combination of:
// - `Label(labelName, labelValue)`
2022-12-19 10:52:05 +00:00
// - `LabelRegex(labelName, regexValue)`.
2019-11-29 16:16:05 +00:00
func MatchLabels(labels map[string]string, expr string) (bool, error) {
if expr == "" {
return true, nil
}
p, err := predicate.NewParser(predicate.Def{
Operators: predicate.Operators{
2019-11-29 16:16:05 +00:00
AND: andLabelFunc,
NOT: notLabelFunc,
OR: orLabelFunc,
},
Functions: map[string]interface{}{
2022-12-19 10:52:05 +00:00
"Label": labelFn,
"LabelRegex": labelRegexFn,
},
})
if err != nil {
return false, err
}
parse, err := p.Parse(expr)
if err != nil {
return false, err
}
2019-11-29 16:16:05 +00:00
fn, ok := parse.(constraintLabelFunc)
if !ok {
2019-11-29 16:16:05 +00:00
return false, errors.New("not a constraintLabelFunc")
}
return fn(labels), nil
}
2019-11-29 16:16:05 +00:00
func labelFn(name, value string) constraintLabelFunc {
return func(labels map[string]string) bool {
return labels[name] == value
}
}
2019-11-29 16:16:05 +00:00
func labelRegexFn(name, expr string) constraintLabelFunc {
return func(labels map[string]string) bool {
matched, err := regexp.MatchString(expr, labels[name])
if err != nil {
return false
}
return matched
}
}
2019-11-29 16:16:05 +00:00
func andLabelFunc(a, b constraintLabelFunc) constraintLabelFunc {
return func(labels map[string]string) bool {
return a(labels) && b(labels)
}
}
2019-11-29 16:16:05 +00:00
func orLabelFunc(a, b constraintLabelFunc) constraintLabelFunc {
return func(labels map[string]string) bool {
return a(labels) || b(labels)
}
}
2019-11-29 16:16:05 +00:00
func notLabelFunc(a constraintLabelFunc) constraintLabelFunc {
return func(labels map[string]string) bool {
return !a(labels)
}
}