summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Berto <roberto.berto@gmail.com>2023-12-13 14:31:35 -0300
committerRoberto Berto <roberto.berto@gmail.com>2023-12-13 14:31:35 -0300
commita7b3027c86464046e6dbd266d0d796d55591806e (patch)
tree7d641f98a26e0568660c1852559f016aa6acea5c
parent1bc018a20ebf7b02907aba63c674a5829f283175 (diff)
downloadpyvyos-a7b3027c86464046e6dbd266d0d796d55591806e.tar.gz
pyvyos-a7b3027c86464046e6dbd266d0d796d55591806e.zip
read the docs
-rw-r--r--docs/Makefile20
-rw-r--r--docs/make.bat35
-rw-r--r--docs/source/conf.py38
-rw-r--r--docs/source/index.rst214
-rw-r--r--docs/source/pyvyos.rst21
-rw-r--r--pyvyos/device.py234
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