diff --git a/examples/apiserver/rest/reststorage.go b/examples/apiserver/rest/reststorage.go index 52de661bf03..15bcc666f96 100644 --- a/examples/apiserver/rest/reststorage.go +++ b/examples/apiserver/rest/reststorage.go @@ -17,6 +17,8 @@ limitations under the License. package rest import ( + "fmt" + "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/test_apis/testgroup.k8s.io" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/fields" @@ -60,7 +62,17 @@ func NewREST(config *storagebackend.Config, storageDecorator generic.StorageDeco }, // Used to match objects based on labels/fields for list. PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(nil) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + testType, ok := obj.(*testgroup.TestType) + if !ok { + return nil, nil, fmt.Errorf("unexpected type of given object") + } + return labels.Set(testType.ObjectMeta.Labels), fields.Set{}, nil + }, + } }, Storage: storageInterface, } diff --git a/federation/registry/cluster/strategy_test.go b/federation/registry/cluster/strategy_test.go index c1ec426d5ba..e7f4487ffd3 100644 --- a/federation/registry/cluster/strategy_test.go +++ b/federation/registry/cluster/strategy_test.go @@ -157,7 +157,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Federation.GroupVersion().String(), "Cluster", - labels.Set(ClusterToSelectableFields(&federation.Cluster{})), + ClusterToSelectableFields(&federation.Cluster{}), nil, ) } diff --git a/pkg/api/testing/conversion.go b/pkg/api/testing/conversion.go index 136d25a37fe..e3360958bda 100644 --- a/pkg/api/testing/conversion.go +++ b/pkg/api/testing/conversion.go @@ -20,14 +20,14 @@ import ( "testing" "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/fields" ) // TestSelectableFieldLabelConversions verifies that given resource have field // label conversion defined for each its selectable field. // fields contains selectable fields of the resource. // labelMap maps deprecated labels to their canonical names. -func TestSelectableFieldLabelConversionsOfKind(t *testing.T, apiVersion string, kind string, fields labels.Set, labelMap map[string]string) { +func TestSelectableFieldLabelConversionsOfKind(t *testing.T, apiVersion string, kind string, fields fields.Set, labelMap map[string]string) { badFieldLabels := []string{ "name", ".name", diff --git a/pkg/registry/certificates/strategy.go b/pkg/registry/certificates/strategy.go index 03e4659aa2d..578e4320193 100644 --- a/pkg/registry/certificates/strategy.go +++ b/pkg/registry/certificates/strategy.go @@ -169,17 +169,20 @@ func (csrApprovalStrategy) ValidateUpdate(ctx api.Context, obj, old runtime.Obje // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*certificates.CertificateSigningRequest) - if !ok { - return false, fmt.Errorf("not a CertificateSigningRequest") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + sa, ok := obj.(*certificates.CertificateSigningRequest) + if !ok { + return nil, nil, fmt.Errorf("not a CertificateSigningRequest") + } + return labels.Set(sa.Labels), SelectableFields(sa), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *certificates.CertificateSigningRequest) labels.Set { - return labels.Set{} +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *certificates.CertificateSigningRequest) fields.Set { + return fields.Set{} } diff --git a/pkg/registry/clusterrole/strategy.go b/pkg/registry/clusterrole/strategy.go index f148a8ca2c5..16ba9e2f6aa 100644 --- a/pkg/registry/clusterrole/strategy.go +++ b/pkg/registry/clusterrole/strategy.go @@ -103,17 +103,20 @@ func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*rbac.ClusterRole) - if !ok { - return false, fmt.Errorf("not a ClusterRole") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + role, ok := obj.(*rbac.ClusterRole) + if !ok { + return nil, nil, fmt.Errorf("not a ClusterRole") + } + return labels.Set(role.Labels), SelectableFields(role), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *rbac.ClusterRole) labels.Set { - return labels.Set{} +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *rbac.ClusterRole) fields.Set { + return fields.Set{} } diff --git a/pkg/registry/clusterrolebinding/strategy.go b/pkg/registry/clusterrolebinding/strategy.go index 78fb2d052a0..8c6778e8ed9 100644 --- a/pkg/registry/clusterrolebinding/strategy.go +++ b/pkg/registry/clusterrolebinding/strategy.go @@ -103,17 +103,20 @@ func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*rbac.ClusterRoleBinding) - if !ok { - return false, fmt.Errorf("not a ClusterRoleBinding") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + roleBinding, ok := obj.(*rbac.ClusterRoleBinding) + if !ok { + return nil, nil, fmt.Errorf("not a ClusterRoleBinding") + } + return labels.Set(roleBinding.Labels), SelectableFields(roleBinding), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *rbac.ClusterRoleBinding) labels.Set { - return labels.Set{} +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *rbac.ClusterRoleBinding) fields.Set { + return fields.Set{} } diff --git a/pkg/registry/configmap/strategy_test.go b/pkg/registry/configmap/strategy_test.go index 0b6d79ab89e..aee36056756 100644 --- a/pkg/registry/configmap/strategy_test.go +++ b/pkg/registry/configmap/strategy_test.go @@ -22,7 +22,6 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" - "k8s.io/kubernetes/pkg/labels" ) func TestConfigMapStrategy(t *testing.T) { @@ -74,7 +73,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "ConfigMap", - labels.Set(ConfigMapToSelectableFields(&api.ConfigMap{})), + ConfigMapToSelectableFields(&api.ConfigMap{}), nil, ) } diff --git a/pkg/registry/controller/strategy_test.go b/pkg/registry/controller/strategy_test.go index ac09ca2e40d..192221c9395 100644 --- a/pkg/registry/controller/strategy_test.go +++ b/pkg/registry/controller/strategy_test.go @@ -22,7 +22,6 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" - "k8s.io/kubernetes/pkg/labels" ) func TestControllerStrategy(t *testing.T) { @@ -146,7 +145,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "ReplicationController", - labels.Set(ControllerToSelectableFields(&api.ReplicationController{})), + ControllerToSelectableFields(&api.ReplicationController{}), nil, ) } diff --git a/pkg/registry/daemonset/strategy_test.go b/pkg/registry/daemonset/strategy_test.go index 00f8a2b1688..306eccd307a 100644 --- a/pkg/registry/daemonset/strategy_test.go +++ b/pkg/registry/daemonset/strategy_test.go @@ -23,14 +23,13 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/labels" ) func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Extensions.GroupVersion().String(), "DaemonSet", - labels.Set(DaemonSetToSelectableFields(&extensions.DaemonSet{})), + DaemonSetToSelectableFields(&extensions.DaemonSet{}), nil, ) } diff --git a/pkg/registry/deployment/strategy_test.go b/pkg/registry/deployment/strategy_test.go index e7575276b63..6e07902e56a 100644 --- a/pkg/registry/deployment/strategy_test.go +++ b/pkg/registry/deployment/strategy_test.go @@ -24,7 +24,6 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" ) @@ -32,7 +31,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Extensions.GroupVersion().String(), "Deployment", - labels.Set(DeploymentToSelectableFields(&extensions.Deployment{})), + DeploymentToSelectableFields(&extensions.Deployment{}), nil, ) } diff --git a/pkg/registry/endpoint/strategy_test.go b/pkg/registry/endpoint/strategy_test.go index 0a4cd87b8be..58d3a249ed0 100644 --- a/pkg/registry/endpoint/strategy_test.go +++ b/pkg/registry/endpoint/strategy_test.go @@ -22,7 +22,6 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" - "k8s.io/kubernetes/pkg/labels" ) func TestSelectableFieldLabelConversions(t *testing.T) { @@ -33,7 +32,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "Endpoints", - labels.Set(fieldsSet), + fieldsSet, nil, ) } diff --git a/pkg/registry/event/strategy_test.go b/pkg/registry/event/strategy_test.go index ca95a7a90f3..45b6c08fa87 100644 --- a/pkg/registry/event/strategy_test.go +++ b/pkg/registry/event/strategy_test.go @@ -94,7 +94,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "Event", - labels.Set(fset), + fset, nil, ) } diff --git a/pkg/registry/generic/matcher.go b/pkg/registry/generic/matcher.go index 3c1b7ecaaeb..c393dfca7af 100644 --- a/pkg/registry/generic/matcher.go +++ b/pkg/registry/generic/matcher.go @@ -115,50 +115,7 @@ type Matcher interface { MatcherIndex() []storage.MatchValue } -// MatcherFunc makes a matcher from the provided function. For easy definition -// of matchers for testing. Note: use SelectionPredicate above for real code! -func MatcherFunc(f func(obj runtime.Object) (bool, error)) Matcher { - return matcherFunc(f) -} - -type matcherFunc func(obj runtime.Object) (bool, error) - -// Matches calls the embedded function. -func (m matcherFunc) Matches(obj runtime.Object) (bool, error) { - return m(obj) -} - -// MatchesSingle always returns "", false-- because this is a predicate -// implementation of Matcher. -func (m matcherFunc) MatchesSingle() (string, bool) { - return "", false -} - -// MatcherIndex always returns empty list. -func (m matcherFunc) MatcherIndex() []storage.MatchValue { - return nil -} - -// MatchOnKey returns a matcher that will send only the object matching key -// through the matching function f. For testing! -// Note: use SelectionPredicate above for real code! -func MatchOnKey(key string, f func(obj runtime.Object) (bool, error)) Matcher { - return matchKey{key, f} -} - -type matchKey struct { - key string - matcherFunc -} - -// MatchesSingle always returns its key, true. -func (m matchKey) MatchesSingle() (string, bool) { - return m.key, true -} - var ( // Assert implementations match the interface. - _ = Matcher(matchKey{}) _ = Matcher(&SelectionPredicate{}) - _ = Matcher(matcherFunc(nil)) ) diff --git a/pkg/registry/generic/matcher_test.go b/pkg/registry/generic/matcher_test.go index 80f57a161f4..ebcab4ee2f3 100644 --- a/pkg/registry/generic/matcher_test.go +++ b/pkg/registry/generic/matcher_test.go @@ -117,14 +117,3 @@ func TestSelectionPredicate(t *testing.T) { } } } - -func TestSingleMatch(t *testing.T) { - m := MatchOnKey("pod-name-here", func(obj runtime.Object) (bool, error) { return true, nil }) - got, ok := m.MatchesSingle() - if !ok { - t.Errorf("Expected MatchesSingle to return true") - } - if e, a := "pod-name-here", got; e != a { - t.Errorf("Expected %#v, got %#v", e, a) - } -} diff --git a/pkg/registry/horizontalpodautoscaler/strategy_test.go b/pkg/registry/horizontalpodautoscaler/strategy_test.go index 12f38da1b6e..f5df8fa211b 100644 --- a/pkg/registry/horizontalpodautoscaler/strategy_test.go +++ b/pkg/registry/horizontalpodautoscaler/strategy_test.go @@ -23,14 +23,13 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/apis/autoscaling" - "k8s.io/kubernetes/pkg/labels" ) func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Autoscaling.GroupVersion().String(), "Autoscaler", - labels.Set(AutoscalerToSelectableFields(&autoscaling.HorizontalPodAutoscaler{})), + AutoscalerToSelectableFields(&autoscaling.HorizontalPodAutoscaler{}), nil, ) } diff --git a/pkg/registry/ingress/strategy_test.go b/pkg/registry/ingress/strategy_test.go index b345bc06d7a..cc2494541f4 100644 --- a/pkg/registry/ingress/strategy_test.go +++ b/pkg/registry/ingress/strategy_test.go @@ -23,7 +23,6 @@ import ( "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/util/intstr" ) @@ -136,7 +135,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Extensions.GroupVersion().String(), "Ingress", - labels.Set(IngressToSelectableFields(&extensions.Ingress{})), + IngressToSelectableFields(&extensions.Ingress{}), nil, ) } diff --git a/pkg/registry/job/strategy_test.go b/pkg/registry/job/strategy_test.go index 638e5e63efa..8d52c30c29c 100644 --- a/pkg/registry/job/strategy_test.go +++ b/pkg/registry/job/strategy_test.go @@ -25,7 +25,6 @@ import ( apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apis/batch" - "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/types" ) @@ -226,7 +225,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Extensions.GroupVersion().String(), "Job", - labels.Set(JobToSelectableFields(&batch.Job{})), + JobToSelectableFields(&batch.Job{}), nil, ) } diff --git a/pkg/registry/limitrange/strategy_test.go b/pkg/registry/limitrange/strategy_test.go index 4c9a8465e7c..df26a551c7f 100644 --- a/pkg/registry/limitrange/strategy_test.go +++ b/pkg/registry/limitrange/strategy_test.go @@ -22,14 +22,13 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" - "k8s.io/kubernetes/pkg/labels" ) func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "LimitRange", - labels.Set(LimitRangeToSelectableFields(&api.LimitRange{})), + LimitRangeToSelectableFields(&api.LimitRange{}), nil, ) } diff --git a/pkg/registry/namespace/strategy.go b/pkg/registry/namespace/strategy.go index bb71d2056a2..39b7aab1839 100644 --- a/pkg/registry/namespace/strategy.go +++ b/pkg/registry/namespace/strategy.go @@ -136,23 +136,26 @@ func (namespaceFinalizeStrategy) PrepareForUpdate(ctx api.Context, obj, old runt // MatchNamespace returns a generic matcher for a given label and field selector. func MatchNamespace(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - namespaceObj, ok := obj.(*api.Namespace) - if !ok { - return false, fmt.Errorf("not a namespace") - } - fields := NamespaceToSelectableFields(namespaceObj) - return label.Matches(labels.Set(namespaceObj.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + namespaceObj, ok := obj.(*api.Namespace) + if !ok { + return nil, nil, fmt.Errorf("not a namespace") + } + return labels.Set(namespaceObj.Labels), NamespaceToSelectableFields(namespaceObj), nil + }, + } } -// NamespaceToSelectableFields returns a label set that represents the object -func NamespaceToSelectableFields(namespace *api.Namespace) labels.Set { +// NamespaceToSelectableFields returns a field set that represents the object +func NamespaceToSelectableFields(namespace *api.Namespace) fields.Set { objectMetaFieldsSet := generic.ObjectMetaFieldsSet(namespace.ObjectMeta, false) specificFieldsSet := fields.Set{ "status.phase": string(namespace.Status.Phase), // This is a bug, but we need to support it for backward compatibility. "name": namespace.Name, } - return labels.Set(generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet)) + return generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet) } diff --git a/pkg/registry/node/strategy_test.go b/pkg/registry/node/strategy_test.go index 18757f5b461..ea51666a210 100644 --- a/pkg/registry/node/strategy_test.go +++ b/pkg/registry/node/strategy_test.go @@ -51,7 +51,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "Node", - labels.Set(NodeToSelectableFields(&api.Node{})), + NodeToSelectableFields(&api.Node{}), nil, ) } diff --git a/pkg/registry/persistentvolume/strategy.go b/pkg/registry/persistentvolume/strategy.go index b8e542c3c21..5d988d45f7c 100644 --- a/pkg/registry/persistentvolume/strategy.go +++ b/pkg/registry/persistentvolume/strategy.go @@ -96,22 +96,25 @@ func (persistentvolumeStatusStrategy) ValidateUpdate(ctx api.Context, obj, old r // MatchPersistentVolume returns a generic matcher for a given label and field selector. func MatchPersistentVolumes(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - persistentvolumeObj, ok := obj.(*api.PersistentVolume) - if !ok { - return false, fmt.Errorf("not a persistentvolume") - } - fields := PersistentVolumeToSelectableFields(persistentvolumeObj) - return label.Matches(labels.Set(persistentvolumeObj.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + persistentvolumeObj, ok := obj.(*api.PersistentVolume) + if !ok { + return nil, nil, fmt.Errorf("not a persistentvolume") + } + return labels.Set(persistentvolumeObj.Labels), PersistentVolumeToSelectableFields(persistentvolumeObj), nil + }, + } } -// PersistentVolumeToSelectableFields returns a label set that represents the object -func PersistentVolumeToSelectableFields(persistentvolume *api.PersistentVolume) labels.Set { +// PersistentVolumeToSelectableFields returns a field set that represents the object +func PersistentVolumeToSelectableFields(persistentvolume *api.PersistentVolume) fields.Set { objectMetaFieldsSet := generic.ObjectMetaFieldsSet(persistentvolume.ObjectMeta, false) specificFieldsSet := fields.Set{ // This is a bug, but we need to support it for backward compatibility. "name": persistentvolume.Name, } - return labels.Set(generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet)) + return generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet) } diff --git a/pkg/registry/persistentvolumeclaim/strategy.go b/pkg/registry/persistentvolumeclaim/strategy.go index 0d88db9361c..c7e2b05480c 100644 --- a/pkg/registry/persistentvolumeclaim/strategy.go +++ b/pkg/registry/persistentvolumeclaim/strategy.go @@ -96,22 +96,25 @@ func (persistentvolumeclaimStatusStrategy) ValidateUpdate(ctx api.Context, obj, // MatchPersistentVolumeClaim returns a generic matcher for a given label and field selector. func MatchPersistentVolumeClaim(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - persistentvolumeclaimObj, ok := obj.(*api.PersistentVolumeClaim) - if !ok { - return false, fmt.Errorf("not a persistentvolumeclaim") - } - fields := PersistentVolumeClaimToSelectableFields(persistentvolumeclaimObj) - return label.Matches(labels.Set(persistentvolumeclaimObj.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + persistentvolumeclaimObj, ok := obj.(*api.PersistentVolumeClaim) + if !ok { + return nil, nil, fmt.Errorf("not a persistentvolumeclaim") + } + return labels.Set(persistentvolumeclaimObj.Labels), PersistentVolumeClaimToSelectableFields(persistentvolumeclaimObj), nil + }, + } } -// PersistentVolumeClaimToSelectableFields returns a label set that represents the object -func PersistentVolumeClaimToSelectableFields(persistentvolumeclaim *api.PersistentVolumeClaim) labels.Set { +// PersistentVolumeClaimToSelectableFields returns a field set that represents the object +func PersistentVolumeClaimToSelectableFields(persistentvolumeclaim *api.PersistentVolumeClaim) fields.Set { objectMetaFieldsSet := generic.ObjectMetaFieldsSet(persistentvolumeclaim.ObjectMeta, true) specificFieldsSet := fields.Set{ // This is a bug, but we need to support it for backward compatibility. "name": persistentvolumeclaim.Name, } - return labels.Set(generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet)) + return generic.MergeFieldsSets(objectMetaFieldsSet, specificFieldsSet) } diff --git a/pkg/registry/pod/strategy_test.go b/pkg/registry/pod/strategy_test.go index c0c42f6d6d0..d76f31af138 100644 --- a/pkg/registry/pod/strategy_test.go +++ b/pkg/registry/pod/strategy_test.go @@ -252,7 +252,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "Pod", - labels.Set(PodToSelectableFields(&api.Pod{})), + PodToSelectableFields(&api.Pod{}), nil, ) } diff --git a/pkg/registry/podtemplate/strategy_test.go b/pkg/registry/podtemplate/strategy_test.go index 5622310e775..6e8b99b9709 100644 --- a/pkg/registry/podtemplate/strategy_test.go +++ b/pkg/registry/podtemplate/strategy_test.go @@ -22,14 +22,13 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" - "k8s.io/kubernetes/pkg/labels" ) func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "PodTemplate", - labels.Set(PodTemplateToSelectableFields(&api.PodTemplate{})), + PodTemplateToSelectableFields(&api.PodTemplate{}), nil, ) } diff --git a/pkg/registry/resourcequota/strategy.go b/pkg/registry/resourcequota/strategy.go index 6b467bbd84f..f8f7f0d4bf4 100644 --- a/pkg/registry/resourcequota/strategy.go +++ b/pkg/registry/resourcequota/strategy.go @@ -99,17 +99,20 @@ func (resourcequotaStatusStrategy) ValidateUpdate(ctx api.Context, obj, old runt // MatchResourceQuota returns a generic matcher for a given label and field selector. func MatchResourceQuota(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - resourcequotaObj, ok := obj.(*api.ResourceQuota) - if !ok { - return false, fmt.Errorf("not a resourcequota") - } - fields := ResourceQuotaToSelectableFields(resourcequotaObj) - return label.Matches(labels.Set(resourcequotaObj.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + resourcequotaObj, ok := obj.(*api.ResourceQuota) + if !ok { + return nil, nil, fmt.Errorf("not a resourcequota") + } + return labels.Set(resourcequotaObj.Labels), ResourceQuotaToSelectableFields(resourcequotaObj), nil + }, + } } -// ResourceQuotaToSelectableFields returns a label set that represents the object -func ResourceQuotaToSelectableFields(resourcequota *api.ResourceQuota) labels.Set { - return labels.Set(generic.ObjectMetaFieldsSet(resourcequota.ObjectMeta, true)) +// ResourceQuotaToSelectableFields returns a field set that represents the object +func ResourceQuotaToSelectableFields(resourcequota *api.ResourceQuota) fields.Set { + return generic.ObjectMetaFieldsSet(resourcequota.ObjectMeta, true) } diff --git a/pkg/registry/role/strategy.go b/pkg/registry/role/strategy.go index e15a0ad5d5e..b5a20e214e6 100644 --- a/pkg/registry/role/strategy.go +++ b/pkg/registry/role/strategy.go @@ -103,17 +103,20 @@ func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*rbac.Role) - if !ok { - return false, fmt.Errorf("not a Role") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + role, ok := obj.(*rbac.Role) + if !ok { + return nil, nil, fmt.Errorf("not a Role") + } + return labels.Set(role.Labels), SelectableFields(role), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *rbac.Role) labels.Set { - return labels.Set{} +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *rbac.Role) fields.Set { + return fields.Set{} } diff --git a/pkg/registry/rolebinding/strategy.go b/pkg/registry/rolebinding/strategy.go index 7c438900500..ac0c2d6860e 100644 --- a/pkg/registry/rolebinding/strategy.go +++ b/pkg/registry/rolebinding/strategy.go @@ -103,17 +103,20 @@ func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*rbac.RoleBinding) - if !ok { - return false, fmt.Errorf("not a RoleBinding") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + roleBinding, ok := obj.(*rbac.RoleBinding) + if !ok { + return nil, nil, fmt.Errorf("not a RoleBinding") + } + return labels.Set(roleBinding.Labels), SelectableFields(roleBinding), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *rbac.RoleBinding) labels.Set { - return labels.Set{} +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *rbac.RoleBinding) fields.Set { + return fields.Set{} } diff --git a/pkg/registry/scheduledjob/strategy_test.go b/pkg/registry/scheduledjob/strategy_test.go index 35fa05667bf..8ef27c402df 100644 --- a/pkg/registry/scheduledjob/strategy_test.go +++ b/pkg/registry/scheduledjob/strategy_test.go @@ -23,7 +23,6 @@ import ( apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/apis/batch" - "k8s.io/kubernetes/pkg/labels" ) func newBool(a bool) *bool { @@ -168,7 +167,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, "batch/v2alpha1", "ScheduledJob", - labels.Set(ScheduledJobToSelectableFields(&batch.ScheduledJob{})), + ScheduledJobToSelectableFields(&batch.ScheduledJob{}), nil, ) } diff --git a/pkg/registry/secret/strategy.go b/pkg/registry/secret/strategy.go index 2101e3b511d..d33aad3f444 100644 --- a/pkg/registry/secret/strategy.go +++ b/pkg/registry/secret/strategy.go @@ -95,21 +95,24 @@ func (s strategy) Export(ctx api.Context, obj runtime.Object, exact bool) error // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*api.Secret) - if !ok { - return false, fmt.Errorf("not a secret") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + secret, ok := obj.(*api.Secret) + if !ok { + return nil, nil, fmt.Errorf("not a secret") + } + return labels.Set(secret.Labels), SelectableFields(secret), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *api.Secret) labels.Set { +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *api.Secret) fields.Set { objectMetaFieldsSet := generic.ObjectMetaFieldsSet(obj.ObjectMeta, true) secretSpecificFieldsSet := fields.Set{ "type": string(obj.Type), } - return labels.Set(generic.MergeFieldsSets(objectMetaFieldsSet, secretSpecificFieldsSet)) + return generic.MergeFieldsSets(objectMetaFieldsSet, secretSpecificFieldsSet) } diff --git a/pkg/registry/service/strategy_test.go b/pkg/registry/service/strategy_test.go index c349309726c..df03927c87b 100644 --- a/pkg/registry/service/strategy_test.go +++ b/pkg/registry/service/strategy_test.go @@ -25,7 +25,6 @@ import ( "k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" - "k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/intstr" ) @@ -216,7 +215,7 @@ func TestSelectableFieldLabelConversions(t *testing.T) { apitesting.TestSelectableFieldLabelConversionsOfKind(t, testapi.Default.GroupVersion().String(), "Service", - labels.Set(ServiceToSelectableFields(&api.Service{})), + ServiceToSelectableFields(&api.Service{}), nil, ) } diff --git a/pkg/registry/serviceaccount/strategy.go b/pkg/registry/serviceaccount/strategy.go index c0f9cd4bb77..70452b2b306 100644 --- a/pkg/registry/serviceaccount/strategy.go +++ b/pkg/registry/serviceaccount/strategy.go @@ -78,17 +78,20 @@ func (strategy) AllowUnconditionalUpdate() bool { // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*api.ServiceAccount) - if !ok { - return false, fmt.Errorf("not a serviceaccount") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + sa, ok := obj.(*api.ServiceAccount) + if !ok { + return nil, nil, fmt.Errorf("not a serviceaccount") + } + return labels.Set(sa.Labels), SelectableFields(sa), nil + }, + } } -// SelectableFields returns a label set that represents the object -func SelectableFields(obj *api.ServiceAccount) labels.Set { - return labels.Set(generic.ObjectMetaFieldsSet(obj.ObjectMeta, true)) +// SelectableFields returns a field set that represents the object +func SelectableFields(obj *api.ServiceAccount) fields.Set { + return generic.ObjectMetaFieldsSet(obj.ObjectMeta, true) } diff --git a/pkg/registry/thirdpartyresource/strategy.go b/pkg/registry/thirdpartyresource/strategy.go index 10162c6a25f..4a09d9288f6 100644 --- a/pkg/registry/thirdpartyresource/strategy.go +++ b/pkg/registry/thirdpartyresource/strategy.go @@ -79,17 +79,20 @@ func (strategy) AllowUnconditionalUpdate() bool { // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*extensions.ThirdPartyResource) - if !ok { - return false, fmt.Errorf("not a ThirdPartyResource") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + tpr, ok := obj.(*extensions.ThirdPartyResource) + if !ok { + return nil, nil, fmt.Errorf("not a ThirdPartyResource") + } + return labels.Set(tpr.Labels), SelectableFields(tpr), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *extensions.ThirdPartyResource) labels.Set { - return labels.Set{} +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *extensions.ThirdPartyResource) fields.Set { + return fields.Set{} } diff --git a/pkg/registry/thirdpartyresourcedata/strategy.go b/pkg/registry/thirdpartyresourcedata/strategy.go index f4afad0a996..0bcfbb4a028 100644 --- a/pkg/registry/thirdpartyresourcedata/strategy.go +++ b/pkg/registry/thirdpartyresourcedata/strategy.go @@ -76,17 +76,20 @@ func (strategy) AllowUnconditionalUpdate() bool { // Matcher returns a generic matcher for a given label and field selector. func Matcher(label labels.Selector, field fields.Selector) generic.Matcher { - return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { - sa, ok := obj.(*extensions.ThirdPartyResourceData) - if !ok { - return false, fmt.Errorf("not a ThirdPartyResourceData") - } - fields := SelectableFields(sa) - return label.Matches(labels.Set(sa.Labels)) && field.Matches(fields), nil - }) + return &generic.SelectionPredicate{ + Label: label, + Field: field, + GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) { + tprd, ok := obj.(*extensions.ThirdPartyResourceData) + if !ok { + return nil, nil, fmt.Errorf("not a ThirdPartyResourceData") + } + return labels.Set(tprd.Labels), SelectableFields(tprd), nil + }, + } } -// SelectableFields returns a label set that can be used for filter selection -func SelectableFields(obj *extensions.ThirdPartyResourceData) labels.Set { - return labels.Set{} +// SelectableFields returns a field set that can be used for filter selection +func SelectableFields(obj *extensions.ThirdPartyResourceData) fields.Set { + return fields.Set{} }