Plenty of writes now works and an expanded example exists in the terraform directory

This commit is contained in:
Joachim Friberg committed 2026-08-25 20:25:08 +02:00
1 parent a6f1019175
commit fb8d468943
15 files changed
+1344 -74

No files matched your search

+62 -2
View File
@@ -100,8 +100,68 @@ toolchain/`go.mod`, not nested in this Python project), scaffolded from HashiCor
further write resources in the risk-triage order below (Safe category first).
- **Status (2026-08-25)**: all 13 data sources are ported and verified with a live
`tofu plan` against the real switch (`~/code/experiments/hpe/terraform/`) — confirmed
port 24 (the active uplink) reads `Link Up`, all other ports `Link Down`. Only
`resource_locator` (and further write resources) remain unbuilt.
port 24 (the active uplink) reads `Link Up`, all other ports `Link Down`.
`resource_locator` is fully built and its whole CRUD lifecycle verified live: `Create`
(enabled=true), `Update` (enabled=false), and `Delete` (`tofu destroy -target=...` ->
reset-to-Disable) all round-tripped correctly, each confirmed visually by the LED
blinking/stopping. First write resource is done end-to-end.
`resource_green_features` (Green Mode, Mode LED Time, Phy Auto Power-Down -- all three
submitted together per write, since the firmware form has no per-field submission) is
also built and its whole CRUD lifecycle verified live: `Create` matched the switch's
actual state, `Update` (mode_led_time 1->5) and `Delete` (reset to factory defaults:
Enable/10/Enable) both confirmed directly via curl against the switch (no LED to eyeball
for this one).
`resource_port` (`hpe1810_port`, `PortConfiguration.html`) is also built and its whole
CRUD lifecycle verified live, driven by `for_each` over a `var.ports` map keyed by port
number (see `~/code/experiments/hpe/terraform/variables.tf`). This page needed dedicated
handling beyond the generic parser -- see `client/port_config.go`'s doc comment for the
full writeup, short version: (1) port selection is a `submit_flag=1` reload POST with
`v_1_1_1=<port>`, not a query param; (2) the page has three duplicate-labeled "Link
Speed" rows (`v_1_8_1`/`v_1_13_1`/`v_1_15_1`, one per SFP/PHY group) that read the same
but do NOT accept the same values on write -- confirmed live, submitting all three at
once was rejected; only `v_1_8_1` (the "No SFP"/RJ45-copper field, which covers every
port on this switch) is used, and any other Physical Type is explicitly rejected rather
than guessed at; (3) three hidden context fields (`v_1_21_1` UnitIndex, `v_1_31_1`
duplicate interface, `v_1_2_1` mstid) must be included on every write or the switch
rejects with `FILTER_MISSING` -- also confirmed live, hardcoded to their observed
constant values since this is a single, non-stacked unit.
New provider-level `admin_port` attribute (int, default **24**, env fallback
`HPE1810_ADMIN_PORT`) protects the switch's uplink: `resource_port`'s `Create`/
`Update`/`Delete` all refuse to touch that interface, verified live -- a scratch resource
targeting interface 24 was correctly rejected with a diagnostic error, and port 24's live
state (`Enable`/`Auto`/`Link Up`) was confirmed unchanged afterward via curl. Full CRUD
(`Create`, `Update` speed 100->10 Mbps, `Delete` -> Disable+Auto) verified live on port 5
only, then restored to its original state (`Enable`/`100 Mbps Full Duplex`).
`resource_system_description` (`hpe1810_system_description`, `SysDescription.html`) is
also built and verified live: only 3 of the page's 9 fields are actually writable (System
Name/Location/Contact, `v_1_2_1`/`v_1_3_1`/`v_1_4_1`) -- confirmed by the page's own
client-side validation script only defining error messages for those three field ids; the
rest (Description, Software Version, Object ID, Up Time, Current Time, Date) stay
read-only, exclusively on the data source. Note this resource's TypeName intentionally
collides with the data source's (`hpe1810_system_description`) -- fine, since Terraform
keeps `resource.*`/`data.*` in separate namespaces. `Create` applied live (System Name
`Draupnir01` -> `draupnir01`), confirmed via curl. Delete resets all three fields to `""`.
Next write resources per the risk triage: Jumbo Frames, then Ping Test.
Note: switch only used on port 24 for uplink — avoid touching that port in any future
port-configuration resource testing.
- **`save_running_config` provider flag (2026-08-25)**: new optional provider attribute
(`HPE1810_SAVE_RUNNING_CONFIG` env fallback, default `false`). If `true`, `Shutdown()`
(called once at process exit, same place as the logout below) POSTs to
`SaveAllChanges.html` ("Save Configuration" in the web UI) -- but ONLY if
`client.Dirty()` is also true, i.e. some `SubmitForm` call actually succeeded this run.
`Client.dirty` is an `atomic.Bool` set inside `SubmitForm` on any successful write.
Rationale (user's, 2026-08-25): config is already source-of-truth as IaC, saving isn't
critical, and unconditionally saving on every `tofu` invocation would wear the switch's
flash for no reason -- so it only fires on runs that actually changed something, and even
then only when explicitly opted into. Verified live: `SaveAllChanges.html` accepts the
same POST shape `SubmitForm` sends (`err_flag=0` back, confirmed via curl); an
apply with `save_running_config=true` that wrote a real change completed with no errors.
- **Session logout on shutdown**: found `GET /index.html?logout=1` invalidates the session
(undocumented, discovered by probing — no `/hp_logout.html` or similar exists).
`client.Logout()` calls it; `main.go` calls `p.Logout()` right after
`providerserver.Serve` returns (process shutdown), freeing the switch's one session slot
so the *next* `tofu` invocation doesn't have to wait out the ~5 min session timeout.
Verified live: two `tofu plan` runs back-to-back now both succeed.
### What this means for code written in this Python project meanwhile