// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements // labels.Selector. func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) { if len(nsm) == 0 { return labels.Nothing(), nil } selector := labels.NewSelector() for _, expr := range nsm { var op selection.Operator switch expr.Operator { case NodeSelectorOpIn: op = selection.In case NodeSelectorOpNotIn: op = selection.NotIn case NodeSelectorOpExists: op = selection.Exists case NodeSelectorOpDoesNotExist: op = selection.DoesNotExist case NodeSelectorOpGt: op = selection.GreaterThan case NodeSelectorOpLt: op = selection.LessThan default: return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator) } r, err := labels.NewRequirement(expr.Key, op, expr.Values) if err != nil { return nil, err } selector = selector.Add(*r) } return selector, nil }
func TestLabelSelectorAsSelector(t *testing.T) { matchLabels := map[string]string{"foo": "bar"} matchExpressions := []LabelSelectorRequirement{{ Key: "baz", Operator: LabelSelectorOpIn, Values: []string{"qux", "norf"}, }} mustParse := func(s string) labels.Selector { out, e := labels.Parse(s) if e != nil { panic(e) } return out } tc := []struct { in *LabelSelector out labels.Selector expectErr bool }{ {in: nil, out: labels.Nothing()}, {in: &LabelSelector{}, out: labels.Everything()}, { in: &LabelSelector{MatchLabels: matchLabels}, out: mustParse("foo=bar"), }, { in: &LabelSelector{MatchExpressions: matchExpressions}, out: mustParse("baz in (norf,qux)"), }, { in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions}, out: mustParse("baz in (norf,qux),foo=bar"), }, { in: &LabelSelector{ MatchExpressions: []LabelSelectorRequirement{{ Key: "baz", Operator: LabelSelectorOpExists, Values: []string{"qux", "norf"}, }}, }, expectErr: true, }, } for i, tc := range tc { out, err := LabelSelectorAsSelector(tc.in) if err == nil && tc.expectErr { t.Errorf("[%v]expected error but got none.", i) } if err != nil && !tc.expectErr { t.Errorf("[%v]did not expect error but got: %v", i, err) } if !reflect.DeepEqual(out, tc.out) { t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out) } } }
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements // labels.Selector // Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) { if ps == nil { return labels.Nothing(), nil } if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 { return labels.Everything(), nil } selector := labels.NewSelector() for k, v := range ps.MatchLabels { r, err := labels.NewRequirement(k, selection.Equals, []string{v}) if err != nil { return nil, err } selector = selector.Add(*r) } for _, expr := range ps.MatchExpressions { var op selection.Operator switch expr.Operator { case LabelSelectorOpIn: op = selection.In case LabelSelectorOpNotIn: op = selection.NotIn case LabelSelectorOpExists: op = selection.Exists case LabelSelectorOpDoesNotExist: op = selection.DoesNotExist default: return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator) } r, err := labels.NewRequirement(expr.Key, op, append([]string(nil), expr.Values...)) if err != nil { return nil, err } selector = selector.Add(*r) } return selector, nil }
func TestNodeSelectorRequirementsAsSelector(t *testing.T) { matchExpressions := []NodeSelectorRequirement{{ Key: "foo", Operator: NodeSelectorOpIn, Values: []string{"bar", "baz"}, }} mustParse := func(s string) labels.Selector { out, e := labels.Parse(s) if e != nil { panic(e) } return out } tc := []struct { in []NodeSelectorRequirement out labels.Selector expectErr bool }{ {in: nil, out: labels.Nothing()}, {in: []NodeSelectorRequirement{}, out: labels.Nothing()}, { in: matchExpressions, out: mustParse("foo in (baz,bar)"), }, { in: []NodeSelectorRequirement{{ Key: "foo", Operator: NodeSelectorOpExists, Values: []string{"bar", "baz"}, }}, expectErr: true, }, { in: []NodeSelectorRequirement{{ Key: "foo", Operator: NodeSelectorOpGt, Values: []string{"1"}, }}, out: mustParse("foo>1"), }, { in: []NodeSelectorRequirement{{ Key: "bar", Operator: NodeSelectorOpLt, Values: []string{"7"}, }}, out: mustParse("bar<7"), }, } for i, tc := range tc { out, err := NodeSelectorRequirementsAsSelector(tc.in) if err == nil && tc.expectErr { t.Errorf("[%v]expected error but got none.", i) } if err != nil && !tc.expectErr { t.Errorf("[%v]did not expect error but got: %v", i, err) } if !reflect.DeepEqual(out, tc.out) { t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out) } } }