go.mod: bump client-go and api machinerie
I had to run `make generate`. Some API functions got additional parameters `Options` and `Context`. I used empty options and `context.TODO()` for now. Signed-off-by: leonnicolas <leonloechner@gmx.de>
This commit is contained in:
43
vendor/k8s.io/apimachinery/pkg/labels/labels.go
generated
vendored
43
vendor/k8s.io/apimachinery/pkg/labels/labels.go
generated
vendored
@@ -20,6 +20,8 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
// Labels allows you to present labels independently from their storage.
|
||||
@@ -57,21 +59,29 @@ func (ls Set) Get(label string) string {
|
||||
return ls[label]
|
||||
}
|
||||
|
||||
// AsSelector converts labels into a selectors.
|
||||
// AsSelector converts labels into a selectors. It does not
|
||||
// perform any validation, which means the server will reject
|
||||
// the request if the Set contains invalid values.
|
||||
func (ls Set) AsSelector() Selector {
|
||||
return SelectorFromSet(ls)
|
||||
}
|
||||
|
||||
// AsValidatedSelector converts labels into a selectors.
|
||||
// The Set is validated client-side, which allows to catch errors early.
|
||||
func (ls Set) AsValidatedSelector() (Selector, error) {
|
||||
return ValidatedSelectorFromSet(ls)
|
||||
}
|
||||
|
||||
// AsSelectorPreValidated converts labels into a selector, but
|
||||
// assumes that labels are already validated and thus don't
|
||||
// preform any validation.
|
||||
// assumes that labels are already validated and thus doesn't
|
||||
// perform any validation.
|
||||
// According to our measurements this is significantly faster
|
||||
// in codepaths that matter at high scale.
|
||||
func (ls Set) AsSelectorPreValidated() Selector {
|
||||
return SelectorFromValidatedSet(ls)
|
||||
}
|
||||
|
||||
// FormatLabels convert label map into plain string
|
||||
// FormatLabels converts label map into plain string
|
||||
func FormatLabels(labelMap map[string]string) string {
|
||||
l := Set(labelMap).String()
|
||||
if l == "" {
|
||||
@@ -133,28 +143,9 @@ func Equals(labels1, labels2 Set) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// AreLabelsInWhiteList verifies if the provided label list
|
||||
// is in the provided whitelist and returns true, otherwise false.
|
||||
func AreLabelsInWhiteList(labels, whitelist Set) bool {
|
||||
if len(whitelist) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for k, v := range labels {
|
||||
value, ok := whitelist[k]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if value != v {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ConvertSelectorToLabelsMap converts selector string to labels map
|
||||
// and validates keys and values
|
||||
func ConvertSelectorToLabelsMap(selector string) (Set, error) {
|
||||
func ConvertSelectorToLabelsMap(selector string, opts ...field.PathOption) (Set, error) {
|
||||
labelsMap := Set{}
|
||||
|
||||
if len(selector) == 0 {
|
||||
@@ -168,11 +159,11 @@ func ConvertSelectorToLabelsMap(selector string) (Set, error) {
|
||||
return labelsMap, fmt.Errorf("invalid selector: %s", l)
|
||||
}
|
||||
key := strings.TrimSpace(l[0])
|
||||
if err := validateLabelKey(key); err != nil {
|
||||
if err := validateLabelKey(key, field.ToPath(opts...)); err != nil {
|
||||
return labelsMap, err
|
||||
}
|
||||
value := strings.TrimSpace(l[1])
|
||||
if err := validateLabelValue(value); err != nil {
|
||||
if err := validateLabelValue(key, value, field.ToPath(opts...)); err != nil {
|
||||
return labelsMap, err
|
||||
}
|
||||
labelsMap[key] = value
|
||||
|
222
vendor/k8s.io/apimachinery/pkg/labels/selector.go
generated
vendored
222
vendor/k8s.io/apimachinery/pkg/labels/selector.go
generated
vendored
@@ -17,16 +17,26 @@ limitations under the License.
|
||||
package labels
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
validRequirementOperators = []string{
|
||||
string(selection.In), string(selection.NotIn),
|
||||
string(selection.Equals), string(selection.DoubleEquals), string(selection.NotEquals),
|
||||
string(selection.Exists), string(selection.DoesNotExist),
|
||||
string(selection.GreaterThan), string(selection.LessThan),
|
||||
}
|
||||
)
|
||||
|
||||
// Requirements is AND of all requirements.
|
||||
@@ -54,6 +64,11 @@ type Selector interface {
|
||||
|
||||
// Make a deep copy of the selector.
|
||||
DeepCopySelector() Selector
|
||||
|
||||
// RequiresExactMatch allows a caller to introspect whether a given selector
|
||||
// requires a single specific label to be set, and if so returns the value it
|
||||
// requires.
|
||||
RequiresExactMatch(label string) (value string, found bool)
|
||||
}
|
||||
|
||||
// Everything returns a selector that matches all labels.
|
||||
@@ -69,6 +84,9 @@ func (n nothingSelector) String() string { return "" }
|
||||
func (n nothingSelector) Add(_ ...Requirement) Selector { return n }
|
||||
func (n nothingSelector) Requirements() (Requirements, bool) { return nil, false }
|
||||
func (n nothingSelector) DeepCopySelector() Selector { return n }
|
||||
func (n nothingSelector) RequiresExactMatch(label string) (value string, found bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Nothing returns a selector that matches no labels
|
||||
func Nothing() Selector {
|
||||
@@ -131,42 +149,47 @@ type Requirement struct {
|
||||
// of characters. See validateLabelKey for more details.
|
||||
//
|
||||
// The empty string is a valid value in the input values set.
|
||||
func NewRequirement(key string, op selection.Operator, vals []string) (*Requirement, error) {
|
||||
if err := validateLabelKey(key); err != nil {
|
||||
return nil, err
|
||||
// Returned error, if not nil, is guaranteed to be an aggregated field.ErrorList
|
||||
func NewRequirement(key string, op selection.Operator, vals []string, opts ...field.PathOption) (*Requirement, error) {
|
||||
var allErrs field.ErrorList
|
||||
path := field.ToPath(opts...)
|
||||
if err := validateLabelKey(key, path.Child("key")); err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
|
||||
valuePath := path.Child("values")
|
||||
switch op {
|
||||
case selection.In, selection.NotIn:
|
||||
if len(vals) == 0 {
|
||||
return nil, fmt.Errorf("for 'in', 'notin' operators, values set can't be empty")
|
||||
allErrs = append(allErrs, field.Invalid(valuePath, vals, "for 'in', 'notin' operators, values set can't be empty"))
|
||||
}
|
||||
case selection.Equals, selection.DoubleEquals, selection.NotEquals:
|
||||
if len(vals) != 1 {
|
||||
return nil, fmt.Errorf("exact-match compatibility requires one single value")
|
||||
allErrs = append(allErrs, field.Invalid(valuePath, vals, "exact-match compatibility requires one single value"))
|
||||
}
|
||||
case selection.Exists, selection.DoesNotExist:
|
||||
if len(vals) != 0 {
|
||||
return nil, fmt.Errorf("values set must be empty for exists and does not exist")
|
||||
allErrs = append(allErrs, field.Invalid(valuePath, vals, "values set must be empty for exists and does not exist"))
|
||||
}
|
||||
case selection.GreaterThan, selection.LessThan:
|
||||
if len(vals) != 1 {
|
||||
return nil, fmt.Errorf("for 'Gt', 'Lt' operators, exactly one value is required")
|
||||
allErrs = append(allErrs, field.Invalid(valuePath, vals, "for 'Gt', 'Lt' operators, exactly one value is required"))
|
||||
}
|
||||
for i := range vals {
|
||||
if _, err := strconv.ParseInt(vals[i], 10, 64); err != nil {
|
||||
return nil, fmt.Errorf("for 'Gt', 'Lt' operators, the value must be an integer")
|
||||
allErrs = append(allErrs, field.Invalid(valuePath.Index(i), vals[i], "for 'Gt', 'Lt' operators, the value must be an integer"))
|
||||
}
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("operator '%v' is not recognized", op)
|
||||
allErrs = append(allErrs, field.NotSupported(path.Child("operator"), op, validRequirementOperators))
|
||||
}
|
||||
|
||||
for i := range vals {
|
||||
if err := validateLabelValue(vals[i]); err != nil {
|
||||
return nil, err
|
||||
if err := validateLabelValue(key, vals[i], valuePath.Index(i)); err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
}
|
||||
return &Requirement{key: key, operator: op, strValues: vals}, nil
|
||||
return &Requirement{key: key, operator: op, strValues: vals}, allErrs.ToAggregate()
|
||||
}
|
||||
|
||||
func (r *Requirement) hasValue(value string) bool {
|
||||
@@ -215,7 +238,7 @@ func (r *Requirement) Matches(ls Labels) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// There should be only one strValue in r.strValues, and can be converted to a integer.
|
||||
// There should be only one strValue in r.strValues, and can be converted to an integer.
|
||||
if len(r.strValues) != 1 {
|
||||
klog.V(10).Infof("Invalid values count %+v of requirement %#v, for 'Gt', 'Lt' operators, exactly one value is required", len(r.strValues), r)
|
||||
return false
|
||||
@@ -254,63 +277,81 @@ func (r *Requirement) Values() sets.String {
|
||||
return ret
|
||||
}
|
||||
|
||||
// Equal checks the equality of requirement.
|
||||
func (r Requirement) Equal(x Requirement) bool {
|
||||
if r.key != x.key {
|
||||
return false
|
||||
}
|
||||
if r.operator != x.operator {
|
||||
return false
|
||||
}
|
||||
return cmp.Equal(r.strValues, x.strValues)
|
||||
}
|
||||
|
||||
// Empty returns true if the internalSelector doesn't restrict selection space
|
||||
func (lsel internalSelector) Empty() bool {
|
||||
if lsel == nil {
|
||||
func (s internalSelector) Empty() bool {
|
||||
if s == nil {
|
||||
return true
|
||||
}
|
||||
return len(lsel) == 0
|
||||
return len(s) == 0
|
||||
}
|
||||
|
||||
// String returns a human-readable string that represents this
|
||||
// Requirement. If called on an invalid Requirement, an error is
|
||||
// returned. See NewRequirement for creating a valid Requirement.
|
||||
func (r *Requirement) String() string {
|
||||
var buffer bytes.Buffer
|
||||
var sb strings.Builder
|
||||
sb.Grow(
|
||||
// length of r.key
|
||||
len(r.key) +
|
||||
// length of 'r.operator' + 2 spaces for the worst case ('in' and 'notin')
|
||||
len(r.operator) + 2 +
|
||||
// length of 'r.strValues' slice times. Heuristically 5 chars per word
|
||||
+5*len(r.strValues))
|
||||
if r.operator == selection.DoesNotExist {
|
||||
buffer.WriteString("!")
|
||||
sb.WriteString("!")
|
||||
}
|
||||
buffer.WriteString(r.key)
|
||||
sb.WriteString(r.key)
|
||||
|
||||
switch r.operator {
|
||||
case selection.Equals:
|
||||
buffer.WriteString("=")
|
||||
sb.WriteString("=")
|
||||
case selection.DoubleEquals:
|
||||
buffer.WriteString("==")
|
||||
sb.WriteString("==")
|
||||
case selection.NotEquals:
|
||||
buffer.WriteString("!=")
|
||||
sb.WriteString("!=")
|
||||
case selection.In:
|
||||
buffer.WriteString(" in ")
|
||||
sb.WriteString(" in ")
|
||||
case selection.NotIn:
|
||||
buffer.WriteString(" notin ")
|
||||
sb.WriteString(" notin ")
|
||||
case selection.GreaterThan:
|
||||
buffer.WriteString(">")
|
||||
sb.WriteString(">")
|
||||
case selection.LessThan:
|
||||
buffer.WriteString("<")
|
||||
sb.WriteString("<")
|
||||
case selection.Exists, selection.DoesNotExist:
|
||||
return buffer.String()
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
switch r.operator {
|
||||
case selection.In, selection.NotIn:
|
||||
buffer.WriteString("(")
|
||||
sb.WriteString("(")
|
||||
}
|
||||
if len(r.strValues) == 1 {
|
||||
buffer.WriteString(r.strValues[0])
|
||||
sb.WriteString(r.strValues[0])
|
||||
} else { // only > 1 since == 0 prohibited by NewRequirement
|
||||
// normalizes value order on output, without mutating the in-memory selector representation
|
||||
// also avoids normalization when it is not required, and ensures we do not mutate shared data
|
||||
buffer.WriteString(strings.Join(safeSort(r.strValues), ","))
|
||||
sb.WriteString(strings.Join(safeSort(r.strValues), ","))
|
||||
}
|
||||
|
||||
switch r.operator {
|
||||
case selection.In, selection.NotIn:
|
||||
buffer.WriteString(")")
|
||||
sb.WriteString(")")
|
||||
}
|
||||
return buffer.String()
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// safeSort sort input strings without modification
|
||||
// safeSort sorts input strings without modification
|
||||
func safeSort(in []string) []string {
|
||||
if sort.StringsAreSorted(in) {
|
||||
return in
|
||||
@@ -322,42 +363,59 @@ func safeSort(in []string) []string {
|
||||
}
|
||||
|
||||
// Add adds requirements to the selector. It copies the current selector returning a new one
|
||||
func (lsel internalSelector) Add(reqs ...Requirement) Selector {
|
||||
var sel internalSelector
|
||||
for ix := range lsel {
|
||||
sel = append(sel, lsel[ix])
|
||||
func (s internalSelector) Add(reqs ...Requirement) Selector {
|
||||
var ret internalSelector
|
||||
for ix := range s {
|
||||
ret = append(ret, s[ix])
|
||||
}
|
||||
for _, r := range reqs {
|
||||
sel = append(sel, r)
|
||||
ret = append(ret, r)
|
||||
}
|
||||
sort.Sort(ByKey(sel))
|
||||
return sel
|
||||
sort.Sort(ByKey(ret))
|
||||
return ret
|
||||
}
|
||||
|
||||
// Matches for a internalSelector returns true if all
|
||||
// its Requirements match the input Labels. If any
|
||||
// Requirement does not match, false is returned.
|
||||
func (lsel internalSelector) Matches(l Labels) bool {
|
||||
for ix := range lsel {
|
||||
if matches := lsel[ix].Matches(l); !matches {
|
||||
func (s internalSelector) Matches(l Labels) bool {
|
||||
for ix := range s {
|
||||
if matches := s[ix].Matches(l); !matches {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (lsel internalSelector) Requirements() (Requirements, bool) { return Requirements(lsel), true }
|
||||
func (s internalSelector) Requirements() (Requirements, bool) { return Requirements(s), true }
|
||||
|
||||
// String returns a comma-separated string of all
|
||||
// the internalSelector Requirements' human-readable strings.
|
||||
func (lsel internalSelector) String() string {
|
||||
func (s internalSelector) String() string {
|
||||
var reqs []string
|
||||
for ix := range lsel {
|
||||
reqs = append(reqs, lsel[ix].String())
|
||||
for ix := range s {
|
||||
reqs = append(reqs, s[ix].String())
|
||||
}
|
||||
return strings.Join(reqs, ",")
|
||||
}
|
||||
|
||||
// RequiresExactMatch introspects whether a given selector requires a single specific field
|
||||
// to be set, and if so returns the value it requires.
|
||||
func (s internalSelector) RequiresExactMatch(label string) (value string, found bool) {
|
||||
for ix := range s {
|
||||
if s[ix].key == label {
|
||||
switch s[ix].operator {
|
||||
case selection.Equals, selection.DoubleEquals, selection.In:
|
||||
if len(s[ix].strValues) == 1 {
|
||||
return s[ix].strValues[0], true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Token represents constant definition for lexer token
|
||||
type Token int
|
||||
|
||||
@@ -419,7 +477,7 @@ func isWhitespace(ch byte) bool {
|
||||
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'
|
||||
}
|
||||
|
||||
// isSpecialSymbol detect if the character ch can be an operator
|
||||
// isSpecialSymbol detects if the character ch can be an operator
|
||||
func isSpecialSymbol(ch byte) bool {
|
||||
switch ch {
|
||||
case '=', '!', '(', ')', ',', '>', '<':
|
||||
@@ -437,7 +495,7 @@ type Lexer struct {
|
||||
pos int
|
||||
}
|
||||
|
||||
// read return the character currently lexed
|
||||
// read returns the character currently lexed
|
||||
// increment the position and check the buffer overflow
|
||||
func (l *Lexer) read() (b byte) {
|
||||
b = 0
|
||||
@@ -535,6 +593,7 @@ type Parser struct {
|
||||
l *Lexer
|
||||
scannedItems []ScannedItem
|
||||
position int
|
||||
path *field.Path
|
||||
}
|
||||
|
||||
// ParserContext represents context during parsing:
|
||||
@@ -628,7 +687,7 @@ func (p *Parser) parseRequirement() (*Requirement, error) {
|
||||
return nil, err
|
||||
}
|
||||
if operator == selection.Exists || operator == selection.DoesNotExist { // operator found lookahead set checked
|
||||
return NewRequirement(key, operator, []string{})
|
||||
return NewRequirement(key, operator, []string{}, field.WithPath(p.path))
|
||||
}
|
||||
operator, err = p.parseOperator()
|
||||
if err != nil {
|
||||
@@ -644,11 +703,11 @@ func (p *Parser) parseRequirement() (*Requirement, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewRequirement(key, operator, values.List())
|
||||
return NewRequirement(key, operator, values.List(), field.WithPath(p.path))
|
||||
|
||||
}
|
||||
|
||||
// parseKeyAndInferOperator parse literals.
|
||||
// parseKeyAndInferOperator parses literals.
|
||||
// in case of no operator '!, in, notin, ==, =, !=' are found
|
||||
// the 'exists' operator is inferred
|
||||
func (p *Parser) parseKeyAndInferOperator() (string, selection.Operator, error) {
|
||||
@@ -662,7 +721,7 @@ func (p *Parser) parseKeyAndInferOperator() (string, selection.Operator, error)
|
||||
err := fmt.Errorf("found '%s', expected: identifier", literal)
|
||||
return "", "", err
|
||||
}
|
||||
if err := validateLabelKey(literal); err != nil {
|
||||
if err := validateLabelKey(literal, p.path); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
if t, _ := p.lookahead(Values); t == EndOfStringToken || t == CommaToken {
|
||||
@@ -673,7 +732,7 @@ func (p *Parser) parseKeyAndInferOperator() (string, selection.Operator, error)
|
||||
return literal, operator, nil
|
||||
}
|
||||
|
||||
// parseOperator return operator and eventually matchType
|
||||
// parseOperator returns operator and eventually matchType
|
||||
// matchType can be exact
|
||||
func (p *Parser) parseOperator() (op selection.Operator, err error) {
|
||||
tok, lit := p.consume(KeyAndOperator)
|
||||
@@ -764,12 +823,12 @@ func (p *Parser) parseIdentifiersList() (sets.String, error) {
|
||||
// parseExactValue parses the only value for exact match style
|
||||
func (p *Parser) parseExactValue() (sets.String, error) {
|
||||
s := sets.NewString()
|
||||
tok, lit := p.lookahead(Values)
|
||||
tok, _ := p.lookahead(Values)
|
||||
if tok == EndOfStringToken || tok == CommaToken {
|
||||
s.Insert("")
|
||||
return s, nil
|
||||
}
|
||||
tok, lit = p.consume(Values)
|
||||
tok, lit := p.consume(Values)
|
||||
if tok == IdentifierToken {
|
||||
s.Insert(lit)
|
||||
return s, nil
|
||||
@@ -808,8 +867,8 @@ func (p *Parser) parseExactValue() (sets.String, error) {
|
||||
// the KEY exists and can be any VALUE.
|
||||
// (5) A requirement with just !KEY requires that the KEY not exist.
|
||||
//
|
||||
func Parse(selector string) (Selector, error) {
|
||||
parsedSelector, err := parse(selector)
|
||||
func Parse(selector string, opts ...field.PathOption) (Selector, error) {
|
||||
parsedSelector, err := parse(selector, field.ToPath(opts...))
|
||||
if err == nil {
|
||||
return parsedSelector, nil
|
||||
}
|
||||
@@ -820,8 +879,8 @@ func Parse(selector string) (Selector, error) {
|
||||
// The callers of this method can then decide how to return the internalSelector struct to their
|
||||
// callers. This function has two callers now, one returns a Selector interface and the other
|
||||
// returns a list of requirements.
|
||||
func parse(selector string) (internalSelector, error) {
|
||||
p := &Parser{l: &Lexer{s: selector, pos: 0}}
|
||||
func parse(selector string, path *field.Path) (internalSelector, error) {
|
||||
p := &Parser{l: &Lexer{s: selector, pos: 0}, path: path}
|
||||
items, err := p.parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -830,39 +889,46 @@ func parse(selector string) (internalSelector, error) {
|
||||
return internalSelector(items), err
|
||||
}
|
||||
|
||||
func validateLabelKey(k string) error {
|
||||
func validateLabelKey(k string, path *field.Path) *field.Error {
|
||||
if errs := validation.IsQualifiedName(k); len(errs) != 0 {
|
||||
return fmt.Errorf("invalid label key %q: %s", k, strings.Join(errs, "; "))
|
||||
return field.Invalid(path, k, strings.Join(errs, "; "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateLabelValue(v string) error {
|
||||
func validateLabelValue(k, v string, path *field.Path) *field.Error {
|
||||
if errs := validation.IsValidLabelValue(v); len(errs) != 0 {
|
||||
return fmt.Errorf("invalid label value: %q: %s", v, strings.Join(errs, "; "))
|
||||
return field.Invalid(path.Key(k), v, strings.Join(errs, "; "))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectorFromSet returns a Selector which will match exactly the given Set. A
|
||||
// nil and empty Sets are considered equivalent to Everything().
|
||||
// It does not perform any validation, which means the server will reject
|
||||
// the request if the Set contains invalid values.
|
||||
func SelectorFromSet(ls Set) Selector {
|
||||
return SelectorFromValidatedSet(ls)
|
||||
}
|
||||
|
||||
// ValidatedSelectorFromSet returns a Selector which will match exactly the given Set. A
|
||||
// nil and empty Sets are considered equivalent to Everything().
|
||||
// The Set is validated client-side, which allows to catch errors early.
|
||||
func ValidatedSelectorFromSet(ls Set) (Selector, error) {
|
||||
if ls == nil || len(ls) == 0 {
|
||||
return internalSelector{}
|
||||
return internalSelector{}, nil
|
||||
}
|
||||
var requirements internalSelector
|
||||
requirements := make([]Requirement, 0, len(ls))
|
||||
for label, value := range ls {
|
||||
r, err := NewRequirement(label, selection.Equals, []string{value})
|
||||
if err == nil {
|
||||
requirements = append(requirements, *r)
|
||||
} else {
|
||||
//TODO: double check errors when input comes from serialization?
|
||||
return internalSelector{}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
requirements = append(requirements, *r)
|
||||
}
|
||||
// sort to have deterministic string representation
|
||||
sort.Sort(ByKey(requirements))
|
||||
return requirements
|
||||
return internalSelector(requirements), nil
|
||||
}
|
||||
|
||||
// SelectorFromValidatedSet returns a Selector which will match exactly the given Set.
|
||||
@@ -872,13 +938,13 @@ func SelectorFromValidatedSet(ls Set) Selector {
|
||||
if ls == nil || len(ls) == 0 {
|
||||
return internalSelector{}
|
||||
}
|
||||
var requirements internalSelector
|
||||
requirements := make([]Requirement, 0, len(ls))
|
||||
for label, value := range ls {
|
||||
requirements = append(requirements, Requirement{key: label, operator: selection.Equals, strValues: []string{value}})
|
||||
}
|
||||
// sort to have deterministic string representation
|
||||
sort.Sort(ByKey(requirements))
|
||||
return requirements
|
||||
return internalSelector(requirements)
|
||||
}
|
||||
|
||||
// ParseToRequirements takes a string representing a selector and returns a list of
|
||||
@@ -886,6 +952,6 @@ func SelectorFromValidatedSet(ls Set) Selector {
|
||||
// processing on selector requirements.
|
||||
// See the documentation for Parse() function for more details.
|
||||
// TODO: Consider exporting the internalSelector type instead.
|
||||
func ParseToRequirements(selector string) ([]Requirement, error) {
|
||||
return parse(selector)
|
||||
func ParseToRequirements(selector string, opts ...field.PathOption) ([]Requirement, error) {
|
||||
return parse(selector, field.ToPath(opts...))
|
||||
}
|
||||
|
Reference in New Issue
Block a user