make labels, fields expose selectable requirements
This commit is contained in:
		@@ -30,6 +30,7 @@ import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/fields"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/labels"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/selection"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/types"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/sets"
 | 
			
		||||
 | 
			
		||||
@@ -383,20 +384,20 @@ func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.S
 | 
			
		||||
	}
 | 
			
		||||
	selector := labels.NewSelector()
 | 
			
		||||
	for _, expr := range nsm {
 | 
			
		||||
		var op labels.Operator
 | 
			
		||||
		var op selection.Operator
 | 
			
		||||
		switch expr.Operator {
 | 
			
		||||
		case NodeSelectorOpIn:
 | 
			
		||||
			op = labels.InOperator
 | 
			
		||||
			op = selection.In
 | 
			
		||||
		case NodeSelectorOpNotIn:
 | 
			
		||||
			op = labels.NotInOperator
 | 
			
		||||
			op = selection.NotIn
 | 
			
		||||
		case NodeSelectorOpExists:
 | 
			
		||||
			op = labels.ExistsOperator
 | 
			
		||||
			op = selection.Exists
 | 
			
		||||
		case NodeSelectorOpDoesNotExist:
 | 
			
		||||
			op = labels.DoesNotExistOperator
 | 
			
		||||
			op = selection.DoesNotExist
 | 
			
		||||
		case NodeSelectorOpGt:
 | 
			
		||||
			op = labels.GreaterThanOperator
 | 
			
		||||
			op = selection.GreaterThan
 | 
			
		||||
		case NodeSelectorOpLt:
 | 
			
		||||
			op = labels.LessThanOperator
 | 
			
		||||
			op = selection.LessThan
 | 
			
		||||
		default:
 | 
			
		||||
			return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator)
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/labels"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/selection"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/sets"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -35,23 +36,23 @@ func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
 | 
			
		||||
	}
 | 
			
		||||
	selector := labels.NewSelector()
 | 
			
		||||
	for k, v := range ps.MatchLabels {
 | 
			
		||||
		r, err := labels.NewRequirement(k, labels.EqualsOperator, sets.NewString(v))
 | 
			
		||||
		r, err := labels.NewRequirement(k, selection.Equals, sets.NewString(v))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		selector = selector.Add(*r)
 | 
			
		||||
	}
 | 
			
		||||
	for _, expr := range ps.MatchExpressions {
 | 
			
		||||
		var op labels.Operator
 | 
			
		||||
		var op selection.Operator
 | 
			
		||||
		switch expr.Operator {
 | 
			
		||||
		case LabelSelectorOpIn:
 | 
			
		||||
			op = labels.InOperator
 | 
			
		||||
			op = selection.In
 | 
			
		||||
		case LabelSelectorOpNotIn:
 | 
			
		||||
			op = labels.NotInOperator
 | 
			
		||||
			op = selection.NotIn
 | 
			
		||||
		case LabelSelectorOpExists:
 | 
			
		||||
			op = labels.ExistsOperator
 | 
			
		||||
			op = selection.Exists
 | 
			
		||||
		case LabelSelectorOpDoesNotExist:
 | 
			
		||||
			op = labels.DoesNotExistOperator
 | 
			
		||||
			op = selection.DoesNotExist
 | 
			
		||||
		default:
 | 
			
		||||
			return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
 | 
			
		||||
		}
 | 
			
		||||
@@ -108,7 +109,7 @@ func ParseToLabelSelector(selector string) (*LabelSelector, error) {
 | 
			
		||||
	for _, req := range reqs {
 | 
			
		||||
		var op LabelSelectorOperator
 | 
			
		||||
		switch req.Operator() {
 | 
			
		||||
		case labels.EqualsOperator, labels.DoubleEqualsOperator:
 | 
			
		||||
		case selection.Equals, selection.DoubleEquals:
 | 
			
		||||
			vals := req.Values()
 | 
			
		||||
			if vals.Len() != 1 {
 | 
			
		||||
				return nil, fmt.Errorf("equals operator must have exactly one value")
 | 
			
		||||
@@ -119,15 +120,15 @@ func ParseToLabelSelector(selector string) (*LabelSelector, error) {
 | 
			
		||||
			}
 | 
			
		||||
			labelSelector.MatchLabels[req.Key()] = val
 | 
			
		||||
			continue
 | 
			
		||||
		case labels.InOperator:
 | 
			
		||||
		case selection.In:
 | 
			
		||||
			op = LabelSelectorOpIn
 | 
			
		||||
		case labels.NotInOperator:
 | 
			
		||||
		case selection.NotIn:
 | 
			
		||||
			op = LabelSelectorOpNotIn
 | 
			
		||||
		case labels.ExistsOperator:
 | 
			
		||||
		case selection.Exists:
 | 
			
		||||
			op = LabelSelectorOpExists
 | 
			
		||||
		case labels.DoesNotExistOperator:
 | 
			
		||||
		case selection.DoesNotExist:
 | 
			
		||||
			op = LabelSelectorOpDoesNotExist
 | 
			
		||||
		case labels.GreaterThanOperator, labels.LessThanOperator:
 | 
			
		||||
		case selection.GreaterThan, selection.LessThan:
 | 
			
		||||
			// Adding a separate case for these operators to indicate that this is deliberate
 | 
			
		||||
			return nil, fmt.Errorf("%q isn't supported in label selectors", req.Operator())
 | 
			
		||||
		default:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								pkg/fields/requirements.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								pkg/fields/requirements.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package fields
 | 
			
		||||
 | 
			
		||||
import "k8s.io/kubernetes/pkg/selection"
 | 
			
		||||
 | 
			
		||||
// Requirements is AND of all requirements.
 | 
			
		||||
type Requirements []Requirement
 | 
			
		||||
 | 
			
		||||
// Requirement contains a field, a value, and an operator that relates the field and value.
 | 
			
		||||
// This is currently for reading internal selection information of field selector.
 | 
			
		||||
type Requirement struct {
 | 
			
		||||
	Operator selection.Operator
 | 
			
		||||
	Field    string
 | 
			
		||||
	Value    string
 | 
			
		||||
}
 | 
			
		||||
@@ -20,6 +20,8 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/selection"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Selector represents a field selector.
 | 
			
		||||
@@ -39,6 +41,10 @@ type Selector interface {
 | 
			
		||||
	// applied to the entire selector, or an error if fn returns an error.
 | 
			
		||||
	Transform(fn TransformFunc) (Selector, error)
 | 
			
		||||
 | 
			
		||||
	// Requirements converts this interface to Requirements to expose
 | 
			
		||||
	// more detailed selection information.
 | 
			
		||||
	Requirements() Requirements
 | 
			
		||||
 | 
			
		||||
	// String returns a human readable string that represents this selector.
 | 
			
		||||
	String() string
 | 
			
		||||
}
 | 
			
		||||
@@ -75,6 +81,14 @@ func (t *hasTerm) Transform(fn TransformFunc) (Selector, error) {
 | 
			
		||||
	return &hasTerm{field, value}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *hasTerm) Requirements() Requirements {
 | 
			
		||||
	return []Requirement{{
 | 
			
		||||
		Field:    t.field,
 | 
			
		||||
		Operator: selection.Equals,
 | 
			
		||||
		Value:    t.value,
 | 
			
		||||
	}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *hasTerm) String() string {
 | 
			
		||||
	return fmt.Sprintf("%v=%v", t.field, t.value)
 | 
			
		||||
}
 | 
			
		||||
@@ -103,6 +117,14 @@ func (t *notHasTerm) Transform(fn TransformFunc) (Selector, error) {
 | 
			
		||||
	return ¬HasTerm{field, value}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *notHasTerm) Requirements() Requirements {
 | 
			
		||||
	return []Requirement{{
 | 
			
		||||
		Field:    t.field,
 | 
			
		||||
		Operator: selection.NotEquals,
 | 
			
		||||
		Value:    t.value,
 | 
			
		||||
	}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t *notHasTerm) String() string {
 | 
			
		||||
	return fmt.Sprintf("%v!=%v", t.field, t.value)
 | 
			
		||||
}
 | 
			
		||||
@@ -157,6 +179,15 @@ func (t andTerm) Transform(fn TransformFunc) (Selector, error) {
 | 
			
		||||
	return andTerm(next), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t andTerm) Requirements() Requirements {
 | 
			
		||||
	reqs := make([]Requirement, 0, len(t))
 | 
			
		||||
	for _, s := range []Selector(t) {
 | 
			
		||||
		rs := s.Requirements()
 | 
			
		||||
		reqs = append(reqs, rs...)
 | 
			
		||||
	}
 | 
			
		||||
	return reqs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (t andTerm) String() string {
 | 
			
		||||
	var terms []string
 | 
			
		||||
	for _, q := range t {
 | 
			
		||||
 
 | 
			
		||||
@@ -24,10 +24,14 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/golang/glog"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/selection"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/sets"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/validation"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Requirements is AND of all requirements.
 | 
			
		||||
type Requirements []Requirement
 | 
			
		||||
 | 
			
		||||
// Selector represents a label selector.
 | 
			
		||||
type Selector interface {
 | 
			
		||||
	// Matches returns true if this selector matches the given set of labels.
 | 
			
		||||
@@ -41,6 +45,12 @@ type Selector interface {
 | 
			
		||||
 | 
			
		||||
	// Add adds requirements to the Selector
 | 
			
		||||
	Add(r ...Requirement) Selector
 | 
			
		||||
 | 
			
		||||
	// Requirements converts this interface into Requirements to expose
 | 
			
		||||
	// more detailed selection information.
 | 
			
		||||
	// If there are querying parameters, it will return converted requirements and selectable=true.
 | 
			
		||||
	// If this selector doesn't want to select anything, it will return selectable=false.
 | 
			
		||||
	Requirements() (requirements Requirements, selectable bool)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Everything returns a selector that matches all labels.
 | 
			
		||||
@@ -54,28 +64,13 @@ func (n nothingSelector) Matches(_ Labels) bool         { return false }
 | 
			
		||||
func (n nothingSelector) Empty() bool                        { return false }
 | 
			
		||||
func (n nothingSelector) String() string                     { return "<null>" }
 | 
			
		||||
func (n nothingSelector) Add(_ ...Requirement) Selector      { return n }
 | 
			
		||||
func (n nothingSelector) Requirements() (Requirements, bool) { return nil, false }
 | 
			
		||||
 | 
			
		||||
// Nothing returns a selector that matches no labels
 | 
			
		||||
func Nothing() Selector {
 | 
			
		||||
	return nothingSelector{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Operator represents a key's relationship
 | 
			
		||||
// to a set of values in a Requirement.
 | 
			
		||||
type Operator string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	DoesNotExistOperator Operator = "!"
 | 
			
		||||
	EqualsOperator       Operator = "="
 | 
			
		||||
	DoubleEqualsOperator Operator = "=="
 | 
			
		||||
	InOperator           Operator = "in"
 | 
			
		||||
	NotEqualsOperator    Operator = "!="
 | 
			
		||||
	NotInOperator        Operator = "notin"
 | 
			
		||||
	ExistsOperator       Operator = "exists"
 | 
			
		||||
	GreaterThanOperator  Operator = "gt"
 | 
			
		||||
	LessThanOperator     Operator = "lt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func NewSelector() Selector {
 | 
			
		||||
	return internalSelector(nil)
 | 
			
		||||
}
 | 
			
		||||
@@ -91,14 +86,13 @@ func (a ByKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
 | 
			
		||||
 | 
			
		||||
func (a ByKey) Less(i, j int) bool { return a[i].key < a[j].key }
 | 
			
		||||
 | 
			
		||||
// Requirement is a selector that contains values, a key
 | 
			
		||||
// and an operator that relates the key and values. The zero
 | 
			
		||||
// value of Requirement is invalid.
 | 
			
		||||
// Requirement contains values, a key, and an operator that relates the key and values.
 | 
			
		||||
// The zero value of Requirement is invalid.
 | 
			
		||||
// Requirement implements both set based match and exact match
 | 
			
		||||
// Requirement is initialized via NewRequirement constructor for creating a valid Requirement.
 | 
			
		||||
// Requirement should be initialized via NewRequirement constructor for creating a valid Requirement.
 | 
			
		||||
type Requirement struct {
 | 
			
		||||
	key       string
 | 
			
		||||
	operator  Operator
 | 
			
		||||
	operator  selection.Operator
 | 
			
		||||
	strValues sets.String
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -113,24 +107,24 @@ 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 Operator, vals sets.String) (*Requirement, error) {
 | 
			
		||||
func NewRequirement(key string, op selection.Operator, vals sets.String) (*Requirement, error) {
 | 
			
		||||
	if err := validateLabelKey(key); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	switch op {
 | 
			
		||||
	case InOperator, NotInOperator:
 | 
			
		||||
	case selection.In, selection.NotIn:
 | 
			
		||||
		if len(vals) == 0 {
 | 
			
		||||
			return nil, fmt.Errorf("for 'in', 'notin' operators, values set can't be empty")
 | 
			
		||||
		}
 | 
			
		||||
	case EqualsOperator, DoubleEqualsOperator, NotEqualsOperator:
 | 
			
		||||
	case selection.Equals, selection.DoubleEquals, selection.NotEquals:
 | 
			
		||||
		if len(vals) != 1 {
 | 
			
		||||
			return nil, fmt.Errorf("exact-match compatibility requires one single value")
 | 
			
		||||
		}
 | 
			
		||||
	case ExistsOperator, DoesNotExistOperator:
 | 
			
		||||
	case selection.Exists, selection.DoesNotExist:
 | 
			
		||||
		if len(vals) != 0 {
 | 
			
		||||
			return nil, fmt.Errorf("values set must be empty for exists and does not exist")
 | 
			
		||||
		}
 | 
			
		||||
	case GreaterThanOperator, LessThanOperator:
 | 
			
		||||
	case selection.GreaterThan, selection.LessThan:
 | 
			
		||||
		if len(vals) != 1 {
 | 
			
		||||
			return nil, fmt.Errorf("for 'Gt', 'Lt' operators, exactly one value is required")
 | 
			
		||||
		}
 | 
			
		||||
@@ -164,21 +158,21 @@ func NewRequirement(key string, op Operator, vals sets.String) (*Requirement, er
 | 
			
		||||
//     the Requirement's key and the corresponding value satisfies mathematical inequality.
 | 
			
		||||
func (r *Requirement) Matches(ls Labels) bool {
 | 
			
		||||
	switch r.operator {
 | 
			
		||||
	case InOperator, EqualsOperator, DoubleEqualsOperator:
 | 
			
		||||
	case selection.In, selection.Equals, selection.DoubleEquals:
 | 
			
		||||
		if !ls.Has(r.key) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		return r.strValues.Has(ls.Get(r.key))
 | 
			
		||||
	case NotInOperator, NotEqualsOperator:
 | 
			
		||||
	case selection.NotIn, selection.NotEquals:
 | 
			
		||||
		if !ls.Has(r.key) {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		return !r.strValues.Has(ls.Get(r.key))
 | 
			
		||||
	case ExistsOperator:
 | 
			
		||||
	case selection.Exists:
 | 
			
		||||
		return ls.Has(r.key)
 | 
			
		||||
	case DoesNotExistOperator:
 | 
			
		||||
	case selection.DoesNotExist:
 | 
			
		||||
		return !ls.Has(r.key)
 | 
			
		||||
	case GreaterThanOperator, LessThanOperator:
 | 
			
		||||
	case selection.GreaterThan, selection.LessThan:
 | 
			
		||||
		if !ls.Has(r.key) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
@@ -202,7 +196,7 @@ func (r *Requirement) Matches(ls Labels) bool {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return (r.operator == GreaterThanOperator && lsValue > rValue) || (r.operator == LessThanOperator && lsValue < rValue)
 | 
			
		||||
		return (r.operator == selection.GreaterThan && lsValue > rValue) || (r.operator == selection.LessThan && lsValue < rValue)
 | 
			
		||||
	default:
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
@@ -211,7 +205,7 @@ func (r *Requirement) Matches(ls Labels) bool {
 | 
			
		||||
func (r *Requirement) Key() string {
 | 
			
		||||
	return r.key
 | 
			
		||||
}
 | 
			
		||||
func (r *Requirement) Operator() Operator {
 | 
			
		||||
func (r *Requirement) Operator() selection.Operator {
 | 
			
		||||
	return r.operator
 | 
			
		||||
}
 | 
			
		||||
func (r *Requirement) Values() sets.String {
 | 
			
		||||
@@ -235,32 +229,32 @@ func (lsel internalSelector) Empty() bool {
 | 
			
		||||
// returned. See NewRequirement for creating a valid Requirement.
 | 
			
		||||
func (r *Requirement) String() string {
 | 
			
		||||
	var buffer bytes.Buffer
 | 
			
		||||
	if r.operator == DoesNotExistOperator {
 | 
			
		||||
	if r.operator == selection.DoesNotExist {
 | 
			
		||||
		buffer.WriteString("!")
 | 
			
		||||
	}
 | 
			
		||||
	buffer.WriteString(r.key)
 | 
			
		||||
 | 
			
		||||
	switch r.operator {
 | 
			
		||||
	case EqualsOperator:
 | 
			
		||||
	case selection.Equals:
 | 
			
		||||
		buffer.WriteString("=")
 | 
			
		||||
	case DoubleEqualsOperator:
 | 
			
		||||
	case selection.DoubleEquals:
 | 
			
		||||
		buffer.WriteString("==")
 | 
			
		||||
	case NotEqualsOperator:
 | 
			
		||||
	case selection.NotEquals:
 | 
			
		||||
		buffer.WriteString("!=")
 | 
			
		||||
	case InOperator:
 | 
			
		||||
	case selection.In:
 | 
			
		||||
		buffer.WriteString(" in ")
 | 
			
		||||
	case NotInOperator:
 | 
			
		||||
	case selection.NotIn:
 | 
			
		||||
		buffer.WriteString(" notin ")
 | 
			
		||||
	case GreaterThanOperator:
 | 
			
		||||
	case selection.GreaterThan:
 | 
			
		||||
		buffer.WriteString(">")
 | 
			
		||||
	case LessThanOperator:
 | 
			
		||||
	case selection.LessThan:
 | 
			
		||||
		buffer.WriteString("<")
 | 
			
		||||
	case ExistsOperator, DoesNotExistOperator:
 | 
			
		||||
	case selection.Exists, selection.DoesNotExist:
 | 
			
		||||
		return buffer.String()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch r.operator {
 | 
			
		||||
	case InOperator, NotInOperator:
 | 
			
		||||
	case selection.In, selection.NotIn:
 | 
			
		||||
		buffer.WriteString("(")
 | 
			
		||||
	}
 | 
			
		||||
	if len(r.strValues) == 1 {
 | 
			
		||||
@@ -270,7 +264,7 @@ func (r *Requirement) String() string {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch r.operator {
 | 
			
		||||
	case InOperator, NotInOperator:
 | 
			
		||||
	case selection.In, selection.NotIn:
 | 
			
		||||
		buffer.WriteString(")")
 | 
			
		||||
	}
 | 
			
		||||
	return buffer.String()
 | 
			
		||||
@@ -301,6 +295,8 @@ func (lsel internalSelector) Matches(l Labels) bool {
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (lsel internalSelector) Requirements() (Requirements, bool) { return Requirements(lsel), true }
 | 
			
		||||
 | 
			
		||||
// String returns a comma-separated string of all
 | 
			
		||||
// the internalSelector Requirements' human-readable strings.
 | 
			
		||||
func (lsel internalSelector) String() string {
 | 
			
		||||
@@ -564,7 +560,7 @@ func (p *Parser) parseRequirement() (*Requirement, error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if operator == ExistsOperator || operator == DoesNotExistOperator { // operator found lookahead set checked
 | 
			
		||||
	if operator == selection.Exists || operator == selection.DoesNotExist { // operator found lookahead set checked
 | 
			
		||||
		return NewRequirement(key, operator, nil)
 | 
			
		||||
	}
 | 
			
		||||
	operator, err = p.parseOperator()
 | 
			
		||||
@@ -573,9 +569,9 @@ func (p *Parser) parseRequirement() (*Requirement, error) {
 | 
			
		||||
	}
 | 
			
		||||
	var values sets.String
 | 
			
		||||
	switch operator {
 | 
			
		||||
	case InOperator, NotInOperator:
 | 
			
		||||
	case selection.In, selection.NotIn:
 | 
			
		||||
		values, err = p.parseValues()
 | 
			
		||||
	case EqualsOperator, DoubleEqualsOperator, NotEqualsOperator, GreaterThanOperator, LessThanOperator:
 | 
			
		||||
	case selection.Equals, selection.DoubleEquals, selection.NotEquals, selection.GreaterThan, selection.LessThan:
 | 
			
		||||
		values, err = p.parseExactValue()
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -588,11 +584,11 @@ func (p *Parser) parseRequirement() (*Requirement, error) {
 | 
			
		||||
// parseKeyAndInferOperator parse literals.
 | 
			
		||||
// in case of no operator '!, in, notin, ==, =, !=' are found
 | 
			
		||||
// the 'exists' operator is inferred
 | 
			
		||||
func (p *Parser) parseKeyAndInferOperator() (string, Operator, error) {
 | 
			
		||||
	var operator Operator
 | 
			
		||||
func (p *Parser) parseKeyAndInferOperator() (string, selection.Operator, error) {
 | 
			
		||||
	var operator selection.Operator
 | 
			
		||||
	tok, literal := p.consume(Values)
 | 
			
		||||
	if tok == DoesNotExistToken {
 | 
			
		||||
		operator = DoesNotExistOperator
 | 
			
		||||
		operator = selection.DoesNotExist
 | 
			
		||||
		tok, literal = p.consume(Values)
 | 
			
		||||
	}
 | 
			
		||||
	if tok != IdentifierToken {
 | 
			
		||||
@@ -603,8 +599,8 @@ func (p *Parser) parseKeyAndInferOperator() (string, Operator, error) {
 | 
			
		||||
		return "", "", err
 | 
			
		||||
	}
 | 
			
		||||
	if t, _ := p.lookahead(Values); t == EndOfStringToken || t == CommaToken {
 | 
			
		||||
		if operator != DoesNotExistOperator {
 | 
			
		||||
			operator = ExistsOperator
 | 
			
		||||
		if operator != selection.DoesNotExist {
 | 
			
		||||
			operator = selection.Exists
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return literal, operator, nil
 | 
			
		||||
@@ -612,24 +608,24 @@ func (p *Parser) parseKeyAndInferOperator() (string, Operator, error) {
 | 
			
		||||
 | 
			
		||||
// parseOperator return operator and eventually matchType
 | 
			
		||||
// matchType can be exact
 | 
			
		||||
func (p *Parser) parseOperator() (op Operator, err error) {
 | 
			
		||||
func (p *Parser) parseOperator() (op selection.Operator, err error) {
 | 
			
		||||
	tok, lit := p.consume(KeyAndOperator)
 | 
			
		||||
	switch tok {
 | 
			
		||||
	// DoesNotExistToken shouldn't be here because it's a unary operator, not a binary operator
 | 
			
		||||
	case InToken:
 | 
			
		||||
		op = InOperator
 | 
			
		||||
		op = selection.In
 | 
			
		||||
	case EqualsToken:
 | 
			
		||||
		op = EqualsOperator
 | 
			
		||||
		op = selection.Equals
 | 
			
		||||
	case DoubleEqualsToken:
 | 
			
		||||
		op = DoubleEqualsOperator
 | 
			
		||||
		op = selection.DoubleEquals
 | 
			
		||||
	case GreaterThanToken:
 | 
			
		||||
		op = GreaterThanOperator
 | 
			
		||||
		op = selection.GreaterThan
 | 
			
		||||
	case LessThanToken:
 | 
			
		||||
		op = LessThanOperator
 | 
			
		||||
		op = selection.LessThan
 | 
			
		||||
	case NotInToken:
 | 
			
		||||
		op = NotInOperator
 | 
			
		||||
		op = selection.NotIn
 | 
			
		||||
	case NotEqualsToken:
 | 
			
		||||
		op = NotEqualsOperator
 | 
			
		||||
		op = selection.NotEquals
 | 
			
		||||
	default:
 | 
			
		||||
		return "", fmt.Errorf("found '%s', expected: '=', '!=', '==', 'in', notin'", lit)
 | 
			
		||||
	}
 | 
			
		||||
@@ -788,7 +784,7 @@ func SelectorFromSet(ls Set) Selector {
 | 
			
		||||
	}
 | 
			
		||||
	var requirements internalSelector
 | 
			
		||||
	for label, value := range ls {
 | 
			
		||||
		if r, err := NewRequirement(label, EqualsOperator, sets.NewString(value)); err != nil {
 | 
			
		||||
		if r, err := NewRequirement(label, selection.Equals, sets.NewString(value)); err != nil {
 | 
			
		||||
			//TODO: double check errors when input comes from serialization?
 | 
			
		||||
			return internalSelector{}
 | 
			
		||||
		} else {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"k8s.io/kubernetes/pkg/selection"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/util/sets"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -300,23 +301,23 @@ func TestParserLookahead(t *testing.T) {
 | 
			
		||||
func TestRequirementConstructor(t *testing.T) {
 | 
			
		||||
	requirementConstructorTests := []struct {
 | 
			
		||||
		Key     string
 | 
			
		||||
		Op      Operator
 | 
			
		||||
		Op      selection.Operator
 | 
			
		||||
		Vals    sets.String
 | 
			
		||||
		Success bool
 | 
			
		||||
	}{
 | 
			
		||||
		{"x", InOperator, nil, false},
 | 
			
		||||
		{"x", NotInOperator, sets.NewString(), false},
 | 
			
		||||
		{"x", InOperator, sets.NewString("foo"), true},
 | 
			
		||||
		{"x", NotInOperator, sets.NewString("foo"), true},
 | 
			
		||||
		{"x", ExistsOperator, nil, true},
 | 
			
		||||
		{"x", DoesNotExistOperator, nil, true},
 | 
			
		||||
		{"1foo", InOperator, sets.NewString("bar"), true},
 | 
			
		||||
		{"1234", InOperator, sets.NewString("bar"), true},
 | 
			
		||||
		{"y", GreaterThanOperator, sets.NewString("1"), true},
 | 
			
		||||
		{"z", LessThanOperator, sets.NewString("6"), true},
 | 
			
		||||
		{"foo", GreaterThanOperator, sets.NewString("bar"), false},
 | 
			
		||||
		{"barz", LessThanOperator, sets.NewString("blah"), false},
 | 
			
		||||
		{strings.Repeat("a", 254), ExistsOperator, nil, false}, //breaks DNS rule that len(key) <= 253
 | 
			
		||||
		{"x", selection.In, nil, false},
 | 
			
		||||
		{"x", selection.NotIn, sets.NewString(), false},
 | 
			
		||||
		{"x", selection.In, sets.NewString("foo"), true},
 | 
			
		||||
		{"x", selection.NotIn, sets.NewString("foo"), true},
 | 
			
		||||
		{"x", selection.Exists, nil, true},
 | 
			
		||||
		{"x", selection.DoesNotExist, nil, true},
 | 
			
		||||
		{"1foo", selection.In, sets.NewString("bar"), true},
 | 
			
		||||
		{"1234", selection.In, sets.NewString("bar"), true},
 | 
			
		||||
		{"y", selection.GreaterThan, sets.NewString("1"), true},
 | 
			
		||||
		{"z", selection.LessThan, sets.NewString("6"), true},
 | 
			
		||||
		{"foo", selection.GreaterThan, sets.NewString("bar"), false},
 | 
			
		||||
		{"barz", selection.LessThan, sets.NewString("blah"), false},
 | 
			
		||||
		{strings.Repeat("a", 254), selection.Exists, nil, false}, //breaks DNS rule that len(key) <= 253
 | 
			
		||||
	}
 | 
			
		||||
	for _, rc := range requirementConstructorTests {
 | 
			
		||||
		if _, err := NewRequirement(rc.Key, rc.Op, rc.Vals); err == nil && !rc.Success {
 | 
			
		||||
@@ -336,34 +337,34 @@ func TestToString(t *testing.T) {
 | 
			
		||||
	}{
 | 
			
		||||
 | 
			
		||||
		{&internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString("abc", "def"), t),
 | 
			
		||||
			getRequirement("y", NotInOperator, sets.NewString("jkl"), t),
 | 
			
		||||
			getRequirement("z", ExistsOperator, nil, t)},
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString("abc", "def"), t),
 | 
			
		||||
			getRequirement("y", selection.NotIn, sets.NewString("jkl"), t),
 | 
			
		||||
			getRequirement("z", selection.Exists, nil, t)},
 | 
			
		||||
			"x in (abc,def),y notin (jkl),z", true},
 | 
			
		||||
		{&internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString("abc", "def"), t),
 | 
			
		||||
			getRequirement("y", NotEqualsOperator, sets.NewString("jkl"), t),
 | 
			
		||||
			getRequirement("z", DoesNotExistOperator, nil, t)},
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString("abc", "def"), t),
 | 
			
		||||
			getRequirement("y", selection.NotEquals, sets.NewString("jkl"), t),
 | 
			
		||||
			getRequirement("z", selection.DoesNotExist, nil, t)},
 | 
			
		||||
			"x notin (abc,def),y!=jkl,!z", true},
 | 
			
		||||
		{&internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString("abc", "def"), t),
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString("abc", "def"), t),
 | 
			
		||||
			req}, // adding empty req for the trailing ','
 | 
			
		||||
			"x in (abc,def),", false},
 | 
			
		||||
		{&internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString("abc"), t),
 | 
			
		||||
			getRequirement("y", InOperator, sets.NewString("jkl", "mno"), t),
 | 
			
		||||
			getRequirement("z", NotInOperator, sets.NewString(""), t)},
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString("abc"), t),
 | 
			
		||||
			getRequirement("y", selection.In, sets.NewString("jkl", "mno"), t),
 | 
			
		||||
			getRequirement("z", selection.NotIn, sets.NewString(""), t)},
 | 
			
		||||
			"x notin (abc),y in (jkl,mno),z notin ()", true},
 | 
			
		||||
		{&internalSelector{
 | 
			
		||||
			getRequirement("x", EqualsOperator, sets.NewString("abc"), t),
 | 
			
		||||
			getRequirement("y", DoubleEqualsOperator, sets.NewString("jkl"), t),
 | 
			
		||||
			getRequirement("z", NotEqualsOperator, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("z", ExistsOperator, nil, t)},
 | 
			
		||||
			getRequirement("x", selection.Equals, sets.NewString("abc"), t),
 | 
			
		||||
			getRequirement("y", selection.DoubleEquals, sets.NewString("jkl"), t),
 | 
			
		||||
			getRequirement("z", selection.NotEquals, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("z", selection.Exists, nil, t)},
 | 
			
		||||
			"x=abc,y==jkl,z!=a,z", true},
 | 
			
		||||
		{&internalSelector{
 | 
			
		||||
			getRequirement("x", GreaterThanOperator, sets.NewString("2"), t),
 | 
			
		||||
			getRequirement("y", LessThanOperator, sets.NewString("8"), t),
 | 
			
		||||
			getRequirement("z", ExistsOperator, nil, t)},
 | 
			
		||||
			getRequirement("x", selection.GreaterThan, sets.NewString("2"), t),
 | 
			
		||||
			getRequirement("y", selection.LessThan, sets.NewString("8"), t),
 | 
			
		||||
			getRequirement("z", selection.Exists, nil, t)},
 | 
			
		||||
			"x>2,y<8,z", true},
 | 
			
		||||
	}
 | 
			
		||||
	for _, ts := range toStringTests {
 | 
			
		||||
@@ -386,33 +387,33 @@ func TestRequirementSelectorMatching(t *testing.T) {
 | 
			
		||||
			req,
 | 
			
		||||
		}, false},
 | 
			
		||||
		{Set{"x": "foo", "y": "baz"}, &internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString("foo"), t),
 | 
			
		||||
			getRequirement("y", NotInOperator, sets.NewString("alpha"), t),
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString("foo"), t),
 | 
			
		||||
			getRequirement("y", selection.NotIn, sets.NewString("alpha"), t),
 | 
			
		||||
		}, true},
 | 
			
		||||
		{Set{"x": "foo", "y": "baz"}, &internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString("foo"), t),
 | 
			
		||||
			getRequirement("y", InOperator, sets.NewString("alpha"), t),
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString("foo"), t),
 | 
			
		||||
			getRequirement("y", selection.In, sets.NewString("alpha"), t),
 | 
			
		||||
		}, false},
 | 
			
		||||
		{Set{"y": ""}, &internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("y", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("y", selection.Exists, nil, t),
 | 
			
		||||
		}, true},
 | 
			
		||||
		{Set{"y": ""}, &internalSelector{
 | 
			
		||||
			getRequirement("x", DoesNotExistOperator, nil, t),
 | 
			
		||||
			getRequirement("y", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("x", selection.DoesNotExist, nil, t),
 | 
			
		||||
			getRequirement("y", selection.Exists, nil, t),
 | 
			
		||||
		}, true},
 | 
			
		||||
		{Set{"y": ""}, &internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("y", DoesNotExistOperator, nil, t),
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("y", selection.DoesNotExist, nil, t),
 | 
			
		||||
		}, false},
 | 
			
		||||
		{Set{"y": "baz"}, &internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString(""), t),
 | 
			
		||||
		}, false},
 | 
			
		||||
		{Set{"z": "2"}, &internalSelector{
 | 
			
		||||
			getRequirement("z", GreaterThanOperator, sets.NewString("1"), t),
 | 
			
		||||
			getRequirement("z", selection.GreaterThan, sets.NewString("1"), t),
 | 
			
		||||
		}, true},
 | 
			
		||||
		{Set{"z": "v2"}, &internalSelector{
 | 
			
		||||
			getRequirement("z", GreaterThanOperator, sets.NewString("1"), t),
 | 
			
		||||
			getRequirement("z", selection.GreaterThan, sets.NewString("1"), t),
 | 
			
		||||
		}, false},
 | 
			
		||||
	}
 | 
			
		||||
	for _, lsm := range labelSelectorMatchingTests {
 | 
			
		||||
@@ -431,80 +432,80 @@ func TestSetSelectorParser(t *testing.T) {
 | 
			
		||||
	}{
 | 
			
		||||
		{"", NewSelector(), true, true},
 | 
			
		||||
		{"\rx", internalSelector{
 | 
			
		||||
			getRequirement("x", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("x", selection.Exists, nil, t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"this-is-a-dns.domain.com/key-with-dash", internalSelector{
 | 
			
		||||
			getRequirement("this-is-a-dns.domain.com/key-with-dash", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("this-is-a-dns.domain.com/key-with-dash", selection.Exists, nil, t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"this-is-another-dns.domain.com/key-with-dash in (so,what)", internalSelector{
 | 
			
		||||
			getRequirement("this-is-another-dns.domain.com/key-with-dash", InOperator, sets.NewString("so", "what"), t),
 | 
			
		||||
			getRequirement("this-is-another-dns.domain.com/key-with-dash", selection.In, sets.NewString("so", "what"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"0.1.2.domain/99 notin (10.10.100.1, tick.tack.clock)", internalSelector{
 | 
			
		||||
			getRequirement("0.1.2.domain/99", NotInOperator, sets.NewString("10.10.100.1", "tick.tack.clock"), t),
 | 
			
		||||
			getRequirement("0.1.2.domain/99", selection.NotIn, sets.NewString("10.10.100.1", "tick.tack.clock"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"foo  in	 (abc)", internalSelector{
 | 
			
		||||
			getRequirement("foo", InOperator, sets.NewString("abc"), t),
 | 
			
		||||
			getRequirement("foo", selection.In, sets.NewString("abc"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x notin\n (abc)", internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString("abc"), t),
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString("abc"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x  notin	\t	(abc,def)", internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString("abc", "def"), t),
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString("abc", "def"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x in (abc,def)", internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString("abc", "def"), t),
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString("abc", "def"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x in (abc,)", internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString("abc", ""), t),
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString("abc", ""), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x in ()", internalSelector{
 | 
			
		||||
			getRequirement("x", InOperator, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("x", selection.In, sets.NewString(""), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x notin (abc,,def),bar,z in (),w", internalSelector{
 | 
			
		||||
			getRequirement("bar", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("w", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString("abc", "", "def"), t),
 | 
			
		||||
			getRequirement("z", InOperator, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("bar", selection.Exists, nil, t),
 | 
			
		||||
			getRequirement("w", selection.Exists, nil, t),
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString("abc", "", "def"), t),
 | 
			
		||||
			getRequirement("z", selection.In, sets.NewString(""), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x,y in (a)", internalSelector{
 | 
			
		||||
			getRequirement("y", InOperator, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("x", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("y", selection.In, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("x", selection.Exists, nil, t),
 | 
			
		||||
		}, false, true},
 | 
			
		||||
		{"x=a", internalSelector{
 | 
			
		||||
			getRequirement("x", EqualsOperator, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("x", selection.Equals, sets.NewString("a"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x>1", internalSelector{
 | 
			
		||||
			getRequirement("x", GreaterThanOperator, sets.NewString("1"), t),
 | 
			
		||||
			getRequirement("x", selection.GreaterThan, sets.NewString("1"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x<7", internalSelector{
 | 
			
		||||
			getRequirement("x", LessThanOperator, sets.NewString("7"), t),
 | 
			
		||||
			getRequirement("x", selection.LessThan, sets.NewString("7"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x=a,y!=b", internalSelector{
 | 
			
		||||
			getRequirement("x", EqualsOperator, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("y", NotEqualsOperator, sets.NewString("b"), t),
 | 
			
		||||
			getRequirement("x", selection.Equals, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("y", selection.NotEquals, sets.NewString("b"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x=a,y!=b,z in (h,i,j)", internalSelector{
 | 
			
		||||
			getRequirement("x", EqualsOperator, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("y", NotEqualsOperator, sets.NewString("b"), t),
 | 
			
		||||
			getRequirement("z", InOperator, sets.NewString("h", "i", "j"), t),
 | 
			
		||||
			getRequirement("x", selection.Equals, sets.NewString("a"), t),
 | 
			
		||||
			getRequirement("y", selection.NotEquals, sets.NewString("b"), t),
 | 
			
		||||
			getRequirement("z", selection.In, sets.NewString("h", "i", "j"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x=a||y=b", internalSelector{}, false, false},
 | 
			
		||||
		{"x,,y", nil, true, false},
 | 
			
		||||
		{",x,y", nil, true, false},
 | 
			
		||||
		{"x nott in (y)", nil, true, false},
 | 
			
		||||
		{"x notin ( )", internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString(""), t),
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString(""), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"x notin (, a)", internalSelector{
 | 
			
		||||
			getRequirement("x", NotInOperator, sets.NewString("", "a"), t),
 | 
			
		||||
			getRequirement("x", selection.NotIn, sets.NewString("", "a"), t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"a in (xyz),", nil, true, false},
 | 
			
		||||
		{"a in (xyz)b notin ()", nil, true, false},
 | 
			
		||||
		{"a ", internalSelector{
 | 
			
		||||
			getRequirement("a", ExistsOperator, nil, t),
 | 
			
		||||
			getRequirement("a", selection.Exists, nil, t),
 | 
			
		||||
		}, true, true},
 | 
			
		||||
		{"a in (x,y,notin, z,in)", internalSelector{
 | 
			
		||||
			getRequirement("a", InOperator, sets.NewString("in", "notin", "x", "y", "z"), t),
 | 
			
		||||
			getRequirement("a", selection.In, sets.NewString("in", "notin", "x", "y", "z"), t),
 | 
			
		||||
		}, true, true}, // operator 'in' inside list of identifiers
 | 
			
		||||
		{"a in (xyz abc)", nil, false, false}, // no comma
 | 
			
		||||
		{"a notin(", nil, true, false},        // bad formed
 | 
			
		||||
@@ -523,7 +524,7 @@ func TestSetSelectorParser(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getRequirement(key string, op Operator, vals sets.String, t *testing.T) Requirement {
 | 
			
		||||
func getRequirement(key string, op selection.Operator, vals sets.String, t *testing.T) Requirement {
 | 
			
		||||
	req, err := NewRequirement(key, op, vals)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("NewRequirement(%v, %v, %v) resulted in error:%v", key, op, vals, err)
 | 
			
		||||
@@ -537,7 +538,7 @@ func TestAdd(t *testing.T) {
 | 
			
		||||
		name        string
 | 
			
		||||
		sel         Selector
 | 
			
		||||
		key         string
 | 
			
		||||
		operator    Operator
 | 
			
		||||
		operator    selection.Operator
 | 
			
		||||
		values      []string
 | 
			
		||||
		refSelector Selector
 | 
			
		||||
	}{
 | 
			
		||||
@@ -545,19 +546,19 @@ func TestAdd(t *testing.T) {
 | 
			
		||||
			"keyInOperator",
 | 
			
		||||
			internalSelector{},
 | 
			
		||||
			"key",
 | 
			
		||||
			InOperator,
 | 
			
		||||
			selection.In,
 | 
			
		||||
			[]string{"value"},
 | 
			
		||||
			internalSelector{Requirement{"key", InOperator, sets.NewString("value")}},
 | 
			
		||||
			internalSelector{Requirement{"key", selection.In, sets.NewString("value")}},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"keyEqualsOperator",
 | 
			
		||||
			internalSelector{Requirement{"key", InOperator, sets.NewString("value")}},
 | 
			
		||||
			internalSelector{Requirement{"key", selection.In, sets.NewString("value")}},
 | 
			
		||||
			"key2",
 | 
			
		||||
			EqualsOperator,
 | 
			
		||||
			selection.Equals,
 | 
			
		||||
			[]string{"value2"},
 | 
			
		||||
			internalSelector{
 | 
			
		||||
				Requirement{"key", InOperator, sets.NewString("value")},
 | 
			
		||||
				Requirement{"key2", EqualsOperator, sets.NewString("value2")},
 | 
			
		||||
				Requirement{"key", selection.In, sets.NewString("value")},
 | 
			
		||||
				Requirement{"key2", selection.Equals, sets.NewString("value2")},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ import (
 | 
			
		||||
	"k8s.io/kubernetes/pkg/labels"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/registry/generic"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/selection"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/storage"
 | 
			
		||||
	etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
 | 
			
		||||
	"k8s.io/kubernetes/pkg/storage/etcd/etcdtest"
 | 
			
		||||
@@ -88,7 +89,7 @@ func NewTestGenericStoreRegistry(t *testing.T) (*etcdtesting.EtcdTestServer, *St
 | 
			
		||||
func matchPodName(names ...string) *generic.SelectionPredicate {
 | 
			
		||||
	// Note: even if pod name is a field, we have to use labels,
 | 
			
		||||
	// because field selector doesn't support "IN" operator.
 | 
			
		||||
	l, err := labels.NewRequirement("name", labels.InOperator, sets.NewString(names...))
 | 
			
		||||
	l, err := labels.NewRequirement("name", selection.In, sets.NewString(names...))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic("Labels requirement must validate successfully")
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								pkg/selection/operator.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								pkg/selection/operator.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
Copyright 2016 The Kubernetes Authors.
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package selection
 | 
			
		||||
 | 
			
		||||
// Operator represents a key/field's relationship to value(s).
 | 
			
		||||
// See labels.Requirement and fields.Requirement for more details.
 | 
			
		||||
type Operator string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	DoesNotExist Operator = "!"
 | 
			
		||||
	Equals       Operator = "="
 | 
			
		||||
	DoubleEquals Operator = "=="
 | 
			
		||||
	In           Operator = "in"
 | 
			
		||||
	NotEquals    Operator = "!="
 | 
			
		||||
	NotIn        Operator = "notin"
 | 
			
		||||
	Exists       Operator = "exists"
 | 
			
		||||
	GreaterThan  Operator = "gt"
 | 
			
		||||
	LessThan     Operator = "lt"
 | 
			
		||||
)
 | 
			
		||||
		Reference in New Issue
	
	Block a user