layer1: prepare managed namespace watchers

This commit is contained in:
Naeel
2026-04-26 10:54:24 +03:00
parent a1517ba4b2
commit 2bbed95c2a
6 changed files with 51 additions and 6 deletions
@@ -0,0 +1,20 @@
# 2026-04-26 — NamespaceManager rewrite, step 44
## Цель шага
Убрать последний дублирующийся orchestration-код из `StartNSWatcher()` в трёх компонентах.
## Что меняем
1. В `utils` добавляем `PrepareManagedNamespaceWatcher()`.
2. Helper:
- создаёт `NamespaceManager`;
- делает bootstrap+dispatch;
- собирает общие event handlers.
3. `buildermgr`, `router`, `executor/multitenant` используют этот helper.
## Что НЕ меняем
- не меняем subscriber logic;
- не меняем managed namespace watcher startup helper;
- не меняем removal strategy по умолчанию.
+2 -2
View File
@@ -26,9 +26,9 @@ func StartNSWatcher(
pkgw *packageWatcher,
mgr manager.Interface,
) {
nsManager, err := utils.NewWatcherNamespaceManager(ctx, utils.DefaultNSResolver().Snapshot(), utils.NamespaceSourceEnv, time.Now().UTC(), NewNamespaceSubscriber(envw, pkgw, mgr))
_, handlers, err := utils.PrepareManagedNamespaceWatcher(ctx, logger, "buildermgr.NSWatcher", utils.DefaultNSResolver().Snapshot(), utils.NamespaceRemovalStrategyTrackOnly, NewNamespaceSubscriber(envw, pkgw, mgr))
if err != nil {
logger.Error("buildermgr.NSWatcher: BootstrapAndDispatch failed", zap.Error(err))
}
utils.StartManagedNamespaceWatcher(ctx, logger, "buildermgr.NSWatcher", kubeClient, mgr, utils.NewNamespaceWatcherEventHandlers(ctx, logger, "buildermgr.NSWatcher", nsManager, utils.NamespaceRemovalStrategyTrackOnly))
utils.StartManagedNamespaceWatcher(ctx, logger, "buildermgr.NSWatcher", kubeClient, mgr, handlers)
}
+2 -2
View File
@@ -88,11 +88,11 @@ func StartNSWatcher(
executorTypes map[fv1.ExecutorType]executortype.ExecutorType,
mgr manager.Interface,
) {
nsManager, err := utils.NewWatcherNamespaceManager(ctx, utils.DefaultNSResolver().Snapshot(), utils.NamespaceSourceEnv, time.Now().UTC(), NewNamespaceSubscriber(logger, kubernetesClient, executorTypes, mgr))
_, handlers, err := utils.PrepareManagedNamespaceWatcher(ctx, logger, "multitenant.NSWatcher", utils.DefaultNSResolver().Snapshot(), utils.NamespaceRemovalStrategyTrackOnly, NewNamespaceSubscriber(logger, kubernetesClient, executorTypes, mgr))
if err != nil {
logger.Error("multitenant.NSWatcher: BootstrapAndDispatch failed", zap.Error(err))
}
utils.StartManagedNamespaceWatcher(ctx, logger, "multitenant.NSWatcher", kubernetesClient, mgr, utils.NewNamespaceWatcherEventHandlers(ctx, logger, "multitenant.NSWatcher", nsManager, utils.NamespaceRemovalStrategyTrackOnly))
utils.StartManagedNamespaceWatcher(ctx, logger, "multitenant.NSWatcher", kubernetesClient, mgr, handlers)
}
// registerNamespace calls AddNamespace on every executor type for the given namespace.
+2 -2
View File
@@ -26,9 +26,9 @@ func StartNSWatcher(
ts *HTTPTriggerSet,
mgr manager.Interface,
) {
nsManager, err := utils.NewWatcherNamespaceManager(ctx, utils.DefaultNSResolver().Snapshot(), utils.NamespaceSourceEnv, time.Now().UTC(), NewNamespaceSubscriber(ts, mgr))
_, handlers, err := utils.PrepareManagedNamespaceWatcher(ctx, logger, "router.NSWatcher", utils.DefaultNSResolver().Snapshot(), utils.NamespaceRemovalStrategyTrackOnly, NewNamespaceSubscriber(ts, mgr))
if err != nil {
logger.Error("router.NSWatcher: BootstrapAndDispatch failed", zap.Error(err))
}
utils.StartManagedNamespaceWatcher(ctx, logger, "router.NSWatcher", kubeClient, mgr, utils.NewNamespaceWatcherEventHandlers(ctx, logger, "router.NSWatcher", nsManager, utils.NamespaceRemovalStrategyTrackOnly))
utils.StartManagedNamespaceWatcher(ctx, logger, "router.NSWatcher", kubeClient, mgr, handlers)
}
+6
View File
@@ -109,6 +109,12 @@ func NewWatcherNamespaceManager(ctx context.Context, namespaces []string, source
return manager, err
}
func PrepareManagedNamespaceWatcher(ctx context.Context, logger *zap.Logger, component string, namespaces []string, removalStrategy NamespaceRemovalStrategy, subscriber NamespaceSubscriber) (NamespaceManager, k8sCache.ResourceEventHandlerFuncs, error) {
manager, err := NewWatcherNamespaceManager(ctx, namespaces, NamespaceSourceEnv, time.Now().UTC(), subscriber)
handlers := NewNamespaceWatcherEventHandlers(ctx, logger, component, manager, removalStrategy)
return manager, handlers, err
}
func NamespaceBecameUnmanaged(oldNamespace *corev1.Namespace, newNamespace *corev1.Namespace) bool {
if oldNamespace == nil || newNamespace == nil {
return false
+19
View File
@@ -429,6 +429,25 @@ func TestNewNamespaceWatcherEventHandlers(t *testing.T) {
}
}
func TestPrepareManagedNamespaceWatcher(t *testing.T) {
router := &testNamespaceSubscriber{name: "router"}
logger := zap.NewNop()
manager, handlers, err := PrepareManagedNamespaceWatcher(context.Background(), logger, "router.NSWatcher", []string{"tenant-a"}, NamespaceRemovalStrategyTrackOnly, router)
if err != nil {
t.Fatalf("expected watcher preparation success: %v", err)
}
if !reflect.DeepEqual([]string{"tenant-a"}, manager.Snapshot()) {
t.Fatalf("expected watcher manager snapshot to contain bootstrapped namespace")
}
namespace := &corev1.Namespace{}
namespace.Name = "tenant-a"
namespace.Labels = map[string]string{ManagedNamespaceLabelKey: ManagedNamespaceLabelValue}
handlers.UpdateFunc(namespace, namespace)
if router.addCalls != 1 || router.resyncCalls != 1 {
t.Fatalf("expected bootstrap add and handler resync calls")
}
}
func TestNamespaceManagerDispatchAdd(t *testing.T) {
manager := NewNamespaceManager()
manager.Upsert(NamespaceEvent{Type: NamespaceEventAdd, Name: "tenant-a", Source: NamespaceSourceWatcher})