/* Copyright 2016 The Kubernetes Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package storage import ( "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" ) // AttrFunc returns label and field sets for List or Watch to match. // In any failure to parse given object, it returns error. type AttrFunc func(obj runtime.Object) (labels.Set, fields.Set, error) // SelectionPredicate is used to represent the way to select objects from api storage. type SelectionPredicate struct { Label labels.Selector Field fields.Selector GetAttrs AttrFunc IndexFields []string } // Matches returns true if the given object's labels and fields (as // returned by s.GetAttrs) match s.Label and s.Field. An error is // returned if s.GetAttrs fails. func (s *SelectionPredicate) Matches(obj runtime.Object) (bool, error) { if s.Label.Empty() && s.Field.Empty() { return true, nil } labels, fields, err := s.GetAttrs(obj) if err != nil { return false, err } matched := s.Label.Matches(labels) if matched && s.Field != nil { matched = (matched && s.Field.Matches(fields)) } return matched, nil } // MatchesLabelsAndFields returns true if the given labels and fields // match s.Label and s.Field. func (s *SelectionPredicate) MatchesLabelsAndFields(l labels.Set, f fields.Set) bool { if s.Label.Empty() && s.Field.Empty() { return true } matched := s.Label.Matches(l) if matched && s.Field != nil { matched = (matched && s.Field.Matches(f)) } return matched } // MatchesSingle will return (name, true) if and only if s.Field matches on the object's // name. func (s *SelectionPredicate) MatchesSingle() (string, bool) { // TODO: should be namespace.name if name, ok := s.Field.RequiresExactMatch("metadata.name"); ok { return name, true } return "", false } // For any index defined by IndexFields, if a matcher can match only (a subset) // of objects that return for a given index, a pair (, ) // wil be returned. // TODO: Consider supporting also labels. func (s *SelectionPredicate) MatcherIndex() []MatchValue { var result []MatchValue for _, field := range s.IndexFields { if value, ok := s.Field.RequiresExactMatch(field); ok { result = append(result, MatchValue{IndexName: field, Value: value}) } } return result }