fix: recover externally removed Talos VMs #29

Merged
eding merged 5 commits from fix/rebuild-absent-vm into main 2026-09-06 10:55:18 +02:00
2 changed files with 27 additions and 1 deletions
Showing only changes of commit 214b00720a - Show all commits

View file

@ -330,6 +330,13 @@ func refreshExternalSecrets(kubeconfig string) error {
if err != nil {
return fmt.Errorf("refresh OpenBao secret store after seed: %w", err)
}
webhook, err := kubectlOutput(kubeconfig, "get", "externalsecret", "forgejo-webhook", "-n", "tekton-pipelines", "--ignore-not-found", "-o=name")
if err != nil {
return fmt.Errorf("check Forgejo webhook ExternalSecret after OpenBao seed: %w", err)
}
if strings.TrimSpace(string(webhook)) == "" {
return nil
}
_, err = kubectlOutput(kubeconfig, externalSecretRefreshArgs(timestamp)...)
if err != nil {
return fmt.Errorf("refresh ExternalSecrets after OpenBao seed: %w", err)

View file

@ -84,13 +84,32 @@ func TestRefreshExternalSecretsIsReadyGatedAndScoped(t *testing.T) {
if len(calls) == 1 {
return []byte("True"), nil
}
if len(calls) == 3 {
return []byte("externalsecret.external-secrets.io/forgejo-webhook"), nil
}
return nil, nil
}
if err := refreshExternalSecrets("kubeconfig"); err != nil || len(calls) != 3 || !strings.Contains(calls[0], "get deployment/external-secrets") || !strings.Contains(calls[1], "annotate clustersecretstore openbao") || !strings.Contains(calls[2], "annotate externalsecret forgejo-webhook") || strings.Contains(calls[1], "--all") || strings.Contains(calls[2], "--all") {
if err := refreshExternalSecrets("kubeconfig"); err != nil || len(calls) != 4 || !strings.Contains(calls[0], "get deployment/external-secrets") || !strings.Contains(calls[1], "annotate clustersecretstore openbao") || !strings.Contains(calls[2], "get externalsecret forgejo-webhook") || !strings.Contains(calls[3], "annotate externalsecret forgejo-webhook") || strings.Contains(calls[1], "--all") || strings.Contains(calls[3], "--all") {
t.Fatalf("ExternalSecret refresh was not readiness-gated and scoped: %q, %v", calls, err)
}
}
func TestRefreshExternalSecretsSkipsWebhookBeforeTekton(t *testing.T) {
original := kubectlOutput
t.Cleanup(func() { kubectlOutput = original })
var calls []string
kubectlOutput = func(_ string, args ...string) ([]byte, error) {
calls = append(calls, strings.Join(args, " "))
if len(calls) == 1 {
return []byte("True"), nil
}
return nil, nil
}
if err := refreshExternalSecrets("kubeconfig"); err != nil || len(calls) != 3 || !strings.Contains(calls[2], "--ignore-not-found") {
t.Fatalf("missing webhook ExternalSecret was not safely skipped: %q, %v", calls, err)
}
}
func TestReadRecoveryMaterialDecryptsAndValidatesBundle(t *testing.T) {
original := decryptRecovery
t.Cleanup(func() { decryptRecovery = original })