Merge pull request #24733 from kargakis/rc-rs-conversions
Automatic merge from submit-queue Custom conversions between RCs/RSs Needed for building storages that still need to work with RCs but also want to facilitate RSs. cc: @deads2k @smarterclayton @liggitt
This commit is contained in:
@@ -64,6 +64,35 @@ func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// LabelSelectorAsMap converts the LabelSelector api type into a map of strings, ie. the
|
||||
// original structure of a label selector. Operators that cannot be converted into plain
|
||||
// labels (Exists, DoesNotExist, NotIn, and In with more than one value) will result in
|
||||
// an error.
|
||||
func LabelSelectorAsMap(ps *LabelSelector) (map[string]string, error) {
|
||||
if ps == nil {
|
||||
return nil, nil
|
||||
}
|
||||
selector := map[string]string{}
|
||||
for k, v := range ps.MatchLabels {
|
||||
selector[k] = v
|
||||
}
|
||||
for _, expr := range ps.MatchExpressions {
|
||||
switch expr.Operator {
|
||||
case LabelSelectorOpIn:
|
||||
if len(expr.Values) != 1 {
|
||||
return selector, fmt.Errorf("operator %q without a single value cannot be converted into the old label selector format", expr.Operator)
|
||||
}
|
||||
// Should we do anything in case this will override a previous key-value pair?
|
||||
selector[expr.Key] = expr.Values[0]
|
||||
case LabelSelectorOpNotIn, LabelSelectorOpExists, LabelSelectorOpDoesNotExist:
|
||||
return selector, fmt.Errorf("operator %q cannot be converted into the old label selector format", expr.Operator)
|
||||
default:
|
||||
return selector, fmt.Errorf("%q is not a valid selector operator", expr.Operator)
|
||||
}
|
||||
}
|
||||
return selector, nil
|
||||
}
|
||||
|
||||
// ParseToLabelSelector parses a string representing a selector into a LabelSelector object.
|
||||
// Note: This function should be kept in sync with the parser in pkg/labels/selector.go
|
||||
func ParseToLabelSelector(selector string) (*LabelSelector, error) {
|
||||
|
@@ -18,6 +18,7 @@ package unversioned
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
@@ -81,3 +82,73 @@ func TestLabelSelectorAsSelector(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLabelSelectorAsMap(t *testing.T) {
|
||||
matchLabels := map[string]string{"foo": "bar"}
|
||||
matchExpressions := func(operator LabelSelectorOperator, values []string) []LabelSelectorRequirement {
|
||||
return []LabelSelectorRequirement{{
|
||||
Key: "baz",
|
||||
Operator: operator,
|
||||
Values: values,
|
||||
}}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
in *LabelSelector
|
||||
out map[string]string
|
||||
errString string
|
||||
}{
|
||||
{in: nil, out: nil},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels},
|
||||
out: map[string]string{"foo": "bar"},
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf"})},
|
||||
out: map[string]string{"foo": "bar", "baz": "norf"},
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf"})},
|
||||
out: map[string]string{"baz": "norf"},
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf", "qux"})},
|
||||
out: map[string]string{"foo": "bar"},
|
||||
errString: "without a single value cannot be converted",
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpNotIn, []string{"norf", "qux"})},
|
||||
out: map[string]string{},
|
||||
errString: "cannot be converted",
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpExists, []string{})},
|
||||
out: map[string]string{"foo": "bar"},
|
||||
errString: "cannot be converted",
|
||||
},
|
||||
{
|
||||
in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpDoesNotExist, []string{})},
|
||||
out: map[string]string{},
|
||||
errString: "cannot be converted",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
out, err := LabelSelectorAsMap(tc.in)
|
||||
if err == nil && len(tc.errString) > 0 {
|
||||
t.Errorf("[%v]expected error but got none.", i)
|
||||
continue
|
||||
}
|
||||
if err != nil && len(tc.errString) == 0 {
|
||||
t.Errorf("[%v]did not expect error but got: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if err != nil && len(tc.errString) > 0 && !strings.Contains(err.Error(), tc.errString) {
|
||||
t.Errorf("[%v]expected error with %q but got: %v", i, tc.errString, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(out, tc.out) {
|
||||
t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user