diff --git a/doc/thinking/2026-04-26-namespace-manager-step15.md b/doc/thinking/2026-04-26-namespace-manager-step15.md new file mode 100644 index 00000000..c1b7d14b --- /dev/null +++ b/doc/thinking/2026-04-26-namespace-manager-step15.md @@ -0,0 +1,16 @@ +# 2026-04-26 — NamespaceManager rewrite, step 15 + +## Цель шага + +Добавить utility helper-методы для построения `NamespaceEvent`. + +## Что меняем + +1. Добавляем `NewNamespaceEvent()`. +2. Добавляем `ManagedNamespaceEvent()`. +3. Добавляем unit tests. + +## Что НЕ меняем + +- не подключаем event helpers к watcher-ам; +- не меняем runtime behavior. \ No newline at end of file diff --git a/pkg/utils/namespace_manager_model.go b/pkg/utils/namespace_manager_model.go index 25cf0bd3..cfde9040 100644 --- a/pkg/utils/namespace_manager_model.go +++ b/pkg/utils/namespace_manager_model.go @@ -61,6 +61,22 @@ type NamespaceEvent struct { ObservedAt time.Time } +func NewNamespaceEvent(eventType NamespaceEventType, name string, labels map[string]string, source NamespaceSource, observedAt time.Time) NamespaceEvent { + return NamespaceEvent{ + Type: eventType, + Name: name, + Labels: cloneStringMap(labels), + Source: source, + ObservedAt: observedAt, + } +} + +func ManagedNamespaceEvent(eventType NamespaceEventType, name string, source NamespaceSource, observedAt time.Time) NamespaceEvent { + return NewNamespaceEvent(eventType, name, map[string]string{ + ManagedNamespaceLabelKey: ManagedNamespaceLabelValue, + }, source, observedAt) +} + func (nr NamespaceRecord) Clone() NamespaceRecord { clone := nr clone.Labels = cloneStringMap(nr.Labels) @@ -98,4 +114,4 @@ func cloneNamespacePartStates(input map[string]NamespacePartState) map[string]Na clone[key] = value } return clone -} \ No newline at end of file +} diff --git a/pkg/utils/namespace_manager_model_test.go b/pkg/utils/namespace_manager_model_test.go index bfa68b2d..c52cceff 100644 --- a/pkg/utils/namespace_manager_model_test.go +++ b/pkg/utils/namespace_manager_model_test.go @@ -64,4 +64,25 @@ func TestNamespaceRecordIsTerminal(t *testing.T) { t.Fatalf("expected terminal=%v for phase %s", test.expected, test.phase) } } -} \ No newline at end of file +} + +func TestNewNamespaceEventClonesLabels(t *testing.T) { + now := time.Now().UTC() + labels := map[string]string{ManagedNamespaceLabelKey: ManagedNamespaceLabelValue} + event := NewNamespaceEvent(NamespaceEventAdd, "tenant-a", labels, NamespaceSourceWatcher, now) + labels[ManagedNamespaceLabelKey] = "false" + + if event.Labels[ManagedNamespaceLabelKey] != ManagedNamespaceLabelValue { + t.Fatalf("expected namespace event labels to be cloned") + } +} + +func TestManagedNamespaceEvent(t *testing.T) { + event := ManagedNamespaceEvent(NamespaceEventAdd, "tenant-a", NamespaceSourceWatcher, time.Now().UTC()) + if event.Labels[ManagedNamespaceLabelKey] != ManagedNamespaceLabelValue { + t.Fatalf("expected managed namespace label in event") + } + if event.Name != "tenant-a" { + t.Fatalf("expected tenant-a event name") + } +}