hub v0.61.0 + felhom-tenantsync v1.1.0: Customer RESET (middle lifecycle tier)
One operator action returns a customer to pre-first-install: all operational state dies (offsite repo, PBS namespace+backups, DR recipe, one-time secret, claim state, retained escrow custody); identity + basic config + provenance + events survive. Sits between host delete and customer Delete. - store/customer_reset.go: customer_resets journal, live inventory, ack-gated purge (never touches identity/provenance/events), DeleteClaim. - claim.ResetToUnclaimed: delete claim row -> fresh code next onboarding. - offsite.Deprovision (idempotent) + OffsiteIdentifier + ClearProvisionedDescriptor. - tenantsync.Deprovision + felhom-tenantsync.sh deprovision op (destroys ns + backup groups + token; shared user untouched; idempotent). - web/customer_reset.go: GET reset -> inventory JSON; POST -> orchestration (external teardown FIRST, DB purge LAST; refuse-while-hosts; typed-id + separate escrow ack). Amber RESET card distinct from red Danger-zone Delete. - Red-proofs: ack-gate + partial-failure resumability (both proven red); store ack-gating + journal round-trip; offsite idempotency + descriptor clear; RESET-card render. Green: build + vet + test.
This commit is contained in:
@@ -24,11 +24,14 @@ import (
|
||||
)
|
||||
|
||||
type fakeTenancy struct {
|
||||
provisionCalls int
|
||||
reissueCalls int
|
||||
err error // both ops fail with this
|
||||
provisionErr error // Provision-only failure (the F-14 token_exists shape: reissue still works)
|
||||
secret string
|
||||
provisionCalls int
|
||||
reissueCalls int
|
||||
deprovisionCalls int
|
||||
err error // both ops fail with this
|
||||
provisionErr error // Provision-only failure (the F-14 token_exists shape: reissue still works)
|
||||
deprovisionErr error // Deprovision-only failure (RESET partial-failure red-proof)
|
||||
deprovisionExisted bool // what Deprovision reports (namespace existed / was destroyed)
|
||||
secret string
|
||||
}
|
||||
|
||||
func (f *fakeTenancy) result(customerID string) *tenantsync.Result {
|
||||
@@ -60,6 +63,17 @@ func (f *fakeTenancy) Reissue(ctx context.Context, customerID string) (*tenantsy
|
||||
return f.result(customerID), nil
|
||||
}
|
||||
|
||||
func (f *fakeTenancy) Deprovision(ctx context.Context, customerID string) (bool, error) {
|
||||
f.deprovisionCalls++
|
||||
if f.deprovisionErr != nil {
|
||||
return false, f.deprovisionErr
|
||||
}
|
||||
if f.err != nil {
|
||||
return false, f.err
|
||||
}
|
||||
return f.deprovisionExisted, nil
|
||||
}
|
||||
|
||||
// newPBSDRServer builds a server + store with the full provisioning preconditions satisfied:
|
||||
// customer config, enrolled host, WG endpoint record, bound WG peer. The logger is captured so
|
||||
// tests can grep-assert the secret never reaches it.
|
||||
|
||||
Reference in New Issue
Block a user