ananke/internal/cluster/orchestrator_vault_health.go
2026-07-07 18:29:51 -03:00

75 lines
2.4 KiB
Go

package cluster
import (
"context"
"fmt"
"strings"
"time"
)
// vaultSealed runs one orchestration or CLI step.
// Signature: (o *Orchestrator) vaultSealed(ctx context.Context) (bool, error).
// Why: treats exec and HTTP health as independent Vault signals so one flaky
// kubectl exec does not block startup when HTTP health proves Vault is usable.
func (o *Orchestrator) vaultSealed(ctx context.Context) (bool, error) {
sealed, err := o.vaultSealedViaExec(ctx)
if err == nil {
return sealed, nil
}
httpSealed, httpErr := o.vaultSealedViaHTTP(ctx)
if httpErr == nil {
o.log.Printf("warning: vault exec status probe failed but HTTP health succeeded; continuing with HTTP health result: %v", err)
return httpSealed, nil
}
return false, fmt.Errorf("vault status check failed: exec=%v http=%v", err, httpErr)
}
// vaultSealedViaExec runs one orchestration or CLI step.
// Signature: (o *Orchestrator) vaultSealedViaExec(ctx context.Context) (bool, error).
// Why: preserves the existing direct Vault CLI probe as the primary status
// signal when kubectl exec is healthy.
func (o *Orchestrator) vaultSealedViaExec(ctx context.Context) (bool, error) {
out, err := o.kubectl(
ctx,
25*time.Second,
"-n", "vault",
"exec", "vault-0", "--",
"sh", "-lc",
"VAULT_ADDR=http://127.0.0.1:8200 vault status -format=json 2>/dev/null || true",
)
if err != nil {
return false, fmt.Errorf("vault status check failed: %w", err)
}
sealed, err := parseVaultSealed(out)
if err != nil {
return false, fmt.Errorf("parse vault status: %w", err)
}
return sealed, nil
}
// vaultSealedViaHTTP runs one orchestration or CLI step.
// Signature: (o *Orchestrator) vaultSealedViaHTTP(ctx context.Context) (bool, error).
// Why: gives startup a second authoritative Vault health path when exec is
// transiently killed or the apiserver exec tunnel is degraded.
func (o *Orchestrator) vaultSealedViaHTTP(ctx context.Context) (bool, error) {
out, err := o.kubectl(
ctx,
15*time.Second,
"-n", "vault",
"get",
"--raw",
"/api/v1/namespaces/vault/pods/vault-0:8200/proxy/v1/sys/health",
)
if err != nil && strings.TrimSpace(out) == "" {
return false, fmt.Errorf("vault HTTP health check failed: %w", err)
}
sealed, parseErr := parseVaultSealed(out)
if parseErr != nil {
if err != nil {
return false, fmt.Errorf("vault HTTP health check failed: %w; parse: %v", err, parseErr)
}
return false, fmt.Errorf("parse vault HTTP health: %w", parseErr)
}
return sealed, nil
}