Commit 1871a220 authored by Hongchao Deng's avatar Hongchao Deng

make labels, fields expose selectable requirements

parent 9030a323
......@@ -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:
......
/*
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 &notHasTerm{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 {
......
......@@ -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")
}
......
/*
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"
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment