Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/operator/hierarchy/selector.go
4094 views
1
package hierarchy
2
3
import (
4
"context"
5
"fmt"
6
7
corev1 "k8s.io/api/core/v1"
8
"k8s.io/apimachinery/pkg/labels"
9
"sigs.k8s.io/controller-runtime/pkg/client"
10
)
11
12
// Selector finding objects within the resource hierarchy.
13
type Selector interface {
14
// ListOption can be passed to List to perform initial filtering of returned
15
// objects.
16
client.ListOption
17
18
// Matches returns true if the Selector matches the provided Object. The
19
// provided Client may be used to perform extra searches.
20
Matches(context.Context, client.Client, client.Object) (bool, error)
21
}
22
23
// LabelsSelector is used for discovering a set of objects in a hierarchy based
24
// on labels.
25
type LabelsSelector struct {
26
// NamespaceName is the default namespace to search for objects in when
27
// NamespaceSelector is nil.
28
NamespaceName string
29
30
// NamespaceLabels causes all namespaces whose labels match NamespaceLabels
31
// to be searched. When nil, only the namespace specified by NamespaceName
32
// will be searched.
33
NamespaceLabels labels.Selector
34
35
// Labels discovers all objects whose labels match the selector. If nil,
36
// no objects will be discovered.
37
Labels labels.Selector
38
}
39
40
var _ Selector = (*LabelsSelector)(nil)
41
42
// ApplyToList implements Selector.
43
func (ls *LabelsSelector) ApplyToList(lo *client.ListOptions) {
44
if ls.NamespaceLabels == nil {
45
lo.Namespace = ls.NamespaceName
46
}
47
lo.LabelSelector = ls.Labels
48
}
49
50
// Matches implements Selector.
51
func (ls *LabelsSelector) Matches(ctx context.Context, cli client.Client, o client.Object) (bool, error) {
52
if !ls.Labels.Matches(labels.Set(o.GetLabels())) {
53
return false, nil
54
}
55
56
// Fast path: we don't need to retrieve the labels of the namespace.
57
if ls.NamespaceLabels == nil {
58
return o.GetNamespace() == ls.NamespaceName, nil
59
}
60
61
// Slow path: we need to look up the namespace to see if its labels match. As
62
// long as cli implements caching, this won't be too bad.
63
var ns corev1.Namespace
64
if err := cli.Get(ctx, client.ObjectKey{Name: o.GetNamespace()}, &ns); err != nil {
65
return false, fmt.Errorf("error looking up namespace %q: %w", o.GetNamespace(), err)
66
}
67
return ls.NamespaceLabels.Matches(labels.Set(ns.GetLabels())), nil
68
}
69
70
// KeySelector is used for discovering a single object based on namespace and
71
// name.
72
type KeySelector struct {
73
Namespace, Name string
74
}
75
76
var _ Selector = (*KeySelector)(nil)
77
78
// ApplyToList implements Selector.
79
func (ks *KeySelector) ApplyToList(lo *client.ListOptions) {
80
lo.Namespace = ks.Namespace
81
}
82
83
// Matches implements Selector.
84
func (ks *KeySelector) Matches(ctx context.Context, cli client.Client, o client.Object) (bool, error) {
85
return ks.Name == o.GetName() && ks.Namespace == o.GetNamespace(), nil
86
}
87
88