# gns3fy
![Tests](https://github.com/davidban77/gns3fy/actions/workflows/tests.yml/badge.svg)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![codecov](https://codecov.io/gh/davidban77/gns3fy/branch/develop/graph/badge.svg)](https://codecov.io/gh/davidban77/gns3fy)
[![Total alerts](https://img.shields.io/lgtm/alerts/g/davidban77/gns3fy.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/davidban77/gns3fy/alerts/)
[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/davidban77/gns3fy.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/davidban77/gns3fy/context:python)
[![pypi](https://img.shields.io/pypi/v/gns3fy.svg)](https://pypi.python.org/pypi/gns3fy)
[![versions](https://img.shields.io/pypi/pyversions/gns3fy.svg)](https://github.com/davidban77/gns3fy)
Python wrapper around [GNS3 Server API](http://api.gns3.net/en/2.2/index.html). Minimal GNS3 version is 2.2.
Its main objective is to interact with the GNS3 server in a programatic way, so it can be integrated with the likes of Ansible, docker and scripts. Ideal for network CI/CD pipeline tooling.
## Documentation
Check out the [Documentation](https://davidban77.github.io/gns3fy/) to explore use cases and the API Reference
## Use cases
Here are some examples where gns3fy is used in a programmatic way:
- [Ansible-collection-gns3](https://galaxy.ansible.com/davidban77/gns3): Useful for CI/CD pipelines to interact with GNS3 server using Ansible. It can create/delete projects, nodes and links in an ansible playbook.
- Terraform: Coming soon... (although it might be a Go version of it)
- [Migrate templates between GNS3 servers](https://davidban77.github.io/gns3fy/user-guide/#migrate-templates-between-gns3-servers)
- [Check server usage](https://davidban77.github.io/gns3fy/user-guide/#check-server-cpu-and-memory-usage) before turning up resource-hungry nodes
- [Manipulate project snapshots](https://davidban77.github.io/gns3fy/user-guide/#create-and-list-project-snapshots) like create, delete or list the snapshots configured for the project.
## Install
```shell
pip install gns3fy
```
### Development version
Use [poetry](https://github.com/sdispater/poetry) to install the package when cloning it.
## How it works
You can start the library and use the `Gns3Connector` object and the `Project` object.
For example:
```python
>>> import gns3fy
>>> from tabulate import tabulate
# Define the server object to establish the connection
>>> gns3_server = gns3fy.Gns3Connector("http://<server address>:3080")
# Show the available projects on the server
>>> print(
tabulate(
gns3_server.projects_summary(is_print=False),
headers=["Project Name", "Project ID", "Total Nodes", "Total Links", "Status"],
)
)
"""
Project Name Project ID Total Nodes Total Links Status
-------------- ------------------------------------ ------------- ------------- --------
test2 c9dc56bf-37b9-453b-8f95-2845ce8908e3 10 9 opened
API_TEST 4b21dfb3-675a-4efa-8613-2f7fb32e76fe 6 4 opened
mpls-bgpv2 f5de5917-0ac5-4850-82b1-1d7e3c777fa1 30 40 closed
"""
# Define the lab you want to load and assign the server connector
>>> lab = gns3fy.Project(name="API_TEST", connector=gns3_server)
# Retrieve its information and display
>>> lab.get()
>>> print(lab)
"Project(project_id='4b21dfb3-675a-4efa-8613-2f7fb32e76fe', name='API_TEST', status='opened', ...)"
# Access the project attributes
>>> print(f"Name: {lab.name} -- Status: {lab.status} -- Is auto_closed?: {lab.auto_close}")
"Name: API_TEST -- Status: closed -- Is auto_closed?: False"
# Open the project
>>> lab.open()
>>> lab.status
opened
# Verify the stats
>>> lab.stats
{'drawings': 0, 'links': 4, 'nodes': 6, 'snapshots': 0}
# List the names and status of all the nodes in the project
>>> for node in lab.nodes:
... print(f"Node: {node.name} -- Node Type: {node.node_type} -- Status: {node.status}")
"Node: Ethernetswitch-1 -- Node Type: ethernet_switch -- Status: started"
...
```
Take a look at the API documentation for complete information about the attributes retrieved.
### Usage of Node and Link objects
You have access to the `Node` and `Link` objects as well, this gives you the ability to start, stop, suspend the individual element in a GNS3 project.
```python
>>> from gns3fy import Node, Link, Gns3Connector
>>> PROJECT_ID = "<some project id>"
>>> server = Gns3Connector("http://<server address>:3080")
>>> alpine1 = Node(project_id=PROJECT_ID, name="alpine-1", connector=server)
>>> alpine1.get()
>>> print(alpine1)
"Node(name='alpine-1', node_type='docker', node_directory= ...)"
# And you can access the attributes the same way as the project
>>> print(f"Name: {alpine1.name} -- Status: {alpine1.status} -- Console: {alpine1.console}")
"Name: alpine-1 -- Status: started -- Console: 5005"
# Stop the node and start (you can just restart it as well)
>>> alpine1.stop()
>>> alpine1.status
stopped
>>> alpine1.start()
>>> alpine1.status
started
# You can also see the Link objects assigned to this node
>>> alpine1.links
[Link(link_id='4d9f1235-7fd1-466b-ad26-0b4b08beb778', link_type='ethernet', ...)]
# And in the same way you can interact with a Link object
>>> link1 = alpine1.links[0]
>>> print(f"Link Type: {link1.link_type} -- Capturing?: {link1.capturing} -- Endpoints: {link1.nodes}")
"Link Type: ethernet -- Capturing?: False -- Endpoints: [{'adapter_number': 2, ...}]"
```
### Useful functions
You also have some commodity methods like the `nodes_summary` and `links_summary`, that if used with a library like `tabulate` you can see the following:
```python
>>> from tabulate import tabulate
>>> nodes_summary = lab.nodes_summary(is_print=False)
>>> print(
... tabulate(nodes_summary, headers=["Node", "Status", "Console Port", "ID"])
... )
"""
Node Status Console Port ID
---------------- -------- -------------- ------------------------------------
Ethernetswitch-1 started 5000 da28e1c0-9465-4f7c-b42c-49b2f4e1c64d
IOU1 started 5001 de23a89a-aa1f-446a-a950-31d4bf98653c
IOU2 started 5002 0d10d697-ef8d-40af-a4f3-fafe71f5458b
vEOS-4.21.5F-1 started 5003 8283b923-df0e-4bc1-8199-be6fea40f500
alpine-1 started 5005 ef503c45-e998-499d-88fc-2765614b313e
Cloud-1 started cde85a31-c97f-4551-9596-a3ed12c08498
"""
>>> links_summary = lab.links_summary(is_print=False)
>>> print(
... tabulate(links_summary, headers=["Node A", "Port A", "Node B", "Port B"])
... )
"""
Node A Port A Node B Port B
-------------- ----------- ---------------- -----------
IOU1 Ethernet1/0 IOU2 Ethernet1/0
vEOS-4.21.5F-1 Management1 Ethernetswitch-1 Ethernet0
vEOS-4.21.5F-1 Ethernet1 alpine-1 eth0
Cloud-1 eth1 Ethernetswitch-1 Ethernet7
"""
```
Raw data
{
"_id": null,
"home_page": "https://github.com/davidban77/gns3fy",
"name": "gns3fy",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6,<4.0",
"maintainer_email": "",
"keywords": "network,gns3,python,restapi,netdev",
"author": "David Flores",
"author_email": "davidflores7_8@hotmail.com",
"download_url": "https://files.pythonhosted.org/packages/83/65/70186ecb29cab60b9dbd0d5143ff687662de7800c70e7897b4ca6422feea/gns3fy-0.8.0.tar.gz",
"platform": null,
"description": "# gns3fy\n\n![Tests](https://github.com/davidban77/gns3fy/actions/workflows/tests.yml/badge.svg)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![codecov](https://codecov.io/gh/davidban77/gns3fy/branch/develop/graph/badge.svg)](https://codecov.io/gh/davidban77/gns3fy)\n[![Total alerts](https://img.shields.io/lgtm/alerts/g/davidban77/gns3fy.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/davidban77/gns3fy/alerts/)\n[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/davidban77/gns3fy.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/davidban77/gns3fy/context:python)\n[![pypi](https://img.shields.io/pypi/v/gns3fy.svg)](https://pypi.python.org/pypi/gns3fy)\n[![versions](https://img.shields.io/pypi/pyversions/gns3fy.svg)](https://github.com/davidban77/gns3fy)\n\nPython wrapper around [GNS3 Server API](http://api.gns3.net/en/2.2/index.html). Minimal GNS3 version is 2.2.\n\nIts main objective is to interact with the GNS3 server in a programatic way, so it can be integrated with the likes of Ansible, docker and scripts. Ideal for network CI/CD pipeline tooling.\n\n## Documentation\n\nCheck out the [Documentation](https://davidban77.github.io/gns3fy/) to explore use cases and the API Reference\n\n## Use cases\n\nHere are some examples where gns3fy is used in a programmatic way:\n\n- [Ansible-collection-gns3](https://galaxy.ansible.com/davidban77/gns3): Useful for CI/CD pipelines to interact with GNS3 server using Ansible. It can create/delete projects, nodes and links in an ansible playbook.\n- Terraform: Coming soon... (although it might be a Go version of it)\n- [Migrate templates between GNS3 servers](https://davidban77.github.io/gns3fy/user-guide/#migrate-templates-between-gns3-servers)\n- [Check server usage](https://davidban77.github.io/gns3fy/user-guide/#check-server-cpu-and-memory-usage) before turning up resource-hungry nodes\n- [Manipulate project snapshots](https://davidban77.github.io/gns3fy/user-guide/#create-and-list-project-snapshots) like create, delete or list the snapshots configured for the project.\n\n## Install\n\n```shell\npip install gns3fy\n```\n\n### Development version\n\nUse [poetry](https://github.com/sdispater/poetry) to install the package when cloning it.\n\n## How it works\n\nYou can start the library and use the `Gns3Connector` object and the `Project` object.\n\nFor example:\n\n```python\n>>> import gns3fy\n>>> from tabulate import tabulate\n\n# Define the server object to establish the connection\n>>> gns3_server = gns3fy.Gns3Connector(\"http://<server address>:3080\")\n\n# Show the available projects on the server\n>>> print(\n tabulate(\n gns3_server.projects_summary(is_print=False),\n headers=[\"Project Name\", \"Project ID\", \"Total Nodes\", \"Total Links\", \"Status\"],\n )\n )\n\"\"\"\nProject Name Project ID Total Nodes Total Links Status\n-------------- ------------------------------------ ------------- ------------- --------\ntest2 c9dc56bf-37b9-453b-8f95-2845ce8908e3 10 9 opened\nAPI_TEST 4b21dfb3-675a-4efa-8613-2f7fb32e76fe 6 4 opened\nmpls-bgpv2 f5de5917-0ac5-4850-82b1-1d7e3c777fa1 30 40 closed\n\"\"\"\n\n# Define the lab you want to load and assign the server connector\n>>> lab = gns3fy.Project(name=\"API_TEST\", connector=gns3_server)\n\n# Retrieve its information and display\n>>> lab.get()\n>>> print(lab)\n\"Project(project_id='4b21dfb3-675a-4efa-8613-2f7fb32e76fe', name='API_TEST', status='opened', ...)\"\n\n# Access the project attributes\n>>> print(f\"Name: {lab.name} -- Status: {lab.status} -- Is auto_closed?: {lab.auto_close}\")\n\"Name: API_TEST -- Status: closed -- Is auto_closed?: False\"\n\n# Open the project\n>>> lab.open()\n>>> lab.status\nopened\n\n# Verify the stats\n>>> lab.stats\n{'drawings': 0, 'links': 4, 'nodes': 6, 'snapshots': 0}\n\n# List the names and status of all the nodes in the project\n>>> for node in lab.nodes:\n... print(f\"Node: {node.name} -- Node Type: {node.node_type} -- Status: {node.status}\")\n\n\"Node: Ethernetswitch-1 -- Node Type: ethernet_switch -- Status: started\"\n...\n```\n\nTake a look at the API documentation for complete information about the attributes retrieved.\n\n### Usage of Node and Link objects\n\nYou have access to the `Node` and `Link` objects as well, this gives you the ability to start, stop, suspend the individual element in a GNS3 project.\n\n```python\n>>> from gns3fy import Node, Link, Gns3Connector\n\n>>> PROJECT_ID = \"<some project id>\"\n>>> server = Gns3Connector(\"http://<server address>:3080\")\n\n>>> alpine1 = Node(project_id=PROJECT_ID, name=\"alpine-1\", connector=server)\n\n>>> alpine1.get()\n>>> print(alpine1)\n\"Node(name='alpine-1', node_type='docker', node_directory= ...)\"\n\n# And you can access the attributes the same way as the project\n>>> print(f\"Name: {alpine1.name} -- Status: {alpine1.status} -- Console: {alpine1.console}\")\n\"Name: alpine-1 -- Status: started -- Console: 5005\"\n\n# Stop the node and start (you can just restart it as well)\n>>> alpine1.stop()\n>>> alpine1.status\nstopped\n\n>>> alpine1.start()\n>>> alpine1.status\nstarted\n\n# You can also see the Link objects assigned to this node\n>>> alpine1.links\n[Link(link_id='4d9f1235-7fd1-466b-ad26-0b4b08beb778', link_type='ethernet', ...)]\n\n# And in the same way you can interact with a Link object\n>>> link1 = alpine1.links[0]\n>>> print(f\"Link Type: {link1.link_type} -- Capturing?: {link1.capturing} -- Endpoints: {link1.nodes}\")\n\"Link Type: ethernet -- Capturing?: False -- Endpoints: [{'adapter_number': 2, ...}]\"\n```\n\n### Useful functions\n\nYou also have some commodity methods like the `nodes_summary` and `links_summary`, that if used with a library like `tabulate` you can see the following:\n\n```python\n\n>>> from tabulate import tabulate\n\n>>> nodes_summary = lab.nodes_summary(is_print=False)\n\n>>> print(\n... tabulate(nodes_summary, headers=[\"Node\", \"Status\", \"Console Port\", \"ID\"])\n... )\n\"\"\"\nNode Status Console Port ID\n---------------- -------- -------------- ------------------------------------\nEthernetswitch-1 started 5000 da28e1c0-9465-4f7c-b42c-49b2f4e1c64d\nIOU1 started 5001 de23a89a-aa1f-446a-a950-31d4bf98653c\nIOU2 started 5002 0d10d697-ef8d-40af-a4f3-fafe71f5458b\nvEOS-4.21.5F-1 started 5003 8283b923-df0e-4bc1-8199-be6fea40f500\nalpine-1 started 5005 ef503c45-e998-499d-88fc-2765614b313e\nCloud-1 started cde85a31-c97f-4551-9596-a3ed12c08498\n\"\"\"\n>>> links_summary = lab.links_summary(is_print=False)\n>>> print(\n... tabulate(links_summary, headers=[\"Node A\", \"Port A\", \"Node B\", \"Port B\"])\n... )\n\"\"\"\nNode A Port A Node B Port B\n-------------- ----------- ---------------- -----------\nIOU1 Ethernet1/0 IOU2 Ethernet1/0\nvEOS-4.21.5F-1 Management1 Ethernetswitch-1 Ethernet0\nvEOS-4.21.5F-1 Ethernet1 alpine-1 eth0\nCloud-1 eth1 Ethernetswitch-1 Ethernet7\n\"\"\"\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python wrapper around GNS3 Server API",
"version": "0.8.0",
"project_urls": {
"Homepage": "https://github.com/davidban77/gns3fy",
"Repository": "https://github.com/davidban77/gns3fy"
},
"split_keywords": [
"network",
"gns3",
"python",
"restapi",
"netdev"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "15acd9e87103a5e5d0e40e9ca814c921934cf8faba1d5a8e72c869b9c3fbf902",
"md5": "c26115ce1ed2ced1132984b42bbe3037",
"sha256": "d3a9d8b7dedf88deca24d580e2916439ab3ab6d21d0f5692d216984391f0f174"
},
"downloads": -1,
"filename": "gns3fy-0.8.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c26115ce1ed2ced1132984b42bbe3037",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6,<4.0",
"size": 15795,
"upload_time": "2022-05-21T18:35:32",
"upload_time_iso_8601": "2022-05-21T18:35:32.545807Z",
"url": "https://files.pythonhosted.org/packages/15/ac/d9e87103a5e5d0e40e9ca814c921934cf8faba1d5a8e72c869b9c3fbf902/gns3fy-0.8.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "836570186ecb29cab60b9dbd0d5143ff687662de7800c70e7897b4ca6422feea",
"md5": "e2ed327afbd01f71b8cadeab222f8ac6",
"sha256": "961e42d789c5154e5d8dd1e1856c4b6a55d6a611cd82da01cf70c1b351bfdbac"
},
"downloads": -1,
"filename": "gns3fy-0.8.0.tar.gz",
"has_sig": false,
"md5_digest": "e2ed327afbd01f71b8cadeab222f8ac6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6,<4.0",
"size": 18666,
"upload_time": "2022-05-21T18:35:35",
"upload_time_iso_8601": "2022-05-21T18:35:35.286604Z",
"url": "https://files.pythonhosted.org/packages/83/65/70186ecb29cab60b9dbd0d5143ff687662de7800c70e7897b4ca6422feea/gns3fy-0.8.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-05-21 18:35:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "davidban77",
"github_project": "gns3fy",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "gns3fy"
}