unversioned: conversion from new to original label selector

This commit is contained in:
Michail Kargakis 2016-04-22 17:36:25 +02:00
parent d347435708
commit d7038f50b6
3 changed files with 128 additions and 0 deletions

View File

@ -17,12 +17,16 @@ limitations under the License.
package api
import (
"fmt"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/util/intstr"
utillabels "k8s.io/kubernetes/pkg/util/labels"
"k8s.io/kubernetes/pkg/util/validation/field"
)
func init() {
@ -69,6 +73,9 @@ func init() {
Convert_Pointer_float64_To_float64,
Convert_float64_To_Pointer_float64,
Convert_map_to_unversioned_LabelSelector,
Convert_unversioned_LabelSelector_to_map,
)
}
@ -195,6 +202,7 @@ func Convert_string_To_labels_Selector(in *string, out *labels.Selector, s conve
*out = selector
return nil
}
func Convert_string_To_fields_Selector(in *string, out *fields.Selector, s conversion.Scope) error {
selector, err := fields.ParseSelector(*in)
if err != nil {
@ -203,6 +211,7 @@ func Convert_string_To_fields_Selector(in *string, out *fields.Selector, s conve
*out = selector
return nil
}
func Convert_labels_Selector_To_string(in *labels.Selector, out *string, s conversion.Scope) error {
if *in == nil {
return nil
@ -210,6 +219,7 @@ func Convert_labels_Selector_To_string(in *labels.Selector, out *string, s conve
*out = (*in).String()
return nil
}
func Convert_fields_Selector_To_string(in *fields.Selector, out *string, s conversion.Scope) error {
if *in == nil {
return nil
@ -217,7 +227,25 @@ func Convert_fields_Selector_To_string(in *fields.Selector, out *string, s conve
*out = (*in).String()
return nil
}
func Convert_resource_Quantity_To_resource_Quantity(in *resource.Quantity, out *resource.Quantity, s conversion.Scope) error {
*out = *in
return nil
}
func Convert_map_to_unversioned_LabelSelector(in *map[string]string, out *unversioned.LabelSelector, s conversion.Scope) error {
out = new(unversioned.LabelSelector)
for labelKey, labelValue := range *in {
utillabels.AddLabelToSelector(out, labelKey, labelValue)
}
return nil
}
func Convert_unversioned_LabelSelector_to_map(in *unversioned.LabelSelector, out *map[string]string, s conversion.Scope) error {
var err error
*out, err = unversioned.LabelSelectorAsMap(in)
if err != nil {
err = field.Invalid(field.NewPath("labelSelector"), *in, fmt.Sprintf("cannot convert to old selector: %v", err))
}
return err
}

View File

@ -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) {

View File

@ -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)
}
}
}