Skip to content

Commit

Permalink
initial changes from skeleton driver
Browse files Browse the repository at this point in the history
  • Loading branch information
glennake committed Feb 21, 2022
1 parent 6007d29 commit c7d6f39
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 163 deletions.
2 changes: 1 addition & 1 deletion AUTHORS
Original file line number Diff line number Diff line change
@@ -1 +1 @@
David Barroso <[email protected]>
Glenn Akester <[email protected]>
4 changes: 2 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
include requirements.txt
include napalm_skeleton/templates/*.j2
include napalm_skeleton/utils/textfsm_templates/*.tpl
include napalm_fortinet/templates/*.j2
include napalm_fortinet/utils/textfsm_templates/*.tpl
141 changes: 44 additions & 97 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,116 +1,63 @@
# napalm-skeleton

Congratulations! You are going to embark on an epic adventure that will bring you glory, fame and
fortune.

> “Don't wish, Miss Tick had said. Do things.”
> -- Terry Pratchett
## Instructions

### Before starting

1. Pick a name. Something that can easily identify which NOS you are supporting. From now on we will
call it `SKELETON` so everytime you see `SKELETON` on this repo, replace it with the name you just
picked.
1. Let the `napalm` community know that you are planning to write a new driver. You can try reaching
out on slack or on the mailing list. Someone will create a repo for you under the
[`napalm-automation-community`](https://github.com/napalm-automation-community) organization. You
can host your own driver if you prefer but we think it's more interesting if we can host all of the
drivers together.
You can find more details regarding the [Community drivers guidelines](http://napalm.readthedocs.io/en/develop/contributing/drivers.html).
1. Feel free to amend the Copyright holder.

### Replacing the skeleton to the new repo

After cloning this repository, you can bootstrap a new repository for
your driver using the following commands (keep `skeleton` as is, but
replace `newname` and `NewName` appropriately):

```sh
git archive --prefix=napalm-newname/ HEAD | tar -C .. -xf -
cd ../napalm-newname
grep -rl skeleton | xargs sed -i"" s/skeleton/newname/g
grep -rl Skeleton | xargs sed -i"" s/Skeleton/NewName/g
for d in $(find . -type d -name '*skeleton*'); do mv $d ${d/skeleton/newname}; done
for f in $(find . -type f -name '*skeleton*'); do mv $f ${f/skeleton/newname}; done
for f in $(find . -type f -name '*Skeleton*'); do mv $f ${f/Skeleton/NewName}; done
git init
git add .
```
# napalm-procurve

[NAPALM](https://napalm-automation.net/) driver for Fortinet networking
equipment.

Alternatively, you can replace the first two commands by using the
*Use this template* button in GitHub interface.
Supported devices
=================

### Fixing the `README.md` and `AUTHORS`
Fortinet FortiOS devices should be supported. The code has been written and tested
against FortiGate firewalls.

1. Replace the occurrences on this file of `SKELETON`. Replace only the ones above
the `CUTTING_LINE`. Don't bother about `pypi`, `travis`, etc. That will be taking care of later,
after the first merge.
1. Feel free to replace the content of AUTHORS as well and put yourself there. That's what will
bring you the fame and fortune after all ;)
1. Add any other useful information on the `README.md` file you think it's interesting.
Please open a GitHub issue if you find an problems.

### The Driver
Development status
==================

All the code should be inside `napalm_skeleton`. You are free to organize your code as you want,
however, there are some parts that have to be done in a certain way:
The driver is functional and can be used to poll status information:

* `napalm_skeleton/__init__.py` - That file should import your class driver. That's what the
dynamic importer will expect.
* `napalm_skeleton/skeleton.py` - Here goes your driver.
* `napalm_skeleton/templates/` - We use this folder to store templates used by the `load_template`
method.
* `napalm_skeleton/utils/` - For consistency with other repos we recommend putting your additional
code here. Helper functions or anything you want to keep out of the main driver file.
* `napalm_skeleton/utils/textfsm_templates` - For consistency as well, we recommend keeping your
`textfsm` templates here. We are planning to do some stuff around here so might have some common
code that will assume they are there.
* `MANIFEST.in` - If you need some additional support files that are not code, don't forget to add
them to this file. Please, don't forget to set the correct paths.
* WIP

### The Tests
How to use
==========

Code for testing is inside the `test` folder.
Install napalm via pip:
```
$ pip install napalm
```

* `test/unit/TestDriver.py` - Here goes the following classes:
* `TestConfigDriver` - Tests for configuration management related methods.
* `TestGetterDriver` - Tests for getters.
* `FakeDevice` - Test double for your device.
* `test/unit/skeleton/` - Here goes some configuration files that are used by `TestConfigDriver`.
* `test/unit/skeleton/mock_data/` - Here goes files that contain mocked data used by
`TestGetterDriver`.
Install napalm-fortinet via pip:
```
$ pip install git+https://github.com/glennake/napalm-fortinet.git
```

#### Testing configuration management methods
Test functionality:
```
#!/usr/bin/env python3
# Simple napalm-procurve test
This is tricky. Cloud CI services like `Travis-CI` don't support running virtual machines and
we currently don't have the resources or the means to test from a cloud service or with real
machines. Moreover, mocking this might be very difficult and error prone. Vendors like changing
the internal with every minor release and we might have end up mocking several parts of the system
that are undocumented and have hundreds of edge cases. The only way we could safely mock this is
if vendors would provide us with their parsers and that's not going to happen. Because of these
reasons, the only safe way of testing is by using a VM or physical machine and testing manually
every time someone pushes code that changes a configuration management method. Luckily, these are
limited so once they are stable we can forget about them.
import json
from napalm import get_network_driver
If there is a VM available, please, provide a vagrant environment and use it for the tests,
that way other developers will be able to test as well.
driver = get_network_driver("fortinet")
If you want Travis CI for your new driver (once hosted under the
[`napalm-automation-community`](https://github.com/napalm-automation-community)
organization), just let us know and we'll enable it for you.
device = driver(
"1.2.3.4",
"admin",
"password",
optional_args={"port": 22},
)
#### Testing getters
device.open()
This is easier, we can use a real machine or just mock the device. Write a test double for your
device and provide the necessary mocked data.
facts = device.get_facts()
After you implement one or more methods, make sure the driver respects the base
NAPALM API. To check this, simply execute ``tox`` on the command line.
device.close()
### Other files
print(facts)
```

Some other stuff you have to do:
License
=======

* `setup.py` - Set yourself as the author and set the correct `name`.
* `requirements.txt` - Make sure requirements are up to date.
Apache License, Version 2.0
6 changes: 3 additions & 3 deletions napalm_skeleton/__init__.py → napalm_fortinet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations under
# the License.

"""napalm-skeleton package."""
from napalm_skeleton.skeleton import SkeletonDriver # noqa
"""napalm-fortinet package."""
from napalm_fortinet.fortinet import FortinetDriver # noqa

__all__ = ('SkeletonDriver',)
__all__ = ("FortinetDriver",)
7 changes: 3 additions & 4 deletions napalm_skeleton/skeleton.py → napalm_fortinet/skeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# the License.

"""
Napalm driver for Skeleton.
Napalm driver for Fortinet.
Read https://napalm.readthedocs.io for more information.
"""
Expand All @@ -29,8 +29,8 @@
)


class SkeletonDriver(NetworkDriver):
"""Napalm driver for Skeleton."""
class FortinetDriver(NetworkDriver):
"""Napalm driver for Fortinet."""

def __init__(self, hostname, username, password, timeout=60, optional_args=None):
"""Constructor."""
Expand All @@ -47,7 +47,6 @@ def open(self):
"""Implement the NAPALM method open (mandatory)"""
pass


def close(self):
"""Implement the NAPALM method close (mandatory)"""
pass
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ jsonapi = true

[coverage:run]
include =
napalm_skeleton/*
napalm_fortinet/*

[coverage:report]
omit =
napalm_skeleton/test/*
napalm_fortinet/test/*
18 changes: 9 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@

from setuptools import setup, find_packages

__author__ = 'David Barroso <[email protected]>'
__author__ = "David Barroso <[email protected]>"

with open("requirements.txt", "r") as fs:
reqs = [r for r in fs.read().splitlines() if (len(r) > 0 and not r.startswith("#"))]

setup(
name="napalm-skeleton",
name="napalm-fortinet",
version="0.1.0",
packages=find_packages(),
author="David Barroso",
author_email="[email protected]",
description="Network Automation and Programmability Abstraction Layer with Multivendor support",
classifiers=[
'Topic :: Utilities',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Operating System :: POSIX :: Linux',
'Operating System :: MacOS',
"Topic :: Utilities",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
],
url="https://github.com/napalm-automation/napalm-skeleton",
url="https://github.com/napalm-automation/napalm-fortinet",
include_package_data=True,
install_requires=reqs,
)
42 changes: 24 additions & 18 deletions test/unit/TestDriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import unittest

from napalm_skeleton import skeleton
from napalm_fortinet import fortinet
from napalm.base.test.base import TestConfigNetworkDriver, TestGettersNetworkDriver
import json

Expand All @@ -27,17 +27,20 @@ class TestConfigDriver(unittest.TestCase, TestConfigNetworkDriver):
@classmethod
def setUpClass(cls):
"""Run before starting the tests."""
hostname = '127.0.0.1'
username = 'vagrant'
password = 'vagrant'
cls.vendor = 'skeleton'

optional_args = {'port': 12443, }
cls.device = skeleton.SkeletonDriver(hostname, username, password, timeout=60,
optional_args=optional_args)
hostname = "127.0.0.1"
username = "vagrant"
password = "vagrant"
cls.vendor = "fortinet"

optional_args = {
"port": 12443,
}
cls.device = fortinet.FortinetDriver(
hostname, username, password, timeout=60, optional_args=optional_args
)
cls.device.open()

cls.device.load_replace_candidate(filename='%s/initial.conf' % cls.vendor)
cls.device.load_replace_candidate(filename="%s/initial.conf" % cls.vendor)
cls.device.commit_config()


Expand All @@ -49,14 +52,17 @@ def setUpClass(cls):
"""Run before starting the tests."""
cls.mock = True

hostname = '127.0.0.1'
username = 'vagrant'
password = 'vagrant'
cls.vendor = 'skeleton'

optional_args = {'port': 12443, }
cls.device = skeleton.SkeletonDriver(hostname, username, password, timeout=60,
optional_args=optional_args)
hostname = "127.0.0.1"
username = "vagrant"
password = "vagrant"
cls.vendor = "fortinet"

optional_args = {
"port": 12443,
}
cls.device = fortinet.FortinetDriver(
hostname, username, password, timeout=60, optional_args=optional_args
)

if cls.mock:
cls.device.device = FakeDevice()
Expand Down
25 changes: 14 additions & 11 deletions test/unit/TestSkeletonDriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,28 @@

import unittest

from napalm_skeleton import skeleton
from napalm_fortinet import fortinet
from napalm.base.test.base import TestConfigNetworkDriver


class TestConfigSkeletonDriver(unittest.TestCase, TestConfigNetworkDriver):
class TestConfigFortinetDriver(unittest.TestCase, TestConfigNetworkDriver):
"""Group of tests that test Configuration related methods."""

@classmethod
def setUpClass(cls):
"""Run before starting the tests."""
hostname = '127.0.0.1'
username = 'vagrant'
password = 'vagrant'
cls.vendor = 'skeleton'

optional_args = {'port': 12443, }
cls.device = skeleton.SkeletonDriver(hostname, username, password, timeout=60,
optional_args=optional_args)
hostname = "127.0.0.1"
username = "vagrant"
password = "vagrant"
cls.vendor = "fortinet"

optional_args = {
"port": 12443,
}
cls.device = fortinet.FortinetDriver(
hostname, username, password, timeout=60, optional_args=optional_args
)
cls.device.open()

cls.device.load_replace_candidate(filename='%s/initial.conf' % cls.vendor)
cls.device.load_replace_candidate(filename="%s/initial.conf" % cls.vendor)
cls.device.commit_config()
Loading

0 comments on commit c7d6f39

Please sign in to comment.