diff options
author | Roberto Berto <roberto.berto@gmail.com> | 2023-12-13 14:31:35 -0300 |
---|---|---|
committer | Roberto Berto <roberto.berto@gmail.com> | 2023-12-13 14:31:35 -0300 |
commit | a7b3027c86464046e6dbd266d0d796d55591806e (patch) | |
tree | 7d641f98a26e0568660c1852559f016aa6acea5c | |
parent | 1bc018a20ebf7b02907aba63c674a5829f283175 (diff) | |
download | pyvyos-a7b3027c86464046e6dbd266d0d796d55591806e.tar.gz pyvyos-a7b3027c86464046e6dbd266d0d796d55591806e.zip |
read the docs
-rw-r--r-- | docs/Makefile | 20 | ||||
-rw-r--r-- | docs/make.bat | 35 | ||||
-rw-r--r-- | docs/source/conf.py | 38 | ||||
-rw-r--r-- | docs/source/index.rst | 214 | ||||
-rw-r--r-- | docs/source/pyvyos.rst | 21 | ||||
-rw-r--r-- | pyvyos/device.py | 234 |
6 files changed, 549 insertions, 13 deletions
diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..747ffb7 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.https://www.sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..8e9f3c2 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,38 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'PyVyOS' +copyright = '2023, Roberto Berto' +author = 'Roberto Berto' +release = '0.2.0' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +templates_path = ['_templates'] +exclude_patterns = [] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'sphinx_rtd_theme' +html_static_path = ['_static'] + + +import os +import sys +sys.path.insert(0, os.path.abspath('../../pyvyos')) + +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx_rtd_theme', + +] + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..05c2aa0 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,214 @@ +.. PyVyOS documentation master file, created by + sphinx-quickstart on Wed Dec 13 13:02:59 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +PyVyOS - documentation +================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + +pyvyos +====== + +.. toctree:: + :maxdepth: 4 + + pyvyos + +PyVyOS Usage +================== + +.. _pyvyos-documentation: + +PyVyOS Documentation +==================== + +PyVyOS is a Python library for interacting with VyOS devices via their API. This documentation provides a guide on how to use PyVyOS to manage your VyOS devices programmatically. + +Installation +------------ + +You can install PyVyOS using pip: + +.. code-block:: bash + + pip install pyvyos + +Getting Started +--------------- + +Importing and Disabling Warnings for verify=False +-------------------------------------------------- + +Before using PyVyOS, it's a good practice to disable urllib3 warnings and import the required modules, IF you use verify=False: + +.. code-block:: python + + import urllib3 + urllib3.disable_warnings() + +Using API Response Class +------------------------ + +PyVyOS uses a custom `ApiResponse` data class to handle API responses: + +.. code-block:: python + + @dataclass + class ApiResponse: + status: int + request: dict + result: dict + error: str + +Initializing a VyDevice Object +------------------------------ + +To interact with your VyOS device, you'll need to create an instance of the `VyDevice` class. You can set up your device using the following code, assuming you've stored your credentials as environment variables: + +.. code-block:: python + + from dotenv import load_dotenv + + # Load environment variables from a .env file + load_dotenv() + + # Retrieve VyOS device connection details from environment variables + hostname = os.getenv('VYDEVICE_HOSTNAME') + apikey = os.getenv('VYDEVICE_APIKEY') + port = os.getenv('VYDEVICE_PORT') + protocol = os.getenv('VYDEVICE_PROTOCOL') + verify_ssl = os.getenv('VYDEVICE_VERIFY_SSL') + + # Convert the verify_ssl value to a boolean + verify = verify_ssl.lower() == "true" if verify_ssl else True + + # Create an instance of the VyOS device + device = VyDevice(hostname=hostname, apikey=apikey, port=port, protocol=protocol, verify=verify) + +Using PyVyOS +------------ + +Once you have created a VyDevice object, you can use it to interact with your VyOS device using various methods provided by the library. + +Reset +----- + +The reset method allows you to run a reset command: + +.. code-block:: python + + # Execute the reset command + response = device.reset(path=["conntrack-sync", "internal-cache"]) + + # Check for errors and print the result + if not response.error: + print(response.result) + +Retrieve Show Configuration +--------------------------- + +The retrieve_show_config method retrieves the VyOS configuration: + +.. code-block:: python + + # Retrieve the VyOS configuration + response = device.retrieve_show_config(path=[]) + + # Check for errors and print the result + if not response.error: + print(response.result) + +Retrieve Return Values +------------------------ + +.. code-block:: python + + # Retrieve VyOS return values for a specific interface + response = device.retrieve_return_values(path=["interfaces", "dummy", "dum1", "address"]) + print(response.result) + +Configure Delete +---------------- + +.. code-block:: python + + # Delete a VyOS interface configuration + response = device.configure_delete(path=["interfaces", "dummy", "dum1"]) + +Generate +---------- + +.. code-block:: python + + # Generate an SSH key with a random string in the name + randstring = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(20)) + keyrand = f'/tmp/key_{randstring}' + response = device.generate(path=["ssh", "client-key", keyrand]) + +Show +------ + +.. code-block:: python + + # Show VyOS system image information + response = device.show(path=["system", "image"]) + print(response.result) + +Reset +------ + +.. code-block:: python + + # Reset VyOS with specific parameters + response = device.reset(path=["conntrack-sync", "internal-cache"]) + +Configure Set +------------- + +The configure_set method sets a VyOS configuration: + +.. code-block:: python + + # Set a VyOS configuration + response = device.configure_set(path=["interfaces ethernet eth0 address '192.168.1.1/24'"]) + + # Check for errors and print the result + if not response.error: + print(response.result) + +Config File Save +---------------- + +.. code-block:: python + + # Save VyOS configuration without specifying a file (default location) + response = device.config_file_save() + +Config File Save with custom filename +------------------------------------- + +.. code-block:: python + + # Save VyOS configuration to a specific file + response = device.config_file_save(file="/config/test300.config") + +Config File Load +---------------- + +.. code-block:: python + + # Load VyOS configuration from a specific file + response = device.config_file_load(file="/config/test300.config") + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search`
\ No newline at end of file diff --git a/docs/source/pyvyos.rst b/docs/source/pyvyos.rst new file mode 100644 index 0000000..fc02f1a --- /dev/null +++ b/docs/source/pyvyos.rst @@ -0,0 +1,21 @@ +pyvyos package +============== + +Submodules +---------- + +pyvyos.device module +-------------------- + +.. automodule:: pyvyos.device + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: pyvyos + :members: + :undoc-members: + :show-inheritance: diff --git a/pyvyos/device.py b/pyvyos/device.py index 1d0933b..cc87a32 100644 --- a/pyvyos/device.py +++ b/pyvyos/device.py @@ -1,6 +1,4 @@ import urllib3 -urllib3.disable_warnings() - import requests import json import pprint @@ -8,13 +6,71 @@ from dataclasses import dataclass @dataclass class ApiResponse: + """ + Represents an API response. + + Attributes: + status (int): The HTTP status code of the response. + request (dict): The request payload sent to the API. + result (dict): The data result of the API response. + error (str): Any error message in case of a failed response. + """ status: int request: dict result: dict error: str - + class VyDevice: + """ + Represents a device for interacting with the VyOS API. + + Args: + hostname (str): The hostname or IP address of the VyOS device. + apikey (str): The API key for authentication. + protocol (str, optional): The protocol to use (default is 'https'). + port (int, optional): The port to use (default is 443). + verify (bool, optional): Whether to verify SSL certificates (default is True). + timeout (int, optional): The request timeout in seconds (default is 10). + + Attributes: + hostname (str): The hostname or IP address of the VyOS device. + apikey (str): The API key for authentication. + protocol (str): The protocol used for communication. + port (int): The port used for communication. + verify (bool): Whether SSL certificate verification is enabled. + timeout (int): The request timeout in seconds. + + Methods: + _get_url(command): Get the full URL for a given API command. + _get_payload(op, path=[], file=None, url=None, name=None): Generate the API request payload. + _api_request(command, op, path=[], method='POST', file=None, url=None, name=None): Make an API request. + retrieve_show_config(path=[]): Retrieve and show the device configuration. + retrieve_return_values(path=[]): Retrieve and return specific configuration values. + reset(path=[]): Reset a specific configuration element. + image_add(url=None, file=None, path=[]): Add an image from a URL or file. + image_delete(name, url=None, file=None, path=[]): Delete a specific image. + show(path=[]): Show configuration information. + generate(path=[]): Generate configuration based on specified path. + configure_set(path=[]): Set configuration based on specified path. + configure_delete(path=[]): Delete configuration based on specified path. + config_file_save(file=None): Save the configuration to a file. + config_file_load(file=None): Load the configuration from a file. + reboot(path=["now"]): Reboot the device. + poweroff(path=["now"]): Power off the device. + """ + def __init__(self, hostname, apikey, protocol='https', port=443, verify=True, timeout=10): + """ + Initializes a VyDevice instance. + + Args: + hostname (str): The hostname or IP address of the VyOS device. + apikey (str): The API key for authentication. + protocol (str, optional): The protocol to use (default is 'https'). + port (int, optional): The port to use (default is 443). + verify (bool, optional): Whether to verify SSL certificates (default is True). + timeout (int, optional): The request timeout in seconds (default is 10). + """ self.hostname = hostname self.apikey = apikey self.protocol = protocol @@ -22,12 +78,32 @@ class VyDevice: self.verify = verify self.timeout = timeout - def _get_url(self, command): - return f"{self.protocol}://{self.hostname}:{self.port}/{command}" + """ + Get the full URL for a specific API command. + + Args: + command (str): The API command to construct the URL for. + Returns: + str: The full URL for the API command. + """ + return f"{self.protocol}://{self.hostname}:{self.port}/{command}" def _get_payload(self, op, path=[], file=None, url=None, name=None): + """ + Generate the payload for an API request. + + Args: + op (str): The operation to perform in the API request. + path (list, optional): The path elements for the API request (default is an empty list). + file (str, optional): The file to include in the request (default is None). + url (str, optional): The URL to include in the request (default is None). + name (str, optional): The name to include in the request (default is None). + + Returns: + dict: The payload for the API request. + """ data = { 'op': op, 'path': path @@ -47,13 +123,26 @@ class VyDevice: 'key': self.apikey } - #print(payload) return payload - + def _api_request(self, command, op, path=[], method='POST', file=None, url=None, name=None): + """ + Make an API request. + + Args: + command (str): The API command to execute. + op (str): The operation to perform in the API request. + path (list, optional): The path elements for the API request (default is an empty list). + method (str, optional): The HTTP method to use for the request (default is 'POST'). + file (str, optional): The file to include in the request (default is None). + url (str, optional): The URL to include in the request (default is None). + name (str, optional): The name to include in the request (default is None). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ url = self._get_url(command) payload = self._get_payload(op, path=path, file=file, url=url, name=name) - #pprint.pprint(payload) headers = {} error = False @@ -61,7 +150,6 @@ class VyDevice: try: resp = requests.post(url, verify=self.verify, data=payload, timeout=self.timeout, headers=headers) - pprint.pprint(resp.text) if resp.status_code == 200: try: @@ -84,47 +172,167 @@ class VyDevice: error = 'connection error: ' + str(e) status = 0 - # removing apikey from payload for security reasons + # Removing apikey from payload for security reasons del(payload['key']) return ApiResponse(status=status, request=payload, result=result, error=error) - def retrieve_show_config(self, path=[]): + """ + Retrieve and show the device configuration. + + Args: + path (list, optional): The path elements for the configuration retrieval (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="retrieve", op='showConfig', path=path, method="POST") def retrieve_return_values(self, path=[]): + """ + Retrieve and return specific configuration values. + + Args: + path (list, optional): The path elements for the configuration retrieval (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="retrieve", op='returnValues', path=path, method="POST") def reset(self, path=[]): + """ + Reset a specific configuration element. + + Args: + path (list, optional): The path elements for the configuration reset (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="reset", op='reset', path=path, method="POST") def image_add(self, url=None, file=None, path=[]): + """ + Add an image from a URL or file. + + Args: + url (str, optional): The URL of the image to add (default is None). + file (str, optional): The path to the local image file to add (default is None). + path (list, optional): The path elements for the image addition (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="image", op='add', url=url, method="POST") def image_delete(self, name, url=None, file=None, path=[]): + """ + Delete a specific image. + + Args: + name (str): The name of the image to delete. + url (str, optional): The URL of the image to delete (default is None). + file (str, optional): The path to the local image file to delete (default is None). + path (list, optional): The path elements for the image deletion (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="image", op='delete', name=name, method="POST") - + def show(self, path=[]): + """ + Show configuration information. + + Args: + path (list, optional): The path elements for the configuration display (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="show", op='show', path=path, method="POST") def generate(self, path=[]): + """ + Generate configuration based on the given path. + + Args: + path (list, optional): The path elements for configuration generation (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="generate", op='generate', path=path, method="POST") def configure_set(self, path=[]): + """ + Set configuration based on the given path. + + Args: + path (list, optional): The path elements for configuration setting (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="configure", op='set', path=path, method="POST") def configure_delete(self, path=[]): + """ + Delete configuration based on the given path. + + Args: + path (list, optional): The path elements for configuration deletion (default is an empty list). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="configure", op='delete', path=path, method="POST") def config_file_save(self, file=None): + """ + Save the configuration to a file. + + Args: + file (str, optional): The path to the file where the configuration will be saved (default is None). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="config-file", op='save', file=file, method="POST") def config_file_load(self, file=None): + """ + Load the configuration from a file. + + Args: + file (str, optional): The path to the file from which the configuration will be loaded (default is None). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="config-file", op='load', file=file, method="POST") def reboot(self, path=["now"]): + """ + Reboot the device. + + Args: + path (list, optional): The path elements for the reboot operation (default is ["now"]). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="reboot", op='reboot', path=path, method="POST") def poweroff(self, path=["now"]): + """ + Power off the device. + + Args: + path (list, optional): The path elements for the power off operation (default is ["now"]). + + Returns: + ApiResponse: An ApiResponse object representing the API response. + """ return self._api_request(command="poweroff", op='poweroff', path=path, method="POST") -
\ No newline at end of file |