diff options
| author | Roberto Bertó <463349+robertoberto@users.noreply.github.com> | 2026-05-19 03:02:52 +0000 |
|---|---|---|
| committer | Roberto Bertó <463349+robertoberto@users.noreply.github.com> | 2026-05-19 03:02:52 +0000 |
| commit | b2f1765d286502307ea07a62648718d0414e4f39 (patch) | |
| tree | cf36ad0de5167cdc75ffb3d4b0533a68752c0019 /examples | |
| parent | 4c19d27c2cf87176dfb983ccc65f2c817ff1f650 (diff) | |
| download | pyvyos-b2f1765d286502307ea07a62648718d0414e4f39.tar.gz pyvyos-b2f1765d286502307ea07a62648718d0414e4f39.zip | |
docs: split examples into read-only basic and guarded smoke
The previous examples/basic.py ran destructive operations (configure_set,
configure_delete, generate, reset, config_file_load) by default. That is
not what a public 'basic' example should do.
- examples/basic.py: rewritten as a read-only example
(retrieve_show_config, show, retrieve_return_values), uses a robust
env-bool parser, prints response.result via a small helper, and uses
the supported public import 'from pyvyos import ApiResponse, VyDevice'.
- examples/integration_smoke.py: renamed from the old basic.py, keeps
the mutating operations, and refuses to run unless
PYVYOS_ALLOW_MUTATING_EXAMPLE=1 is set.
- README: link both examples and describe what each one does.
Note: the dev/ note about a future Docker-based e2e harness is tracked
in the unreleased issue drafts; it is not part of this release.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/basic.py | 80 | ||||
| -rw-r--r-- | examples/integration_smoke.py | 105 |
2 files changed, 135 insertions, 50 deletions
diff --git a/examples/basic.py b/examples/basic.py index c133d41..1e1b552 100644 --- a/examples/basic.py +++ b/examples/basic.py @@ -1,85 +1,65 @@ -"""Basic pyvyos usage example. +"""Basic read-only pyvyos usage example. -Run with environment variables loaded from a .env file (see ../.env.example) -or exported in your shell: +Run with environment variables loaded from a .env file or exported in your +shell: VYDEVICE_HOSTNAME=192.0.2.1 \\ VYDEVICE_APIKEY=secret \\ python examples/basic.py + +This example only runs read-only commands. """ import os import pprint -import random -import string from dotenv import load_dotenv -from pyvyos import VyDevice +from pyvyos import ApiResponse, VyDevice load_dotenv() +def env_bool(name: str, default: str = "true") -> bool: + return os.environ.get(name, default).lower() in ("1", "true", "yes") + + def make_device() -> VyDevice: return VyDevice( hostname=os.environ["VYDEVICE_HOSTNAME"], apikey=os.environ["VYDEVICE_APIKEY"], port=int(os.environ.get("VYDEVICE_PORT", "443")), protocol=os.environ.get("VYDEVICE_PROTOCOL", "https"), - verify=os.environ.get("VYDEVICE_VERIFY_SSL", "true").lower() == "true", - timeout=60, + verify=env_bool("VYDEVICE_VERIFY_SSL"), + timeout=int(os.environ.get("VYDEVICE_TIMEOUT", "60")), ) +def print_response(label: str, response: ApiResponse) -> None: + print(f"\n== {label} ==") + if response.error: + print(f"Error {response.status}: {response.error}") + return + + pprint.pprint(response.result) + + def main() -> None: device = make_device() - # Retrieve the running configuration for the system tree. - pprint.pprint(device.retrieve_show_config(path=["system"])) - - # Configure a dummy interface, read it back, then delete it. - pprint.pprint( - device.configure_set( - path=["interfaces", "dummy", "dum1", "address", "192.168.56.100/24"] - ) + print_response( + "Running system configuration", + device.retrieve_show_config(path=["system"]), ) - pprint.pprint( - device.retrieve_return_values( - path=["interfaces", "dummy", "dum1", "address"] - ) - ) - pprint.pprint(device.configure_delete(path=["interfaces", "dummy", "dum1"])) - # Generate a one-shot SSH client key. - randstring = "".join( - random.choice(string.ascii_letters + string.digits) for _ in range(20) - ) - pprint.pprint( - device.generate(path=["ssh", "client-key", f"/tmp/key_{randstring}"]) + print_response( + "System images", + device.show(path=["system", "image"]), ) - # Operational commands. - pprint.pprint(device.show(path=["system", "image"])) - pprint.pprint(device.reset(path=["conntrack-sync", "internal-cache"])) - - # Save and reload the running configuration to/from a file on the device. - pprint.pprint(device.config_file_save(file="/config/test300.config")) - pprint.pprint(device.config_file_load(file="/config/test300.config")) - - # Batch multiple configuration operations in a single request. - pprint.pprint( - device.configure_multiple_op( - op_path=[ - { - "op": "set", - "path": [ - "interfaces", "dummy", "dum1", "address", - "192.168.56.100/24", - ], - }, - {"op": "delete", "path": ["interfaces", "dummy", "dum1"]}, - ] - ) + print_response( + "Interface address values", + device.retrieve_return_values(path=["interfaces"]), ) diff --git a/examples/integration_smoke.py b/examples/integration_smoke.py new file mode 100644 index 0000000..137ca9b --- /dev/null +++ b/examples/integration_smoke.py @@ -0,0 +1,105 @@ +"""Integration smoke test for pyvyos. + +This script changes configuration on the target VyOS device and should only +be used against a disposable lab device, such as the one provided by +``examples/vagrant/``. + +It may create and delete dummy interfaces, generate temporary files on the +device, and save/load configuration files. + +Run only against a lab device:: + + PYVYOS_ALLOW_MUTATING_EXAMPLE=1 \\ + VYDEVICE_HOSTNAME=127.0.0.1 \\ + VYDEVICE_APIKEY=secret \\ + python examples/integration_smoke.py +""" + +import os +import pprint +import random +import string +import sys + +from dotenv import load_dotenv + +from pyvyos import VyDevice + +load_dotenv() + + +def env_bool(name: str, default: str = "true") -> bool: + return os.environ.get(name, default).lower() in ("1", "true", "yes") + + +def make_device() -> VyDevice: + return VyDevice( + hostname=os.environ["VYDEVICE_HOSTNAME"], + apikey=os.environ["VYDEVICE_APIKEY"], + port=int(os.environ.get("VYDEVICE_PORT", "443")), + protocol=os.environ.get("VYDEVICE_PROTOCOL", "https"), + verify=env_bool("VYDEVICE_VERIFY_SSL"), + timeout=int(os.environ.get("VYDEVICE_TIMEOUT", "60")), + ) + + +def main() -> None: + if os.environ.get("PYVYOS_ALLOW_MUTATING_EXAMPLE") != "1": + sys.exit( + "This example mutates the target device. " + "Set PYVYOS_ALLOW_MUTATING_EXAMPLE=1 to run it." + ) + + device = make_device() + + # Retrieve the running configuration for the system tree. + pprint.pprint(device.retrieve_show_config(path=["system"])) + + # Configure a dummy interface, read it back, then delete it. + pprint.pprint( + device.configure_set( + path=["interfaces", "dummy", "dum1", "address", "192.168.56.100/24"] + ) + ) + pprint.pprint( + device.retrieve_return_values( + path=["interfaces", "dummy", "dum1", "address"] + ) + ) + pprint.pprint(device.configure_delete(path=["interfaces", "dummy", "dum1"])) + + # Generate a one-shot SSH client key. + randstring = "".join( + random.choice(string.ascii_letters + string.digits) for _ in range(20) + ) + pprint.pprint( + device.generate(path=["ssh", "client-key", f"/tmp/key_{randstring}"]) + ) + + # Operational commands. + pprint.pprint(device.show(path=["system", "image"])) + pprint.pprint(device.reset(path=["conntrack-sync", "internal-cache"])) + + # Save and reload the running configuration to/from a file on the device. + pprint.pprint(device.config_file_save(file="/config/test300.config")) + pprint.pprint(device.config_file_load(file="/config/test300.config")) + + # Batch multiple configuration operations in a single request. + pprint.pprint( + device.configure_multiple_op( + op_path=[ + { + "op": "set", + "path": [ + "interfaces", "dummy", "dum1", "address", + "192.168.56.100/24", + ], + }, + {"op": "delete", "path": ["interfaces", "dummy", "dum1"]}, + ] + ) + ) + + +if __name__ == "__main__": + main() |
