ananke/internal/cluster/orchestrator_startup_scope.go

82 lines
2.9 KiB
Go

package cluster
import "strings"
// startupRequiredNodes runs one orchestration or CLI step.
// Signature: startupRequiredNodes(nodes []string, required []string) []string.
// Why: lets startup enforce a smaller core node set during outage recovery
// without losing the stricter all-nodes behavior when no override is configured.
func startupRequiredNodes(nodes []string, required []string) []string {
requiredSet := makeStringSet(required)
if len(requiredSet) == 0 {
return nodes
}
filtered := make([]string, 0, len(nodes))
for _, node := range nodes {
node = strings.TrimSpace(node)
if node == "" {
continue
}
if _, ok := requiredSet[node]; ok {
filtered = append(filtered, node)
}
}
return filtered
}
// startupNodeStrictlyRequired runs one orchestration or CLI step.
// Signature: (o *Orchestrator) startupNodeStrictlyRequired(node string) bool.
// Why: absent or broken non-core nodes should not block recovery-only actions
// like label reconciliation once the operator has narrowed startup to core nodes.
func (o *Orchestrator) startupNodeStrictlyRequired(node string) bool {
node = strings.TrimSpace(node)
if node == "" {
return false
}
if len(o.cfg.Startup.NodeInventoryReachRequiredNodes) == 0 && len(o.cfg.Startup.NodeSSHAuthRequiredNodes) == 0 {
return true
}
for _, controlPlane := range o.cfg.ControlPlanes {
if strings.TrimSpace(controlPlane) == node {
return true
}
}
if containsNode(o.cfg.Startup.NodeInventoryReachRequiredNodes, node) {
return true
}
return containsNode(o.cfg.Startup.NodeSSHAuthRequiredNodes, node)
}
// startupRequiredFluxKustomizations runs one orchestration or CLI step.
// Signature: (o *Orchestrator) startupRequiredFluxKustomizations() map[string]struct{}.
// Why: lets outage recovery wait on a declared core GitOps slice while leaving
// optional stacks free to converge after bootstrap succeeds.
func (o *Orchestrator) startupRequiredFluxKustomizations() map[string]struct{} {
return makeStringSet(o.cfg.Startup.FluxHealthRequiredKustomizations)
}
// startupRequiredWorkloadNamespaces runs one orchestration or CLI step.
// Signature: (o *Orchestrator) startupRequiredWorkloadNamespaces() map[string]struct{}.
// Why: keeps workload readiness scoped to core namespaces during recovery while
// preserving broad convergence checks when no explicit core list is configured.
func (o *Orchestrator) startupRequiredWorkloadNamespaces() map[string]struct{} {
return makeStringSet(o.cfg.Startup.WorkloadConvergenceRequiredNamespaces)
}
// containsNode runs one orchestration or CLI step.
// Signature: containsNode(entries []string, needle string) bool.
// Why: keeps node-scope checks small and explicit anywhere startup narrows its
// recovery gates to a declared core set.
func containsNode(entries []string, needle string) bool {
needle = strings.TrimSpace(needle)
if needle == "" {
return false
}
for _, entry := range entries {
if strings.TrimSpace(entry) == needle {
return true
}
}
return false
}