layer1: add managed watcher config
This commit is contained in:
@@ -0,0 +1,17 @@
|
|||||||
|
# 2026-04-26 — NamespaceManager rewrite, step 50
|
||||||
|
|
||||||
|
## Цель шага
|
||||||
|
|
||||||
|
Сделать orchestration API для managed namespace watcher-а жёстче и читабельнее.
|
||||||
|
|
||||||
|
## Что меняем
|
||||||
|
|
||||||
|
1. Добавляем `ManagedNamespaceWatcherConfig`.
|
||||||
|
2. `PrepareManagedNamespaceWatcher()` и `RunManagedNamespaceWatcher()` принимают config struct.
|
||||||
|
3. Если strategy не задана, используется `track-only`.
|
||||||
|
4. Обновляем unit tests и call sites.
|
||||||
|
|
||||||
|
## Что НЕ меняем
|
||||||
|
|
||||||
|
- не меняем runtime semantics;
|
||||||
|
- не меняем subscriber logic.
|
||||||
@@ -25,7 +25,12 @@ func StartNSWatcher(
|
|||||||
pkgw *packageWatcher,
|
pkgw *packageWatcher,
|
||||||
mgr manager.Interface,
|
mgr manager.Interface,
|
||||||
) {
|
) {
|
||||||
_, err := utils.RunManagedNamespaceWatcher(ctx, logger, "buildermgr.NSWatcher", kubeClient, mgr, utils.DefaultNSResolver().Snapshot(), utils.NamespaceRemovalStrategyTrackOnly, NewNamespaceSubscriber(envw, pkgw, mgr))
|
_, err := utils.RunManagedNamespaceWatcher(ctx, logger, kubeClient, mgr, utils.ManagedNamespaceWatcherConfig{
|
||||||
|
Component: "buildermgr.NSWatcher",
|
||||||
|
Namespaces: utils.DefaultNSResolver().Snapshot(),
|
||||||
|
RemovalStrategy: utils.NamespaceRemovalStrategyTrackOnly,
|
||||||
|
Subscriber: NewNamespaceSubscriber(envw, pkgw, mgr),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("buildermgr.NSWatcher: BootstrapAndDispatch failed", zap.Error(err))
|
logger.Error("buildermgr.NSWatcher: BootstrapAndDispatch failed", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,12 @@ import (
|
|||||||
"github.com/fission/fission/pkg/utils"
|
"github.com/fission/fission/pkg/utils"
|
||||||
"github.com/fission/fission/pkg/utils/manager"
|
"github.com/fission/fission/pkg/utils/manager"
|
||||||
)
|
)
|
||||||
|
_, err := utils.RunManagedNamespaceWatcher(ctx, logger, kubernetesClient, mgr, utils.ManagedNamespaceWatcherConfig{
|
||||||
|
Component: "multitenant.NSWatcher",
|
||||||
|
Namespaces: utils.DefaultNSResolver().Snapshot(),
|
||||||
|
RemovalStrategy: utils.NamespaceRemovalStrategyTrackOnly,
|
||||||
|
Subscriber: NewNamespaceSubscriber(logger, kubernetesClient, executorTypes, mgr),
|
||||||
|
})
|
||||||
// StartNSWatcher registers a Kubernetes Namespace Informer that reacts immediately
|
// StartNSWatcher registers a Kubernetes Namespace Informer that reacts immediately
|
||||||
// when a Namespace with label fission.io/managed=true is created or relabeled.
|
// when a Namespace with label fission.io/managed=true is created or relabeled.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -14,7 +14,12 @@ import (
|
|||||||
"github.com/fission/fission/pkg/utils"
|
"github.com/fission/fission/pkg/utils"
|
||||||
"github.com/fission/fission/pkg/utils/manager"
|
"github.com/fission/fission/pkg/utils/manager"
|
||||||
)
|
)
|
||||||
|
_, err := utils.RunManagedNamespaceWatcher(ctx, logger, kubeClient, mgr, utils.ManagedNamespaceWatcherConfig{
|
||||||
|
Component: "router.NSWatcher",
|
||||||
|
Namespaces: utils.DefaultNSResolver().Snapshot(),
|
||||||
|
RemovalStrategy: utils.NamespaceRemovalStrategyTrackOnly,
|
||||||
|
Subscriber: NewNamespaceSubscriber(ts, mgr),
|
||||||
|
})
|
||||||
// StartNSWatcher registers a Kubernetes Namespace Informer for the router.
|
// StartNSWatcher registers a Kubernetes Namespace Informer for the router.
|
||||||
// Whenever a Namespace with label fission.io/managed=true appears (or is relabeled),
|
// Whenever a Namespace with label fission.io/managed=true appears (or is relabeled),
|
||||||
// the router immediately subscribes to HTTPTriggers and Functions in that namespace.
|
// the router immediately subscribes to HTTPTriggers and Functions in that namespace.
|
||||||
|
|||||||
@@ -110,16 +110,20 @@ func NewWatcherNamespaceManager(ctx context.Context, namespaces []string, source
|
|||||||
return manager, err
|
return manager, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrepareManagedNamespaceWatcher(ctx context.Context, logger *zap.Logger, component string, namespaces []string, removalStrategy NamespaceRemovalStrategy, subscriber NamespaceSubscriber) (NamespaceManager, k8sCache.ResourceEventHandlerFuncs, error) {
|
func PrepareManagedNamespaceWatcher(ctx context.Context, logger *zap.Logger, config ManagedNamespaceWatcherConfig) (NamespaceManager, k8sCache.ResourceEventHandlerFuncs, error) {
|
||||||
manager, err := NewWatcherNamespaceManager(ctx, namespaces, NamespaceSourceEnv, time.Now().UTC(), subscriber)
|
strategy := config.RemovalStrategy
|
||||||
handlers := NewNamespaceWatcherEventHandlers(ctx, logger, component, manager, removalStrategy)
|
if strategy == "" {
|
||||||
LogNamespaceManagerSummary(logger, component+": prepared namespace manager", manager.Summary())
|
strategy = NamespaceRemovalStrategyTrackOnly
|
||||||
|
}
|
||||||
|
manager, err := NewWatcherNamespaceManager(ctx, config.Namespaces, NamespaceSourceEnv, time.Now().UTC(), config.Subscriber)
|
||||||
|
handlers := NewNamespaceWatcherEventHandlers(ctx, logger, config.Component, manager, strategy)
|
||||||
|
LogNamespaceManagerSummary(logger, config.Component+": prepared namespace manager", manager.Summary())
|
||||||
return manager, handlers, err
|
return manager, handlers, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunManagedNamespaceWatcher(ctx context.Context, logger *zap.Logger, component string, kubeClient kubernetes.Interface, mgr managerPkg.Interface, namespaces []string, removalStrategy NamespaceRemovalStrategy, subscriber NamespaceSubscriber) (NamespaceManager, error) {
|
func RunManagedNamespaceWatcher(ctx context.Context, logger *zap.Logger, kubeClient kubernetes.Interface, mgr managerPkg.Interface, config ManagedNamespaceWatcherConfig) (NamespaceManager, error) {
|
||||||
manager, handlers, err := PrepareManagedNamespaceWatcher(ctx, logger, component, namespaces, removalStrategy, subscriber)
|
manager, handlers, err := PrepareManagedNamespaceWatcher(ctx, logger, config)
|
||||||
StartManagedNamespaceWatcher(ctx, logger, component, kubeClient, mgr, handlers)
|
StartManagedNamespaceWatcher(ctx, logger, config.Component, kubeClient, mgr, handlers)
|
||||||
return manager, err
|
return manager, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,13 @@ type NamespaceManagerSummary struct {
|
|||||||
Subscribers []string
|
Subscribers []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ManagedNamespaceWatcherConfig struct {
|
||||||
|
Component string
|
||||||
|
Namespaces []string
|
||||||
|
RemovalStrategy NamespaceRemovalStrategy
|
||||||
|
Subscriber NamespaceSubscriber
|
||||||
|
}
|
||||||
|
|
||||||
func NewNamespaceEvent(eventType NamespaceEventType, name string, labels map[string]string, source NamespaceSource, observedAt time.Time) NamespaceEvent {
|
func NewNamespaceEvent(eventType NamespaceEventType, name string, labels map[string]string, source NamespaceSource, observedAt time.Time) NamespaceEvent {
|
||||||
return NamespaceEvent{
|
return NamespaceEvent{
|
||||||
Type: eventType,
|
Type: eventType,
|
||||||
|
|||||||
@@ -445,7 +445,12 @@ func TestNewNamespaceWatcherEventHandlers(t *testing.T) {
|
|||||||
func TestPrepareManagedNamespaceWatcher(t *testing.T) {
|
func TestPrepareManagedNamespaceWatcher(t *testing.T) {
|
||||||
router := &testNamespaceSubscriber{name: "router"}
|
router := &testNamespaceSubscriber{name: "router"}
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
manager, handlers, err := PrepareManagedNamespaceWatcher(context.Background(), logger, "router.NSWatcher", []string{"tenant-a"}, NamespaceRemovalStrategyTrackOnly, router)
|
manager, handlers, err := PrepareManagedNamespaceWatcher(context.Background(), logger, ManagedNamespaceWatcherConfig{
|
||||||
|
Component: "router.NSWatcher",
|
||||||
|
Namespaces: []string{"tenant-a"},
|
||||||
|
RemovalStrategy: NamespaceRemovalStrategyTrackOnly,
|
||||||
|
Subscriber: router,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected watcher preparation success: %v", err)
|
t.Fatalf("expected watcher preparation success: %v", err)
|
||||||
}
|
}
|
||||||
@@ -466,7 +471,12 @@ func TestRunManagedNamespaceWatcher(t *testing.T) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
router := &testNamespaceSubscriber{name: "router"}
|
router := &testNamespaceSubscriber{name: "router"}
|
||||||
logger := zap.NewNop()
|
logger := zap.NewNop()
|
||||||
manager, err := RunManagedNamespaceWatcher(ctx, logger, "router.NSWatcher", k8sfake.NewSimpleClientset(), managerPkg.New(), []string{"tenant-a"}, NamespaceRemovalStrategyTrackOnly, router)
|
manager, err := RunManagedNamespaceWatcher(ctx, logger, k8sfake.NewSimpleClientset(), managerPkg.New(), ManagedNamespaceWatcherConfig{
|
||||||
|
Component: "router.NSWatcher",
|
||||||
|
Namespaces: []string{"tenant-a"},
|
||||||
|
RemovalStrategy: NamespaceRemovalStrategyTrackOnly,
|
||||||
|
Subscriber: router,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected managed namespace watcher run success: %v", err)
|
t.Fatalf("expected managed namespace watcher run success: %v", err)
|
||||||
}
|
}
|
||||||
@@ -475,6 +485,30 @@ func TestRunManagedNamespaceWatcher(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrepareManagedNamespaceWatcherDefaultsToTrackOnly(t *testing.T) {
|
||||||
|
router := &testNamespaceSubscriber{name: "router"}
|
||||||
|
logger := zap.NewNop()
|
||||||
|
manager, handlers, err := PrepareManagedNamespaceWatcher(context.Background(), logger, ManagedNamespaceWatcherConfig{
|
||||||
|
Component: "router.NSWatcher",
|
||||||
|
Namespaces: []string{"tenant-a"},
|
||||||
|
Subscriber: router,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected watcher preparation success: %v", err)
|
||||||
|
}
|
||||||
|
namespace := &corev1.Namespace{}
|
||||||
|
namespace.Name = "tenant-a"
|
||||||
|
namespace.Labels = map[string]string{ManagedNamespaceLabelKey: ManagedNamespaceLabelValue}
|
||||||
|
handlers.DeleteFunc(k8sCache.DeletedFinalStateUnknown{Obj: namespace})
|
||||||
|
record, ok := manager.Get("tenant-a")
|
||||||
|
if !ok || record.Phase != NamespacePhaseRemoved {
|
||||||
|
t.Fatalf("expected default strategy to keep track-only removal semantics")
|
||||||
|
}
|
||||||
|
if router.removeCalls != 0 {
|
||||||
|
t.Fatalf("expected default strategy not to dispatch remove")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNamespaceManagerSummary(t *testing.T) {
|
func TestNamespaceManagerSummary(t *testing.T) {
|
||||||
manager := NewNamespaceManager()
|
manager := NewNamespaceManager()
|
||||||
manager.Upsert(NamespaceEvent{Type: NamespaceEventAdd, Name: "tenant-a", Source: NamespaceSourceWatcher})
|
manager.Upsert(NamespaceEvent{Type: NamespaceEventAdd, Name: "tenant-a", Source: NamespaceSourceWatcher})
|
||||||
|
|||||||
Reference in New Issue
Block a user