This is the provider being promoted to v0.1.0: a Python/Pyvider implementation with the original provider's schema and hardware-verified reads and writes against the Archer AX23 v2.0 (firmware 1.1.2 Build 20250814) — the only advertised target. The original Go implementation has been retired and is available only through Git history.
It uses Pyvider 0.8.1 for Terraform protocol v6 and the reviewed tplinkrouterc6u fork commit 588f74f57a35e3818deb40825c8788d0240a2f62
for the TP-Link SG router protocol. No sidecar or duplicated router crypto.
Current proof:
- seven resources/data sources with compatible schemas for migrating existing state
tplink_dhcp_reservationandtplink_port_forwardCRUD adapters- read-only
tplink_firmware,tplink_router,tplink_devices,tplink_dhcp_reservations, andtplink_port_forwards - Terraform plan/apply/import/replacement/drift/destroy against a CI-only persistent mock router, without physical router changes
- Terraform schema handshake for the Python development wrapper and frozen Linux binary; packaged Windows/macOS/Linux schema tests have passed in CI
- the pinned fork commit adds hardware-tested in-place DHCP updates and RSA key checks; replace the Git dependency with a released library once upstream accepts it
Hardware verification status: full read parity (five data sources, compared
field-by-field against the Go provider) and a complete write lifecycle
(create/update/import/destroy of disposable rows) executed on the AX23 v2;
session-expiry handling covered by unit tests. Transport timeouts do not trigger write replay. NixOS frozen-executable
execution requires programs.nix-ld.enable = true; — the only runtime
requirement. Remaining release work: transitive source/license archive verification, signing configuration,
and registry registration (RELEASING.md).
This prototype explicitly selects TplinkRouterSG instead of the legacy
auto-detect routine to avoid credential-probing across router families.
Switch to upstream get_client_safe when that API lands.
Run isolated unit tests:
python -m venv .venv
. .venv/bin/activate
pip install -e './python[test]'
pytest python/testsThe Go build and release workflow has been removed. Any final Python registry package must be a self-contained single executable tested through the full provider installation lifecycle.
The project and frozen Python executable are GPL-3.0-or-later covered. The retired Go implementation remains available in Git history under MIT. The packaging workflow gathers a source archive and license inventory for each platform. Release publication is blocked when a dependency source archive cannot be obtained; review the resulting archive and license evidence before the first public release.
The retired Go cmd/keyprobe has been replaced by a Python read-only
probe. Run python -m tplink_py.keyprobe --host http://192.168.0.1
over a trusted connection and separately verify the fingerprints before
configuring password_key_pin and auth_key_pin. The command reads
the two public RSA keys without authenticating.
The provider schema exposes optional password_key_pin and auth_key_pin
attributes, equivalent to the originally verified RSA
pre-authentication SPKI fingerprints. The pins must be enrolled over a trusted
connection. They are intentionally optional; configuring them against a Python
library without SG pin verification fails closed instead of silently ignoring
them.
The pinned library commit includes both key checks and explicit SG session-expiry errors. A separate,
unmerged fork PR #3
contains an alternative implementation; it is not the code installed
by this provider. The immutable commit and its branch reachability are checked in CI against
dependency-lock.json.
The pinned dependency commit contains both SG pin verifiers. Its
test/test_sg_key_pins.py tests are run against that exact commit in provider CI.
Correctly pinned login and mismatched password/authentication pins were checked
on the AX23. In each mismatch case authorization failed before session setup.
No router I/O occurs during provider configuration.
The replacement for cmd/tfinventory uses the pinned Python SG client and
never changes router configuration. It writes inventory.auto.tfvars and
imports.tf with restrictive file permissions. Both contain private LAN data
and must remain gitignored.
. .venv/bin/activate
export TPLINK_PASSWORD='...'
# Optionally supply trusted fingerprints via TPLINK_PASSWORD_KEY_PIN / TPLINK_AUTH_KEY_PIN
python -m tplink_py.inventory --dry-run --dir /path/to/nix/infra/router
python -m tplink_py.inventory --dir /path/to/nix/infra/routerReview both generated files and confirm that existing household reservations
are preserved before tofu plan. Never run tofu apply until the plan has
been checked. This tool requires local access to the router; all of its tests
run against local objects only.