proxmox: thin HTTP client, seam, log decorator and in-memory fake

httpAPI implements the sixteen seam methods over net/http: the token is
read per request, non-2xx answers become apiError from the body message or
the reason phrase, echoed secrets are redacted, the CA loads lazily, HTTP/2
is off, and uploads stream with an exact Content-Length. The observed
decorator logs one V(1) line per call and starts no span; New wires both.
fakeAPI simulates clone locks, tasks and ISOs with the captured error texts.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-23 14:47:50 +00:00
co-authored by Claude Opus 5.5
parent 0a6c8624f3
commit e05d994974
9 changed files with 2775 additions and 7 deletions
+6 -4
View File
@@ -76,9 +76,11 @@ func New(ctx context.Context, pc provider.ProviderConfig) (provider.Provider, er
if pc.Proxmox != nil {
cfg = *pc.Proxmox
}
// The HTTP client behind the api seam arrives in Phase 4 of the plan;
// until then every method is a stub that makes no request.
p := newProvider(pc.Name, cfg, nil)
client, err := newHTTPAPI(withDefaults(cfg))
if err != nil {
return nil, fmt.Errorf("proxmox provider %s: %w", pc.Name, err)
}
p := newProvider(pc.Name, cfg, observe(client, pc.Name))
log := p.logger(ctx)
if _, err := os.Stat(p.cfg.TokenFile); err != nil {
log.Info("WARNING: token file is not readable; every call fails until it is", "path", p.cfg.TokenFile, "reason", err.Error())
@@ -89,7 +91,7 @@ func New(ctx context.Context, pc provider.ProviderConfig) (provider.Provider, er
return p, nil
}
// newProvider is the constructor tests use, with a in-memory api.
// newProvider is the constructor tests use, with an in-memory api.
func newProvider(name string, cfg provider.ProxmoxConfig, a api) *Provider {
return &Provider{
name: name,