package utils import ( "time" corev1 "k8s.io/api/core/v1" k8sCache "k8s.io/client-go/tools/cache" ) const ( NamespacePartStateRegistering string = "registering" NamespacePartStateActive string = "active" NamespacePartStateFailed string = "failed" ) type NamespacePhase string const ( NamespacePhaseDiscovered NamespacePhase = "discovered" NamespacePhaseRegistering NamespacePhase = "registering" NamespacePhaseActive NamespacePhase = "active" NamespacePhaseDeregistering NamespacePhase = "deregistering" NamespacePhaseRemoved NamespacePhase = "removed" NamespacePhaseFailed NamespacePhase = "failed" ) type NamespaceSource string const ( NamespaceSourceEnv NamespaceSource = "env" NamespaceSourceWatcher NamespaceSource = "watcher" NamespaceSourceBackfill NamespaceSource = "backfill" ) type NamespaceEventType string const ( NamespaceEventAdd NamespaceEventType = "add" NamespaceEventUpdate NamespaceEventType = "update" NamespaceEventRemove NamespaceEventType = "remove" NamespaceEventResync NamespaceEventType = "resync" ) type NamespaceRemovalStrategy string const ( NamespaceRemovalStrategyTrackOnly NamespaceRemovalStrategy = "track-only" NamespaceRemovalStrategyDispatchRemove NamespaceRemovalStrategy = "dispatch-remove" ) type NamespacePartState struct { State string LastError string UpdatedAt time.Time } type NamespaceRecord struct { Name string Source NamespaceSource Labels map[string]string Phase NamespacePhase LastError string Generation int64 UpdatedAt time.Time RegisteredParts map[string]NamespacePartState } type NamespaceEvent struct { Type NamespaceEventType Name string Labels map[string]string Source NamespaceSource ObservedAt time.Time } type NamespaceManagerSummary struct { TotalNamespaces int PhaseCounts map[NamespacePhase]int Subscribers []string } 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 NamespaceEventFromNamespace(eventType NamespaceEventType, namespace *corev1.Namespace, source NamespaceSource, observedAt time.Time) NamespaceEvent { if namespace == nil { return NewNamespaceEvent(eventType, "", nil, source, observedAt) } return NewNamespaceEvent(eventType, namespace.Name, namespace.Labels, source, observedAt) } func NamespaceFromObject(obj interface{}) (*corev1.Namespace, bool) { switch typed := obj.(type) { case *corev1.Namespace: return typed, true case k8sCache.DeletedFinalStateUnknown: namespace, ok := typed.Obj.(*corev1.Namespace) return namespace, ok case *k8sCache.DeletedFinalStateUnknown: if typed == nil { return nil, false } namespace, ok := typed.Obj.(*corev1.Namespace) return namespace, ok default: return nil, false } } func NamespaceEventFromObject(eventType NamespaceEventType, obj interface{}, source NamespaceSource, observedAt time.Time) NamespaceEvent { namespace, ok := NamespaceFromObject(obj) if !ok { return NewNamespaceEvent(eventType, "", nil, source, observedAt) } return NamespaceEventFromNamespace(eventType, namespace, source, observedAt) } func (nr NamespaceRecord) Clone() NamespaceRecord { clone := nr clone.Labels = cloneStringMap(nr.Labels) clone.RegisteredParts = cloneNamespacePartStates(nr.RegisteredParts) return clone } func (nr NamespaceRecord) IsActive() bool { return nr.Phase == NamespacePhaseActive } func (nr NamespaceRecord) IsTerminal() bool { return nr.Phase == NamespacePhaseRemoved || nr.Phase == NamespacePhaseFailed } func cloneStringMap(input map[string]string) map[string]string { if input == nil { return nil } clone := make(map[string]string, len(input)) for key, value := range input { clone[key] = value } return clone } func cloneNamespacePartStates(input map[string]NamespacePartState) map[string]NamespacePartState { if input == nil { return nil } clone := make(map[string]NamespacePartState, len(input)) for key, value := range input { clone[key] = value } return clone }