python-netgear-switch-library 0.0.post350__tar.gz → 0.0.post352__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.post350 → python_netgear_switch_library-0.0.post352}/PKG-INFO +1 -1
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/_version.py +2 -2
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/models.py +11 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/cli/parse.py +35 -3
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/seed.py +21 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/state.py +49 -0
- python_netgear_switch_library-0.0.post352/tests/virtual/test_syslog_fidelity.py +68 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/.github/workflows/ci.yml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/.github/workflows/deb.yml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/.github/workflows/publish-pypi.yml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/.gitignore +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/.readthedocs.yaml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/CLAUDE.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/LICENSE +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/README.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/RELEASING.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/debian/changelog +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/debian/control +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/debian/copyright +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/debian/rules +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/debian/source/format +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/Makefile +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_ext/filelinks.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_ext/support_tables.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/gs105pe.png +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/gs110emx.png +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/gs305ep.png +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/gs728tpp.png +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/gsm7228ps.jpg +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/gsm7252ps.jpg +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/m4300-16x.png +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/models/m4300-24x.png +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/_static/ngsw.css +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/cli.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/core.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/facades.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/index.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/mcp.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/operations.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/protocols.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/transport.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/api/virtual.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/cli.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/conf.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/development.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/fake/index.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/fake/internals.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/fake/serving.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/fake/testing.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/guide/concepts.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/guide/configuration.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/guide/installation.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/guide/principles.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/guide/quickstart.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/guide/reading.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/guide/writing.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/index.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/mcp.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/gs105pe.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/gs110emx.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/gs305ep.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/gs728tpp.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/gsm7228ps.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/gsm7252ps.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/index.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/m4300-16x.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/m4300-24x.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/models/support.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/cli.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/http/cheetah-form.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/http/cheetah-v1.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/http/gambit.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/http/merge-hash-cgi.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/http/xml-api.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/http.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/index.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/nsdp.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/protocols/snmp.rst +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-15-foundation.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-17-slice-02-snmp-read-core.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-17-slice-03-read-apis.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-18-slice-04-snmp-write.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-18-slice-05-nsdp.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-18-slice-06-http.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-18-slice-07-cli.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-18-slice-08-packaging-ci.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/plans/2026-07-23-gsm7252ps-http-xe-dialect.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/specs/2026-07-15-netgear-control-library-design.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/specs/2026-07-23-gsm7252ps-http-xe-dialect-design.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/superpowers/specs/2026-08-02-snmp-surface-findings.md +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/packaging/apt-index.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/packaging/ci-build.sh +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/packaging/deb-version.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/pyproject.toml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/aio_api.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/capabilities.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli/capture.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli/context.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli/format.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli/main.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli/resolve.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli/safety.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/cli_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/config.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/errors.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/http_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/http_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/mcp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/mcp/server.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/nsdp_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/nsdp_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/cli/commands.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/http/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/http/crypt.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/http/endpoints.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/http/forms.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/http/parse.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/http/session.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/http/types.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/nsdp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/nsdp/auth.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/nsdp/client.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/nsdp/parsers.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/nsdp/protocol.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/nsdp/types.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/nsdp/write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/snmp/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/snmp/client.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/snmp/oids.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/snmp/parse.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/protocols/snmp/write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/py.typed +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/registry.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/snmp_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/sync_api.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/aio/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/aio/nsdp_udp.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/aio/snmp_pysnmp.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/cli/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/cli/console.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/cli/session.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/cli/ssh.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/cli/telnet.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/http/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/http/client.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/sync/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/sync/nsdp_udp.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/transport/sync/snmp_netsnmp_cli.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/cli_fastpath.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/faces/__init__.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/faces/cli.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/faces/http.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/faces/mibview.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/faces/nsdp.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/faces/snmp.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/server.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_fastpath_vlan.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_fastpath_xui.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_gs105pe.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_gs110emx.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_gs110emx_templates.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_gs728tpp.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_gsm7228ps.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_gsm7252ps.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/src/netgear_switch/virtual/web_m4300.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/capture_parity.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_capture.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_cli_integration.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_control_poe_port.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_control_vlan_ip.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_format.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_main_framework.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_new_commands.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_op_coverage.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_prompt_wiring.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_read_commands.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_resolve.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_safety.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/cli/test_serve.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/conftest.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/captures/gsm7228ps.json +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/captures/gsm7252ps.json +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/captures/m4300-16x.json +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/captures/m4300-24x.json +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_lldp.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_mac_table.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_network.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_poe.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_vlan_brief.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7228ps_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_network.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_poe_port_info_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_vlan_90.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_vlan_brief.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/gsm7252ps_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_ip_management.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_poe_port_info_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_vlan_1.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_vlan_4.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_vlan_5.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_16x_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_environment.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_interface_ethernet_1_0_1.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_ip_management.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_lldp_remote_device_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_mac_addr_table.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_version.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_vlan.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_vlan_5.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_vlan_90.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/cli/m4300_24x_show_vlan_port_all.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs105pe_membership.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs105pe_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs105pe_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs105pe_status.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs105pe_switch_info.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs105pe_vlancfg.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_cf8021q.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_interface_stats.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_login.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_port_settings.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_redirect.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_sysinfo.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs110emx_vlanmembership.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs305ep_dashboard.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs305ep_login.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs305ep_membership.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs305ep_poestatus.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs305ep_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs305ep_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs305ep_vlancfg.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_device_info_and_sensors.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_lldp.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_macs.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_mgmt_ip.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_poe.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_ports.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_pvids_membership.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_vlan_membership_per_vlan.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gs728tpp_vlans.xml +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_basicAddressTable.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_ipConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_portPvidConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_portStatistics.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_sysInfo.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_vlanPortCfg_vlan5.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7228ps_vlanStatus.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_basicAddressTable.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_ipConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_login.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_portPvidConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_portStatistics.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_sysInfo.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan1.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_vlanPortCfg_vlan141.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/gsm7252ps_vlanStatus.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_16x_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_16x_mgmtVlanIpv4Configuration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_16x_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_16x_portsConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_16x_vlanportcfg_vlan4.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_24x_poeInterfaceConfiguration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_addresstable.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_lldpRemoteInventory.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_mgmtVlanIpv4Configuration.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_ports.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_portstats.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_pvid.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_sysinfo.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_vlanportcfg_vlan1.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/http/m4300_vlanstatus.html +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/snmp/gsm7252ps_fans.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/snmp/gsm7252ps_ifhighspeed.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/snmp/gsm7252ps_ifoperstatus.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/fixtures/snmp/gsm7252ps_psu.txt +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/http_specs.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/cli/test_cli_parse.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/http/test_crypt.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/http/test_endpoints.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/http/test_forms.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/http/test_parse.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/nsdp/test_auth.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/nsdp/test_parsers.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/nsdp/test_protocol.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/nsdp/test_write_frame.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_client.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_oids.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_parse_lldp_macs.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_parse_mgmt_ip.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_parse_poe_sensors.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_parse_ports.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_parse_system_info.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_parse_vlans.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/protocols/snmp/test_write_encode.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_aio_api.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_capabilities.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_cli_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_cli_vlan_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_cli_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_config.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_cross_backend_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_deb_version.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_docs_coverage.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_errors.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_facade_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_http_dispatch.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_http_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_http_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_http_vlan_membership.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_http_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_http_xui_writes.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_import.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_mcp_server.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_models.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_models_snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_nsdp_integration.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_nsdp_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_nsdp_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_public_api.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_quality_gates.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_registry.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_snmp_integration.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_snmp_read.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_snmp_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_sync_api.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_version.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/test_write_equivalence.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/_fastpath_fake.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_cli_console.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_cli_scp_cert.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_cli_telnet.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_http_client.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_nsdp_udp_sync.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_set_transport.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_snmp_netsnmp_cli.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_snmp_pysnmp.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/transport/test_value_parity.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_cli_cross_backend.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_cli_gsm7228ps_parity.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_gsm7228ps_seed.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_hostname.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_m4300_seeds.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_mibview.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_mutable_state.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_nsdp_state.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_serve_daemon.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_snmp_write_face.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_state_seed.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_switchport_vlan_write.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_virtual_http_face.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_virtual_nsdp_face.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_virtual_snmp_face.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/tests/virtual/test_web_projection.py +0 -0
- {python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/uv.lock +0 -0
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/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.post352
|
|
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
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 0, '
|
|
21
|
+
__version__ = version = '0.0.post352'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 0, 'post352')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -38,6 +38,17 @@ class PortStatus:
|
|
|
38
38
|
# older tests) keep constructing without it; a backend that cannot read
|
|
39
39
|
# ifAlias (NSDP, HTTP) leaves it honestly None rather than fabricating "".
|
|
40
40
|
description: str | None = None
|
|
41
|
+
#: Whether the link negotiated FULL duplex. ``None`` when the backend cannot
|
|
42
|
+
#: tell -- a down port has no negotiated duplex, and not every backend
|
|
43
|
+
#: reports it at all. Measured 2026-08-02: the M4300's EtherLike-MIB dot3
|
|
44
|
+
#: table exposes only error counters, NOT dot3StatsDuplexStatus (column 19
|
|
45
|
+
#: is absent), so SNMP cannot answer this and leaves it None. The FASTPATH
|
|
46
|
+
#: CLI does: `show port all` reports "1000 Full" in its Physical Status
|
|
47
|
+
#: column, carrying speed and duplex together.
|
|
48
|
+
full_duplex: bool | None = None
|
|
49
|
+
#: Whether IEEE 802.3x flow control is enabled on the port ("Flow Mode" in
|
|
50
|
+
#: `show port all`). ``None`` where the backend does not report it.
|
|
51
|
+
flow_control: bool | None = None
|
|
41
52
|
|
|
42
53
|
|
|
43
54
|
@dataclass(frozen=True)
|
|
@@ -244,6 +244,11 @@ def parse_version(text: str, models: Mapping[str, SwitchModel]) -> DetectedModel
|
|
|
244
244
|
# Link Status | Link Trap | LACP Mode | Flow Mode
|
|
245
245
|
_PORT_INTF, _PORT_TYPE, _PORT_ADMIN = 0, 1, 2
|
|
246
246
|
_PORT_PHYS_MODE, _PORT_PHYS_STATUS, _PORT_LINK = 3, 4, 5
|
|
247
|
+
# Flow Mode is the LAST column of `show port all` (Intf, Type, Admin Mode,
|
|
248
|
+
# Physical Mode, Physical Status, Link Status, Link Trap, LACP Mode, Flow
|
|
249
|
+
# Mode). Indexed from the end so a firmware that omits an intermediate
|
|
250
|
+
# column cannot silently shift it.
|
|
251
|
+
_PORT_FLOW = -1
|
|
247
252
|
|
|
248
253
|
_SPEED_RE = re.compile(r"(\d+)\s*([GgMm]?)")
|
|
249
254
|
|
|
@@ -261,13 +266,30 @@ def _speed_mbps(phys_status: str) -> int | None:
|
|
|
261
266
|
return value * 1000 if m.group(2).upper() == "G" else value
|
|
262
267
|
|
|
263
268
|
|
|
269
|
+
def _duplex(phys_status: str) -> bool | None:
|
|
270
|
+
"""FULL/HALF from the Physical Status cell, e.g. "1000 Full" -> True.
|
|
271
|
+
|
|
272
|
+
Blank on a down port, which has no negotiated duplex -- honestly None rather
|
|
273
|
+
than a fabricated False.
|
|
274
|
+
"""
|
|
275
|
+
text = phys_status.strip().lower()
|
|
276
|
+
if "full" in text:
|
|
277
|
+
return True
|
|
278
|
+
if "half" in text:
|
|
279
|
+
return False
|
|
280
|
+
return None
|
|
281
|
+
|
|
282
|
+
|
|
264
283
|
def parse_port_status(text: str) -> list[PortStatus]:
|
|
265
284
|
"""``show port all`` -> per physical-port ``PortStatus``.
|
|
266
285
|
|
|
267
286
|
``admin_enabled`` = Admin Mode == "Enable"; ``link_up`` = Link Status ==
|
|
268
|
-
"Up"; ``speed_mbps`` from Physical Status
|
|
269
|
-
|
|
270
|
-
|
|
287
|
+
"Up"; ``speed_mbps`` and ``full_duplex`` both from Physical Status, which
|
|
288
|
+
carries them together ("1000 Full"); ``flow_control`` from the Flow Mode
|
|
289
|
+
column. All three are ``None`` on a down port, which has negotiated nothing.
|
|
290
|
+
``lag N`` aggregation rows are skipped (not physical ports).
|
|
291
|
+
``description`` is honestly ``None``: this command carries no ifAlias
|
|
292
|
+
column.
|
|
271
293
|
"""
|
|
272
294
|
out: list[PortStatus] = []
|
|
273
295
|
for cells in iter_table_rows(text):
|
|
@@ -288,6 +310,16 @@ def parse_port_status(text: str) -> list[PortStatus]:
|
|
|
288
310
|
else None
|
|
289
311
|
),
|
|
290
312
|
description=None,
|
|
313
|
+
full_duplex=(
|
|
314
|
+
_duplex(cells[_PORT_PHYS_STATUS])
|
|
315
|
+
if cells[_PORT_LINK].strip().lower() == "up"
|
|
316
|
+
else None
|
|
317
|
+
),
|
|
318
|
+
flow_control=(
|
|
319
|
+
cells[_PORT_FLOW].strip().lower() == "enable"
|
|
320
|
+
if len(cells) > _PORT_LINK + 1
|
|
321
|
+
else None
|
|
322
|
+
),
|
|
291
323
|
)
|
|
292
324
|
)
|
|
293
325
|
return out
|
|
@@ -31,6 +31,8 @@ from .state import (
|
|
|
31
31
|
PoeSim,
|
|
32
32
|
PortSim,
|
|
33
33
|
SensorSim,
|
|
34
|
+
SyslogCollectorSim,
|
|
35
|
+
SyslogSim,
|
|
34
36
|
VirtualSwitchState,
|
|
35
37
|
VlanMembershipPageSim,
|
|
36
38
|
VlanSim,
|
|
@@ -1237,6 +1239,13 @@ def seed_gsm7252ps() -> VirtualSwitchState:
|
|
|
1237
1239
|
# capture of this switch (tests/fixtures/http/gsm7252ps_sysInfo.html).
|
|
1238
1240
|
serial="2BW20A47000CC",
|
|
1239
1241
|
firmware="10.0.0.53",
|
|
1242
|
+
# MEASURED 2026-08-02 on 10.1.5.22: identical to the m4300 pair --
|
|
1243
|
+
# enabled, port 514, one collector 10.1.5.1 info(6) 514 Active.
|
|
1244
|
+
syslog=SyslogSim(
|
|
1245
|
+
admin_mode=1,
|
|
1246
|
+
local_port=514,
|
|
1247
|
+
collectors=[SyslogCollectorSim("10.1.5.1", 514, 6)],
|
|
1248
|
+
),
|
|
1240
1249
|
hostname="sw-netgear-gsm7252ps-s1.welland.mithis.com",
|
|
1241
1250
|
nsdp_mac=b"\xe0\x91\xf5\x0c\xd6\xdb", # captured System MAC Address
|
|
1242
1251
|
# Illustrative sysDescr text -- NOT a captured real firmware string;
|
|
@@ -1798,6 +1807,10 @@ def seed_gsm7228ps() -> VirtualSwitchState:
|
|
|
1798
1807
|
lldp=lldp,
|
|
1799
1808
|
mgmt=mgmt,
|
|
1800
1809
|
model_name="GSM7228PS",
|
|
1810
|
+
# MEASURED 2026-08-02 on 10.1.5.11: the vendor admin-mode column
|
|
1811
|
+
# reads 2 (disabled) and the host table is EMPTY -- this switch has
|
|
1812
|
+
# no collector configured, which is why get_syslog returns none.
|
|
1813
|
+
syslog=SyslogSim(admin_mode=2, local_port=514, collectors=[]),
|
|
1801
1814
|
hostname="sw-netgear-s3300-1",
|
|
1802
1815
|
nsdp_mac=b"\x08\xbd\x43\x6b\xb8\xd8", # captured base/System MAC
|
|
1803
1816
|
# REAL captured identity: the S3300-52X-PoE+'s actual sysDescr and
|
|
@@ -2397,6 +2410,14 @@ def seed_m4300_24x() -> VirtualSwitchState:
|
|
|
2397
2410
|
state = VirtualSwitchState(
|
|
2398
2411
|
# Measured 2026-08-02: sysName and `show hosts` both report this on the
|
|
2399
2412
|
# real switch. Was empty here, which no real FASTPATH switch is.
|
|
2413
|
+
# MEASURED 2026-08-02 on 10.1.5.13: `show logging` reports
|
|
2414
|
+
# "Syslog Logging : enabled" and local port 514, and
|
|
2415
|
+
# `show logging hosts` one row 10.1.5.1 / info(6) / 514 / Active.
|
|
2416
|
+
syslog=SyslogSim(
|
|
2417
|
+
admin_mode=1,
|
|
2418
|
+
local_port=514,
|
|
2419
|
+
collectors=[SyslogCollectorSim("10.1.5.1", 514, 6)],
|
|
2420
|
+
),
|
|
2400
2421
|
hostname="sw-netgear-m4300-24x",
|
|
2401
2422
|
model_key="m4300-24x",
|
|
2402
2423
|
ports=ports,
|
|
@@ -155,6 +155,37 @@ class PortSim:
|
|
|
155
155
|
flow_control: bool = True
|
|
156
156
|
|
|
157
157
|
|
|
158
|
+
@dataclass
|
|
159
|
+
class SyslogCollectorSim:
|
|
160
|
+
"""One remote syslog collector row, as the vendor host table reports it.
|
|
161
|
+
|
|
162
|
+
Field values are SEEDED from a live switch, never computed: the severity is
|
|
163
|
+
the standard syslog number the device actually returns (6 for "info" on
|
|
164
|
+
m4300-24x, cross-checked against its own `show logging hosts`), and status 1
|
|
165
|
+
is what that command prints as "Active".
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
host: str
|
|
169
|
+
port: int
|
|
170
|
+
severity: int
|
|
171
|
+
status: int = 1
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@dataclass
|
|
175
|
+
class SyslogSim:
|
|
176
|
+
"""The switch's remote-logging state, as the vendor `.14` subtree reports it.
|
|
177
|
+
|
|
178
|
+
MEASURED 2026-08-02 -- see docs/superpowers/specs/. ``admin_mode`` is the
|
|
179
|
+
device's own enum (1 = enabled, 2 = disabled), kept as the raw integer
|
|
180
|
+
rather than a bool so the mock emits exactly what a real agent emits and the
|
|
181
|
+
reader's own decoding is what gets exercised.
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
admin_mode: int = 2
|
|
185
|
+
local_port: int = 514
|
|
186
|
+
collectors: list[SyslogCollectorSim] = field(default_factory=list)
|
|
187
|
+
|
|
188
|
+
|
|
158
189
|
@dataclass
|
|
159
190
|
class VlanSim:
|
|
160
191
|
"""One dot1q VLAN: display name plus egress-member and untagged port sets.
|
|
@@ -374,6 +405,10 @@ class VirtualSwitchState:
|
|
|
374
405
|
serial: str = ""
|
|
375
406
|
firmware: str = ""
|
|
376
407
|
hostname: str = ""
|
|
408
|
+
#: Remote-logging state. Only meaningful for a model with a vendor subtree;
|
|
409
|
+
#: oid_map() projects it under <vendor base>.14 for those models only, which
|
|
410
|
+
#: is what makes gs728tpp (no vendor OIDs) correctly unable to answer.
|
|
411
|
+
syslog: SyslogSim = field(default_factory=SyslogSim)
|
|
377
412
|
nsdp_password: str = "password"
|
|
378
413
|
# Write-auth scheme this mock advertises via AUTH_V2_ENCPASS (0x0014), and
|
|
379
414
|
# the ONLY scheme it accepts on a WRITE_REQUEST:
|
|
@@ -737,6 +772,20 @@ class VirtualSwitchState:
|
|
|
737
772
|
# publishes no vendor subtree at all.
|
|
738
773
|
m[oids.SYS_NAME] = ("OCTETSTR", self.hostname)
|
|
739
774
|
|
|
775
|
+
# Remote logging, under <vendor base>.14 -- the same columns the real
|
|
776
|
+
# agents publish, and ONLY for a model that has a vendor subtree. A
|
|
777
|
+
# model with none (gs728tpp) must stay unable to answer get_syslog here
|
|
778
|
+
# exactly as it is on the wire, rather than the mock inventing a reply.
|
|
779
|
+
if v is not None:
|
|
780
|
+
m[f"{v.base}.14.1.4.1.0"] = ("INTEGER", str(self.syslog.admin_mode))
|
|
781
|
+
m[f"{v.base}.14.1.4.3.0"] = ("Gauge32", str(self.syslog.local_port))
|
|
782
|
+
for index, col in enumerate(self.syslog.collectors, start=1):
|
|
783
|
+
m[f"{v.base}.14.1.4.5.1.2.{index}"] = ("INTEGER", "1")
|
|
784
|
+
m[f"{v.base}.14.1.4.5.1.3.{index}"] = ("OCTETSTR", col.host)
|
|
785
|
+
m[f"{v.base}.14.1.4.5.1.4.{index}"] = ("Gauge32", str(col.port))
|
|
786
|
+
m[f"{v.base}.14.1.4.5.1.5.{index}"] = ("INTEGER", str(col.severity))
|
|
787
|
+
m[f"{v.base}.14.1.4.5.1.7.{index}"] = ("INTEGER", str(col.status))
|
|
788
|
+
|
|
740
789
|
for port, sim in self.ports.items():
|
|
741
790
|
m[f"{oids.IF_ADMIN_STATUS}.{port}"] = ("INTEGER", "1" if sim.admin else "2")
|
|
742
791
|
m[f"{oids.IF_OPER_STATUS}.{port}"] = ("INTEGER", "1" if sim.link else "2")
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# tests/virtual/test_syslog_fidelity.py
|
|
2
|
+
"""The fake must answer ``get_syslog`` exactly as the real switches did.
|
|
3
|
+
|
|
4
|
+
Every expected value below was READ OFF A LIVE DEVICE on 2026-08-02 and
|
|
5
|
+
cross-checked against that switch's own ``show logging`` / ``show logging
|
|
6
|
+
hosts``. They are transcribed here, not computed: a mock that derived them with
|
|
7
|
+
the same code under test could only ever agree with itself (principle 5).
|
|
8
|
+
|
|
9
|
+
The gs728tpp row is the important one. It has no Netgear vendor subtree at all,
|
|
10
|
+
the logging columns are vendor-only, and the reader refuses BY NAME rather than
|
|
11
|
+
returning an empty config -- because "no collectors configured" and "this
|
|
12
|
+
backend cannot tell you" are different answers and must not collapse into one.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
19
|
+
from netgear_switch.errors import UnsupportedCapabilityError
|
|
20
|
+
from netgear_switch.registry import get_model
|
|
21
|
+
from netgear_switch.snmp_read import SnmpReader
|
|
22
|
+
from netgear_switch.transport.sync.snmp_netsnmp_cli import NetsnmpCliClient
|
|
23
|
+
from netgear_switch.virtual.server import VirtualSwitch
|
|
24
|
+
|
|
25
|
+
#: model -> (enabled, local_port, [(host, port, severity, active)])
|
|
26
|
+
#: transcribed from the live reads.
|
|
27
|
+
MEASURED = {
|
|
28
|
+
# 10.1.5.13, `show logging hosts`: 1 10.1.5.1 info 514 Active
|
|
29
|
+
"m4300-24x": (True, 514, [("10.1.5.1", 514, 6, True)]),
|
|
30
|
+
# 10.1.5.22, same row (its host table prints five columns, not eight)
|
|
31
|
+
"gsm7252ps": (True, 514, [("10.1.5.1", 514, 6, True)]),
|
|
32
|
+
# 10.1.5.11: admin-mode column reads 2, and the host table is empty
|
|
33
|
+
"gsm7228ps": (False, 514, []),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _reader(mock: VirtualSwitch, key: str) -> SnmpReader:
|
|
38
|
+
client = NetsnmpCliClient(f"{mock.host}:{mock.port}", mock.community)
|
|
39
|
+
return SnmpReader(client, get_model(key))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.mark.parametrize("key", sorted(MEASURED))
|
|
43
|
+
def test_fake_matches_the_live_switch(key: str) -> None:
|
|
44
|
+
enabled, local_port, collectors = MEASURED[key]
|
|
45
|
+
with VirtualSwitch(model=key) as mock:
|
|
46
|
+
cfg = _reader(mock, key).get_syslog()
|
|
47
|
+
assert cfg.enabled is enabled
|
|
48
|
+
assert cfg.local_port == local_port
|
|
49
|
+
assert [(s.host, s.port, s.severity, s.active) for s in cfg.servers] == collectors
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_severity_is_the_device_number_not_a_label() -> None:
|
|
53
|
+
"""6 is what the column holds where the CLI prints "info".
|
|
54
|
+
|
|
55
|
+
Pinned separately because it is the one value a future refactor might be
|
|
56
|
+
tempted to "improve" into an enum name, breaking agreement with the wire.
|
|
57
|
+
"""
|
|
58
|
+
with VirtualSwitch(model="m4300-24x") as mock:
|
|
59
|
+
cfg = _reader(mock, "m4300-24x").get_syslog()
|
|
60
|
+
assert cfg.servers[0].severity == 6
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_a_model_with_no_vendor_subtree_refuses_rather_than_answering_empty() -> None:
|
|
64
|
+
with (
|
|
65
|
+
VirtualSwitch(model="gs728tpp") as mock,
|
|
66
|
+
pytest.raises(UnsupportedCapabilityError, match="vendor"),
|
|
67
|
+
):
|
|
68
|
+
_reader(mock, "gs728tpp").get_syslog()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/.gitignore
RENAMED
|
File without changes
|
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/CLAUDE.md
RENAMED
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/LICENSE
RENAMED
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/README.md
RENAMED
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/RELEASING.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/debian/rules
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/cli.rst
RENAMED
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/conf.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_netgear_switch_library-0.0.post350 → python_netgear_switch_library-0.0.post352}/docs/mcp.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|