summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Berto <roberto.berto@gmail.com>2023-12-13 12:50:45 -0300
committerRoberto Berto <roberto.berto@gmail.com>2023-12-13 12:50:45 -0300
commit4148924483f14e5ecde296df09e0c2a2fef20787 (patch)
treef88b368e9d9a40f9daa34b88a7df204d27cde4a4
parent1cd622e219ceed9ba669bb373a4e4407a9542215 (diff)
downloadpyvyos-4148924483f14e5ecde296df09e0c2a2fef20787.tar.gz
pyvyos-4148924483f14e5ecde296df09e0c2a2fef20787.zip
version 0.2.0 with all api and tests
-rw-r--r--CONTRIB.md10
-rw-r--r--README.md153
-rw-r--r--example.py62
-rw-r--r--pyproject.toml12
-rw-r--r--pyvyos/__init__.py (renamed from vyapi/__init__.py)0
-rw-r--r--pyvyos/device.py (renamed from vyapi/device.py)70
-rw-r--r--tests/test_vy_device.py42
-rw-r--r--vyapi/utils.py0
8 files changed, 281 insertions, 68 deletions
diff --git a/CONTRIB.md b/CONTRIB.md
index 6a7317a..28e3685 100644
--- a/CONTRIB.md
+++ b/CONTRIB.md
@@ -1,6 +1,6 @@
-# Contributing to VyAPI
+# Contributing to PyVyOS
-We welcome contributions to the VyAPI project! If you're looking to contribute, please take a moment to read this guide to understand how you can be a part of our community and help make VyAPI better.
+We welcome contributions to the PyVyOS project! If you're looking to contribute, please take a moment to read this guide to understand how you can be a part of our community and help make PyVyOS better.
## Code of Conduct
@@ -8,7 +8,7 @@ We expect all contributors to adhere to our Code of Conduct. Respectful, collabo
## How to Contribute
-There are many ways to contribute to VyAPI:
+There are many ways to contribute to PyVyOS:
- **Submitting bug reports and feature requests:** Use our issue tracker to report bugs or suggest features.
- **Writing code:** Feel free to take on open issues or propose new changes. Please follow the guidelines outlined below.
@@ -61,7 +61,7 @@ There are many ways to contribute to VyAPI:
## License
-By contributing to VyAPI, you agree that your contributions will be licensed under the same license that covers the project.
+By contributing to PyVyOS, you agree that your contributions will be licensed under the same license that covers the project.
-Thank you for considering contributing to VyAPI. Your efforts are what make this project great!
+Thank you for considering contributing to PyVyOS. Your efforts are what make this project great!
diff --git a/README.md b/README.md
index 48dd73c..5ac7560 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,150 @@
-# vyapi
-Python SDK for interacting with VyOS API
+# 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.
-## .env for example.py
-run example.py after you create and .env
+## Installation
+
+You can install PyVyOS using pip:
+
+```
+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:
```
-VYDEVICE_HOSTNAME=
-VYDEVICE_KEY=
-VYDEVICE_PORT=443
-VYDEVICE_PROTOCOL=https
-VYDEVICE_VERIFY_SSL=False
+import urllib3
+urllib3.disable_warnings()
```
+### Using API Response Class
+PyVyOS uses a custom ApiResponse data class to handle API responses:
+
+```
+@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:
+
+```
+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:
+
+```
+# 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:
+
+```
+# 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
+```
+# Retrieve VyOS return values for a specific interface
+response = device.retrieve_return_values(path=["interfaces", "dummy", "dum1", "address"])
+print(response.result)
+```
+
+### Configure Delete
+```
+# Delete a VyOS interface configuration
+response = device.configure_delete(path=["interfaces", "dummy", "dum1"])
+```
+
+### Generate
+```
+# 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
+```
+# Show VyOS system image information
+response = device.show(path=["system", "image"])
+print(response.result)
+```
+
+### Reset
+```
+# Reset VyOS with specific parameters
+response = device.reset(path=["conntrack-sync", "internal-cache"])
+```
+
+### Configure Set
+The configure_set method sets a VyOS configuration:
+
+```
+# 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
+```
+# Save VyOS configuration without specifying a file (default location)
+response = device.config_file_save()
+```
+
+### Config File Save with custom filename
+```
+# Save VyOS configuration to a specific file
+response = device.config_file_save(file="/config/test300.config")
+```
+
+### Config File Load
+```
+# Load VyOS configuration from a specific file
+response = device.config_file_load(file="/config/test300.config")
+``` \ No newline at end of file
diff --git a/example.py b/example.py
index a58b656..3f81de0 100644
--- a/example.py
+++ b/example.py
@@ -1,34 +1,66 @@
-#import warnings
-#warnings.filterwarnings("ignore", category=RuntimeWarning)
-
+# importing modules
+import warnings
+warnings.filterwarnings("ignore", category=RuntimeWarning)
import sys
import os
-
-# Adicione o diretório raiz do projeto ao sys.path para que possa importar vyapi
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__))))
-
+# adding pyvyos to sys.path
+#sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__))))
import unittest
-from vyapi.device import VyDevice
-from vyapi.device import ApiResponse
from dotenv import load_dotenv
import pprint
+import random
+import string
+
+# importing pyvyos modules
+from pyvyos.device import VyDevice
+from pyvyos.device import ApiResponse
-load_dotenv()
+# getting env variables
+load_dotenv()
hostname = os.getenv('VYDEVICE_HOSTNAME')
-key = os.getenv('VYDEVICE_KEY')
+apikey = os.getenv('VYDEVICE_APIKEY')
port = os.getenv('VYDEVICE_PORT')
protocol = os.getenv('VYDEVICE_PROTOCOL')
verify = os.getenv('VYDEVICE_VERIFY_SSL')
if verify == "False":
verify = False
-
else:
verify = True
+# running example
if __name__ == '__main__':
- device = VyDevice(hostname=hostname, key=key, port=port, protocol=protocol, verify=verify)
- response = device.retrieve_show_config(['system'])
- pprint.pprint(response)
+ # preparing connection to vyos device
+ device = VyDevice(hostname=hostname, apikey=apikey, port=port, protocol=protocol, verify=verify)
+
+
+
+ #response = device.retrieve_show_config(['system'])
+ #pprint.pprint(response)
+
+ #print("### Generating ssh key ###")
+ #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])
+ #pprint.pprint(response)
+
+
+
+ #response = device.retrieve_return_values(path=["interfaces", "ethernet", "eth0", "address"])
+ #pprint.pprint(response)
+
+ #response = device.reset(path=["conntrack-sync", "internal-cache"])
+ #pprint.pprint(response)
+
+ #response = device.reboot(path=["now"])
+ #pprint.pprint(response)
+
+ #response = device.shutdown(path=["now"])
+ #pprint.pprint(response)
+
+ #response = device.image_add(url="https://github.com/vyos/vyos-rolling-nightly-builds/releases/download/1.5-rolling-202312130023/vyos-1.5-rolling-202312130023-amd64.iso")
+ #pprint.pprint(response)
+ response = device.image_delete(name="foo")
+ pprint.pprint(response)
diff --git a/pyproject.toml b/pyproject.toml
index ef4c9c8..82ac6cc 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -3,8 +3,8 @@ requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
-name = "vyapi"
-version = "0.1.1"
+name = "pyvyos"
+version = "0.2.0"
authors = [
{ name="Roberto Berto", email="roberto.berto@gmail.com" },
]
@@ -18,8 +18,8 @@ classifiers = [
]
[project.urls]
-Homepage = "https://github.com/gravscale/vyapi"
-Issues = "https://github.com/gravscale/vyapi/issues"
+Homepage = "https://github.com/gravscale/pyvyos"
+Issues = "https://github.com/gravscale/pyvyos/issues"
[tool.hatch.metadata]
dependencies = [
@@ -31,10 +31,10 @@ dev-dependencies = [
]
[tool.poetry]
-name = "vyapi"
+name = "pyvyos"
description = "Python SDK for interacting with VyOS API"
authors = ["Roberto Berto <roberto.berto@gmail.com>"]
-version = "0.1.1"
+version = "0.2.0"
[tool.poetry.dependencies]
python = ">=3.8"
diff --git a/vyapi/__init__.py b/pyvyos/__init__.py
index 7c327e5..7c327e5 100644
--- a/vyapi/__init__.py
+++ b/pyvyos/__init__.py
diff --git a/vyapi/device.py b/pyvyos/device.py
index f601f36..1d0933b 100644
--- a/vyapi/device.py
+++ b/pyvyos/device.py
@@ -26,25 +26,34 @@ class VyDevice:
def _get_url(self, command):
return f"{self.protocol}://{self.hostname}:{self.port}/{command}"
- def _get_payload(self, op, path, file=None):
+
+ def _get_payload(self, op, path=[], file=None, url=None, name=None):
+ data = {
+ 'op': op,
+ 'path': path
+ }
+
if file is not None:
- return {
- 'data': json.dumps({
- 'op': op,
- 'file': file,
- }),
- 'key': self.apikey
- }
- else:
- return {
- 'data': json.dumps({'op': op, 'path': path}),
- 'key': self.apikey
- }
-
- def _api_request(self, command, op, path=[], method='POST', file=None):
+ data['file'] = file
+
+ if url is not None:
+ data['url'] = url
+
+ if name is not None:
+ data['name'] = name
+
+ payload = {
+ 'data': json.dumps(data),
+ 'key': self.apikey
+ }
+
+ #print(payload)
+ return payload
+
+ def _api_request(self, command, op, path=[], method='POST', file=None, url=None, name=None):
url = self._get_url(command)
- payload = self._get_payload(op, path, file)
- pprint.pprint(payload)
+ payload = self._get_payload(op, path=path, file=file, url=url, name=name)
+ #pprint.pprint(payload)
headers = {}
error = False
@@ -53,6 +62,7 @@ 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:
resp_decoded = resp.json()
@@ -74,6 +84,8 @@ class VyDevice:
error = 'connection error: ' + str(e)
status = 0
+ # removing apikey from payload for security reasons
+ del(payload['key'])
return ApiResponse(status=status, request=payload, result=result, error=error)
@@ -81,22 +93,22 @@ class VyDevice:
return self._api_request(command="retrieve", op='showConfig', path=path, method="POST")
def retrieve_return_values(self, path=[]):
- pass
+ return self._api_request(command="retrieve", op='returnValues', path=path, method="POST")
def reset(self, path=[]):
- pass
+ return self._api_request(command="reset", op='reset', path=path, method="POST")
- def image_add(self):
- pass
+ def image_add(self, url=None, file=None, path=[]):
+ return self._api_request(command="image", op='add', url=url, method="POST")
- def image_delete(self):
- pass
+ def image_delete(self, name, url=None, file=None, path=[]):
+ return self._api_request(command="image", op='delete', name=name, method="POST")
def show(self, path=[]):
- pass
+ return self._api_request(command="show", op='show', path=path, method="POST")
def generate(self, path=[]):
- pass
+ return self._api_request(command="generate", op='generate', path=path, method="POST")
def configure_set(self, path=[]):
return self._api_request(command="configure", op='set', path=path, method="POST")
@@ -110,5 +122,9 @@ class VyDevice:
def config_file_load(self, file=None):
return self._api_request(command="config-file", op='load', file=file, method="POST")
-
- \ No newline at end of file
+ def reboot(self, path=["now"]):
+ return self._api_request(command="reboot", op='reboot', path=path, method="POST")
+
+ def poweroff(self, path=["now"]):
+ return self._api_request(command="poweroff", op='poweroff', path=path, method="POST")
+ \ No newline at end of file
diff --git a/tests/test_vy_device.py b/tests/test_vy_device.py
index b101c1d..84ff0ed 100644
--- a/tests/test_vy_device.py
+++ b/tests/test_vy_device.py
@@ -1,11 +1,12 @@
import sys
import os
import unittest
-from vyapi.device import VyDevice
-from vyapi.device import ApiResponse
+from pyvyos.device import VyDevice
+from pyvyos.device import ApiResponse
from dotenv import load_dotenv
import os
import pprint
+import random, string
load_dotenv()
@@ -25,7 +26,7 @@ class TestVyDevice(unittest.TestCase):
self.device = VyDevice(hostname=hostname, apikey=apikey, port=port, protocol=protocol, verify=verify)
def test_001_retrieve_show_config(self):
- response = self.device.retrieve_show_config(['system'])
+ response = self.device.retrieve_show_config([])
pprint.pprint(response)
self.assertEqual(response.status, 200)
@@ -40,8 +41,14 @@ class TestVyDevice(unittest.TestCase):
self.assertIsNone(response.result)
self.assertFalse(response.error)
+ def test_011_retrieve_return_values(self):
+ response = self.device.retrieve_return_values(path=["interfaces", "dummy", "dum1", "address"])
+ self.assertEqual(response.status, 200)
+ self.assertIsNotNone(response.result)
+ self.assertFalse(response.error)
+ self.assertEqual(response.result, ['192.168.140.1/24'])
- def test_011_configure_delete_interface(self):
+ def test_020_configure_delete_interface(self):
response = self.device.configure_delete(path=["interfaces", "dummy", "dum1"])
pprint.pprint(response)
@@ -49,6 +56,31 @@ class TestVyDevice(unittest.TestCase):
self.assertIsNone(response.result)
self.assertFalse(response.error)
+ def test_050_generate(self):
+ randstring = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(20))
+ keyrand = f'/tmp/key_{randstring}'
+ response = self.device.generate(path=["ssh", "client-key", keyrand])
+ pprint.pprint(response)
+
+ self.assertEqual(response.status, 200)
+ self.assertIsNotNone(response.result)
+ self.assertFalse(response.error)
+
+ def test_100_show(self):
+ response = self.device.show(path=["system", "image"])
+ pprint.pprint(response)
+
+ self.assertEqual(response.status, 200)
+ self.assertIsNotNone(response.result)
+ self.assertFalse(response.error)
+
+ def test_200_reset(self):
+ response = self.device.reset(path=["conntrack-sync", "internal-cache"])
+ pprint.pprint(response)
+
+ self.assertEqual(response.status, 200)
+ self.assertIsNotNone(response.result)
+ self.assertFalse(response.error)
def test_300_config_file_save(self):
response = self.device.config_file_save(file="/config/test300.config")
@@ -76,8 +108,6 @@ class TestVyDevice(unittest.TestCase):
self.assertFalse(response.error)
-
-
def tearDown(self):
pass
diff --git a/vyapi/utils.py b/vyapi/utils.py
deleted file mode 100644
index e69de29..0000000
--- a/vyapi/utils.py
+++ /dev/null