Replace the single `switch_admin_user` day-2 task with a `switch_operators`
list in host_vars: one RouterOS user per person, each with the public keys
that may log in as it. Logins become attributable and revocable per person
instead of accreting as extra keys on `sjat`.
Adds claus@stjerno.dk as user `claus` (group full), and codifies the two
keys already on the device (sjat's mamba seat, the claude@ubongo automation
seat that was hand-imported earlier today).
Two things the mechanism has to get right:
- Idempotency: query /user/ssh-keys first and upload only missing keys.
An unconditional net_put reports changed on every run.
- No passwordless accounts: WinBox/console accept an empty password and
WinBox is deliberately left on for recovery, so each operator gets a
vaulted password. users.yml asserts one exists before touching anything.
Verified: yamllint, ansible-lint (production), syntax-check, and the play
run twice against crs310-maker — second run changed=0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EyYJWABgSEHzbjsZGrkxVE
Makerspace experiment: plug into ether8 and get a 192.168.88.x lease, reach the
admin at http://192.168.88.1 (web UI re-enabled) / WinBox / SSH. Login still
required; default admin stays disabled. mamba keeps static .2 (outside the pool).
New flags switch_web_enabled + switch_mgmt_dhcp_enabled/pool/network (off by
default). Verified: www HTTP 200, lease handed out + bound, run-twice idempotent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
host_vars: DATA VLAN 30 (ether1 uplink + ether2-7 + sfp1/2), isolated MGMT VLAN 99
on ether8, mgmt 192.168.88.1/24, no gateway, NTP disabled. Role: switch_ntp_enabled
flag (enable/disable NTP), conditional default route (skip when no gateway), and a
guarded removal of the legacy defconf bridge IP so the mgmt IP lives only on vlan-mgmt.
Membership Jinja re-validated; lint+syntax clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>