mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
add RequiresExactMatch for label.Selector
Signed-off-by: shaloulcy <lcy041536@gmail.com>
This commit is contained in:
parent
36acfecd4b
commit
5a23bffd42
@ -54,6 +54,11 @@ type Selector interface {
|
|||||||
|
|
||||||
// Make a deep copy of the selector.
|
// Make a deep copy of the selector.
|
||||||
DeepCopySelector() Selector
|
DeepCopySelector() Selector
|
||||||
|
|
||||||
|
// RequiresExactMatch allows a caller to introspect whether a given selector
|
||||||
|
// requires a single specific label to be set, and if so returns the value it
|
||||||
|
// requires.
|
||||||
|
RequiresExactMatch(label string) (value string, found bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything returns a selector that matches all labels.
|
// Everything returns a selector that matches all labels.
|
||||||
@ -63,12 +68,13 @@ func Everything() Selector {
|
|||||||
|
|
||||||
type nothingSelector struct{}
|
type nothingSelector struct{}
|
||||||
|
|
||||||
func (n nothingSelector) Matches(_ Labels) bool { return false }
|
func (n nothingSelector) Matches(_ Labels) bool { return false }
|
||||||
func (n nothingSelector) Empty() bool { return false }
|
func (n nothingSelector) Empty() bool { return false }
|
||||||
func (n nothingSelector) String() string { return "" }
|
func (n nothingSelector) String() string { return "" }
|
||||||
func (n nothingSelector) Add(_ ...Requirement) Selector { return n }
|
func (n nothingSelector) Add(_ ...Requirement) Selector { return n }
|
||||||
func (n nothingSelector) Requirements() (Requirements, bool) { return nil, false }
|
func (n nothingSelector) Requirements() (Requirements, bool) { return nil, false }
|
||||||
func (n nothingSelector) DeepCopySelector() Selector { return n }
|
func (n nothingSelector) DeepCopySelector() Selector { return n }
|
||||||
|
func (n nothingSelector) RequiresExactMatch(label string) (value string, found bool) { return "", false }
|
||||||
|
|
||||||
// Nothing returns a selector that matches no labels
|
// Nothing returns a selector that matches no labels
|
||||||
func Nothing() Selector {
|
func Nothing() Selector {
|
||||||
@ -358,6 +364,23 @@ func (lsel internalSelector) String() string {
|
|||||||
return strings.Join(reqs, ",")
|
return strings.Join(reqs, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RequiresExactMatch introspect whether a given selector requires a single specific field
|
||||||
|
// to be set, and if so returns the value it requires.
|
||||||
|
func (lsel internalSelector) RequiresExactMatch(label string) (value string, found bool) {
|
||||||
|
for ix := range lsel {
|
||||||
|
if lsel[ix].key == label {
|
||||||
|
switch lsel[ix].operator {
|
||||||
|
case selection.Equals, selection.DoubleEquals, selection.In:
|
||||||
|
if len(lsel[ix].strValues) == 1 {
|
||||||
|
return lsel[ix].strValues[0], true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
// Token represents constant definition for lexer token
|
// Token represents constant definition for lexer token
|
||||||
type Token int
|
type Token int
|
||||||
|
|
||||||
|
@ -630,3 +630,81 @@ func BenchmarkSelectorFromValidatedSet(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRequiresExactMatch(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
sel Selector
|
||||||
|
label string
|
||||||
|
expectedFound bool
|
||||||
|
expectedValue string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "keyInOperatorExactMatch",
|
||||||
|
sel: internalSelector{Requirement{"key", selection.In, []string{"value"}}},
|
||||||
|
label: "key",
|
||||||
|
expectedFound: true,
|
||||||
|
expectedValue: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keyInOperatorNotExactMatch",
|
||||||
|
sel: internalSelector{Requirement{"key", selection.In, []string{"value", "value2"}}},
|
||||||
|
label: "key",
|
||||||
|
expectedFound: false,
|
||||||
|
expectedValue: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keyInOperatorNotExactMatch",
|
||||||
|
sel: internalSelector{
|
||||||
|
Requirement{"key", selection.In, []string{"value", "value1"}},
|
||||||
|
Requirement{"key2", selection.In, []string{"value2"}},
|
||||||
|
},
|
||||||
|
label: "key2",
|
||||||
|
expectedFound: true,
|
||||||
|
expectedValue: "value2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keyEqualOperatorExactMatch",
|
||||||
|
sel: internalSelector{Requirement{"key", selection.Equals, []string{"value"}}},
|
||||||
|
label: "key",
|
||||||
|
expectedFound: true,
|
||||||
|
expectedValue: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keyDoubleEqualOperatorExactMatch",
|
||||||
|
sel: internalSelector{Requirement{"key", selection.DoubleEquals, []string{"value"}}},
|
||||||
|
label: "key",
|
||||||
|
expectedFound: true,
|
||||||
|
expectedValue: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keyNotEqualOperatorExactMatch",
|
||||||
|
sel: internalSelector{Requirement{"key", selection.NotEquals, []string{"value"}}},
|
||||||
|
label: "key",
|
||||||
|
expectedFound: false,
|
||||||
|
expectedValue: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keyEqualOperatorExactMatchFirst",
|
||||||
|
sel: internalSelector{
|
||||||
|
Requirement{"key", selection.In, []string{"value"}},
|
||||||
|
Requirement{"key2", selection.In, []string{"value2"}},
|
||||||
|
},
|
||||||
|
label: "key",
|
||||||
|
expectedFound: true,
|
||||||
|
expectedValue: "value",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, ts := range testCases {
|
||||||
|
t.Run(ts.name, func(t *testing.T) {
|
||||||
|
value, found := ts.sel.RequiresExactMatch(ts.label)
|
||||||
|
if found != ts.expectedFound {
|
||||||
|
t.Errorf("Expected match %v, found %v", ts.expectedFound, found)
|
||||||
|
}
|
||||||
|
if found && value != ts.expectedValue {
|
||||||
|
t.Errorf("Expected value %v, found %v", ts.expectedValue, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user