Skip to content

Commit dfc6377

Browse files
authored
Merge pull request #792 from vincepri/selector-contains
✨Add HasLabels helper option for List calls
2 parents 702a4a4 + ddfd3ec commit dfc6377

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

pkg/client/fake/client_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ var _ = Describe("Fake client", func() {
122122
Expect(list.Items).To(HaveLen(2))
123123
})
124124

125-
It("should support filtering by labels", func() {
126-
By("Listing deployments with a particular label")
125+
It("should support filtering by labels and their values", func() {
126+
By("Listing deployments with a particular label and value")
127127
list := &appsv1.DeploymentList{}
128128
err := cl.List(nil, list, client.InNamespace("ns1"),
129129
client.MatchingLabels(map[string]string{
@@ -134,6 +134,16 @@ var _ = Describe("Fake client", func() {
134134
Expect(list.Items).To(ConsistOf(*dep2))
135135
})
136136

137+
It("should support filtering by label existence", func() {
138+
By("Listing deployments with a particular label")
139+
list := &appsv1.DeploymentList{}
140+
err := cl.List(nil, list, client.InNamespace("ns1"),
141+
client.HasLabels{"test-label"})
142+
Expect(err).To(BeNil())
143+
Expect(list.Items).To(HaveLen(1))
144+
Expect(list.Items).To(ConsistOf(*dep2))
145+
})
146+
137147
It("should be able to Create", func() {
138148
By("Creating a new configmap")
139149
newcm := &corev1.ConfigMap{

pkg/client/options.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
"k8s.io/apimachinery/pkg/fields"
2222
"k8s.io/apimachinery/pkg/labels"
23+
"k8s.io/apimachinery/pkg/selection"
2324
)
2425

2526
// {{{ "Functional" Option Interfaces
@@ -388,6 +389,25 @@ func (m MatchingLabels) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
388389
m.ApplyToList(&opts.ListOptions)
389390
}
390391

392+
// HasLabels filters the list/delete operation checking if the set of labels exists
393+
// without checking their values.
394+
type HasLabels []string
395+
396+
func (m HasLabels) ApplyToList(opts *ListOptions) {
397+
sel := labels.NewSelector()
398+
for _, label := range m {
399+
r, err := labels.NewRequirement(label, selection.Exists, nil)
400+
if err == nil {
401+
sel = sel.Add(*r)
402+
}
403+
}
404+
opts.LabelSelector = sel
405+
}
406+
407+
func (m HasLabels) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
408+
m.ApplyToList(&opts.ListOptions)
409+
}
410+
391411
// MatchingLabelsSelector filters the list/delete operation on the given label
392412
// selector (or index in the case of cached lists). A struct is used because
393413
// labels.Selector is an interface, which cannot be aliased.

0 commit comments

Comments
 (0)