cart and checkout
This commit is contained in:
@@ -2,7 +2,9 @@ package discovery
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@@ -13,14 +15,33 @@ import (
|
||||
toolsWatch "k8s.io/client-go/tools/watch"
|
||||
)
|
||||
|
||||
// InClusterNamespace returns the namespace the current pod runs in: POD_NAMESPACE
|
||||
// (downward API) if set, else the service-account namespace file mounted into
|
||||
// every pod. Empty means "not in a cluster" — callers can treat that as
|
||||
// all-namespaces or single-node. Pass the result to NewK8sDiscoveryInNamespace
|
||||
// to keep pod discovery (and thus the required RBAC) scoped to one namespace.
|
||||
func InClusterNamespace() string {
|
||||
if ns := os.Getenv("POD_NAMESPACE"); ns != "" {
|
||||
return ns
|
||||
}
|
||||
if b, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
|
||||
return strings.TrimSpace(string(b))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type K8sDiscovery struct {
|
||||
ctx context.Context
|
||||
client *kubernetes.Clientset
|
||||
listOptions metav1.ListOptions
|
||||
// namespace scopes the pod list/watch. Empty means all namespaces (requires
|
||||
// a cluster-scoped RBAC role); a specific namespace only needs a namespaced
|
||||
// Role, which is the least-privilege option.
|
||||
namespace string
|
||||
}
|
||||
|
||||
func (k *K8sDiscovery) Discover() ([]string, error) {
|
||||
return k.DiscoverInNamespace("")
|
||||
return k.DiscoverInNamespace(k.namespace)
|
||||
}
|
||||
func (k *K8sDiscovery) DiscoverInNamespace(namespace string) ([]string, error) {
|
||||
pods, err := k.client.CoreV1().Pods(namespace).List(k.ctx, k.listOptions)
|
||||
@@ -46,7 +67,7 @@ func (k *K8sDiscovery) Watch() (<-chan HostChange, error) {
|
||||
ipsThatAreReady := make(map[string]bool)
|
||||
m := sync.Mutex{}
|
||||
watcherFn := func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
return k.client.CoreV1().Pods("").Watch(k.ctx, k.listOptions)
|
||||
return k.client.CoreV1().Pods(k.namespace).Watch(k.ctx, k.listOptions)
|
||||
}
|
||||
watcher, err := toolsWatch.NewRetryWatcherWithContext(k.ctx, "1", &cache.ListWatch{WatchFunc: watcherFn})
|
||||
if err != nil {
|
||||
@@ -77,6 +98,8 @@ func (k *K8sDiscovery) Watch() (<-chan HostChange, error) {
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
// NewK8sDiscovery watches pods across ALL namespaces (label-filtered via
|
||||
// listOptions). It requires a cluster-scoped RBAC role for pod list/watch.
|
||||
func NewK8sDiscovery(client *kubernetes.Clientset, listOptions metav1.ListOptions) *K8sDiscovery {
|
||||
return &K8sDiscovery{
|
||||
ctx: context.Background(),
|
||||
@@ -84,3 +107,14 @@ func NewK8sDiscovery(client *kubernetes.Clientset, listOptions metav1.ListOption
|
||||
listOptions: listOptions,
|
||||
}
|
||||
}
|
||||
|
||||
// NewK8sDiscoveryInNamespace watches pods only within namespace, so it needs
|
||||
// just a namespaced Role (pods: get/list/watch) rather than a ClusterRole.
|
||||
func NewK8sDiscoveryInNamespace(client *kubernetes.Clientset, namespace string, listOptions metav1.ListOptions) *K8sDiscovery {
|
||||
return &K8sDiscovery{
|
||||
ctx: context.Background(),
|
||||
client: client,
|
||||
listOptions: listOptions,
|
||||
namespace: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user