package hierarchy
import (
"context"
"fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type Selector interface {
client.ListOption
Matches(context.Context, client.Client, client.Object) (bool, error)
}
type LabelsSelector struct {
NamespaceName string
NamespaceLabels labels.Selector
Labels labels.Selector
}
var _ Selector = (*LabelsSelector)(nil)
func (ls *LabelsSelector) ApplyToList(lo *client.ListOptions) {
if ls.NamespaceLabels == nil {
lo.Namespace = ls.NamespaceName
}
lo.LabelSelector = ls.Labels
}
func (ls *LabelsSelector) Matches(ctx context.Context, cli client.Client, o client.Object) (bool, error) {
if !ls.Labels.Matches(labels.Set(o.GetLabels())) {
return false, nil
}
if ls.NamespaceLabels == nil {
return o.GetNamespace() == ls.NamespaceName, nil
}
var ns corev1.Namespace
if err := cli.Get(ctx, client.ObjectKey{Name: o.GetNamespace()}, &ns); err != nil {
return false, fmt.Errorf("error looking up namespace %q: %w", o.GetNamespace(), err)
}
return ls.NamespaceLabels.Matches(labels.Set(ns.GetLabels())), nil
}
type KeySelector struct {
Namespace, Name string
}
var _ Selector = (*KeySelector)(nil)
func (ks *KeySelector) ApplyToList(lo *client.ListOptions) {
lo.Namespace = ks.Namespace
}
func (ks *KeySelector) Matches(ctx context.Context, cli client.Client, o client.Object) (bool, error) {
return ks.Name == o.GetName() && ks.Namespace == o.GetNamespace(), nil
}