package app import "strings" type transportInterfacesStateSnapshot struct { ClientsUpdatedAt string InterfacesUpdatedAt string } type transportInterfacesOnlySnapshot struct { InterfacesUpdatedAt string } type transportPolicyPlanStateSnapshot struct { PolicyRevision int64 PlanPolicyRevision int64 } type transportOwnershipStateSnapshot struct { PolicyRevision int64 OwnershipPolicyRevision int64 OwnershipUpdatedAt string OwnershipPlanDigest string } func captureTransportInterfacesStateSnapshot(clients transportClientsState, ifaces transportInterfacesState) transportInterfacesStateSnapshot { return transportInterfacesStateSnapshot{ ClientsUpdatedAt: clients.UpdatedAt, InterfacesUpdatedAt: ifaces.UpdatedAt, } } func captureTransportInterfacesOnlySnapshot(ifaces transportInterfacesState) transportInterfacesOnlySnapshot { return transportInterfacesOnlySnapshot{InterfacesUpdatedAt: ifaces.UpdatedAt} } func captureTransportPolicyPlanStateSnapshot(policy TransportPolicyState, plan TransportPolicyCompilePlan) transportPolicyPlanStateSnapshot { return transportPolicyPlanStateSnapshot{ PolicyRevision: policy.Revision, PlanPolicyRevision: plan.PolicyRevision, } } func captureTransportOwnershipStateSnapshot(policy TransportPolicyState, ownership TransportOwnershipState) transportOwnershipStateSnapshot { return transportOwnershipStateSnapshot{ PolicyRevision: policy.Revision, OwnershipPolicyRevision: ownership.PolicyRevision, OwnershipUpdatedAt: ownership.UpdatedAt, OwnershipPlanDigest: ownership.PlanDigest, } } func compileTransportPolicyPlanForSnapshot( policy TransportPolicyState, clients []TransportClient, plan TransportPolicyCompilePlan, ) (TransportPolicyCompilePlan, bool) { if !transportPolicyPlanNeedsRecompile(policy, plan) { return plan, false } compiled, _ := compileTransportPolicyPlan(policy.Intents, clients, policy.Revision) return compiled, true } func transportPolicyPlanNeedsRecompile(policy TransportPolicyState, plan TransportPolicyCompilePlan) bool { if plan.PolicyRevision != policy.Revision { return true } for _, iface := range plan.Interfaces { ifaceID := normalizeTransportIfaceID(iface.IfaceID) for _, set := range iface.Sets { ownerScope := strings.TrimSpace(set.OwnerScope) if ownerScope == "" { return true } expected := transportPolicyNftSetName(ownerScope, set.SelectorType) if strings.TrimSpace(set.Name) != expected { return true } } for _, rule := range iface.Rules { ownerScope := strings.TrimSpace(rule.OwnerScope) expectedScope := transportPolicyNftOwnerScope(ifaceID, rule.ClientID) if ownerScope == "" || ownerScope != expectedScope { return true } expectedSet := transportPolicyNftSetName(ownerScope, rule.SelectorType) if strings.TrimSpace(rule.NftSet) != expectedSet { return true } } } return false } func saveTransportInterfacesIfSnapshotCurrent(snapshot transportInterfacesStateSnapshot, next transportInterfacesState) error { transportMu.Lock() defer transportMu.Unlock() currentClients := loadTransportClientsState() currentIfaces := loadTransportInterfacesState() if snapshot.ClientsUpdatedAt != currentClients.UpdatedAt { return nil } if snapshot.InterfacesUpdatedAt != currentIfaces.UpdatedAt { return nil } return saveTransportInterfacesState(next) } func saveTransportInterfacesIfUnchanged(snapshot transportInterfacesOnlySnapshot, next transportInterfacesState) error { transportMu.Lock() defer transportMu.Unlock() currentIfaces := loadTransportInterfacesState() if snapshot.InterfacesUpdatedAt != currentIfaces.UpdatedAt { return nil } return saveTransportInterfacesState(next) } func saveTransportPlanIfSnapshotCurrent(snapshot transportPolicyPlanStateSnapshot, next TransportPolicyCompilePlan) error { transportMu.Lock() defer transportMu.Unlock() currentPolicy := loadTransportPolicyState() if currentPolicy.Revision != snapshot.PolicyRevision { return nil } currentPlan := loadTransportPolicyCompilePlan() if currentPlan.PolicyRevision != snapshot.PlanPolicyRevision { return nil } if next.PolicyRevision != currentPolicy.Revision { return nil } return saveTransportPolicyCompilePlan(next) } func saveTransportOwnershipIfSnapshotCurrent(snapshot transportOwnershipStateSnapshot, next TransportOwnershipState) error { transportMu.Lock() defer transportMu.Unlock() currentPolicy := loadTransportPolicyState() if currentPolicy.Revision != snapshot.PolicyRevision { return nil } currentOwnership := loadTransportOwnershipState() if currentOwnership.PolicyRevision != snapshot.OwnershipPolicyRevision { return nil } if currentOwnership.UpdatedAt != snapshot.OwnershipUpdatedAt { return nil } if currentOwnership.PlanDigest != snapshot.OwnershipPlanDigest { return nil } if next.PolicyRevision != currentPolicy.Revision { return nil } return saveTransportOwnershipState(next) }