Adding fields selector

This commit is contained in:
Salvatore Dario Minonne 2015-03-07 00:29:03 +01:00
parent 9aa744925e
commit 925fa6baf8
46 changed files with 725 additions and 116 deletions

View File

@ -34,6 +34,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" apierrs "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -216,7 +217,7 @@ type SimpleRESTStorage struct {
// These are set when Watch is called // These are set when Watch is called
fakeWatch *watch.FakeWatcher fakeWatch *watch.FakeWatcher
requestedLabelSelector labels.Selector requestedLabelSelector labels.Selector
requestedFieldSelector labels.Selector requestedFieldSelector fields.Selector
requestedResourceVersion string requestedResourceVersion string
requestedResourceNamespace string requestedResourceNamespace string
@ -230,7 +231,7 @@ type SimpleRESTStorage struct {
injectedFunction func(obj runtime.Object) (returnObj runtime.Object, err error) injectedFunction func(obj runtime.Object) (returnObj runtime.Object, err error)
} }
func (storage *SimpleRESTStorage) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (storage *SimpleRESTStorage) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
storage.checkContext(ctx) storage.checkContext(ctx)
result := &SimpleList{ result := &SimpleList{
Items: storage.list, Items: storage.list,
@ -296,7 +297,7 @@ func (storage *SimpleRESTStorage) Update(ctx api.Context, obj runtime.Object) (r
} }
// Implement ResourceWatcher. // Implement ResourceWatcher.
func (storage *SimpleRESTStorage) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (storage *SimpleRESTStorage) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
storage.checkContext(ctx) storage.checkContext(ctx)
storage.requestedLabelSelector = label storage.requestedLabelSelector = label
storage.requestedFieldSelector = field storage.requestedFieldSelector = field

View File

@ -18,6 +18,7 @@ package apiserver
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -38,7 +39,7 @@ type RESTLister interface {
// This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object) // This object must be a pointer type for use with Codec.DecodeInto([]byte, runtime.Object)
NewList() runtime.Object NewList() runtime.Object
// List selects resources in the storage which match to the selector. // List selects resources in the storage which match to the selector.
List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error)
} }
type RESTGetter interface { type RESTGetter interface {
@ -100,7 +101,7 @@ type ResourceWatcher interface {
// are supported; an error should be returned if 'field' tries to select on a field that // are supported; an error should be returned if 'field' tries to select on a field that
// isn't supported. 'resourceVersion' allows for continuing/starting a watch at a // isn't supported. 'resourceVersion' allows for continuing/starting a watch at a
// particular version. // particular version.
Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
} }
// Redirector know how to return a remote resource's location. // Redirector know how to return a remote resource's location.

View File

@ -26,6 +26,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/admission"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -82,7 +83,7 @@ func GetResource(r RESTGetter, ctxFn ContextFunc, namer ScopeNamer, codec runtim
} }
} }
func parseSelectorQueryParams(query url.Values, version, apiResource string) (label, field labels.Selector, err error) { func parseSelectorQueryParams(query url.Values, version, apiResource string) (label labels.Selector, field fields.Selector, err error) {
labelString := query.Get("labels") labelString := query.Get("labels")
label, err = labels.Parse(labelString) label, err = labels.Parse(labelString)
if err != nil { if err != nil {
@ -93,7 +94,7 @@ func parseSelectorQueryParams(query url.Values, version, apiResource string) (la
return api.Scheme.ConvertFieldLabel(version, apiResource, label, value) return api.Scheme.ConvertFieldLabel(version, apiResource, label, value)
} }
fieldString := query.Get("fields") fieldString := query.Get("fields")
field, err = labels.ParseAndTransformSelector(fieldString, convertToInternalVersionFunc) field, err = fields.ParseAndTransformSelector(fieldString, convertToInternalVersionFunc)
if err != nil { if err != nil {
return nil, nil, errors.NewBadRequest(fmt.Sprintf("The 'fields' selector parameter (%s) could not be parsed: %v", fieldString, err)) return nil, nil, errors.NewBadRequest(fmt.Sprintf("The 'fields' selector parameter (%s) could not be parsed: %v", fieldString, err))
} }

View File

@ -25,6 +25,7 @@ import (
"testing" "testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -209,7 +210,7 @@ func TestWatchParamParsing(t *testing.T) {
for _, item := range table { for _, item := range table {
simpleStorage.requestedLabelSelector = labels.Everything() simpleStorage.requestedLabelSelector = labels.Everything()
simpleStorage.requestedFieldSelector = labels.Everything() simpleStorage.requestedFieldSelector = fields.Everything()
simpleStorage.requestedResourceVersion = "5" // Prove this is set in all cases simpleStorage.requestedResourceVersion = "5" // Prove this is set in all cases
simpleStorage.requestedResourceNamespace = "" simpleStorage.requestedResourceNamespace = ""
dest.RawQuery = item.rawQuery dest.RawQuery = item.rawQuery

View File

@ -31,6 +31,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -255,20 +256,26 @@ func (r *Request) RequestURI(uri string) *Request {
return r return r
} }
// ParseSelectorParam parses the given string as a resource label selector. // ParseSelectorParam parses the given string as a resource selector.
// This is a convenience function so you don't have to first check that it's a // This is a convenience function so you don't have to first check that it's a
// validly formatted selector. // validly formatted selector.
func (r *Request) ParseSelectorParam(paramName, item string) *Request { func (r *Request) ParseSelectorParam(paramName, item string) *Request {
if r.err != nil { if r.err != nil {
return r return r
} }
var sel labels.Selector var selector string
var err error var err error
switch paramName { switch paramName {
case "labels": case "labels":
sel, err = labels.Parse(item) var lsel labels.Selector
if lsel, err = labels.Parse(item); err == nil {
selector = lsel.String()
}
case "fields": case "fields":
sel, err = labels.ParseSelector(item) var fsel fields.Selector
if fsel, err = fields.ParseSelector(item); err == nil {
selector = fsel.String()
}
default: default:
err = fmt.Errorf("unknown parameter name '%s'", paramName) err = fmt.Errorf("unknown parameter name '%s'", paramName)
} }
@ -276,7 +283,7 @@ func (r *Request) ParseSelectorParam(paramName, item string) *Request {
r.err = err r.err = err
return r return r
} }
return r.setParam(paramName, sel.String()) return r.setParam(paramName, selector)
} }
// SelectorParam adds the given selector as a query parameter with the name paramName. // SelectorParam adds the given selector as a query parameter with the name paramName.
@ -537,7 +544,6 @@ func (r *Request) DoRaw() ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
r.resp, err = client.Do(r.req) r.resp, err = client.Do(r.req)
if err != nil { if err != nil {
return nil, err return nil, err

19
pkg/fields/doc.go Normal file
View File

@ -0,0 +1,19 @@
/*
Copyright 2015 Google Inc. All rights reserved.
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 implements a simple field system, parsing and matching
// selectors with sets of fields.
package fields

62
pkg/fields/fields.go Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright 2015 Google Inc. All rights reserved.
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 (
"sort"
"strings"
)
// Fields allows you to present fields independently from their storage.
type Fields interface {
// Has returns whether the provided field exists.
Has(field string) (exists bool)
// Get returns the value for the provided field.
Get(field string) (value string)
}
// Set is a map of field:value. It implements Fields.
type Set map[string]string
// String returns all fields listed as a human readable string.
// Conveniently, exactly the format that ParseSelector takes.
func (ls Set) String() string {
selector := make([]string, 0, len(ls))
for key, value := range ls {
selector = append(selector, key+"="+value)
}
// Sort for determinism.
sort.StringSlice(selector).Sort()
return strings.Join(selector, ",")
}
// Has returns whether the provided field exists in the map.
func (ls Set) Has(field string) bool {
_, exists := ls[field]
return exists
}
// Get returns the value in the map for the provided field.
func (ls Set) Get(field string) string {
return ls[field]
}
// AsSelector converts fields into a selectors.
func (ls Set) AsSelector() Selector {
return SelectorFromSet(ls)
}

57
pkg/fields/fields_test.go Normal file
View File

@ -0,0 +1,57 @@
/*
Copyright 2015 Google Inc. All rights reserved.
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 (
"testing"
)
func matches(t *testing.T, ls Set, want string) {
if ls.String() != want {
t.Errorf("Expected '%s', but got '%s'", want, ls.String())
}
}
func TestSetString(t *testing.T) {
matches(t, Set{"x": "y"}, "x=y")
matches(t, Set{"foo": "bar"}, "foo=bar")
matches(t, Set{"foo": "bar", "baz": "qup"}, "baz=qup,foo=bar")
}
func TestFieldHas(t *testing.T) {
fieldHasTests := []struct {
Ls Fields
Key string
Has bool
}{
{Set{"x": "y"}, "x", true},
{Set{"x": ""}, "x", true},
{Set{"x": "y"}, "foo", false},
}
for _, lh := range fieldHasTests {
if has := lh.Ls.Has(lh.Key); has != lh.Has {
t.Errorf("%#v.Has(%#v) => %v, expected %v", lh.Ls, lh.Key, has, lh.Has)
}
}
}
func TestFieldGet(t *testing.T) {
ls := Set{"x": "y"}
if ls.Get("x") != "y" {
t.Errorf("Set.Get is broken")
}
}

217
pkg/fields/selector.go Normal file
View File

@ -0,0 +1,217 @@
/*
Copyright 2015 Google Inc. All rights reserved.
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 (
"fmt"
"sort"
"strings"
)
// Selector represents a field selector.
type Selector interface {
// Matches returns true if this selector matches the given set of fields.
Matches(Fields) bool
// Empty returns true if this selector does not restrict the selection space.
Empty() bool
// RequiresExactMatch allows a caller to introspect whether a given selector
// requires a single specific field to be set, and if so returns the value it
// requires.
RequiresExactMatch(field string) (value string, found bool)
// String returns a human readable string that represents this selector.
String() string
}
// Everything returns a selector that matches all fields.
func Everything() Selector {
return andTerm{}
}
type hasTerm struct {
field, value string
}
func (t *hasTerm) Matches(ls Fields) bool {
return ls.Get(t.field) == t.value
}
func (t *hasTerm) Empty() bool {
return false
}
func (t *hasTerm) RequiresExactMatch(field string) (value string, found bool) {
if t.field == field {
return t.value, true
}
return "", false
}
func (t *hasTerm) String() string {
return fmt.Sprintf("%v=%v", t.field, t.value)
}
type notHasTerm struct {
field, value string
}
func (t *notHasTerm) Matches(ls Fields) bool {
return ls.Get(t.field) != t.value
}
func (t *notHasTerm) Empty() bool {
return false
}
func (t *notHasTerm) RequiresExactMatch(field string) (value string, found bool) {
return "", false
}
func (t *notHasTerm) String() string {
return fmt.Sprintf("%v!=%v", t.field, t.value)
}
type andTerm []Selector
func (t andTerm) Matches(ls Fields) bool {
for _, q := range t {
if !q.Matches(ls) {
return false
}
}
return true
}
func (t andTerm) Empty() bool {
if t == nil {
return true
}
if len([]Selector(t)) == 0 {
return true
}
for i := range t {
if !t[i].Empty() {
return false
}
}
return true
}
func (t andTerm) RequiresExactMatch(field string) (string, bool) {
if t == nil || len([]Selector(t)) == 0 {
return "", false
}
for i := range t {
if value, found := t[i].RequiresExactMatch(field); found {
return value, found
}
}
return "", false
}
func (t andTerm) String() string {
var terms []string
for _, q := range t {
terms = append(terms, q.String())
}
return strings.Join(terms, ",")
}
// SelectorFromSet returns a Selector which will match exactly the given Set. A
// nil Set is considered equivalent to Everything().
func SelectorFromSet(ls Set) Selector {
if ls == nil {
return Everything()
}
items := make([]Selector, 0, len(ls))
for field, value := range ls {
items = append(items, &hasTerm{field: field, value: value})
}
if len(items) == 1 {
return items[0]
}
return andTerm(items)
}
// ParseSelector takes a string representing a selector and returns an
// object suitable for matching, or an error.
func ParseSelector(selector string) (Selector, error) {
return parseSelector(selector,
func(lhs, rhs string) (newLhs, newRhs string, err error) {
return lhs, rhs, nil
})
}
// Parses the selector and runs them through the given TransformFunc.
func ParseAndTransformSelector(selector string, fn TransformFunc) (Selector, error) {
return parseSelector(selector, fn)
}
// Function to transform selectors.
type TransformFunc func(field, value string) (newField, newValue string, err error)
func try(selectorPiece, op string) (lhs, rhs string, ok bool) {
pieces := strings.Split(selectorPiece, op)
if len(pieces) == 2 {
return pieces[0], pieces[1], true
}
return "", "", false
}
func parseSelector(selector string, fn TransformFunc) (Selector, error) {
parts := strings.Split(selector, ",")
sort.StringSlice(parts).Sort()
var items []Selector
for _, part := range parts {
if part == "" {
continue
}
if lhs, rhs, ok := try(part, "!="); ok {
lhs, rhs, err := fn(lhs, rhs)
if err != nil {
return nil, err
}
items = append(items, &notHasTerm{field: lhs, value: rhs})
} else if lhs, rhs, ok := try(part, "=="); ok {
lhs, rhs, err := fn(lhs, rhs)
if err != nil {
return nil, err
}
items = append(items, &hasTerm{field: lhs, value: rhs})
} else if lhs, rhs, ok := try(part, "="); ok {
lhs, rhs, err := fn(lhs, rhs)
if err != nil {
return nil, err
}
items = append(items, &hasTerm{field: lhs, value: rhs})
} else {
return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
}
}
if len(items) == 1 {
return items[0], nil
}
return andTerm(items), nil
}
// OneTermEqualSelector returns an object that matches objects where one field/field equals one value.
// Cannot return an error.
func OneTermEqualSelector(k, v string) Selector {
return &hasTerm{field: k, value: v}
}

208
pkg/fields/selector_test.go Normal file
View File

@ -0,0 +1,208 @@
/*
Copyright 2015 Google Inc. All rights reserved.
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 (
"testing"
)
func TestSelectorParse(t *testing.T) {
testGoodStrings := []string{
"x=a,y=b,z=c",
"",
"x!=a,y=b",
}
testBadStrings := []string{
"x=a||y=b",
"x==a==b",
}
for _, test := range testGoodStrings {
lq, err := ParseSelector(test)
if err != nil {
t.Errorf("%v: error %v (%#v)\n", test, err, err)
}
if test != lq.String() {
t.Errorf("%v restring gave: %v\n", test, lq.String())
}
}
for _, test := range testBadStrings {
_, err := ParseSelector(test)
if err == nil {
t.Errorf("%v: did not get expected error\n", test)
}
}
}
func TestDeterministicParse(t *testing.T) {
s1, err := ParseSelector("x=a,a=x")
s2, err2 := ParseSelector("a=x,x=a")
if err != nil || err2 != nil {
t.Errorf("Unexpected parse error")
}
if s1.String() != s2.String() {
t.Errorf("Non-deterministic parse")
}
}
func expectMatch(t *testing.T, selector string, ls Set) {
lq, err := ParseSelector(selector)
if err != nil {
t.Errorf("Unable to parse %v as a selector\n", selector)
return
}
if !lq.Matches(ls) {
t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls)
}
}
func expectNoMatch(t *testing.T, selector string, ls Set) {
lq, err := ParseSelector(selector)
if err != nil {
t.Errorf("Unable to parse %v as a selector\n", selector)
return
}
if lq.Matches(ls) {
t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls)
}
}
func TestEverything(t *testing.T) {
if !Everything().Matches(Set{"x": "y"}) {
t.Errorf("Nil selector didn't match")
}
if !Everything().Empty() {
t.Errorf("Everything was not empty")
}
}
func TestSelectorMatches(t *testing.T) {
expectMatch(t, "", Set{"x": "y"})
expectMatch(t, "x=y", Set{"x": "y"})
expectMatch(t, "x=y,z=w", Set{"x": "y", "z": "w"})
expectMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "a"})
expectMatch(t, "notin=in", Set{"notin": "in"}) // in and notin in exactMatch
expectNoMatch(t, "x=y", Set{"x": "z"})
expectNoMatch(t, "x=y,z=w", Set{"x": "w", "z": "w"})
expectNoMatch(t, "x!=y,z!=w", Set{"x": "z", "z": "w"})
labelset := Set{
"foo": "bar",
"baz": "blah",
}
expectMatch(t, "foo=bar", labelset)
expectMatch(t, "baz=blah", labelset)
expectMatch(t, "foo=bar,baz=blah", labelset)
expectNoMatch(t, "foo=blah", labelset)
expectNoMatch(t, "baz=bar", labelset)
expectNoMatch(t, "foo=bar,foobar=bar,baz=blah", labelset)
}
func TestOneTermEqualSelector(t *testing.T) {
if !OneTermEqualSelector("x", "y").Matches(Set{"x": "y"}) {
t.Errorf("No match when match expected.")
}
if OneTermEqualSelector("x", "y").Matches(Set{"x": "z"}) {
t.Errorf("Match when none expected.")
}
}
func expectMatchDirect(t *testing.T, selector, ls Set) {
if !SelectorFromSet(selector).Matches(ls) {
t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls)
}
}
func expectNoMatchDirect(t *testing.T, selector, ls Set) {
if SelectorFromSet(selector).Matches(ls) {
t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls)
}
}
func TestSetMatches(t *testing.T) {
labelset := Set{
"foo": "bar",
"baz": "blah",
}
expectMatchDirect(t, Set{}, labelset)
expectMatchDirect(t, Set{"foo": "bar"}, labelset)
expectMatchDirect(t, Set{"baz": "blah"}, labelset)
expectMatchDirect(t, Set{"foo": "bar", "baz": "blah"}, labelset)
expectNoMatchDirect(t, Set{"foo": "=blah"}, labelset)
expectNoMatchDirect(t, Set{"baz": "=bar"}, labelset)
expectNoMatchDirect(t, Set{"foo": "=bar", "foobar": "bar", "baz": "blah"}, labelset)
}
func TestNilMapIsValid(t *testing.T) {
selector := Set(nil).AsSelector()
if selector == nil {
t.Errorf("Selector for nil set should be Everything")
}
if !selector.Empty() {
t.Errorf("Selector for nil set should be Empty")
}
}
func TestSetIsEmpty(t *testing.T) {
if !(Set{}).AsSelector().Empty() {
t.Errorf("Empty set should be empty")
}
if !(andTerm(nil)).Empty() {
t.Errorf("Nil andTerm should be empty")
}
if (&hasTerm{}).Empty() {
t.Errorf("hasTerm should not be empty")
}
if (&notHasTerm{}).Empty() {
t.Errorf("notHasTerm should not be empty")
}
if !(andTerm{andTerm{}}).Empty() {
t.Errorf("Nested andTerm should be empty")
}
if (andTerm{&hasTerm{"a", "b"}}).Empty() {
t.Errorf("Nested andTerm should not be empty")
}
}
func TestRequiresExactMatch(t *testing.T) {
testCases := map[string]struct {
S Selector
Label string
Value string
Found bool
}{
"empty set": {Set{}.AsSelector(), "test", "", false},
"nil andTerm": {andTerm(nil), "test", "", false},
"empty hasTerm": {&hasTerm{}, "test", "", false},
"skipped hasTerm": {&hasTerm{"a", "b"}, "test", "", false},
"valid hasTerm": {&hasTerm{"test", "b"}, "test", "b", true},
"valid hasTerm no value": {&hasTerm{"test", ""}, "test", "", true},
"valid notHasTerm": {&notHasTerm{"test", "b"}, "test", "", false},
"valid notHasTerm no value": {&notHasTerm{"test", ""}, "test", "", false},
"nested andTerm": {andTerm{andTerm{}}, "test", "", false},
"nested andTerm matches": {andTerm{&hasTerm{"test", "b"}}, "test", "b", true},
"andTerm with non-match": {andTerm{&hasTerm{}, &hasTerm{"test", "b"}}, "test", "b", true},
}
for k, v := range testCases {
value, found := v.S.RequiresExactMatch(v.Label)
if value != v.Value {
t.Errorf("%s: expected value %s, got %s", k, v.Value, value)
}
if found != v.Found {
t.Errorf("%s: expected found %t, got %t", k, v.Found, found)
}
}
}

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
) )
@ -64,7 +65,7 @@ func (n *nodeAdaptor) Create(minion *api.Node) (*api.Node, error) {
// List lists all the nodes in the cluster. // List lists all the nodes in the cluster.
func (n *nodeAdaptor) List() (*api.NodeList, error) { func (n *nodeAdaptor) List() (*api.NodeList, error) {
ctx := api.NewContext() ctx := api.NewContext()
obj, err := n.storage.(apiserver.RESTLister).List(ctx, labels.Everything(), labels.Everything()) obj, err := n.storage.(apiserver.RESTLister).List(ctx, labels.Everything(), fields.Everything())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -18,6 +18,7 @@ package controller
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -25,7 +26,7 @@ import (
// Registry is an interface for things that know how to store ReplicationControllers. // Registry is an interface for things that know how to store ReplicationControllers.
type Registry interface { type Registry interface {
ListControllers(ctx api.Context) (*api.ReplicationControllerList, error) ListControllers(ctx api.Context) (*api.ReplicationControllerList, error)
WatchControllers(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) WatchControllers(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
GetController(ctx api.Context, controllerID string) (*api.ReplicationController, error) GetController(ctx api.Context, controllerID string) (*api.ReplicationController, error)
CreateController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error) CreateController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error)
UpdateController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error) UpdateController(ctx api.Context, controller *api.ReplicationController) (*api.ReplicationController, error)

View File

@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
rc "github.com/GoogleCloudPlatform/kubernetes/pkg/controller" rc "github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -82,7 +83,7 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
} }
// List obtains a list of ReplicationControllers that match selector. // List obtains a list of ReplicationControllers that match selector.
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
if !field.Empty() { if !field.Empty() {
return nil, fmt.Errorf("field selector not supported yet") return nil, fmt.Errorf("field selector not supported yet")
} }
@ -129,7 +130,7 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, boo
// Watch returns ReplicationController events via a watch.Interface. // Watch returns ReplicationController events via a watch.Interface.
// It implements apiserver.ResourceWatcher. // It implements apiserver.ResourceWatcher.
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchControllers(ctx, label, field, resourceVersion) return rs.registry.WatchControllers(ctx, label, field, resourceVersion)
} }

View File

@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
) )
@ -41,7 +42,7 @@ func TestListControllersError(t *testing.T) {
registry: &mockRegistry, registry: &mockRegistry,
} }
ctx := api.NewContext() ctx := api.NewContext()
controllers, err := storage.List(ctx, labels.Everything(), labels.Everything()) controllers, err := storage.List(ctx, labels.Everything(), fields.Everything())
if err != mockRegistry.Err { if err != mockRegistry.Err {
t.Errorf("Expected %#v, Got %#v", mockRegistry.Err, err) t.Errorf("Expected %#v, Got %#v", mockRegistry.Err, err)
} }
@ -58,7 +59,7 @@ func TestListEmptyControllerList(t *testing.T) {
registry: &mockRegistry, registry: &mockRegistry,
} }
ctx := api.NewContext() ctx := api.NewContext()
controllers, err := storage.List(ctx, labels.Everything(), labels.Everything()) controllers, err := storage.List(ctx, labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@ -92,7 +93,7 @@ func TestListControllerList(t *testing.T) {
registry: &mockRegistry, registry: &mockRegistry,
} }
ctx := api.NewContext() ctx := api.NewContext()
controllersObj, err := storage.List(ctx, labels.Everything(), labels.Everything()) controllersObj, err := storage.List(ctx, labels.Everything(), fields.Everything())
controllers := controllersObj.(*api.ReplicationControllerList) controllers := controllersObj.(*api.ReplicationControllerList)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)

View File

@ -18,6 +18,7 @@ package endpoint
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -26,6 +27,6 @@ import (
type Registry interface { type Registry interface {
ListEndpoints(ctx api.Context) (*api.EndpointsList, error) ListEndpoints(ctx api.Context) (*api.EndpointsList, error)
GetEndpoints(ctx api.Context, name string) (*api.Endpoints, error) GetEndpoints(ctx api.Context, name string) (*api.Endpoints, error)
WatchEndpoints(ctx api.Context, labels, fields labels.Selector, resourceVersion string) (watch.Interface, error) WatchEndpoints(ctx api.Context, labels labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
UpdateEndpoints(ctx api.Context, e *api.Endpoints) error UpdateEndpoints(ctx api.Context, e *api.Endpoints) error
} }

View File

@ -21,6 +21,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -44,7 +45,7 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
} }
// List satisfies the RESTStorage interface. // List satisfies the RESTStorage interface.
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
if !label.Empty() || !field.Empty() { if !label.Empty() || !field.Empty() {
return nil, errors.NewBadRequest("label/field selectors are not supported on endpoints") return nil, errors.NewBadRequest("label/field selectors are not supported on endpoints")
} }
@ -53,7 +54,7 @@ func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Obj
// Watch returns Endpoint events via a watch.Interface. // Watch returns Endpoint events via a watch.Interface.
// It implements apiserver.ResourceWatcher. // It implements apiserver.ResourceWatcher.
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchEndpoints(ctx, label, field, resourceVersion) return rs.registry.WatchEndpoints(ctx, label, field, resourceVersion)
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
) )
@ -81,7 +82,7 @@ func TestEndpointsRegistryList(t *testing.T) {
}, },
} }
ctx := api.NewContext() ctx := api.NewContext()
s, _ := storage.List(ctx, labels.Everything(), labels.Everything()) s, _ := storage.List(ctx, labels.Everything(), fields.Everything())
sl := s.(*api.EndpointsList) sl := s.(*api.EndpointsList)
if len(sl.Items) != 2 { if len(sl.Items) != 2 {
t.Fatalf("Expected 2 endpoints, but got %v", len(sl.Items)) t.Fatalf("Expected 2 endpoints, but got %v", len(sl.Items))

View File

@ -21,6 +21,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd" etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -93,7 +94,7 @@ func (r *Registry) ListControllers(ctx api.Context) (*api.ReplicationControllerL
} }
// WatchControllers begins watching for new, changed, or deleted controllers. // WatchControllers begins watching for new, changed, or deleted controllers.
func (r *Registry) WatchControllers(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *Registry) WatchControllers(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
if !field.Empty() { if !field.Empty() {
return nil, fmt.Errorf("field selectors are not supported on replication controllers") return nil, fmt.Errorf("field selectors are not supported on replication controllers")
} }
@ -284,7 +285,7 @@ func (r *Registry) UpdateService(ctx api.Context, svc *api.Service) (*api.Servic
} }
// WatchServices begins watching for new, changed, or deleted service configurations. // WatchServices begins watching for new, changed, or deleted service configurations.
func (r *Registry) WatchServices(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *Registry) WatchServices(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
version, err := tools.ParseWatchResourceVersion(resourceVersion, "service") version, err := tools.ParseWatchResourceVersion(resourceVersion, "service")
if err != nil { if err != nil {
return nil, err return nil, err
@ -329,7 +330,7 @@ func (r *Registry) UpdateEndpoints(ctx api.Context, endpoints *api.Endpoints) er
} }
// WatchEndpoints begins watching for new, changed, or deleted endpoint configurations. // WatchEndpoints begins watching for new, changed, or deleted endpoint configurations.
func (r *Registry) WatchEndpoints(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *Registry) WatchEndpoints(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
version, err := tools.ParseWatchResourceVersion(resourceVersion, "endpoints") version, err := tools.ParseWatchResourceVersion(resourceVersion, "endpoints")
if err != nil { if err != nil {
return nil, err return nil, err
@ -395,7 +396,7 @@ func (r *Registry) DeleteMinion(ctx api.Context, minionID string) error {
return nil return nil
} }
func (r *Registry) WatchMinions(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *Registry) WatchMinions(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
version, err := tools.ParseWatchResourceVersion(resourceVersion, "node") version, err := tools.ParseWatchResourceVersion(resourceVersion, "node")
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
@ -281,7 +282,7 @@ func TestEtcdWatchController(t *testing.T) {
registry := NewTestEtcdRegistry(fakeClient) registry := NewTestEtcdRegistry(fakeClient)
watching, err := registry.WatchControllers(ctx, watching, err := registry.WatchControllers(ctx,
labels.Everything(), labels.Everything(),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -310,7 +311,7 @@ func TestEtcdWatchControllersMatch(t *testing.T) {
registry := NewTestEtcdRegistryWithPods(fakeClient) registry := NewTestEtcdRegistryWithPods(fakeClient)
watching, err := registry.WatchControllers(ctx, watching, err := registry.WatchControllers(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -351,7 +352,7 @@ func TestEtcdWatchControllersNotMatch(t *testing.T) {
registry := NewTestEtcdRegistryWithPods(fakeClient) registry := NewTestEtcdRegistryWithPods(fakeClient)
watching, err := registry.WatchControllers(ctx, watching, err := registry.WatchControllers(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -678,7 +679,7 @@ func TestEtcdWatchServices(t *testing.T) {
registry := NewTestEtcdRegistry(fakeClient) registry := NewTestEtcdRegistry(fakeClient)
watching, err := registry.WatchServices(ctx, watching, err := registry.WatchServices(ctx,
labels.Everything(), labels.Everything(),
labels.SelectorFromSet(labels.Set{"name": "foo"}), fields.SelectorFromSet(fields.Set{"name": "foo"}),
"1", "1",
) )
if err != nil { if err != nil {
@ -707,7 +708,7 @@ func TestEtcdWatchServicesBadSelector(t *testing.T) {
_, err := registry.WatchServices( _, err := registry.WatchServices(
ctx, ctx,
labels.Everything(), labels.Everything(),
labels.SelectorFromSet(labels.Set{"Field.Selector": "foo"}), fields.SelectorFromSet(fields.Set{"Field.Selector": "foo"}),
"", "",
) )
if err == nil { if err == nil {
@ -717,7 +718,7 @@ func TestEtcdWatchServicesBadSelector(t *testing.T) {
_, err = registry.WatchServices( _, err = registry.WatchServices(
ctx, ctx,
labels.SelectorFromSet(labels.Set{"Label.Selector": "foo"}), labels.SelectorFromSet(labels.Set{"Label.Selector": "foo"}),
labels.Everything(), fields.Everything(),
"", "",
) )
if err == nil { if err == nil {
@ -732,7 +733,7 @@ func TestEtcdWatchEndpoints(t *testing.T) {
watching, err := registry.WatchEndpoints( watching, err := registry.WatchEndpoints(
ctx, ctx,
labels.Everything(), labels.Everything(),
labels.SelectorFromSet(labels.Set{"name": "foo"}), fields.SelectorFromSet(fields.Set{"name": "foo"}),
"1", "1",
) )
if err != nil { if err != nil {
@ -761,7 +762,7 @@ func TestEtcdWatchEndpointsAcrossNamespaces(t *testing.T) {
watching, err := registry.WatchEndpoints( watching, err := registry.WatchEndpoints(
ctx, ctx,
labels.Everything(), labels.Everything(),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -790,7 +791,7 @@ func TestEtcdWatchEndpointsBadSelector(t *testing.T) {
_, err := registry.WatchEndpoints( _, err := registry.WatchEndpoints(
ctx, ctx,
labels.Everything(), labels.Everything(),
labels.SelectorFromSet(labels.Set{"Field.Selector": "foo"}), fields.SelectorFromSet(fields.Set{"Field.Selector": "foo"}),
"", "",
) )
if err == nil { if err == nil {
@ -800,7 +801,7 @@ func TestEtcdWatchEndpointsBadSelector(t *testing.T) {
_, err = registry.WatchEndpoints( _, err = registry.WatchEndpoints(
ctx, ctx,
labels.SelectorFromSet(labels.Set{"Label.Selector": "foo"}), labels.SelectorFromSet(labels.Set{"Label.Selector": "foo"}),
labels.Everything(), fields.Everything(),
"", "",
) )
if err == nil { if err == nil {
@ -925,7 +926,7 @@ func TestEtcdWatchMinion(t *testing.T) {
registry := NewTestEtcdRegistry(fakeClient) registry := NewTestEtcdRegistry(fakeClient)
watching, err := registry.WatchMinions(ctx, watching, err := registry.WatchMinions(ctx,
labels.Everything(), labels.Everything(),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -953,7 +954,7 @@ func TestEtcdWatchMinionsMatch(t *testing.T) {
registry := NewTestEtcdRegistry(fakeClient) registry := NewTestEtcdRegistry(fakeClient)
watching, err := registry.WatchMinions(ctx, watching, err := registry.WatchMinions(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -993,7 +994,7 @@ func TestEtcdWatchMinionsNotMatch(t *testing.T) {
registry := NewTestEtcdRegistry(fakeClient) registry := NewTestEtcdRegistry(fakeClient)
watching, err := registry.WatchMinions(ctx, watching, err := registry.WatchMinions(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -111,13 +112,13 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
return event, err return event, err
} }
func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, err error) { func (rs *REST) getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
event, ok := obj.(*api.Event) event, ok := obj.(*api.Event)
if !ok { if !ok {
return nil, nil, fmt.Errorf("invalid object type") return nil, nil, fmt.Errorf("invalid object type")
} }
// TODO: internal version leaks through here. This should be versioned. // TODO: internal version leaks through here. This should be versioned.
return labels.Set{}, labels.Set{ return labels.Set{}, fields.Set{
"involvedObject.kind": event.InvolvedObject.Kind, "involvedObject.kind": event.InvolvedObject.Kind,
"involvedObject.namespace": event.InvolvedObject.Namespace, "involvedObject.namespace": event.InvolvedObject.Namespace,
"involvedObject.name": event.InvolvedObject.Name, "involvedObject.name": event.InvolvedObject.Name,
@ -130,13 +131,13 @@ func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, e
}, nil }, nil
} }
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}) return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs})
} }
// Watch returns Events events via a watch.Interface. // Watch returns Events events via a watch.Interface.
// It implements apiserver.ResourceWatcher. // It implements apiserver.ResourceWatcher.
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion)
} }

View File

@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -180,7 +181,7 @@ func TestRESTgetAttrs(t *testing.T) {
if e, a := label, (labels.Set{}); !reflect.DeepEqual(e, a) { if e, a := label, (labels.Set{}); !reflect.DeepEqual(e, a) {
t.Errorf("diff: %s", util.ObjectDiff(e, a)) t.Errorf("diff: %s", util.ObjectDiff(e, a))
} }
expect := labels.Set{ expect := fields.Set{
"involvedObject.kind": "Pod", "involvedObject.kind": "Pod",
"involvedObject.name": "foo", "involvedObject.name": "foo",
"involvedObject.namespace": "baz", "involvedObject.namespace": "baz",
@ -237,7 +238,7 @@ func TestRESTList(t *testing.T) {
reg.ObjectList = &api.EventList{ reg.ObjectList = &api.EventList{
Items: []api.Event{*eventA, *eventB, *eventC}, Items: []api.Event{*eventA, *eventB, *eventC},
} }
got, err := rest.List(api.NewContext(), labels.Everything(), labels.Set{"source": "GoodSource"}.AsSelector()) got, err := rest.List(api.NewContext(), labels.Everything(), fields.Set{"source": "GoodSource"}.AsSelector())
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
@ -262,7 +263,7 @@ func TestRESTWatch(t *testing.T) {
Reason: "ForTesting", Reason: "ForTesting",
} }
reg, rest := NewTestREST() reg, rest := NewTestREST()
wi, err := rest.Watch(api.NewContext(), labels.Everything(), labels.Everything(), "0") wi, err := rest.Watch(api.NewContext(), labels.Everything(), fields.Everything(), "0")
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }

View File

@ -23,6 +23,7 @@ import (
kubeerr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" kubeerr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd" etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -72,7 +73,7 @@ type Etcd struct {
TTLFunc func(obj runtime.Object, update bool) (uint64, error) TTLFunc func(obj runtime.Object, update bool) (uint64, error)
// Returns a matcher corresponding to the provided labels and fields. // Returns a matcher corresponding to the provided labels and fields.
PredicateFunc func(label, field labels.Selector) generic.Matcher PredicateFunc func(label labels.Selector, field fields.Selector) generic.Matcher
// Called on all objects returned from the underlying store, after // Called on all objects returned from the underlying store, after
// the exit hooks are invoked. Decorators are intended for integrations // the exit hooks are invoked. Decorators are intended for integrations
@ -134,7 +135,7 @@ func (e *Etcd) NewList() runtime.Object {
} }
// List returns a list of items matching labels and field // List returns a list of items matching labels and field
func (e *Etcd) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (e *Etcd) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return e.ListPredicate(ctx, e.PredicateFunc(label, field)) return e.ListPredicate(ctx, e.PredicateFunc(label, field))
} }
@ -358,7 +359,7 @@ func (e *Etcd) Delete(ctx api.Context, name string) (runtime.Object, error) {
// WatchPredicate starts a watch for the items that m matches. // WatchPredicate starts a watch for the items that m matches.
// TODO: Detect if m references a single object instead of a list. // TODO: Detect if m references a single object instead of a list.
func (e *Etcd) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (e *Etcd) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return e.WatchPredicate(ctx, e.PredicateFunc(label, field), resourceVersion) return e.WatchPredicate(ctx, e.PredicateFunc(label, field), resourceVersion)
} }

View File

@ -18,19 +18,20 @@ package generic
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
// AttrFunc returns label and field sets for List or Watch to compare against, or an error. // AttrFunc returns label and field sets for List or Watch to compare against, or an error.
type AttrFunc func(obj runtime.Object) (label, field labels.Set, err error) type AttrFunc func(obj runtime.Object) (label labels.Set, field fields.Set, err error)
// SelectionPredicate implements a generic predicate that can be passed to // SelectionPredicate implements a generic predicate that can be passed to
// GenericRegistry's List or Watch methods. Implements the Matcher interface. // GenericRegistry's List or Watch methods. Implements the Matcher interface.
type SelectionPredicate struct { type SelectionPredicate struct {
Label labels.Selector Label labels.Selector
Field labels.Selector Field fields.Selector
GetAttrs AttrFunc GetAttrs AttrFunc
} }

View File

@ -21,6 +21,7 @@ import (
"reflect" "reflect"
"testing" "testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
) )
@ -39,7 +40,8 @@ func (*IgnoredList) IsAnAPIObject() {}
func TestSelectionPredicate(t *testing.T) { func TestSelectionPredicate(t *testing.T) {
table := map[string]struct { table := map[string]struct {
labelSelector, fieldSelector string labelSelector, fieldSelector string
labels, fields labels.Set labels labels.Set
fields fields.Set
err error err error
shouldMatch bool shouldMatch bool
}{ }{
@ -47,21 +49,21 @@ func TestSelectionPredicate(t *testing.T) {
labelSelector: "name=foo", labelSelector: "name=foo",
fieldSelector: "uid=12345", fieldSelector: "uid=12345",
labels: labels.Set{"name": "foo"}, labels: labels.Set{"name": "foo"},
fields: labels.Set{"uid": "12345"}, fields: fields.Set{"uid": "12345"},
shouldMatch: true, shouldMatch: true,
}, },
"B": { "B": {
labelSelector: "name=foo", labelSelector: "name=foo",
fieldSelector: "uid=12345", fieldSelector: "uid=12345",
labels: labels.Set{"name": "foo"}, labels: labels.Set{"name": "foo"},
fields: labels.Set{}, fields: fields.Set{},
shouldMatch: false, shouldMatch: false,
}, },
"C": { "C": {
labelSelector: "name=foo", labelSelector: "name=foo",
fieldSelector: "uid=12345", fieldSelector: "uid=12345",
labels: labels.Set{}, labels: labels.Set{},
fields: labels.Set{"uid": "12345"}, fields: fields.Set{"uid": "12345"},
shouldMatch: false, shouldMatch: false,
}, },
"error": { "error": {
@ -77,14 +79,14 @@ func TestSelectionPredicate(t *testing.T) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
parsedField, err := labels.ParseSelector(item.fieldSelector) parsedField, err := fields.ParseSelector(item.fieldSelector)
if err != nil { if err != nil {
panic(err) panic(err)
} }
sp := &SelectionPredicate{ sp := &SelectionPredicate{
Label: parsedLabel, Label: parsedLabel,
Field: parsedField, Field: parsedField,
GetAttrs: func(runtime.Object) (label, field labels.Set, err error) { GetAttrs: func(runtime.Object) (label labels.Set, field fields.Set, err error) {
return item.labels, item.fields, item.err return item.labels, item.fields, item.err
}, },
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -130,15 +131,15 @@ func (rs *REST) Get(ctx api.Context, name string) (runtime.Object, error) {
return limitRange, err return limitRange, err
} }
func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, err error) { func (rs *REST) getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
return labels.Set{}, labels.Set{}, nil return labels.Set{}, fields.Set{}, nil
} }
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}) return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs})
} }
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion)
} }

View File

@ -18,6 +18,7 @@ package minion
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -29,5 +30,5 @@ type Registry interface {
UpdateMinion(ctx api.Context, minion *api.Node) error UpdateMinion(ctx api.Context, minion *api.Node) error
GetMinion(ctx api.Context, minionID string) (*api.Node, error) GetMinion(ctx api.Context, minionID string) (*api.Node, error)
DeleteMinion(ctx api.Context, minionID string) error DeleteMinion(ctx api.Context, minionID string) error
WatchMinions(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) WatchMinions(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
} }

View File

@ -26,6 +26,7 @@ import (
kerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" kerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports" "github.com/GoogleCloudPlatform/kubernetes/pkg/master/ports"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -90,7 +91,7 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
} }
// List satisfies the RESTStorage interface. // List satisfies the RESTStorage interface.
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return rs.registry.ListMinions(ctx) return rs.registry.ListMinions(ctx)
} }
@ -134,7 +135,7 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (runtime.Object, boo
// Watch returns Minions events via a watch.Interface. // Watch returns Minions events via a watch.Interface.
// It implements apiserver.ResourceWatcher. // It implements apiserver.ResourceWatcher.
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchMinions(ctx, label, field, resourceVersion) return rs.registry.WatchMinions(ctx, label, field, resourceVersion)
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
) )
@ -69,7 +70,7 @@ func TestMinionRegistryREST(t *testing.T) {
t.Fatalf("delete returned wrong error") t.Fatalf("delete returned wrong error")
} }
list, err := ms.List(ctx, labels.Everything(), labels.Everything()) list, err := ms.List(ctx, labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Errorf("got error calling List") t.Errorf("got error calling List")
} }

View File

@ -23,6 +23,7 @@ import (
kerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" kerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -104,15 +105,15 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
return namespace, err return namespace, err
} }
func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, err error) { func (rs *REST) getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
return labels.Set{}, labels.Set{}, nil return labels.Set{}, fields.Set{}, nil
} }
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}) return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs})
} }
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion)
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -155,7 +156,7 @@ func TestRESTList(t *testing.T) {
reg.ObjectList = &api.NamespaceList{ reg.ObjectList = &api.NamespaceList{
Items: []api.Namespace{*namespaceA, *namespaceB, *namespaceC}, Items: []api.Namespace{*namespaceA, *namespaceB, *namespaceC},
} }
got, err := rest.List(api.NewContext(), labels.Everything(), labels.Everything()) got, err := rest.List(api.NewContext(), labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
@ -170,7 +171,7 @@ func TestRESTList(t *testing.T) {
func TestRESTWatch(t *testing.T) { func TestRESTWatch(t *testing.T) {
namespaceA := testNamespace("foo") namespaceA := testNamespace("foo")
reg, rest := NewTestREST() reg, rest := NewTestREST()
wi, err := rest.Watch(api.NewContext(), labels.Everything(), labels.Everything(), "0") wi, err := rest.Watch(api.NewContext(), labels.Everything(), fields.Everything(), "0")
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }

View File

@ -24,6 +24,7 @@ import (
etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd" etcderr "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/constraint" "github.com/GoogleCloudPlatform/kubernetes/pkg/constraint"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd" etcdgeneric "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
@ -55,7 +56,7 @@ func NewREST(h tools.EtcdHelper, factory pod.BoundPodFactory) (*REST, *BindingRE
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Pod).Name, nil return obj.(*api.Pod).Name, nil
}, },
PredicateFunc: func(label, field labels.Selector) generic.Matcher { PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
return pod.MatchPod(label, field) return pod.MatchPod(label, field)
}, },
EndpointName: "pods", EndpointName: "pods",
@ -96,12 +97,12 @@ func (r *REST) NewList() runtime.Object {
} }
// List obtains a list of pods with labels that match selector. // List obtains a list of pods with labels that match selector.
func (r *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (r *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return r.store.List(ctx, label, field) return r.store.List(ctx, label, field)
} }
// Watch begins watching for new, changed, or deleted pods. // Watch begins watching for new, changed, or deleted pods.
func (r *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return r.store.Watch(ctx, label, field, resourceVersion) return r.store.Watch(ctx, label, field, resourceVersion)
} }

View File

@ -29,6 +29,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -179,7 +180,7 @@ func TestListError(t *testing.T) {
storage, _, _ := NewREST(helper, nil) storage, _, _ := NewREST(helper, nil)
cache := &fakeCache{} cache := &fakeCache{}
storage = storage.WithPodStatus(cache) storage = storage.WithPodStatus(cache)
pods, err := storage.List(api.NewDefaultContext(), labels.Everything(), labels.Everything()) pods, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
if err != fakeEtcdClient.Err { if err != fakeEtcdClient.Err {
t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err) t.Fatalf("Expected %#v, Got %#v", fakeEtcdClient.Err, err)
} }
@ -208,7 +209,7 @@ func TestListCacheError(t *testing.T) {
cache := &fakeCache{errorToReturn: client.ErrPodInfoNotAvailable} cache := &fakeCache{errorToReturn: client.ErrPodInfoNotAvailable}
storage = storage.WithPodStatus(cache) storage = storage.WithPodStatus(cache)
pods, err := storage.List(api.NewDefaultContext(), labels.Everything(), labels.Everything()) pods, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Fatalf("Expected no error, got %#v", err) t.Fatalf("Expected no error, got %#v", err)
} }
@ -232,7 +233,7 @@ func TestListEmptyPodList(t *testing.T) {
storage, _, _ := NewREST(helper, nil) storage, _, _ := NewREST(helper, nil)
cache := &fakeCache{} cache := &fakeCache{}
storage = storage.WithPodStatus(cache) storage = storage.WithPodStatus(cache)
pods, err := storage.List(api.NewContext(), labels.Everything(), labels.Everything()) pods, err := storage.List(api.NewContext(), labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -271,7 +272,7 @@ func TestListPodList(t *testing.T) {
cache := &fakeCache{statusToReturn: &api.PodStatus{Phase: api.PodRunning}} cache := &fakeCache{statusToReturn: &api.PodStatus{Phase: api.PodRunning}}
storage = storage.WithPodStatus(cache) storage = storage.WithPodStatus(cache)
podsObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), labels.Everything()) podsObj, err := storage.List(api.NewDefaultContext(), labels.Everything(), fields.Everything())
pods := podsObj.(*api.PodList) pods := podsObj.(*api.PodList)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -357,7 +358,7 @@ func TestListPodListSelection(t *testing.T) {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
continue continue
} }
field, err := labels.ParseSelector(item.field) field, err := fields.ParseSelector(item.field)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
continue continue
@ -1451,7 +1452,7 @@ func TestEtcdEmptyList(t *testing.T) {
E: nil, E: nil,
} }
obj, err := registry.List(ctx, labels.Everything(), labels.Everything()) obj, err := registry.List(ctx, labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@ -1469,7 +1470,7 @@ func TestEtcdListNotFound(t *testing.T) {
R: &etcd.Response{}, R: &etcd.Response{},
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
obj, err := registry.List(ctx, labels.Everything(), labels.Everything()) obj, err := registry.List(ctx, labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@ -1504,7 +1505,7 @@ func TestEtcdList(t *testing.T) {
}, },
E: nil, E: nil,
} }
obj, err := registry.List(ctx, labels.Everything(), labels.Everything()) obj, err := registry.List(ctx, labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@ -1524,7 +1525,7 @@ func TestEtcdWatchPods(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := registry.Watch(ctx,
labels.Everything(), labels.Everything(),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -1551,7 +1552,7 @@ func TestEtcdWatchPodsMatch(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := registry.Watch(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {
@ -1590,7 +1591,7 @@ func TestEtcdWatchPodsNotMatch(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := registry.Watch(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
labels.Everything(), fields.Everything(),
"1", "1",
) )
if err != nil { if err != nil {

View File

@ -19,6 +19,7 @@ package pod
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -29,7 +30,7 @@ type Registry interface {
// ListPods obtains a list of pods having labels which match selector. // ListPods obtains a list of pods having labels which match selector.
ListPods(ctx api.Context, selector labels.Selector) (*api.PodList, error) ListPods(ctx api.Context, selector labels.Selector) (*api.PodList, error)
// Watch for new/changed/deleted pods // Watch for new/changed/deleted pods
WatchPods(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) WatchPods(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
// Get a specific pod // Get a specific pod
GetPod(ctx api.Context, podID string) (*api.Pod, error) GetPod(ctx api.Context, podID string) (*api.Pod, error)
// Create a pod based on a specification. // Create a pod based on a specification.
@ -64,14 +65,14 @@ func NewRegistry(s Storage) Registry {
} }
func (s *storage) ListPods(ctx api.Context, label labels.Selector) (*api.PodList, error) { func (s *storage) ListPods(ctx api.Context, label labels.Selector) (*api.PodList, error) {
obj, err := s.List(ctx, label, labels.Everything()) obj, err := s.List(ctx, label, fields.Everything())
if err != nil { if err != nil {
return nil, err return nil, err
} }
return obj.(*api.PodList), nil return obj.(*api.PodList), nil
} }
func (s *storage) WatchPods(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (s *storage) WatchPods(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return s.Watch(ctx, label, field, resourceVersion) return s.Watch(ctx, label, field, resourceVersion)
} }

View File

@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -116,7 +117,7 @@ func PodStatusReset(cache PodStatusGetter) rest.ObjectFunc {
} }
// MatchPod returns a generic matcher for a given label and field selector. // MatchPod returns a generic matcher for a given label and field selector.
func MatchPod(label, field labels.Selector) generic.Matcher { func MatchPod(label labels.Selector, field fields.Selector) generic.Matcher {
return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { return generic.MatcherFunc(func(obj runtime.Object) (bool, error) {
podObj, ok := obj.(*api.Pod) podObj, ok := obj.(*api.Pod)
if !ok { if !ok {

View File

@ -20,6 +20,7 @@ import (
"sync" "sync"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -67,7 +68,7 @@ func (r *ControllerRegistry) DeleteController(ctx api.Context, ID string) error
return r.Err return r.Err
} }
func (r *ControllerRegistry) WatchControllers(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *ControllerRegistry) WatchControllers(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
r.Lock() r.Lock()
defer r.Unlock() defer r.Unlock()
return nil, r.Err return nil, r.Err

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -60,7 +61,7 @@ func (e *EndpointRegistry) GetEndpoints(ctx api.Context, name string) (*api.Endp
return nil, errors.NewNotFound("Endpoints", name) return nil, errors.NewNotFound("Endpoints", name)
} }
func (e *EndpointRegistry) WatchEndpoints(ctx api.Context, labels, fields labels.Selector, resourceVersion string) (watch.Interface, error) { func (e *EndpointRegistry) WatchEndpoints(ctx api.Context, labels labels.Selector, fields fields.Selector, resourceVersion string) (watch.Interface, error) {
return nil, fmt.Errorf("unimplemented!") return nil, fmt.Errorf("unimplemented!")
} }

View File

@ -21,6 +21,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -111,6 +112,6 @@ func (r *MinionRegistry) DeleteMinion(ctx api.Context, minionID string) error {
return r.Err return r.Err
} }
func (r *MinionRegistry) WatchMinions(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *MinionRegistry) WatchMinions(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return nil, r.Err return nil, r.Err
} }

View File

@ -20,6 +20,7 @@ import (
"sync" "sync"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -69,7 +70,7 @@ func (r *PodRegistry) ListPods(ctx api.Context, selector labels.Selector) (*api.
}) })
} }
func (r *PodRegistry) WatchPods(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *PodRegistry) WatchPods(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return r.broadcaster.Watch(), nil return r.broadcaster.Watch(), nil
} }

View File

@ -20,6 +20,7 @@ import (
"sync" "sync"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
) )
@ -107,7 +108,7 @@ func (r *ServiceRegistry) UpdateService(ctx api.Context, svc *api.Service) (*api
return svc, r.Err return svc, r.Err
} }
func (r *ServiceRegistry) WatchServices(ctx api.Context, label labels.Selector, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *ServiceRegistry) WatchServices(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
r.mu.Lock() r.mu.Lock()
defer r.mu.Unlock() defer r.mu.Unlock()
@ -137,7 +138,7 @@ func (r *ServiceRegistry) UpdateEndpoints(ctx api.Context, e *api.Endpoints) err
return r.Err return r.Err
} }
func (r *ServiceRegistry) WatchEndpoints(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (r *ServiceRegistry) WatchEndpoints(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
r.mu.Lock() r.mu.Lock()
defer r.mu.Unlock() defer r.mu.Unlock()

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -133,15 +134,15 @@ func (rs *REST) Get(ctx api.Context, name string) (runtime.Object, error) {
return resourceQuota, err return resourceQuota, err
} }
func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, err error) { func (rs *REST) getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
return labels.Set{}, labels.Set{}, nil return labels.Set{}, fields.Set{}, nil
} }
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}) return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs})
} }
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion)
} }

View File

@ -24,6 +24,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -77,7 +78,7 @@ func TestList(t *testing.T) {
}) })
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
obj, err := rest.List(ctx, labels.Set{}.AsSelector(), labels.Set{}.AsSelector()) obj, err := rest.List(ctx, labels.Set{}.AsSelector(), fields.Set{}.AsSelector())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@ -89,7 +90,7 @@ func TestList(t *testing.T) {
t.Errorf("unexpected list object: %v", obj) t.Errorf("unexpected list object: %v", obj)
} }
obj, err = rest.List(ctx, labels.Set{"foo": "bar"}.AsSelector(), labels.Set{}.AsSelector()) obj, err = rest.List(ctx, labels.Set{"foo": "bar"}.AsSelector(), fields.Set{}.AsSelector())
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -133,22 +134,22 @@ func (rs *REST) Get(ctx api.Context, name string) (runtime.Object, error) {
return secret, err return secret, err
} }
func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, err error) { func (rs *REST) getAttrs(obj runtime.Object) (objLabels labels.Set, objFields fields.Set, err error) {
secret, ok := obj.(*api.Secret) secret, ok := obj.(*api.Secret)
if !ok { if !ok {
return nil, nil, fmt.Errorf("invalid object type") return nil, nil, fmt.Errorf("invalid object type")
} }
return labels.Set{}, labels.Set{ return labels.Set{}, fields.Set{
"type": string(secret.Type), "type": string(secret.Type),
}, nil }, nil
} }
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) { func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}) return rs.registry.ListPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs})
} }
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion) return rs.registry.WatchPredicate(ctx, &generic.SelectionPredicate{label, field, rs.getAttrs}, resourceVersion)
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -163,7 +164,7 @@ func TestRESTgetAttrs(t *testing.T) {
if e, a := label, (labels.Set{}); !reflect.DeepEqual(e, a) { if e, a := label, (labels.Set{}); !reflect.DeepEqual(e, a) {
t.Errorf("diff: %s", util.ObjectDiff(e, a)) t.Errorf("diff: %s", util.ObjectDiff(e, a))
} }
expect := labels.Set{ expect := fields.Set{
"type": string(api.SecretTypeOpaque), "type": string(api.SecretTypeOpaque),
} }
if e, a := expect, field; !reflect.DeepEqual(e, a) { if e, a := expect, field; !reflect.DeepEqual(e, a) {
@ -183,7 +184,7 @@ func TestRESTList(t *testing.T) {
reg.ObjectList = &api.SecretList{ reg.ObjectList = &api.SecretList{
Items: []api.Secret{*secretA, *secretB, *secretC}, Items: []api.Secret{*secretA, *secretB, *secretC},
} }
got, err := rest.List(api.NewContext(), labels.Everything(), labels.Everything()) got, err := rest.List(api.NewContext(), labels.Everything(), fields.Everything())
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
@ -198,7 +199,7 @@ func TestRESTList(t *testing.T) {
func TestRESTWatch(t *testing.T) { func TestRESTWatch(t *testing.T) {
secretA := testSecret("a") secretA := testSecret("a")
reg, rest := NewTestREST() reg, rest := NewTestREST()
wi, err := rest.Watch(api.NewContext(), labels.Everything(), labels.Everything(), "0") wi, err := rest.Watch(api.NewContext(), labels.Everything(), fields.Everything(), "0")
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }

View File

@ -18,6 +18,7 @@ package service
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/endpoint"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
@ -30,7 +31,7 @@ type Registry interface {
GetService(ctx api.Context, name string) (*api.Service, error) GetService(ctx api.Context, name string) (*api.Service, error)
DeleteService(ctx api.Context, name string) error DeleteService(ctx api.Context, name string) error
UpdateService(ctx api.Context, svc *api.Service) (*api.Service, error) UpdateService(ctx api.Context, svc *api.Service) (*api.Service, error)
WatchServices(ctx api.Context, labels, fields labels.Selector, resourceVersion string) (watch.Interface, error) WatchServices(ctx api.Context, labels labels.Selector, fields fields.Selector, resourceVersion string) (watch.Interface, error)
// TODO: endpoints and their implementation should be separated, setting endpoints should be // TODO: endpoints and their implementation should be separated, setting endpoints should be
// supported via the API, and the endpoints-controller should use the API to update endpoints. // supported via the API, and the endpoints-controller should use the API to update endpoints.

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/minion"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
@ -151,8 +152,7 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
return service, err return service, err
} }
// TODO: implement field selector? func (rs *REST) List(ctx api.Context, label labels.Selector, field fields.Selector) (runtime.Object, error) {
func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Object, error) {
list, err := rs.registry.ListServices(ctx) list, err := rs.registry.ListServices(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
@ -169,7 +169,7 @@ func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Obj
// Watch returns Services events via a watch.Interface. // Watch returns Services events via a watch.Interface.
// It implements apiserver.ResourceWatcher. // It implements apiserver.ResourceWatcher.
func (rs *REST) Watch(ctx api.Context, label, field labels.Selector, resourceVersion string) (watch.Interface, error) { func (rs *REST) Watch(ctx api.Context, label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error) {
return rs.registry.WatchServices(ctx, label, field, resourceVersion) return rs.registry.WatchServices(ctx, label, field, resourceVersion)
} }

View File

@ -27,6 +27,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake" cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
) )
@ -421,7 +422,7 @@ func TestServiceRegistryList(t *testing.T) {
}, },
}) })
registry.List.ResourceVersion = "1" registry.List.ResourceVersion = "1"
s, _ := storage.List(ctx, labels.Everything(), labels.Everything()) s, _ := storage.List(ctx, labels.Everything(), fields.Everything())
sl := s.(*api.ServiceList) sl := s.(*api.ServiceList)
if len(fakeCloud.Calls) != 0 { if len(fakeCloud.Calls) != 0 {
t.Errorf("Unexpected call(s): %#v", fakeCloud.Calls) t.Errorf("Unexpected call(s): %#v", fakeCloud.Calls)