python-netgear-switch-library 0.0.post330__tar.gz → 0.0.post332__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/PKG-INFO +1 -1
- python_netgear_switch_library-0.0.post332/docs/_static/models/gs305ep.png +0 -0
- python_netgear_switch_library-0.0.post332/docs/_static/models/gsm7252ps.jpg +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/cli.rst +2 -2
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/index.rst +3 -3
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/transport.rst +2 -2
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/cli.rst +3 -3
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/conf.py +17 -2
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/development.rst +4 -4
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/fake/index.rst +8 -8
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/fake/internals.rst +7 -7
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/fake/serving.rst +10 -10
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/fake/testing.rst +11 -11
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/guide/concepts.rst +12 -11
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/guide/configuration.rst +3 -3
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/guide/installation.rst +4 -4
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/guide/principles.rst +4 -4
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/guide/quickstart.rst +8 -8
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/guide/reading.rst +8 -8
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/guide/writing.rst +22 -23
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/index.rst +7 -7
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/mcp.rst +2 -2
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/gs105pe.rst +4 -4
- python_netgear_switch_library-0.0.post332/docs/models/gs110emx.rst +53 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/gs305ep.rst +6 -6
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/gs728tpp.rst +9 -9
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/gsm7228ps.rst +10 -11
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/gsm7252ps.rst +6 -6
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/index.rst +3 -3
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/m4300-16x.rst +10 -9
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/m4300-24x.rst +8 -8
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/models/support.rst +6 -5
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/cli.rst +9 -9
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/http/cheetah-form.rst +6 -6
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/http/cheetah-v1.rst +11 -11
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/http/gambit.rst +11 -11
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/http/merge-hash-cgi.rst +13 -12
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/http/xml-api.rst +4 -4
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/http.rst +21 -22
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/index.rst +7 -7
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/nsdp.rst +25 -25
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/protocols/snmp.rst +11 -10
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/_version.py +2 -2
- python_netgear_switch_library-0.0.post330/docs/models/gs110emx.rst +0 -54
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/.github/workflows/ci.yml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/.github/workflows/deb.yml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/.github/workflows/publish-pypi.yml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/.gitignore +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/.readthedocs.yaml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/CLAUDE.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/LICENSE +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/README.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/RELEASING.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/debian/changelog +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/debian/control +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/debian/copyright +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/debian/rules +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/debian/source/format +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/Makefile +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_ext/filelinks.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_ext/support_tables.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_static/models/gs105pe.png +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_static/models/gs110emx.png +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_static/models/gs728tpp.png +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_static/models/gsm7228ps.jpg +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_static/models/m4300-16x.png +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_static/models/m4300-24x.png +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/_static/ngsw.css +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/core.rst +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/facades.rst +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/mcp.rst +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/operations.rst +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/protocols.rst +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/api/virtual.rst +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-15-foundation.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-17-slice-02-snmp-read-core.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-17-slice-03-read-apis.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-18-slice-04-snmp-write.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-18-slice-05-nsdp.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-18-slice-06-http.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-18-slice-07-cli.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-18-slice-08-packaging-ci.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/plans/2026-07-23-gsm7252ps-http-xe-dialect.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/specs/2026-07-15-netgear-control-library-design.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/superpowers/specs/2026-07-23-gsm7252ps-http-xe-dialect-design.md +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/packaging/apt-index.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/packaging/ci-build.sh +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/packaging/deb-version.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/pyproject.toml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/aio_api.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/capabilities.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli/capture.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli/context.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli/format.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli/main.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli/resolve.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli/safety.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/cli_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/config.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/errors.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/http_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/http_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/mcp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/mcp/server.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/models.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/nsdp_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/nsdp_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/cli/commands.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/cli/parse.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/http/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/http/crypt.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/http/endpoints.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/http/forms.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/http/parse.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/http/session.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/http/types.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/nsdp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/nsdp/auth.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/nsdp/client.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/nsdp/parsers.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/nsdp/protocol.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/nsdp/types.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/nsdp/write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/snmp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/snmp/client.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/snmp/oids.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/snmp/parse.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/protocols/snmp/write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/py.typed +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/registry.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/snmp_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/sync_api.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/aio/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/aio/nsdp_udp.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/aio/snmp_pysnmp.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/cli/console.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/cli/session.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/cli/ssh.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/cli/telnet.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/http/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/http/client.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/sync/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/sync/nsdp_udp.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/transport/sync/snmp_netsnmp_cli.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/cli_fastpath.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/faces/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/faces/cli.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/faces/http.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/faces/mibview.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/faces/nsdp.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/faces/snmp.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/seed.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/server.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/state.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_fastpath_vlan.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_fastpath_xui.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_gs105pe.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_gs110emx.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_gs110emx_templates.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_gs728tpp.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_gsm7228ps.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_gsm7252ps.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/src/netgear_switch/virtual/web_m4300.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/capture_parity.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_capture.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_cli_integration.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_control_poe_port.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_control_vlan_ip.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_format.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_main_framework.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_new_commands.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_op_coverage.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_prompt_wiring.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_read_commands.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_resolve.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_safety.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/cli/test_serve.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/conftest.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/captures/gsm7228ps.json +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/captures/gsm7252ps.json +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/captures/m4300-16x.json +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/captures/m4300-24x.json +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_lldp.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_mac_table.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_network.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_poe.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_vlan_brief.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7228ps_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_network.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_poe_port_info_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_vlan_90.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_vlan_brief.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/gsm7252ps_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_ip_management.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_poe_port_info_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_vlan_1.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_vlan_4.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_vlan_5.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_16x_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_ip_management.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_vlan_5.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_vlan_90.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/cli/m4300_24x_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs105pe_membership.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs105pe_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs105pe_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs105pe_status.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs105pe_switch_info.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs105pe_vlancfg.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_cf8021q.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_interface_stats.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_login.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_port_settings.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_redirect.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_sysinfo.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs110emx_vlanmembership.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs305ep_dashboard.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs305ep_login.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs305ep_membership.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs305ep_poestatus.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs305ep_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs305ep_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs305ep_vlancfg.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_device_info_and_sensors.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_lldp.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_macs.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_mgmt_ip.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_poe.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_ports.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_pvids_membership.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_vlan_membership_per_vlan.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gs728tpp_vlans.xml +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_basicAddressTable.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_ipConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_portPvidConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_portStatistics.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_sysInfo.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_vlanPortCfg_vlan5.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7228ps_vlanStatus.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_basicAddressTable.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_ipConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_login.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_portPvidConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_portStatistics.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_sysInfo.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan1.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan141.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/gsm7252ps_vlanStatus.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_16x_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_16x_mgmtVlanIpv4Configuration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_16x_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_16x_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_16x_vlanportcfg_vlan4.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_24x_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_addresstable.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_mgmtVlanIpv4Configuration.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_ports.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_sysinfo.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_vlanportcfg_vlan1.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/http/m4300_vlanstatus.html +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/snmp/gsm7252ps_fans.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/snmp/gsm7252ps_ifhighspeed.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/snmp/gsm7252ps_ifoperstatus.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/fixtures/snmp/gsm7252ps_psu.txt +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/http_specs.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/cli/test_cli_parse.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/http/test_crypt.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/http/test_endpoints.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/http/test_forms.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/http/test_parse.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/nsdp/test_auth.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/nsdp/test_parsers.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/nsdp/test_protocol.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/nsdp/test_write_frame.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_client.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_oids.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_parse_lldp_macs.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_parse_mgmt_ip.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_parse_poe_sensors.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_parse_ports.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_parse_system_info.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_parse_vlans.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/protocols/snmp/test_write_encode.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_aio_api.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_capabilities.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_cli_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_cli_vlan_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_cli_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_config.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_cross_backend_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_deb_version.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_docs_coverage.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_errors.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_facade_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_http_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_http_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_http_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_http_vlan_membership.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_http_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_http_xui_writes.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_import.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_mcp_server.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_models.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_models_snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_nsdp_integration.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_nsdp_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_nsdp_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_public_api.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_quality_gates.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_registry.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_snmp_integration.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_snmp_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_sync_api.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_version.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/test_write_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/_fastpath_fake.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_cli_console.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_cli_scp_cert.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_cli_telnet.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_http_client.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_nsdp_udp_sync.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_set_transport.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_snmp_netsnmp_cli.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_snmp_pysnmp.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/transport/test_value_parity.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_cli_cross_backend.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_cli_gsm7228ps_parity.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_gsm7228ps_seed.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_m4300_seeds.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_mibview.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_mutable_state.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_nsdp_state.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_serve_daemon.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_snmp_write_face.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_state_seed.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_switchport_vlan_write.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_virtual_http_face.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_virtual_nsdp_face.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_virtual_snmp_face.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/tests/virtual/test_web_projection.py +0 -0
- {python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/uv.lock +0 -0
{python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-netgear-switch-library
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.post332
|
|
4
4
|
Summary: Python library and CLI to query and control Netgear switches over SNMP, NSDP and HTTP.
|
|
5
5
|
Author-email: Tim Ansell <me@mith.ro>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -16,8 +16,8 @@ Entry point
|
|
|
16
16
|
Switch and credential resolution
|
|
17
17
|
--------------------------------
|
|
18
18
|
|
|
19
|
-
The shared path the CLI *and* the MCP server
|
|
20
|
-
|
|
19
|
+
The shared path the CLI *and* the MCP server use to turn arguments, environment
|
|
20
|
+
variables and an inventory into a ready :py:obj:`~netgear_switch.sync_api.SyncSwitch`.
|
|
21
21
|
|
|
22
22
|
.. automodule:: netgear_switch.cli.resolve
|
|
23
23
|
|
|
@@ -6,8 +6,8 @@ generated from the source.
|
|
|
6
6
|
|
|
7
7
|
Most callers need only :doc:`core` (the data model, the registry, the
|
|
8
8
|
capability oracle) and :doc:`facades` (:py:obj:`~netgear_switch.sync_api.SyncSwitch` and :py:obj:`~netgear_switch.aio_api.AsyncSwitch`).
|
|
9
|
-
The rest
|
|
10
|
-
|
|
9
|
+
The rest serves anyone reading the source, extending a backend, or building on
|
|
10
|
+
the protocol layer directly.
|
|
11
11
|
|
|
12
12
|
.. toctree::
|
|
13
13
|
:maxdepth: 2
|
|
@@ -39,7 +39,7 @@ Layering
|
|
|
39
39
|
transport/… sockets, subprocesses, sessions
|
|
40
40
|
|
|
41
41
|
``registry.py``, ``models.py``, ``errors.py``, ``capabilities.py`` and
|
|
42
|
-
``config.py`` sit beside all of it: every layer uses them, none of them
|
|
42
|
+
``config.py`` sit beside all of it: every layer uses them, none of them imports a
|
|
43
43
|
layer.
|
|
44
44
|
|
|
45
45
|
The package namespace
|
|
@@ -39,8 +39,8 @@ HTTP
|
|
|
39
39
|
CLI
|
|
40
40
|
---
|
|
41
41
|
|
|
42
|
-
Three transports for one command surface.
|
|
43
|
-
|
|
42
|
+
Three transports for one command surface. All three satisfy the ``CliSession``
|
|
43
|
+
protocol — and so does the mock's in-process CLI face.
|
|
44
44
|
|
|
45
45
|
.. automodule:: netgear_switch.transport.cli
|
|
46
46
|
|
{python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/cli.rst
RENAMED
|
@@ -14,7 +14,7 @@ state capture, and the mock switch daemons.
|
|
|
14
14
|
Selecting a switch
|
|
15
15
|
------------------
|
|
16
16
|
|
|
17
|
-
Two ways
|
|
17
|
+
Two ways; pick exactly one:
|
|
18
18
|
|
|
19
19
|
**From an inventory** — ``--switch NAME`` together with ``--config
|
|
20
20
|
<inventory.toml>``; ``--switch`` without ``--config`` is an error. Credentials
|
|
@@ -31,7 +31,7 @@ Choosing the protocol
|
|
|
31
31
|
---------------------
|
|
32
32
|
|
|
33
33
|
``--backend snmp|nsdp|http|ssh|telnet|console`` runs the operation over exactly
|
|
34
|
-
that protocol. If it cannot serve the operation the command fails saying so; it
|
|
34
|
+
that protocol. If it cannot serve the operation, the command fails saying so; it
|
|
35
35
|
is never re-routed. Without the flag, the model's default backend is used — see
|
|
36
36
|
:doc:`guide/concepts`.
|
|
37
37
|
|
|
@@ -115,7 +115,7 @@ The ``--model`` is only a placeholder to carry the host and credentials;
|
|
|
115
115
|
|
|
116
116
|
ngsw --switch core capture core-2026-07-31.json
|
|
117
117
|
|
|
118
|
-
This is how
|
|
118
|
+
This is how the project's fixtures and mock seeds are produced — see
|
|
119
119
|
:doc:`fake/internals`.
|
|
120
120
|
|
|
121
121
|
**Run mock switches for another tool to talk to**
|
{python_netgear_switch_library-0.0.post330 → python_netgear_switch_library-0.0.post332}/docs/conf.py
RENAMED
|
@@ -32,6 +32,9 @@ REPO_ROOT = DOCS_DIR.parent
|
|
|
32
32
|
sys.path.insert(0, str(DOCS_DIR / "_ext"))
|
|
33
33
|
sys.path.insert(0, str(REPO_ROOT / "src"))
|
|
34
34
|
|
|
35
|
+
# Imported after the path is set up, so a bare checkout resolves it too.
|
|
36
|
+
from netgear_switch.protocols.http.endpoints import HTTP_SPECS # noqa: E402
|
|
37
|
+
|
|
35
38
|
# -- Project ------------------------------------------------------------------
|
|
36
39
|
|
|
37
40
|
project = "python-netgear-switch-library"
|
|
@@ -73,8 +76,6 @@ exclude_patterns = [
|
|
|
73
76
|
"README.md",
|
|
74
77
|
]
|
|
75
78
|
|
|
76
|
-
# Single backticks mean "a Python object", which is what most inline references
|
|
77
|
-
# in this project are.
|
|
78
79
|
# Single backticks mean "literal", not "cross-reference". The library's
|
|
79
80
|
# docstrings use them loosely for prose and shell fragments (`snmpget`,
|
|
80
81
|
# `apt-get install -y snmp`, `type: ignore`), which a py:obj default role turns
|
|
@@ -84,6 +85,20 @@ exclude_patterns = [
|
|
|
84
85
|
# link to that file.
|
|
85
86
|
default_role = "literal"
|
|
86
87
|
|
|
88
|
+
# Counted from the library rather than written into the prose, because a
|
|
89
|
+
# hand-written count goes stale silently: this documentation claimed "Four
|
|
90
|
+
# distinct login schemes and five HTML dialects" when there were five and seven.
|
|
91
|
+
#
|
|
92
|
+
# There is deliberately no count of read or write OPERATIONS here. How many
|
|
93
|
+
# there are is not a useful thing for a reader to know -- the pages that used to
|
|
94
|
+
# open with one are followed immediately by a table naming every operation, so
|
|
95
|
+
# the number told nobody anything the table did not. What matters is that the
|
|
96
|
+
# set is the same on every backend, which is what those pages now say.
|
|
97
|
+
rst_prolog = f"""
|
|
98
|
+
.. |scheme-count| replace:: {len({s.scheme for s in HTTP_SPECS.values()})}
|
|
99
|
+
.. |dialect-count| replace:: {len({s.html_dialect for s in HTTP_SPECS.values()})}
|
|
100
|
+
"""
|
|
101
|
+
|
|
87
102
|
# Every cross-reference must resolve, or the build fails. This is what keeps the
|
|
88
103
|
# documentation actually hyperlinked: an unresolved `py:obj` renders as plain
|
|
89
104
|
# text, so without this a whole page of API names can silently stop being links
|
|
@@ -75,7 +75,7 @@ honest:
|
|
|
75
75
|
warnings fail the build, so the documentation cannot keep pointing at a file
|
|
76
76
|
that has been renamed or deleted.
|
|
77
77
|
|
|
78
|
-
Writing documentation
|
|
78
|
+
Writing documentation is therefore mostly a matter of naming files in double
|
|
79
79
|
backticks and letting the extension do the rest::
|
|
80
80
|
|
|
81
81
|
See ``src/netgear_switch/registry.py`` for the registry.
|
|
@@ -92,7 +92,7 @@ a real device, writing a seed, and when a verification flag may be flipped.
|
|
|
92
92
|
The rules
|
|
93
93
|
---------
|
|
94
94
|
|
|
95
|
-
:doc:`guide/principles` is
|
|
95
|
+
:doc:`guide/principles` is required reading for contributors. In particular:
|
|
96
96
|
|
|
97
97
|
* **Never declare something unsupported to finish a task.** If you cannot
|
|
98
98
|
implement it, say so plainly — naming the model, backend and operation — and
|
|
@@ -117,8 +117,8 @@ Releasing
|
|
|
117
117
|
---------
|
|
118
118
|
|
|
119
119
|
A rolling release: every merge to ``main`` publishes to PyPI and the apt
|
|
120
|
-
repository, with the version derived from git
|
|
121
|
-
|
|
120
|
+
repository, with the version derived from git — no manual version bumps. See
|
|
121
|
+
``RELEASING.md``.
|
|
122
122
|
|
|
123
123
|
Continuous integration
|
|
124
124
|
----------------------
|
|
@@ -24,8 +24,8 @@ Then, from any tool:
|
|
|
24
24
|
|
|
25
25
|
snmpwalk -v2c -c public 127.0.0.1:36540 1.3.6.1.2.1.1
|
|
26
26
|
|
|
27
|
-
Why
|
|
28
|
-
|
|
27
|
+
Why you can trust it
|
|
28
|
+
--------------------
|
|
29
29
|
|
|
30
30
|
A mock is only useful if it behaves like the thing it stands in for. This one is
|
|
31
31
|
built to a strict rule: **where the fake differs from real hardware, the fake is
|
|
@@ -59,12 +59,12 @@ can only ever agree with that code.
|
|
|
59
59
|
with a comment naming the host and firmware version it was observed on. A
|
|
60
60
|
finding that lives only in a report gets regressed by the next change.
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
Tools that know nothing about this library have cross-checked it too. The
|
|
63
|
+
third-party ProSafeLinux NSDP implementation decodes both mock switches
|
|
64
|
+
completely, every value matching the seed; the C tool ``ngadmin`` validated the
|
|
65
|
+
packet header — and surfaced a real four-byte sequence-number bug in the
|
|
66
|
+
process, since fixed. A mock validated only by the client that talks to it
|
|
67
|
+
proves nothing.
|
|
68
68
|
|
|
69
69
|
What it is not
|
|
70
70
|
--------------
|
|
@@ -82,9 +82,9 @@ The HTML dialects differ enough that each has its own renderer:
|
|
|
82
82
|
``web_gs105pe.py`` and ``web_gs728tpp.py``, with shared pieces in ``web.py``.
|
|
83
83
|
|
|
84
84
|
``web_gs110emx_templates.py`` is pure data: single-line HTML strings copied
|
|
85
|
-
byte-for-byte from real captures. It is excluded from lint precisely because
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
byte-for-byte from real captures. It is excluded from lint precisely because a
|
|
86
|
+
literal capture has no meaningful style to enforce, and reformatting it would
|
|
87
|
+
destroy its value as evidence.
|
|
88
88
|
|
|
89
89
|
From a real switch to a seed
|
|
90
90
|
----------------------------
|
|
@@ -96,8 +96,8 @@ From a real switch to a seed
|
|
|
96
96
|
:doc:`ngsw capture <../cli>` records the switch's full state via
|
|
97
97
|
:py:obj:`~netgear_switch.sync_api.SyncSwitch.snapshot`, and — given live access and a raw-walk callable — the
|
|
98
98
|
reference ``snmpbulkwalk`` output alongside it. The result is a JSON file used
|
|
99
|
-
**for reference** when hand-authoring a seed
|
|
100
|
-
directly
|
|
99
|
+
**for reference** when hand-authoring a seed; the mock deliberately never loads
|
|
100
|
+
it directly.
|
|
101
101
|
|
|
102
102
|
That last point is the important one. A seed is written by hand *from* a
|
|
103
103
|
capture, which forces a human to decide what each value means, and lets the
|
|
@@ -145,8 +145,8 @@ library:
|
|
|
145
145
|
* **ngadmin** (a C implementation) validated the packet header — and surfaced a
|
|
146
146
|
real four-byte sequence-number bug in the process, which was fixed.
|
|
147
147
|
|
|
148
|
-
The harness
|
|
149
|
-
|
|
148
|
+
The harness is a veth pair into a network namespace, so NSDP's broadcast
|
|
149
|
+
behaviour is exercised rather than bypassed.
|
|
150
150
|
|
|
151
151
|
Adding a model
|
|
152
152
|
--------------
|
|
@@ -11,8 +11,8 @@ tool — in any language — can talk to one when hardware is unavailable.
|
|
|
11
11
|
ngsw serve --all # every registered model
|
|
12
12
|
|
|
13
13
|
Each switch that comes up prints its model, bind address, the port it actually
|
|
14
|
-
bound for each protocol, and the credentials it accepts.
|
|
15
|
-
interrupted,
|
|
14
|
+
bound for each protocol, and the credentials it accepts. The command then blocks
|
|
15
|
+
until interrupted, stopping every switch cleanly.
|
|
16
16
|
|
|
17
17
|
.. code-block:: text
|
|
18
18
|
|
|
@@ -29,9 +29,9 @@ interrupted, at which point every switch is stopped cleanly.
|
|
|
29
29
|
community='public' http_password='password'
|
|
30
30
|
serving 10 mock switch(es); press Ctrl-C to stop
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
The model's registry entry decides which faces bind, which is why the GS110EMX
|
|
33
|
+
above offers NSDP and HTTP while the M7300 offers only SNMP — the mocks have
|
|
34
|
+
exactly the backends the real switches have.
|
|
35
35
|
|
|
36
36
|
Options
|
|
37
37
|
-------
|
|
@@ -60,8 +60,8 @@ Options
|
|
|
60
60
|
.. note::
|
|
61
61
|
|
|
62
62
|
A pinned port is a single listener, so ``--port``/``--http-port`` are only
|
|
63
|
-
accepted when serving exactly one model.
|
|
64
|
-
and read the printed ports.
|
|
63
|
+
accepted when serving exactly one model. When serving several, leave them
|
|
64
|
+
unset and read the printed ports.
|
|
65
65
|
|
|
66
66
|
One bad model never takes the fleet down: a switch that cannot bind is reported
|
|
67
67
|
and skipped, and the rest keep serving.
|
|
@@ -140,9 +140,9 @@ The FASTPATH CLI
|
|
|
140
140
|
|
|
141
141
|
The CLI face is deliberately **in-process**: it implements the ``CliSession``
|
|
142
142
|
protocol rather than binding an SSH or telnet listener, so there is no key
|
|
143
|
-
exchange or terminal emulation to fight.
|
|
144
|
-
:py:obj:`~netgear_switch.virtual.server.VirtualSwitch.cli_session`, not over a socket
|
|
145
|
-
|
|
143
|
+
exchange or terminal emulation to fight. Reach it through
|
|
144
|
+
:py:obj:`~netgear_switch.virtual.server.VirtualSwitch.cli_session`, not over a socket; ``ngsw serve`` therefore does
|
|
145
|
+
not expose it. See :doc:`testing`.
|
|
146
146
|
|
|
147
147
|
This library against a mock
|
|
148
148
|
---------------------------
|
|
@@ -133,8 +133,8 @@ Every backend takes an injected client:
|
|
|
133
133
|
All four at once
|
|
134
134
|
----------------
|
|
135
135
|
|
|
136
|
-
One mock, one facade, three protocols —
|
|
137
|
-
|
|
136
|
+
One mock, one facade, three protocols — what makes cross-backend behaviour
|
|
137
|
+
testable without hardware:
|
|
138
138
|
|
|
139
139
|
.. tab-set::
|
|
140
140
|
|
|
@@ -207,9 +207,9 @@ behaviour testable without hardware:
|
|
|
207
207
|
internal and link-aggregation interfaces (here, ifIndexes 418 and above)
|
|
208
208
|
that the web UI's port table does not list, and this model's VLAN 1 has two
|
|
209
209
|
ports SNMP shows as *configured* members while the web UI shows *current*
|
|
210
|
-
ones. Both are genuine properties of the two interfaces, not mock
|
|
211
|
-
``tests/test_cross_backend_equivalence.py`` restricts to physical
|
|
212
|
-
pins the known difference explicitly rather than hiding it.
|
|
210
|
+
ones. Both are genuine properties of the two management interfaces, not mock
|
|
211
|
+
artefacts — ``tests/test_cross_backend_equivalence.py`` restricts to physical
|
|
212
|
+
ports and pins the known difference explicitly rather than hiding it.
|
|
213
213
|
|
|
214
214
|
The CLI, with no SSH server
|
|
215
215
|
---------------------------
|
|
@@ -229,7 +229,7 @@ CLI backend.
|
|
|
229
229
|
Testing that your code handles refusals
|
|
230
230
|
---------------------------------------
|
|
231
231
|
|
|
232
|
-
The most valuable thing a faithful mock gives you
|
|
232
|
+
The *failure* paths are the most valuable thing a faithful mock gives you. The
|
|
233
233
|
mock refuses exactly what the hardware refuses, with the same message:
|
|
234
234
|
|
|
235
235
|
.. tab-set::
|
|
@@ -358,7 +358,7 @@ condition you want to test — a dead link, a PoE fault, a full MAC table:
|
|
|
358
358
|
binds, so a direct edit to ``state`` after ``start()`` is picked up by the
|
|
359
359
|
HTTP, NSDP and CLI faces — which read the state live — but **not** by SNMP.
|
|
360
360
|
Writes performed *through* a protocol rebuild the view and are consistent
|
|
361
|
-
everywhere;
|
|
361
|
+
everywhere; only out-of-band edits need to happen first.
|
|
362
362
|
|
|
363
363
|
Testing model detection
|
|
364
364
|
-----------------------
|
|
@@ -384,8 +384,8 @@ with the wrong model:
|
|
|
384
384
|
Smart Switch with PoE+ and 4 10G uplinks',
|
|
385
385
|
sys_object_id='1.3.6.1.4.1.4526.100.10.19')
|
|
386
386
|
|
|
387
|
-
|
|
388
|
-
|
|
387
|
+
Identification came from ``sysObjectID`` — the only way to tell this SKU apart
|
|
388
|
+
from the S3300-28X, whose ``sysDescr`` text is indistinguishable.
|
|
389
389
|
|
|
390
390
|
Testing tools that are not this library
|
|
391
391
|
---------------------------------------
|
|
@@ -435,7 +435,7 @@ A common case: your exporter or check script takes a host and a community.
|
|
|
435
435
|
|
|
436
436
|
Parametrising over models is where the fake earns its keep: the M4300-24X has no
|
|
437
437
|
PoE at all, the GS728TPP has no vendor OIDs, and the S3300 answers to a different
|
|
438
|
-
vendor subtree. Code
|
|
438
|
+
vendor subtree. Code written against a single switch tends to assume all three
|
|
439
439
|
away.
|
|
440
440
|
|
|
441
441
|
Choosing a model to test against
|
|
@@ -476,7 +476,7 @@ trustworthy:
|
|
|
476
476
|
session for ordinary page ``GET``\ s. Real firmware does.
|
|
477
477
|
* **Out-of-band state edits after** ``start()`` **are invisible to SNMP.** See
|
|
478
478
|
the note above.
|
|
479
|
-
* **The CLI face is in-process.**
|
|
479
|
+
* **The CLI face is in-process.** No SSH or telnet listener exists to test a
|
|
480
480
|
transport against; it exercises the command surface, not the connection.
|
|
481
481
|
* **Not every page of a real web UI exists** — only the pages the library uses.
|
|
482
482
|
|
|
@@ -13,7 +13,8 @@ SNMP vendor OID subtree, and a few per-model protocol dialect flags. The whole
|
|
|
13
13
|
registry lives in ``src/netgear_switch/registry.py``, and :py:obj:`~netgear_switch.registry.get_model` resolves a
|
|
14
14
|
key (or an alias, such as ``s3300`` for ``gsm7228ps``) to the record.
|
|
15
15
|
|
|
16
|
-
Models fall into three classes,
|
|
16
|
+
Models fall into three classes, and the class decides which protocols are
|
|
17
|
+
available:
|
|
17
18
|
|
|
18
19
|
Fully Managed (``FULLY_MANAGED``)
|
|
19
20
|
M4300, GSM7252PS. Full SNMP with the Netgear ``4526.10`` vendor subtree, a
|
|
@@ -48,18 +49,18 @@ A backend is *the protocol an operation travels over*:
|
|
|
48
49
|
- The Netgear Switch Discovery Protocol, over UDP. The only management
|
|
49
50
|
protocol besides the web UI on Plus switches.
|
|
50
51
|
* - ``HTTP``
|
|
51
|
-
- The switch's own web UI, scraped and driven as a browser would.
|
|
52
|
-
distinct login schemes and
|
|
52
|
+
- The switch's own web UI, scraped and driven as a browser would.
|
|
53
|
+
|scheme-count| distinct login schemes and |dialect-count| page dialects
|
|
54
|
+
across the fleet.
|
|
53
55
|
* - ``SSH`` / ``TELNET`` / ``CONSOLE``
|
|
54
56
|
- The FASTPATH command line. One command surface reached over three
|
|
55
57
|
transports; ``CONSOLE`` is a serial line rather than a network backend,
|
|
56
58
|
so it is never registered on a model.
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
gaps that remain.
|
|
60
|
+
Every read and every write is implemented on every backend a model has. That is
|
|
61
|
+
deliberate: if SNMP writes are locked down on your network, or the web UI is the
|
|
62
|
+
only port through a firewall, you can pick a different protocol and get the same
|
|
63
|
+
answer. :doc:`../models/support` lists the gaps that remain.
|
|
63
64
|
|
|
64
65
|
Dispatch: exactly one backend, every time
|
|
65
66
|
-----------------------------------------
|
|
@@ -181,9 +182,9 @@ All errors derive from :py:obj:`~netgear_switch.errors.NetgearSwitchError`. The
|
|
|
181
182
|
implemented yet" — a missing implementation is a bug to fix, not a
|
|
182
183
|
device limitation to document.
|
|
183
184
|
* - :py:obj:`~netgear_switch.errors.CredentialError`
|
|
184
|
-
- A credential is missing or wrong.
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
- A credential is missing or wrong. An SNMP agent **silently drops** an
|
|
186
|
+
unauthorised request, so a wrong write community looks exactly like an
|
|
187
|
+
unreachable host.
|
|
187
188
|
* - :py:obj:`~netgear_switch.errors.WriteVerificationError`
|
|
188
189
|
- The write was sent and accepted, but reading back did not show the
|
|
189
190
|
intended value.
|
|
@@ -65,7 +65,7 @@ Per switch:
|
|
|
65
65
|
* - ``nsdp.interface``
|
|
66
66
|
- no
|
|
67
67
|
- Interface to send NSDP from, e.g. ``eth0``. NSDP is broadcast-based, so
|
|
68
|
-
on a multi-homed host
|
|
68
|
+
this matters on a multi-homed host.
|
|
69
69
|
|
|
70
70
|
Secret specs
|
|
71
71
|
------------
|
|
@@ -176,7 +176,7 @@ Plus switch reached over NSDP is never asked for an SNMP community.
|
|
|
176
176
|
Protected ports
|
|
177
177
|
---------------
|
|
178
178
|
|
|
179
|
-
``protected_ports`` is enforced by the library, not
|
|
179
|
+
``protected_ports`` is enforced by the library, not only the CLI. Every write
|
|
180
180
|
that names a port checks it and raises :py:obj:`~netgear_switch.errors.ProtectedPortError` unless
|
|
181
181
|
``force=True``:
|
|
182
182
|
|
|
@@ -206,5 +206,5 @@ that names a port checks it and raises :py:obj:`~netgear_switch.errors.Protected
|
|
|
206
206
|
await switch.set_port_enabled(49, False) # ProtectedPortError
|
|
207
207
|
await switch.set_port_enabled(49, False, force=True) # proceeds
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
That one list is the cheapest guard against disabling the uplink you are
|
|
210
210
|
connected through.
|
|
@@ -62,8 +62,8 @@ The net-snmp system dependency
|
|
|
62
62
|
------------------------------
|
|
63
63
|
|
|
64
64
|
The **synchronous** SNMP transport shells out to the net-snmp command-line
|
|
65
|
-
tools rather than binding a Python SNMP library.
|
|
66
|
-
a Python dependency:
|
|
65
|
+
tools rather than binding a Python SNMP library. Those tools are a system
|
|
66
|
+
package, not a Python dependency:
|
|
67
67
|
|
|
68
68
|
.. code-block:: sh
|
|
69
69
|
|
|
@@ -104,8 +104,8 @@ Versioning
|
|
|
104
104
|
|
|
105
105
|
A **rolling release**. The version is derived from git by ``hatch-vcs``
|
|
106
106
|
(``0.0.postN``, or ``X.Y.postN`` once a ``vX.Y`` tag exists); every merge to
|
|
107
|
-
``main`` publishes to PyPI and to the apt repository.
|
|
108
|
-
|
|
107
|
+
``main`` publishes to PyPI and to the apt repository. No manual version bumps —
|
|
108
|
+
see ``RELEASING.md``.
|
|
109
109
|
|
|
110
110
|
.. note::
|
|
111
111
|
|
|
@@ -6,8 +6,8 @@ and each is stated here with the concrete failure that produced it — an abstra
|
|
|
6
6
|
principle is easy to rationalise around, a remembered bug is not. The canonical
|
|
7
7
|
text lives in ``CLAUDE.md`` at the repository root.
|
|
8
8
|
|
|
9
|
-
They matter to *users*
|
|
10
|
-
|
|
9
|
+
They matter to *users* because they explain what the library guarantees, and
|
|
10
|
+
what a message from it actually means.
|
|
11
11
|
|
|
12
12
|
1. Fail fast and loud
|
|
13
13
|
---------------------
|
|
@@ -52,7 +52,7 @@ is not a device limitation until proven otherwise. Remaining gaps are listed in
|
|
|
52
52
|
*Why:* every managed switch was once marked as having no HTTP VLAN-membership
|
|
53
53
|
path, so the web UI could neither report tagged/untagged membership nor write
|
|
54
54
|
it — while the same file already carried the working page for a sibling model.
|
|
55
|
-
|
|
55
|
+
The library also had no CLI write backend at all, though the FASTPATH command
|
|
56
56
|
sequences were known to work.
|
|
57
57
|
|
|
58
58
|
3. Models have parity
|
|
@@ -111,7 +111,7 @@ recorded — naming the firmware version it applies to.
|
|
|
111
111
|
The :doc:`virtual switch <../fake/index>` exists so this library can be tested
|
|
112
112
|
honestly without hardware. That only works if it is a **faithful** model of the
|
|
113
113
|
real devices — including their refusals, quirks and ordering requirements, not
|
|
114
|
-
|
|
114
|
+
only their happy paths.
|
|
115
115
|
|
|
116
116
|
* When live hardware differs from the mock, **the mock is wrong** and gets
|
|
117
117
|
fixed. Never adjust a test's expectation to match a mock already known to be
|
|
@@ -82,8 +82,8 @@ Either way:
|
|
|
82
82
|
netmask='255.255.255.0', gateway='10.1.5.1',
|
|
83
83
|
base_mac='E0:91:F5:0C:D6:DB')
|
|
84
84
|
|
|
85
|
-
That output is
|
|
86
|
-
|
|
85
|
+
That output is real GSM7252PS data: the mock is seeded from a capture of the
|
|
86
|
+
switch at 10.1.5.22, not from invented values. See :doc:`../fake/index`.
|
|
87
87
|
|
|
88
88
|
Talk to a real switch
|
|
89
89
|
---------------------
|
|
@@ -187,9 +187,9 @@ back to another protocol — see :doc:`concepts`.
|
|
|
187
187
|
|
|
188
188
|
That the three agree is asserted, not assumed —
|
|
189
189
|
``tests/test_cross_backend_equivalence.py`` compares them for every model with
|
|
190
|
-
more than one backend. They agree on the *physical* ports; SNMP
|
|
191
|
-
|
|
192
|
-
|
|
190
|
+
more than one backend. They agree on the *physical* ports; SNMP also reports
|
|
191
|
+
internal and link-aggregation interfaces that a web UI's port table does not
|
|
192
|
+
list, and one model has a VLAN where SNMP shows configured members and the
|
|
193
193
|
web UI shows current ones. Both are real properties of the interfaces, and the
|
|
194
194
|
tests pin them explicitly rather than papering over them.
|
|
195
195
|
|
|
@@ -198,7 +198,7 @@ Ask before you act
|
|
|
198
198
|
|
|
199
199
|
:py:mod:`netgear_switch.capabilities` answers "can this model do this, over
|
|
200
200
|
that?" without touching the switch. It is the same data that generates
|
|
201
|
-
:doc:`../models/support`,
|
|
201
|
+
:doc:`../models/support`, exposed as a plain function — nothing to await.
|
|
202
202
|
|
|
203
203
|
.. code-block:: python
|
|
204
204
|
|
|
@@ -254,8 +254,8 @@ rules this project follows when testing writes against live hardware.
|
|
|
254
254
|
Sweep a fleet
|
|
255
255
|
-------------
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
Concurrency is where the two APIs genuinely differ: the async facade talks to a
|
|
258
|
+
whole inventory at once.
|
|
259
259
|
|
|
260
260
|
.. tab-set::
|
|
261
261
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Reading a switch
|
|
2
2
|
================
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Every read below is available on :py:obj:`~netgear_switch.sync_api.SyncSwitch` and :py:obj:`~netgear_switch.aio_api.AsyncSwitch` alike, and each
|
|
5
|
+
takes an optional ``backend=``. They return frozen dataclasses from
|
|
6
6
|
`netgear_switch.models`, identical whichever protocol produced them.
|
|
7
7
|
|
|
8
8
|
The operations
|
|
@@ -129,7 +129,7 @@ Snapshots
|
|
|
129
129
|
snap = await switch.snapshot()
|
|
130
130
|
print(snap.model, snap.host, len(snap.ports), len(snap.vlans))
|
|
131
131
|
|
|
132
|
-
Fields
|
|
132
|
+
Fields the backend cannot serve degrade to ``()`` or ``None``. They are *not*
|
|
133
133
|
re-read over another protocol — so a snapshot describes what one protocol
|
|
134
134
|
really reports, rather than a blend of several. To compare protocols, take two
|
|
135
135
|
snapshots:
|
|
@@ -158,7 +158,7 @@ snapshots:
|
|
|
158
158
|
over_web = await switch.snapshot(backend=Backend.HTTP)
|
|
159
159
|
assert over_snmp.vlans == over_web.vlans
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
The cross-backend equivalence tests do exactly this; see
|
|
162
162
|
``tests/test_cross_backend_equivalence.py``.
|
|
163
163
|
|
|
164
164
|
.. note::
|
|
@@ -172,8 +172,8 @@ This is exactly what the cross-backend equivalence tests do; see
|
|
|
172
172
|
Reading a fleet
|
|
173
173
|
---------------
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
Here the two APIs stop being interchangeable: the asynchronous facade reads
|
|
176
|
+
every switch at once, the synchronous one reads them in turn.
|
|
177
177
|
|
|
178
178
|
.. tab-set::
|
|
179
179
|
|
|
@@ -257,8 +257,8 @@ Handling refusals
|
|
|
257
257
|
Capturing what a switch says
|
|
258
258
|
----------------------------
|
|
259
259
|
|
|
260
|
-
``ngsw capture`` writes a complete JSON record of a switch's readable state
|
|
261
|
-
|
|
260
|
+
``ngsw capture`` writes a complete JSON record of a switch's readable state.
|
|
261
|
+
This project's fixtures and mock seeds are produced with it:
|
|
262
262
|
|
|
263
263
|
.. code-block:: sh
|
|
264
264
|
|