Compare commits

..

49 Commits

Author SHA1 Message Date
Piotr Pieprzycki a5d3b94663
Merge pull request #39 from marcushoff/get_config
Add get_config method
2020-12-17 22:31:52 +01:00
Piotr Pieprzycki 29ad1b85bd
Merge pull request #38 from marcushoff/get_facts
Update serial_number and model
2020-12-17 22:29:55 +01:00
Piotr Pieprzycki 27bc0c7623 Change version to 0.2.1 2020-12-17 22:16:09 +01:00
Piotr Pieprzycki 7fda2abd47
Merge pull request #40 from marcushoff/configure
Update file mode
2020-12-17 21:54:38 +01:00
Marcus Hoff d4e25b4e46 Update file mode
Default file mode i binary, updated to string
2020-11-16 09:27:15 +01:00
Marcus Hoff 619fc3d32c Fix expected results for sanitized
changed the return password to be hidden
2020-10-23 11:21:13 +02:00
Marcus Hoff 7e470df55e Fix expected results
Fixed wrong output and new lines in expected results and corrected the show output for test_get_config
2020-10-23 10:46:52 +02:00
Marcus Hoff 1200cf4328 Fix sanitized_test, Add str return to candidate
Change the expected results of sanitized test.
If candidate config is None return empty string
2020-10-22 18:28:34 +02:00
Marcus Hoff d970ad22c9 Fixed tests
Add missing case test_get_config_filtere
Correct names of mock files
2020-10-22 16:51:57 +02:00
Marcus Hoff 7107560f84 Add tests for get_config
Add test cases for normal and sanitized versions.
Add support for config mode in mock device.
2020-10-22 14:54:34 +02:00
Marcus Hoff 5ab6f4de21 Add get_config method
Supports all retrive options, where 'candidate' is the Napalm candidate.
Either gets the boot config as 'startup' or output from 'show' in edit mode for 'running'
Supports sanitized only for 'running'. Outputs the 'show' in op mode.
2020-10-21 16:34:52 +02:00
Marcus Hoff a205b99ca5 Update serial_number and model
Fixes my bugs
2020-10-18 15:06:58 +02:00
Marcus Hoff a4a0645f27 Update serial_number and model
Updated the match pattern of serial_number and model to the current 1.2/1.3 release of Vyos, maintained code for older versions
2020-10-18 14:22:50 +02:00
Piotr Pieprzycki fe3d5560ab
Merge pull request #32 from bradmwalker/napalm3
Napalm 3 Compatibility
2020-05-17 23:46:12 +02:00
Piotr Pieprzycki 05296bc1fa
Merge branch 'develop' into napalm3 2020-05-17 23:43:38 +02:00
Piotr Pieprzycki ea4bc1a4ae
Merge pull request #34 from bradmwalker/lldp
Implement get_lldp_neighbors() for simple case
2020-05-17 23:39:10 +02:00
Piotr Pieprzycki 011db99dcc
Merge pull request #33 from bradmwalker/mtu
Add MTU to get_interfaces() results
2020-05-17 23:35:08 +02:00
Brad Walker 0420304a6d Implement get_lldp_neighbors() for simple case 2020-05-17 10:53:07 -06:00
Brad Walker b883dcbbb0 Bump to 0.1.7 and require NAPALM 2.5 2020-05-16 13:06:10 -06:00
Brad Walker c78fd09304 Add invalid mtu to get_interfaces 2020-05-16 13:02:21 -06:00
Brad Walker d2d0f2723f Bump minor version and use NAPALM 3 2020-05-16 12:34:21 -06:00
Brad Walker 2bdb499b14 Replace _get_value with dict.get usage 2020-05-16 10:50:09 -06:00
Brad Walker cbfe8ae0c4 Fix invalid escape sequence DeprecationWarnings 2020-05-16 10:44:11 -06:00
Brad Walker 3b53afd852 Improve SyntaxWarning for empty string checks 2020-05-16 10:39:20 -06:00
Brad Walker b287f3d6c7 Remove py23_compat.text_type usage 2020-05-16 10:26:39 -06:00
Piotr Pieprzycki df1d827038
Merge pull request #29 from ppieprzycki/issue28
Fix installation fails with the pip > 10
2019-02-15 09:19:34 +01:00
Pieprzycki Piotr 0175531bbb add additional parameters 2019-02-14 23:55:18 +01:00
Pieprzycki Piotr 42953c84ae add additional parameters 2019-02-14 23:43:56 +01:00
Pieprzycki Piotr 57b6110f13 fix pip issue 2019-02-14 07:03:57 +01:00
Piotr Pieprzycki f1549d8af3
Merge pull request #25 from napalm-automation-community/master
Update develop branch
2018-04-08 18:26:36 +02:00
Piotr Pieprzycki 2278bddd3a
Merge pull request #24 from ppieprzycki/master
Support for salt
2018-04-08 18:19:57 +02:00
Pieprzycki Piotr 55a6b15c3e Update docs 2018-04-08 18:15:28 +02:00
Pieprzycki Piotr 580da0edeb Update docs 2018-04-08 18:12:07 +02:00
Pieprzycki Piotr 23fe045167 Update docs 2018-04-08 18:09:21 +02:00
Pieprzycki Piotr b8ec1396f7 Update docs 2018-04-08 17:56:49 +02:00
Pieprzycki Piotr 5c3492f13c Update docs 2018-04-08 11:28:15 +02:00
Pieprzycki Piotr 47227d1cf0 handle config as text in load and merge functions 2018-04-08 00:23:04 +02:00
Piotr Pieprzycki 06f9fc28d3
Merge pull request #23 from napalm-automation-community/develop
Merge develop branch with master
2018-02-22 21:30:01 +01:00
Piotr Pieprzycki 6e68dba692
Merge pull request #22 from ppieprzycki/master
Fix travis status and set new version 0.1.4
2018-02-22 20:36:50 +01:00
Piotr Pieprzycki 7d0e30fdba
Merge pull request #20 from thomseddon/fix/use-napalm-base
Use napalm instead of napalm_base
2018-02-22 20:29:11 +01:00
Pieprzycki Piotr 4d52216866 Fix travis status and set new version 0.1.4 2018-02-22 20:28:24 +01:00
Piotr Pieprzycki 5c440b3df9
Merge pull request #21 from ppieprzycki/master
Fix imports to napalm2
2018-02-22 20:19:15 +01:00
Pieprzycki Piotr 69c8c66652 napalm 2 2018-02-22 20:00:24 +01:00
Thom Seddon b9bcbbc7bc Use napalm instead of napalm_base 2018-02-22 10:16:54 +00:00
Mircea Ulinic 347d6a6603 Merge pull request #14 from napalm-automation/develop
Release 0.1.3
2017-02-08 15:28:04 -05:00
Mircea Ulinic cc98324b6d Merge pull request #13 from napalm-automation/rel-0.1.3
Version 0.1.3
2017-02-08 15:09:07 -05:00
Mircea Ulinic fcdcfb719f Merge pull request #12 from mirceaulinic/patch-1
Add vrf arg to ping
2017-02-08 15:08:59 -05:00
Mircea Ulinic 673cb74593 Version 0.1.3 2017-02-07 01:06:01 -05:00
Mircea Ulinic 44948805bc Add vrf arg to ping
Looks like vyos doesn't know about VRF
so these changes should be reflected only
in the method header
2017-02-02 12:06:48 +00:00
22 changed files with 1163 additions and 132 deletions

View File

@ -1,8 +1,8 @@
language: python
python:
- 2.7
- 3.4
- 3.5
- 3.6
- 3.7
- 3.8
install:
- pip install tox-travis
- pip install coveralls

107
README.md
View File

@ -1,5 +1,110 @@
[![PyPI](https://img.shields.io/pypi/v/napalm-vyos.svg)](https://pypi.python.org/pypi/napalm-vyos)
[![PyPI](https://img.shields.io/pypi/dm/napalm-vyos.svg)](https://pypi.python.org/pypi/napalm-vyos)
[![Build Status](https://travis-ci.org/napalm-automation/napalm-vyos.svg?branch=master)](https://travis-ci.org/napalm-automation/napalm-vyos)
[![Build Status](https://travis-ci.org/napalm-automation-community/napalm-vyos.svg?branch=master)](https://travis-ci.org/napalm-automation-community/napalm-vyos)
# napalm-vyos
Community NAPALM driver for the VyOS. https://vyos.io/
Also it can be used for other similar systems: Vyatta or EdgeOS
General support matrix
----------------------
| | VyOS |
|--------------------|--------------|
|**Module Name** | napalm-vyos |
|**Driver Name** | vyos |
|**Structured data** | Yes |
|**Minimum version** | 1.1.6 |
|**Backend library** | netmiko |
Configuration support matrix
----------------------------
| | VyOS |
| ------------------- | ----- |
| **Config. replace** | Yes |
| **Config. merge** | Yes |
|**Compare config** | Yes |
| **Atomic Changes** | Yes |
| **Rollback** | Yes |
Optional arguments
------------------
NAPALM supports passing certain optional arguments to some drivers. To do that you have to pass a dictionary via the
:code:`optional_args` parameter when creating the object::
>>> from napalm import get_network_driver
>>> driver = get_network_driver('vyos')
>>> optional_args = {'my_optional_arg1': 'my_value1', 'my_optional_arg2': 'my_value2'}
>>> device = driver('192.168.76.10', 'vagrant', 'this_is_not_a_secure_password', optional_args=optional_args)
>>> device.open()
List of supported optional arguments
____________________________________
* :code:`port` (vyos) - Allows you to specify a port other than the default.
* :code:`key_file` (vyos) - Netmiko/Paramiko argument, path to a private key file (default: 'False').
Prerequisites
-------------
VyOS has no native HTTP API or NETCONF capability.
We are using Netmiko for ssh connections and scp file transfers.
Having Netmiko installed in your working box is a prerequisite.
VyOS in version 1.1.x (tested 1.1.7)
napalm==2.*
paramiko
netmiko>=1.1.0
vyattaconfparser
Configuration file
------------------
Currently VyOS driver supports two different configuration formats:
* load_replace_candidate - Full config file (with brackets) like in /config/config.boot
Due to the OS nature, we do not support a replace using
a set-style configuration format.
* load_merge_candidate - Currently driver supports set-style configuration format.
Example
`set system login banner pre-login "test"`
Vyos require configuration file (load_replace) to contain comment like following
`/* Warning: Do not remove the following line. */
/* === vyatta-config-version: "cluster@1:config-management@1:conntrack-sync@1:conntrack@1:cron@1:dhcp-relay@1:dhcp-server@4:firewall@5:ipsec@4:nat@4:qos@1:quagga@2:system@6:vrrp@1:wanloadbalance@3:webgui@1:webproxy@1:zone-policy@1" === */
/* Release version: VyOS 1.1.7 */`
Otherwise VyOS reject `load` operation
Notes
------------------
* The NAPALM-vyos driver supports all Netmiko arguments as either standard arguments (hostname, username, password, timeout) or as optional_args (everything else).
* The NAPALM-vyos driver supports authentication with ssh key. Please specify path to a key in optional_args
`'optional_args': {'key_file': '/home/user/ssh_private_key'}`
Configuration Examples
----------------------
* Vyos as IPSec VPN endpoint and BGP router - https://github.com/DreamLab/ansible-vyos
* CI Demo for vyos+junos (Polish only) https://github.com/ppieprzycki/plnog2016
VyOS Community
------------------
Slack Channel https://slack.vyos.io

View File

@ -22,6 +22,7 @@ Read napalm.readthedocs.org for more information.
import re
import os
import tempfile
import vyattaconfparser
@ -30,10 +31,11 @@ from netmiko import ConnectHandler
from netmiko import SCPConn
# NAPALM base
from napalm_base.utils import py23_compat
from napalm_base.base import NetworkDriver
from napalm_base.exceptions import ConnectionException, \
MergeConfigException, ReplaceConfigException
import napalm.base.constants as C
from napalm.base.base import NetworkDriver
from napalm.base.exceptions import ConnectionException, MergeConfigException, \
ReplaceConfigException, CommitError, \
CommandErrorException
class VyOSDriver(NetworkDriver):
@ -120,53 +122,73 @@ class VyOSDriver(NetworkDriver):
Due to the OS nature, we do not
support a replace using a configuration string.
"""
if filename is not None:
if os.path.exists(filename) is True:
self._scp_client.scp_transfer_file(filename, self._DEST_FILENAME)
self.device.send_command("cp "+self._BOOT_FILENAME+" "+self._BACKUP_FILENAME)
output_loadcmd = self.device.send_config_set(['load '+self._DEST_FILENAME])
match_loaded = re.findall("Load complete.", output_loadcmd)
match_notchanged = re.findall("No configuration changes to commit", output_loadcmd)
match_failed = re.findall("Failed to parse specified config file", output_loadcmd)
if not filename and not config:
raise ReplaceConfigException('filename or config param must be provided.')
if match_failed:
if filename is None:
temp_file = tempfile.NamedTemporaryFile(mode='w+')
temp_file.write(config)
temp_file.flush()
cfg_filename = temp_file.name
else:
cfg_filename = filename
if os.path.exists(cfg_filename) is True:
self._scp_client.scp_transfer_file(cfg_filename, self._DEST_FILENAME)
self.device.send_command("cp "+self._BOOT_FILENAME+" "+self._BACKUP_FILENAME)
output_loadcmd = self.device.send_config_set(['load '+self._DEST_FILENAME])
match_loaded = re.findall("Load complete.", output_loadcmd)
match_notchanged = re.findall("No configuration changes to commit", output_loadcmd)
match_failed = re.findall("Failed to parse specified config file", output_loadcmd)
if match_failed:
raise ReplaceConfigException("Failed replace config: "
+ output_loadcmd)
if not match_loaded:
if not match_notchanged:
raise ReplaceConfigException("Failed replace config: "
+ output_loadcmd)
if not match_loaded:
if not match_notchanged:
raise ReplaceConfigException("Failed replace config: "
+ output_loadcmd)
else:
raise ReplaceConfigException("config file is not found")
else:
raise ReplaceConfigException("no configuration found")
raise ReplaceConfigException("config file is not found")
def load_merge_candidate(self, filename=None, config=None):
"""
Only configuration in set-format is supported with load_merge_candidate.
"""
if filename is not None:
if os.path.exists(filename) is True:
with open(filename) as f:
self.device.send_command("cp "+self._BOOT_FILENAME+" "
+ self._BACKUP_FILENAME)
self._new_config = f.read()
cfg = [x for x in self._new_config.split("\n") if x is not ""]
output_loadcmd = self.device.send_config_set(cfg)
match_setfailed = re.findall("Delete failed", output_loadcmd)
match_delfailed = re.findall("Set failed", output_loadcmd)
if match_setfailed or match_delfailed:
raise MergeConfigException("Failed merge config: "
+ output_loadcmd)
else:
raise MergeConfigException("config file is not found")
elif config is not None:
self._new_config = config
if not filename and not config:
raise MergeConfigException('filename or config param must be provided.')
if filename is None:
temp_file = tempfile.NamedTemporaryFile(mode='w+')
temp_file.write(config)
temp_file.flush()
cfg_filename = temp_file.name
else:
raise MergeConfigException("no configuration found")
cfg_filename = filename
if os.path.exists(cfg_filename) is True:
with open(cfg_filename) as f:
self.device.send_command("cp "+self._BOOT_FILENAME+" "
+ self._BACKUP_FILENAME)
self._new_config = f.read()
cfg = [x for x in self._new_config.split("\n") if x]
output_loadcmd = self.device.send_config_set(cfg)
match_setfailed = re.findall("Delete failed", output_loadcmd)
match_delfailed = re.findall("Set failed", output_loadcmd)
if match_setfailed or match_delfailed:
raise MergeConfigException("Failed merge config: "
+ output_loadcmd)
else:
raise MergeConfigException("config file is not found")
def discard_config(self):
self.device.exit_config_mode()
@ -181,9 +203,18 @@ class VyOSDriver(NetworkDriver):
diff = ''.join(output_compare.splitlines(True)[1:-1])
return diff
def commit_config(self):
if self.device.commit():
self.device.send_config_set(['save'])
def commit_config(self, message=""):
if message:
raise NotImplementedError(
"Commit message not implemented for this platform"
)
try:
self.device.commit()
except ValueError:
raise CommitError("Failed to commit config on the device")
self.device.send_config_set(['save'])
self.device.exit_config_mode()
def rollback(self):
@ -277,7 +308,7 @@ class VyOSDriver(NetworkDriver):
output_iface = self.device.send_command("show interfaces")
# Collect all interfaces' name and status
match = re.findall("(\S+)\s+[:\-\d/\.]+\s+([uAD])/([uAD])", output_iface)
match = re.findall(r"(\S+)\s+[:\-\d/\.]+\s+([uAD])/([uAD])", output_iface)
# 'match' example:
# [("br0", "u", "D"), ("eth0", "u", "u"), ("eth1", "u", "u")...]
@ -296,17 +327,12 @@ class VyOSDriver(NetworkDriver):
ifaces_detail = config["interfaces"][iface_type]
for iface_name in ifaces_detail:
description = self._get_value("description", ifaces_detail[iface_name])
if description is None:
description = ""
speed = self._get_value("speed", ifaces_detail[iface_name])
if speed is None:
speed = 0
details = ifaces_detail[iface_name]
description = details.get("description", "")
speed = details.get("speed", "0")
if speed == "auto":
speed = 0
hw_id = self._get_value("hw-id", ifaces_detail[iface_name])
if hw_id is None:
hw_id = "00:00:00:00:00:00"
hw_id = details.get("hw-id", "00:00:00:00:00:00")
is_up = (iface_state[iface_name]["Link"] == "u")
is_enabled = (iface_state[iface_name]["State"] == "u")
@ -315,23 +341,17 @@ class VyOSDriver(NetworkDriver):
iface_name: {
"is_up": bool(is_up),
"is_enabled": bool(is_enabled),
"description": py23_compat.text_type(description),
"description": description,
"last_flapped": float(-1),
"mtu": -1,
"speed": int(speed),
"mac_address": py23_compat.text_type(hw_id)
"mac_address": hw_id,
}
})
return iface_dict
@staticmethod
def _get_value(key, target_dict):
if key in target_dict:
return target_dict[key]
else:
return None
def get_arp_table(self):
def get_arp_table(self, vrf=""):
# 'age' is not implemented yet
"""
@ -343,6 +363,12 @@ class VyOSDriver(NetworkDriver):
10.129.2.97 ether 00:50:56:9f:64:09 C eth0
192.168.1.3 ether 00:50:56:86:7b:06 C eth1
"""
if vrf:
raise NotImplementedError(
"VRF support has not been added for this getter on this platform."
)
output = self.device.send_command("show arp")
output = output.split("\n")
@ -357,16 +383,16 @@ class VyOSDriver(NetworkDriver):
# ["10.129.2.254", "ether", "00:50:56:97:af:b1", "C", "eth0"]
# [u'10.0.12.33', u'(incomplete)', u'eth1']
if "incomplete" in line[1]:
macaddr = py23_compat.text_type("00:00:00:00:00:00")
macaddr = "00:00:00:00:00:00"
else:
macaddr = py23_compat.text_type(line[2])
macaddr = line[2]
arp_table.append(
{
'interface': py23_compat.text_type(line[-1]),
'interface': line[-1],
'mac': macaddr,
'ip': py23_compat.text_type(line[0]),
'age': 0.0
'ip': line[0],
'age': 0.0,
}
)
@ -394,23 +420,23 @@ class VyOSDriver(NetworkDriver):
# 'remote' contains '*' if the machine synchronized with NTP server
synchronized = "*" in remote
match = re.search("(\d+\.\d+\.\d+\.\d+)", remote)
match = re.search(r"(\d+\.\d+\.\d+\.\d+)", remote)
ip = match.group(1)
when = when if when != '-' else 0
ntp_stats.append({
"remote": py23_compat.text_type(ip),
"referenceid": py23_compat.text_type(refid),
"remote": ip,
"referenceid": refid,
"synchronized": bool(synchronized),
"stratum": int(st),
"type": py23_compat.text_type(t),
"when": py23_compat.text_type(when),
"type": t,
"when": when,
"hostpoll": int(hostpoll),
"reachability": int(reachability),
"delay": float(delay),
"offset": float(offset),
"jitter": float(jitter)
"jitter": float(jitter),
})
return ntp_stats
@ -422,9 +448,9 @@ class VyOSDriver(NetworkDriver):
for line in output_peers:
if len(line) > 0:
match = re.search("(\d+\.\d+\.\d+\.\d+)\s+", line)
match = re.search(r"(\d+\.\d+\.\d+\.\d+)\s+", line)
ntp_peers.update({
py23_compat.text_type(match.group(1)): {}
match.group(1): {}
})
return ntp_peers
@ -448,11 +474,11 @@ class VyOSDriver(NetworkDriver):
output = self.device.send_command("show ip bgp summary")
output = output.split("\n")
match = re.search(".* router identifier (\d+\.\d+\.\d+\.\d+), local AS number (\d+)",
match = re.search(r".* router identifier (\d+\.\d+\.\d+\.\d+), local AS number (\d+)",
output[0])
if not match:
return {}
router_id = py23_compat.text_type(match.group(1))
router_id = match.group(1)
local_as = int(match.group(2))
bgp_neighbor_data = dict()
@ -461,7 +487,7 @@ class VyOSDriver(NetworkDriver):
bgp_neighbor_data["global"]["peers"] = {}
# delete the header and empty element
bgp_info = [i.strip() for i in output[6:-2] if i is not ""]
bgp_info = [i.strip() for i in output[6:-2] if i]
for i in bgp_info:
if len(i) > 0:
@ -477,6 +503,8 @@ class VyOSDriver(NetworkDriver):
received_prefixes = int(state_prefix)
is_up = True
except ValueError:
state_prefix = -1
received_prefixes = -1
is_up = False
if bgp_version == "4":
@ -498,19 +526,19 @@ class VyOSDriver(NetworkDriver):
"""
bgp_detail = self.device.send_command("show ip bgp neighbors %s" % peer_id)
match_rid = re.search("remote router ID (\d+\.\d+\.\d+\.\d+).*", bgp_detail)
match_rid = re.search(r"remote router ID (\d+\.\d+\.\d+\.\d+).*", bgp_detail)
remote_rid = match_rid.group(1)
match_prefix_accepted = re.search("(\d+) accepted prefixes", bgp_detail)
match_prefix_accepted = re.search(r"(\d+) accepted prefixes", bgp_detail)
accepted_prefixes = match_prefix_accepted.group(1)
bgp_neighbor_data["global"]["peers"].setdefault(peer_id, {})
peer_dict = {
"description": py23_compat.text_type(""),
"description": "",
"is_enabled": bool(is_enabled),
"local_as": int(local_as),
"is_up": bool(is_up),
"remote_id": py23_compat.text_type(remote_rid),
"remote_id": remote_rid,
"uptime": int(self._bgp_time_conversion(up_time)),
"remote_as": int(remote_as)
}
@ -534,19 +562,19 @@ class VyOSDriver(NetworkDriver):
return -1
else:
if "y" in bgp_uptime:
match = re.search("(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime)
match = re.search(r"(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime)
uptime = ((int(match.group(1)) * self._YEAR_SECONDS) +
(int(match.group(3)) * self._WEEK_SECONDS) +
(int(match.group(5)) * self._DAY_SECONDS))
return uptime
elif "w" in bgp_uptime:
match = re.search("(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime)
match = re.search(r"(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime)
uptime = ((int(match.group(1)) * self._WEEK_SECONDS) +
(int(match.group(3)) * self._DAY_SECONDS) +
(int(match.group(5)) * self._HOUR_SECONDS))
return uptime
elif "d" in bgp_uptime:
match = re.search("(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime)
match = re.search(r"(\d+)(\w)(\d+)(\w)(\d+)(\w)", bgp_uptime)
uptime = ((int(match.group(1)) * self._DAY_SECONDS) +
(int(match.group(3)) * self._HOUR_SECONDS) +
(int(match.group(5)) * self._MINUTE_SECONDS))
@ -557,6 +585,29 @@ class VyOSDriver(NetworkDriver):
(minutes * self._MINUTE_SECONDS) + seconds)
return uptime
def get_lldp_neighbors(self):
# Multiple neighbors per port are not implemented
# The show lldp neighbors commands lists port descriptions, not IDs
output = self.device.send_command("show lldp neighbors detail")
pattern = r'''(?s)Interface: +(?P<interface>\S+), [^\n]+
.+?
+SysName: +(?P<hostname>\S+)
.+?
+PortID: +ifname (?P<port>\S+)'''
def _get_interface(match):
return [
{
'hostname': match.group('hostname'),
'port': match.group('port'),
}
]
return {
match.group('interface'): _get_interface(match)
for match in re.finditer(pattern, output)
}
def get_interfaces_counters(self):
# 'rx_unicast_packet', 'rx_broadcast_packets', 'tx_unicast_packets',
# 'tx_multicast_packets' and 'tx_broadcast_packets' are not implemented yet
@ -573,9 +624,9 @@ class VyOSDriver(NetworkDriver):
32776498 279273 0 0 0 0
"""
output = self.device.send_command("show interfaces detail")
interfaces = re.findall("(\S+): <.*", output)
interfaces = re.findall(r"(\S+): <.*", output)
# count = re.findall("(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+", output)
count = re.findall("(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", output)
count = re.findall(r"(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)", output)
counters = dict()
j = 0
@ -623,15 +674,15 @@ class VyOSDriver(NetworkDriver):
for i in config["service"]["snmp"]["community"]:
snmp["community"].update({
i: {
"acl": py23_compat.text_type(""),
"mode": py23_compat.text_type(config["service"]["snmp"]["community"][i]["authorization"])
"acl": "",
"mode": config["service"]["snmp"]["community"][i]["authorization"],
}
})
snmp.update({
"chassis_id": py23_compat.text_type(""),
"contact": py23_compat.text_type(config["service"]["snmp"]["contact"]),
"location": py23_compat.text_type(config["service"]["snmp"]["location"])
"chassis_id": "",
"contact": config["service"]["snmp"]["contact"],
"location": config["service"]["snmp"]["location"],
})
return snmp
@ -647,10 +698,15 @@ class VyOSDriver(NetworkDriver):
ver_str = [line for line in output if "Version" in line][0]
version = self.parse_version(ver_str)
sn_str = [line for line in output if "S/N" in line][0]
snumber = self.parse_snumber(sn_str)
above_1_1 = False if version.startswith('1.0') or version.startswith('1.1') else True
if above_1_1:
sn_str = [line for line in output if "Hardware S/N" in line][0]
hwmodel_str = [line for line in output if "Hardware model" in line][0]
else:
sn_str = [line for line in output if "S/N" in line][0]
hwmodel_str = [line for line in output if "HW model" in line][0]
hwmodel_str = [line for line in output if "HW model" in line][0]
snumber = self.parse_snumber(sn_str)
hwmodel = self.parse_hwmodel(hwmodel_str)
output = self.device.send_command("show configuration")
@ -673,13 +729,13 @@ class VyOSDriver(NetworkDriver):
facts = {
"uptime": int(uptime),
"vendor": py23_compat.text_type("VyOS"),
"os_version": py23_compat.text_type(version),
"serial_number": py23_compat.text_type(snumber),
"model": py23_compat.text_type(hwmodel),
"hostname": py23_compat.text_type(hostname),
"fqdn": py23_compat.text_type(fqdn),
"interface_list": iface_list
"vendor": "VyOS",
"os_version": version,
"serial_number": snumber,
"model": hwmodel,
"hostname": hostname,
"fqdn": fqdn,
"interface_list": iface_list,
}
return facts
@ -782,7 +838,14 @@ class VyOSDriver(NetworkDriver):
return user_auth
def ping(self, destination, source='', ttl=255, timeout=2, size=100, count=5):
def ping(self,
destination,
source=C.PING_SOURCE,
ttl=C.PING_TTL,
timeout=C.PING_TIMEOUT,
size=C.PING_SIZE,
count=C.PING_COUNT,
vrf=C.PING_VRF):
# does not support multiple destination yet
deadline = timeout * count
@ -803,7 +866,7 @@ class VyOSDriver(NetworkDriver):
else:
err = ""
if err is not "":
if err:
ping_result["error"] = err
else:
# 'packet_info' example:
@ -831,7 +894,7 @@ class VyOSDriver(NetworkDriver):
else:
rtt_info = rtt_info[-2]
match = re.search("([\d\.]+)/([\d\.]+)/([\d\.]+)/([\d\.]+)", rtt_info)
match = re.search(r"([\d\.]+)/([\d\.]+)/([\d\.]+)/([\d\.]+)", rtt_info)
if match is not None:
rtt_min = float(match.group(1))
@ -856,3 +919,42 @@ class VyOSDriver(NetworkDriver):
}
return ping_result
def get_config(self, retrieve="all", full=False, sanitized=False):
"""
Return the configuration of a device.
:param retrieve: String to determine which configuration type you want to retrieve, default is all of them.
The rest will be set to "".
:param full: Boolean to retrieve all the configuration. (Not supported)
:param sanitized: Boolean to remove secret data. (Only supported for 'running')
:return: The object returned is a dictionary with a key for each configuration store:
- running(string) - Representation of the native running configuration
- candidate(string) - Representation of the candidate configuration.
- startup(string) - Representation of the native startup configuration.
"""
if retrieve not in ["running", "candidate", "startup", "all"]:
raise Exception("ERROR: Not a valid option to retrieve.\nPlease select from 'running', 'candidate', "
"'startup', or 'all'")
else:
config_dict = {
"running": "",
"startup": "",
"candidate": ""
}
if retrieve in ["running", "all"]:
config_dict['running'] = self._get_running_config(sanitized)
if retrieve in ["startup", "all"]:
config_dict['startup'] = self.device.send_command(f"cat {self._BOOT_FILENAME}")
if retrieve in ["candidate", "all"]:
config_dict['candidate'] = self._new_config or ""
return config_dict
def _get_running_config(self, sanitized):
if sanitized:
return self.device.send_command("show configuration")
self.device.config_mode()
config = self.device.send_command("show")
config = config[:config.rfind('\n')]
self.device.exit_config_mode()
return config

View File

@ -1,4 +1,3 @@
future
coveralls
pytest
pytest-cov

View File

@ -1,4 +1,4 @@
napalm_base
napalm>=3.0
paramiko
netmiko>=1.1.0
netmiko>=3.1.0
vyattaconfparser

View File

@ -1,30 +1,32 @@
"""setup.py file."""
import uuid
from setuptools import setup, find_packages
from pip.req import parse_requirements
with open("requirements.txt", "r") as fs:
reqs = [r for r in fs.read().splitlines()
if (len(r) > 0 and not r.startswith("#"))]
__author__ = 'Piotr Pieprzycki <piotr.pieprzycki@dreamlab.pl>'
install_reqs = parse_requirements('requirements.txt', session=uuid.uuid1())
reqs = [str(ir.req) for ir in install_reqs]
setup(
name="napalm-vyos",
version="0.1.2",
version="0.2.1",
packages=find_packages(),
author="Piotr Pieprzycki",
author_email="piotr.pieprzycki@dreamlab.pl",
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',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Operating System :: POSIX :: Linux',
'Operating System :: MacOS',
],
url="https://github.com/napalm-automation-community/napalm-vyos",
include_package_data=True,
install_requires=reqs,
)

View File

@ -15,7 +15,7 @@
import unittest
from napalm_vyos import vyos
from napalm_base.test.base import TestConfigNetworkDriver
from napalm.base.test.base import TestConfigNetworkDriver
class TestConfigVyOSDriver(unittest.TestCase, TestConfigNetworkDriver):

View File

@ -2,10 +2,9 @@
from builtins import super
import pytest
from napalm_base.test import conftest as parent_conftest
from napalm.base.test import conftest as parent_conftest
from napalm_base.test.double import BaseTestDouble
from napalm_base.utils import py23_compat
from napalm.base.test.double import BaseTestDouble
from napalm_vyos import vyos
@ -52,8 +51,16 @@ class PatchedVyOSDriver(vyos.VyOSDriver):
class FakeVyOSDevice(BaseTestDouble):
"""VyOS device test double."""
def __init__(self):
self.mode_config = False
def send_command(self, command, **kwargs):
filename = '{}.text'.format(self.sanitize_text(command))
full_path = self.find_file(filename)
result = self.read_txt_file(full_path)
return py23_compat.text_type(result)
return self.read_txt_file(full_path)
def config_mode(self):
self.mode_config = True
def exit_config_mode(self):
self.mode_config = False

View File

@ -0,0 +1,123 @@
interfaces {
ethernet eth0 {
address dhcp
}
ethernet eth1 {
address 10.0.1.222/24
}
loopback lo {
address 10.2.2.2/32
address 8.8.8.8/32
}
}
policy {
prefix-list EXPORT {
rule 1 {
action permit
prefix 172.16.2.0/24
}
rule 65535 {
action permit
prefix 10.2.2.2/32
}
}
route-map EXPORT-POLICY {
rule 1 {
action permit
match {
ip {
address {
prefix-list EXPORT
}
}
}
}
}
}
protocols {
bgp 65002 {
neighbor 10.0.1.100 {
remote-as 65001
route-map {
export EXPORT-POLICY
}
}
redistribute {
connected {
route-map EXPORT-POLICY
}
}
}
}
service {
snmp {
community commro {
authorization ro
}
contact admin@foo.corp
location PL,Krakow
}
ssh {
disable-host-validation
port 22
}
}
system {
config-management {
commit-revisions 20
}
host-name vyos2
login {
banner {
pre-login "My banner for all devices"
}
user vagrant {
authentication {
encrypted-password $6$fcHhBu3T$WLmiu6/txlEfWK5uh4mKE8v7qocuftsoAN1oHqPIIoogXAX8zS.SKhB105EExYU6yBy4cKHUD/Q6Mm7CUbVTr.
plaintext-password ""
public-keys vagrant {
key AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==
type ssh-rsa
}
}
level admin
}
user vyos {
authentication {
encrypted-password $1$yHIMnG/J$aWDkd3oDYSYps8twB5vpw1
plaintext-password ""
}
level admin
}
}
ntp {
server 10.0.1.100 {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ""
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}
/* Warning: Do not remove the following line. */
/* === vyatta-config-version: "cluster@1:config-management@1:conntrack-sync@1:conntrack@1:cron@1:dhcp-relay@1:dhcp-server@4:firewall@5:ipsec@4:nat@4:qos@1:quagga@2:system@6:vrrp@1:wanloadbalance@3:webgui@1:webproxy@1:zone-policy@1" === */
/* Release version: VyOS 1.1.7 */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,125 @@
interfaces {
ethernet eth0 {
address dhcp
duplex auto
smp_affinity auto
speed auto
}
ethernet eth1 {
address 10.0.1.222/24
duplex auto
smp_affinity auto
speed auto
}
loopback lo {
address 10.2.2.2/32
address 8.8.8.8/32
}
}
policy {
prefix-list EXPORT {
rule 1 {
action permit
prefix 172.16.2.0/24
}
rule 65535 {
action permit
prefix 10.2.2.2/32
}
}
route-map EXPORT-POLICY {
rule 1 {
action permit
match {
ip {
address {
prefix-list EXPORT
}
}
}
}
}
}
protocols {
bgp 65002 {
neighbor 10.0.1.100 {
remote-as 65001
route-map {
export EXPORT-POLICY
}
}
redistribute {
connected {
route-map EXPORT-POLICY
}
}
}
}
service {
snmp {
community commro {
authorization ro
}
contact admin@foo.corp
location PL,Krakow
}
ssh {
disable-host-validation
port 22
}
}
system {
config-management {
commit-revisions 20
}
host-name vyos2
login {
banner {
pre-login "My banner for all devices"
}
user vagrant {
authentication {
encrypted-password $6$fcHhBu3T$WLmiu6/txlEfWK5uh4mKE8v7qocuftsoAN1oHqPIIoogXAX8zS.SKhB105EExYU6yBy4cKHUD/Q6Mm7CUbVTr.
plaintext-password ""
public-keys vagrant {
key AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==
type ssh-rsa
}
}
level admin
}
user vyos {
authentication {
encrypted-password $1$yHIMnG/J$aWDkd3oDYSYps8twB5vpw1
plaintext-password ""
}
level admin
}
}
ntp {
server 10.0.1.100 {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ""
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}
[edit]

View File

@ -0,0 +1,123 @@
interfaces {
ethernet eth0 {
address dhcp
}
ethernet eth1 {
address 10.0.1.222/24
}
loopback lo {
address 10.2.2.2/32
address 8.8.8.8/32
}
}
policy {
prefix-list EXPORT {
rule 1 {
action permit
prefix 172.16.2.0/24
}
rule 65535 {
action permit
prefix 10.2.2.2/32
}
}
route-map EXPORT-POLICY {
rule 1 {
action permit
match {
ip {
address {
prefix-list EXPORT
}
}
}
}
}
}
protocols {
bgp 65002 {
neighbor 10.0.1.100 {
remote-as 65001
route-map {
export EXPORT-POLICY
}
}
redistribute {
connected {
route-map EXPORT-POLICY
}
}
}
}
service {
snmp {
community commro {
authorization ro
}
contact admin@foo.corp
location PL,Krakow
}
ssh {
disable-host-validation
port 22
}
}
system {
config-management {
commit-revisions 20
}
host-name vyos2
login {
banner {
pre-login "My banner for all devices"
}
user vagrant {
authentication {
encrypted-password $6$fcHhBu3T$WLmiu6/txlEfWK5uh4mKE8v7qocuftsoAN1oHqPIIoogXAX8zS.SKhB105EExYU6yBy4cKHUD/Q6Mm7CUbVTr.
plaintext-password ""
public-keys vagrant {
key AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==
type ssh-rsa
}
}
level admin
}
user vyos {
authentication {
encrypted-password $1$yHIMnG/J$aWDkd3oDYSYps8twB5vpw1
plaintext-password ""
}
level admin
}
}
ntp {
server 10.0.1.100 {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ""
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}
/* Warning: Do not remove the following line. */
/* === vyatta-config-version: "cluster@1:config-management@1:conntrack-sync@1:conntrack@1:cron@1:dhcp-relay@1:dhcp-server@4:firewall@5:ipsec@4:nat@4:qos@1:quagga@2:system@6:vrrp@1:wanloadbalance@3:webgui@1:webproxy@1:zone-policy@1" === */
/* Release version: VyOS 1.1.7 */

View File

@ -0,0 +1 @@
{"running": "", "startup": "", "candidate": ""}

View File

@ -0,0 +1,125 @@
interfaces {
ethernet eth0 {
address dhcp
duplex auto
smp_affinity auto
speed auto
}
ethernet eth1 {
address 10.0.1.222/24
duplex auto
smp_affinity auto
speed auto
}
loopback lo {
address 10.2.2.2/32
address 8.8.8.8/32
}
}
policy {
prefix-list EXPORT {
rule 1 {
action permit
prefix 172.16.2.0/24
}
rule 65535 {
action permit
prefix 10.2.2.2/32
}
}
route-map EXPORT-POLICY {
rule 1 {
action permit
match {
ip {
address {
prefix-list EXPORT
}
}
}
}
}
}
protocols {
bgp 65002 {
neighbor 10.0.1.100 {
remote-as 65001
route-map {
export EXPORT-POLICY
}
}
redistribute {
connected {
route-map EXPORT-POLICY
}
}
}
}
service {
snmp {
community commro {
authorization ro
}
contact admin@foo.corp
location PL,Krakow
}
ssh {
disable-host-validation
port 22
}
}
system {
config-management {
commit-revisions 20
}
host-name vyos2
login {
banner {
pre-login "My banner for all devices"
}
user vagrant {
authentication {
encrypted-password $6$fcHhBu3T$WLmiu6/txlEfWK5uh4mKE8v7qocuftsoAN1oHqPIIoogXAX8zS.SKhB105EExYU6yBy4cKHUD/Q6Mm7CUbVTr.
plaintext-password ""
public-keys vagrant {
key AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==
type ssh-rsa
}
}
level admin
}
user vyos {
authentication {
encrypted-password $1$yHIMnG/J$aWDkd3oDYSYps8twB5vpw1
plaintext-password ""
}
level admin
}
}
ntp {
server 10.0.1.100 {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ""
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}
[edit]

View File

@ -0,0 +1,123 @@
interfaces {
ethernet eth0 {
address dhcp
}
ethernet eth1 {
address 10.0.1.222/24
}
loopback lo {
address 10.2.2.2/32
address 8.8.8.8/32
}
}
policy {
prefix-list EXPORT {
rule 1 {
action permit
prefix 172.16.2.0/24
}
rule 65535 {
action permit
prefix 10.2.2.2/32
}
}
route-map EXPORT-POLICY {
rule 1 {
action permit
match {
ip {
address {
prefix-list EXPORT
}
}
}
}
}
}
protocols {
bgp 65002 {
neighbor 10.0.1.100 {
remote-as 65001
route-map {
export EXPORT-POLICY
}
}
redistribute {
connected {
route-map EXPORT-POLICY
}
}
}
}
service {
snmp {
community commro {
authorization ro
}
contact admin@foo.corp
location PL,Krakow
}
ssh {
disable-host-validation
port 22
}
}
system {
config-management {
commit-revisions 20
}
host-name vyos2
login {
banner {
pre-login "My banner for all devices"
}
user vagrant {
authentication {
encrypted-password $6$fcHhBu3T$WLmiu6/txlEfWK5uh4mKE8v7qocuftsoAN1oHqPIIoogXAX8zS.SKhB105EExYU6yBy4cKHUD/Q6Mm7CUbVTr.
plaintext-password ""
public-keys vagrant {
key AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==
type ssh-rsa
}
}
level admin
}
user vyos {
authentication {
encrypted-password $1$yHIMnG/J$aWDkd3oDYSYps8twB5vpw1
plaintext-password ""
}
level admin
}
}
ntp {
server 10.0.1.100 {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ""
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}
/* Warning: Do not remove the following line. */
/* === vyatta-config-version: "cluster@1:config-management@1:conntrack-sync@1:conntrack@1:cron@1:dhcp-relay@1:dhcp-server@4:firewall@5:ipsec@4:nat@4:qos@1:quagga@2:system@6:vrrp@1:wanloadbalance@3:webgui@1:webproxy@1:zone-policy@1" === */
/* Release version: VyOS 1.1.7 */

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,124 @@
interfaces {
ethernet eth0 {
address dhcp
duplex auto
smp_affinity auto
speed auto
}
ethernet eth1 {
address 10.0.1.222/24
duplex auto
smp_affinity auto
speed auto
}
loopback lo {
address 10.2.2.2/32
address 8.8.8.8/32
}
}
policy {
prefix-list EXPORT {
rule 1 {
action permit
prefix 172.16.2.0/24
}
rule 65535 {
action permit
prefix 10.2.2.2/32
}
}
route-map EXPORT-POLICY {
rule 1 {
action permit
match {
ip {
address {
prefix-list EXPORT
}
}
}
}
}
}
protocols {
bgp 65002 {
neighbor 10.0.1.100 {
remote-as 65001
route-map {
export EXPORT-POLICY
}
}
redistribute {
connected {
route-map EXPORT-POLICY
}
}
}
}
service {
snmp {
community commro {
authorization ro
}
contact admin@foo.corp
location PL,Krakow
}
ssh {
disable-host-validation
port 22
}
}
system {
config-management {
commit-revisions 20
}
host-name vyos2
login {
banner {
pre-login "My banner for all devices"
}
user vagrant {
authentication {
encrypted-password **********
plaintext-password ""
public-keys vagrant {
key AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ==
type ssh-rsa
}
}
level admin
}
user vyos {
authentication {
encrypted-password **********
plaintext-password ""
}
level admin
}
}
ntp {
server 10.0.1.100 {
}
}
package {
auto-sync 1
repository community {
components main
distribution helium
password ""
url http://packages.vyos.net/vyos
username ""
}
}
syslog {
global {
facility all {
level notice
}
facility protocols {
level debug
}
}
}
time-zone UTC
}

View File

@ -1 +1 @@
{"lo": {"is_enabled": true, "description": "", "last_flapped": -1.0, "is_up": true, "mac_address": "00:00:00:00:00:00", "speed": 0}, "eth1": {"is_enabled": true, "description": "", "last_flapped": -1.0, "is_up": true, "mac_address": "...", "speed": 0}, "eth0": {"is_enabled": true, "description": "", "last_flapped": -1.0, "is_up": true, "mac_address": "...", "speed": 0}}
{"lo": {"is_enabled": true, "description": "", "last_flapped": -1.0, "is_up": true, "mac_address": "00:00:00:00:00:00", "mtu": -1, "speed": 0}, "eth1": {"is_enabled": true, "description": "", "last_flapped": -1.0, "is_up": true, "mac_address": "...", "mtu": -1, "speed": 0}, "eth0": {"is_enabled": true, "description": "", "last_flapped": -1.0, "is_up": true, "mac_address": "...", "mtu": -1, "speed": 0}}

View File

@ -0,0 +1 @@
{"eth1": [{"hostname": "branch", "port": "eth0"}], "eth2": [{"hostname": "dmz", "port": "eth0"}]}

View File

@ -0,0 +1,69 @@
-------------------------------------------------------------------------------
LLDP neighbors:
-------------------------------------------------------------------------------
Interface: eth1, via: LLDP, RID: 2, Time: 1 day, 18:17:44
Chassis:
ChassisID: mac 52:54:00:99:84:8a
SysName: branch
SysDescr: VyOS 1.3-rolling-202005151915
MgmtIP: 10.0.0.3
Capability: Bridge, off
Capability: Router, on
Capability: Wlan, off
Capability: Station, off
Port:
PortID: ifname eth0
PortDescr: to DC
TTL: 120
PMD autoneg: supported: yes, enabled: yes
Adv: 10Base-T, HD: yes, FD: yes
Adv: 100Base-TX, HD: yes, FD: yes
MAU oper type: 100BaseTXFD - 2 pair category 5 UTP, full duplex mode
LLDP-MED:
Device Type: Network Connectivity Device
Capability: Capabilities, yes
Capability: Policy, yes
Capability: Location, yes
Capability: MDI/PSE, yes
Capability: MDI/PD, yes
Capability: Inventory, yes
Inventory:
Hardware Revision: pc-i440fx-4.2
Software Revision: 4.19.122-amd64-vyos
Firmware Revision: 1.13.0-1ubuntu1
Manufacturer: QEMU
Model: Standard PC (i440FX + PIIX, 1996
-------------------------------------------------------------------------------
Interface: eth2, via: LLDP, RID: 1, Time: 1 day, 18:17:45
Chassis:
ChassisID: mac 52:54:00:98:e5:9f
SysName: dmz
SysDescr: VyOS 1.3-rolling-202005151915
MgmtIP: 10.0.0.2
Capability: Bridge, off
Capability: Router, on
Capability: Wlan, off
Capability: Station, off
Port:
PortID: ifname eth0
PortDescr: to DC
TTL: 120
PMD autoneg: supported: yes, enabled: yes
Adv: 10Base-T, HD: yes, FD: yes
Adv: 100Base-TX, HD: yes, FD: yes
MAU oper type: 100BaseTXFD - 2 pair category 5 UTP, full duplex mode
LLDP-MED:
Device Type: Network Connectivity Device
Capability: Capabilities, yes
Capability: Policy, yes
Capability: Location, yes
Capability: MDI/PSE, yes
Capability: MDI/PD, yes
Capability: Inventory, yes
Inventory:
Hardware Revision: pc-i440fx-4.2
Software Revision: 4.19.122-amd64-vyos
Firmware Revision: 1.13.0-1ubuntu1
Manufacturer: QEMU
Model: Standard PC (i440FX + PIIX, 1996
-------------------------------------------------------------------------------

View File

@ -1,6 +1,6 @@
"""Tests for getters."""
from napalm_base.test.getters import BaseTestGetters
from napalm.base.test.getters import BaseTestGetters
import pytest

View File

@ -1,5 +1,5 @@
[tox]
envlist = py27,py34,py35
envlist = py36,py37,py38
[testenv]
deps =