feat(ansible): openwrt-iot-vlan role foundation (Phase C start) #112

Merged
kblack0610 merged 2 commits from feat/openwrt-iot-vlan-role into master 2026-07-09 19:28:14 +00:00
Owner

Phase 0 (inert foundation) of the IoT VLAN isolation project: the community.openwrt-based openwrt-iot-vlan Ansible role. Applies nothing until run; disruptive steps gated behind default-false vars. Verified with a read-only --check --diff against the live router. (Re-opened from #110 after a concurrent-session branch collision on the shared checkout.)

Phase 0 (inert foundation) of the IoT VLAN isolation project: the community.openwrt-based openwrt-iot-vlan Ansible role. Applies nothing until run; disruptive steps gated behind default-false vars. Verified with a read-only --check --diff against the live router. (Re-opened from #110 after a concurrent-session branch collision on the shared checkout.)
Phase 1 of the Spotify-as-a-module plan. First OAuth integration seeded here.

- seed-spotify init container writes BOTH storage files (format verified vs HA
  source, logic unit-tested, idempotent, non-destructive):
  * .storage/application_credentials (items=LIST; auth_domain=spotify)
  * .storage/core.config_entries spotify entry with the OAuth token blob;
    token.expires_at=0 so HA refreshes on boot from refresh_token + client creds.
  Runs only when the OPTIONAL spotify-credentials secret exists (pod boots fine
  without it).
- spotify-ha-bootstrap.py: mints a refresh token with HA's exact 10 SPOTIFY_SCOPES
  (a superset that also satisfies the concerts bridge) + fetches the Spotify user
  id/name the seeder needs.
- spotify-secret.yaml.template: the creds shape.

INERT until the SOPS secret is created from real creds — NOT merged yet; will
verify media_player.spotify end-to-end (real token refresh) before merging.
No dashboard edits needed: media_player.spotify auto-appears in the domain-
filtered Media/Speakers cards.
Starts the repo's Phase C (OpenWrt config on Ansible) with the first role:
isolate the IoT SSID onto its own VLAN. Uses the community.openwrt collection
whose modules are pure shell (ash) - no Python on the router - and whose uci
module is genuinely idempotent (check_mode + diff_mode), unlike openwrt.sh.

This commit is the inert foundation (Phase 0): the role, the play wiring, and
connection tuning. It applies NOTHING until run, and the disruptive steps
(firewall, SSID migration) are gated behind default-false vars, so a plain run
only creates the non-disruptive br-iot interface + DHCP pool.

- requirements.yml: + community.openwrt (>=1.0.0; needs ansible-core >= 2.18 on
  the control node; runner image bump is a separate follow-up).
- group_vars/openwrt: piped SSH transfer (no SFTP on OpenWrt); python_interpreter
  /bin/false (never run Python on the router).
- roles/openwrt-iot-vlan: network (portless br-iot bridge + iot interface), dhcp
  (per-interface pool), wireless (test SSID / real-SSID migration), firewall
  (iot zone: IoT->WAN allow, IoT->LAN block, LAN->IoT allow, DHCP/DNS input,
  one MQTT pinhole). Portless bridge over VLAN-filtering because Filogic/mt76 has
  confirmed VLAN-filtering bugs. Full runbook in the role README.
- site.yml: openwrt play (gather_facts: false; community.openwrt.init tags:always).

Verified: ansible-playbook --limit openwrt --check --diff connects via the
shell path and previews exactly the intended non-disruptive network+dhcp config
(br-iot device, iot interface 192.168.20.1/24, iot dhcp pool); firewall and
wireless tasks correctly skip on the default gates; 0 failed, 0 unreachable.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kblack0610/home-config!112
No description provided.