Skip to content

Commit ee25d29

Browse files
authored
Merge pull request #221 from networktocode/develop
Develop
2 parents 983a89f + d45b81f commit ee25d29

38 files changed

+1782
-184
lines changed

.travis.yml

+19-8
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,25 @@ python:
88

99
install:
1010
# XXX: Migrate this to Poetry fully
11-
- pip install virtualenv
11+
- "pip install virtualenv"
12+
- "virtualenv ./venv"
13+
- "source ./venv/bin/activate"
14+
- "python -m pip install -U pip"
15+
- "pip install tox"
1216

17+
jobs:
18+
include:
19+
- stage: "lint"
20+
name: "Linting Tests"
21+
script: "tox -e black"
22+
- script: "tox -e flake8"
23+
- script: "tox -e bandit"
24+
- script: "tox -e pydocstyle"
25+
26+
stages:
27+
- "lint"
28+
- "test"
1329

1430
script:
15-
# Activate virtualenv, install tox and run all tests.
16-
- virtualenv ./venv
17-
- source ./venv/bin/activate
18-
- python -m pip install -U pip
19-
- pip install tox
20-
- tox
21-
- tox -e coveralls
31+
- "tox -e py46,py37,py38"
32+
- "tox -e coveralls"

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/)
1212
### Fixed
1313
### Security
1414

15+
## [0.18.0]
16+
### Added
17+
- IOSXEWLCDevice device Driver.
18+
### Fixed
19+
- IOS `rollback()` method derives filesystem name using `_get_file_system()` method to discover it from system.
20+
1521
## [0.17.0]
1622
### Added
1723
- ASADevice supports connecting to HA Peer

pyntc/__init__.py

+10-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
"""Kickoff functions for getting instancs of device objects.
2-
"""
1+
"""Kickoff functions for getting instancs of device objects."""
32

43
import os
54
import warnings
@@ -12,7 +11,7 @@
1211
except ImportError:
1312
from ConfigParser import SafeConfigParser
1413

15-
__version__ = "0.17.0"
14+
__version__ = "0.18.0"
1615

1716
LIB_PATH_ENV_VAR = "PYNTC_CONF"
1817
LIB_PATH_DEFAULT = "~/.ntc.conf"
@@ -22,9 +21,10 @@
2221

2322

2423
def ntc_device(device_type, *args, **kwargs):
25-
"""Instantiate and return an instance of a device subclassed
26-
from ``pyntc.devices.BaseDevice``. ``*args`` and ``*kwargs`` are passed
27-
directly to the device initializer.
24+
"""
25+
Instantiate an instance of a ``pyntc.devices.BaseDevice`` by ``device_type``.
26+
27+
The ``*args`` and ``*kwargs`` are passed directly to the device initializer.
2828
2929
Arguments:
3030
device_type (string): A valid device_type
@@ -36,7 +36,6 @@ def ntc_device(device_type, *args, **kwargs):
3636
Raises:
3737
UnsupportedDeviceError: if the device_type is unsupported.
3838
"""
39-
4039
try:
4140
device_class = supported_devices[device_type]
4241
return device_class(*args, **kwargs)
@@ -45,9 +44,8 @@ def ntc_device(device_type, *args, **kwargs):
4544

4645

4746
def ntc_device_by_name(name, filename=None):
48-
"""Instantiate and return an instance of a device subclassed
49-
from ``pyntc.devices.BaseDevice`` based on its name in an
50-
NTC configuration file.
47+
"""
48+
Instantiate an instance of a ``pyntc.devices.BaseDevice`` from ntc.conf file.
5149
5250
If no filename is given the environment variable PYNTC_CONF is checked
5351
for a path, and then ~/.ntc.conf.
@@ -58,9 +56,8 @@ def ntc_device_by_name(name, filename=None):
5856
the ``name`` argument as section header.
5957
6058
Raises:
61-
DeviceNameNotFoundError: if the name is not found in the
62-
NTC configuration file.
63-
ConfFileNotFoundError: if no NTC configuration can be found.
59+
DeviceNameNotFoundError: If the name is not found in the NTC configuration file.
60+
ConfFileNotFoundError: If no NTC configuration can be found.
6461
"""
6562
config, filename = _get_config_from_file(filename=filename)
6663
sections = config.sections()

pyntc/devices/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
"""Supported devices are stored here. Every supported device needs a
2-
device_type stored as a string, and a class subclassed from BaseDevice.
3-
"""
1+
"""Device drivers."""
42

53
from .eos_device import EOSDevice
64
from .nxos_device import NXOSDevice
@@ -9,6 +7,7 @@
97
from .asa_device import ASADevice
108
from .f5_device import F5Device
119
from .aireos_device import AIREOSDevice
10+
from .iosxewlc_device import IOSXEWLCDevice
1211

1312

1413
supported_devices = {
@@ -19,4 +18,5 @@
1918
"juniper_junos_netconf": JunosDevice,
2019
"cisco_nxos_nxapi": NXOSDevice,
2120
"cisco_aireos_ssh": AIREOSDevice,
21+
"cisco_iosxewlc_ssh": IOSXEWLCDevice,
2222
}

pyntc/devices/aireos_device.py

+69-15
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class AIREOSDevice(BaseDevice):
6969
vendor = "cisco"
7070
active_redundancy_states = {None, "active"}
7171

72-
def __init__(self, host, username, password, secret="", port=22, confirm_active=True, **kwargs):
72+
def __init__(self, host, username, password, secret="", port=22, confirm_active=True, **kwargs): # noqa: D403
7373
"""
7474
PyNTC Device implementation for Cisco WLC.
7575
@@ -388,7 +388,7 @@ def ap_boot_options(self):
388388
@property
389389
def ap_image_stats(self):
390390
"""
391-
The stats of downloading the the image to all APs.
391+
Stats of downloading the the image to all APs.
392392
393393
Returns:
394394
dict: The AP count, and the downloaded, unsupported, and failed APs.
@@ -417,12 +417,21 @@ def ap_image_stats(self):
417417
}
418418

419419
def backup_running_config(self, filename):
420+
"""
421+
Create backup of running config.
422+
423+
Args:
424+
filename (str): Name of backup file.
425+
426+
Raises:
427+
NotImplementedError: Function currently not implemented
428+
"""
420429
raise NotImplementedError
421430

422431
@property
423432
def boot_options(self):
424433
"""
425-
The images that are candidates for booting on reload.
434+
Images that are candidates for booting on reload.
426435
427436
Returns:
428437
dict: The boot options on the device. The "sys" key is the expected image on reload.
@@ -458,6 +467,16 @@ def boot_options(self):
458467
return result
459468

460469
def checkpoint(self, filename):
470+
"""
471+
Create a checkpoint file of the current config.
472+
473+
Args:
474+
checkpoint_file (str): Saves a checkpoint file with the name provided to the function.
475+
476+
Raises:
477+
NotImplementedError: Function currently not implemented
478+
479+
"""
461480
raise NotImplementedError
462481

463482
def close(self):
@@ -467,7 +486,7 @@ def close(self):
467486
self._connected = False
468487

469488
def config(self, command, **netmiko_args):
470-
"""
489+
r"""
471490
Send config commands to device.
472491
473492
By default, entering and exiting config mode is handled automatically.
@@ -535,7 +554,7 @@ def config(self, command, **netmiko_args):
535554

536555
return command_responses
537556

538-
def config_list(self, commands, **netmiko_args):
557+
def config_list(self, commands, **netmiko_args): # noqa: D401
539558
"""
540559
DEPRECATED - Use the `config` method.
541560
@@ -602,7 +621,7 @@ def confirm_is_active(self):
602621
@property
603622
def connected(self):
604623
"""
605-
The connection status of the device.
624+
Get connection status of the device.
606625
607626
Returns:
608627
bool: True if the device is connected, else False.
@@ -657,9 +676,9 @@ def disable_wlans(self, wlan_ids):
657676
raise WLANDisableError(self.host, desired_wlans, post_disabled_wlans)
658677

659678
@property
660-
def disabled_wlans(self):
679+
def disabled_wlans(self): # noqa: D403
661680
"""
662-
The IDs for all disabled WLANs.
681+
IDs for all disabled WLANs.
663682
664683
Returns:
665684
list: Disabled WLAN IDs.
@@ -741,9 +760,9 @@ def enable_wlans(self, wlan_ids):
741760
raise WLANEnableError(self.host, desired_wlans, post_enabled_wlans)
742761

743762
@property
744-
def enabled_wlans(self):
763+
def enabled_wlans(self): # noqa: D403
745764
"""
746-
The IDs for all enabled WLANs.
765+
IDs for all enabled WLANs.
747766
748767
Returns:
749768
list: Enabled WLAN IDs.
@@ -768,6 +787,12 @@ def enabled_wlans(self):
768787

769788
@property
770789
def facts(self):
790+
"""
791+
Get facts from device.
792+
793+
Raises:
794+
NotImplementedError: Function currently not implemented.
795+
"""
771796
raise NotImplementedError
772797

773798
def file_copy(
@@ -851,6 +876,17 @@ def file_copy(
851876
return True
852877

853878
def file_copy_remote_exists(self, src, dest=None, **kwargs):
879+
"""
880+
Copy 'src' file to remote device.
881+
882+
Args:
883+
src (str): The path to the file to be copied to the device.
884+
dest (str, optional): The name to use for storing the file on the device.
885+
Defaults to use the name of the ``src`` file.
886+
887+
Raises:
888+
NotImplementedError: Function currently not implemented.
889+
"""
854890
raise NotImplementedError
855891

856892
def install_os(self, image_name, controller="both", save_config=True, disable_wlans=None, **vendor_specifics):
@@ -1056,7 +1092,7 @@ def handler(signum, frame):
10561092
@property
10571093
def redundancy_mode(self):
10581094
"""
1059-
The oprating redundancy mode of the controller.
1095+
Get operating redundancy mode of the controller.
10601096
10611097
Returns:
10621098
str: The redundancy mode the device is operating in.
@@ -1097,10 +1133,22 @@ def redundancy_state(self):
10971133
return redundancy_state
10981134

10991135
def rollback(self):
1136+
"""
1137+
Rollback to stored file config.
1138+
1139+
Raises:
1140+
NotImplementedError: Function currently not implemented.
1141+
"""
11001142
raise NotImplementedError
11011143

11021144
@property
11031145
def running_config(self):
1146+
"""
1147+
Show running config.
1148+
1149+
Raises:
1150+
NotImplementedError: Function currently not implemented.
1151+
"""
11041152
raise NotImplementedError
11051153

11061154
def save(self):
@@ -1222,9 +1270,10 @@ def show(self, command, expect_string=None, **netmiko_args):
12221270

12231271
return command_responses
12241272

1225-
def show_list(self, commands, **netmiko_args):
1273+
def show_list(self, commands, **netmiko_args): # noqa: D401
12261274
"""
12271275
DEPRECATED - Use the `show` method.
1276+
12281277
Send operational commands to the device.
12291278
12301279
Args:
@@ -1255,6 +1304,12 @@ def show_list(self, commands, **netmiko_args):
12551304

12561305
@property
12571306
def startup_config(self):
1307+
"""
1308+
Get startup config.
1309+
1310+
Raises:
1311+
NotImplementedError: Function currently not implemented.
1312+
"""
12581313
raise NotImplementedError
12591314

12601315
def transfer_image_to_ap(self, image, timeout=None):
@@ -1334,7 +1389,7 @@ def transfer_image_to_ap(self, image, timeout=None):
13341389
@property
13351390
def uptime(self):
13361391
"""
1337-
The uptime of the device in seconds.
1392+
Get uptime of the device in seconds.
13381393
13391394
Returns:
13401395
int: The number of seconds the device has been up.
@@ -1354,8 +1409,7 @@ def uptime(self):
13541409
@property
13551410
def uptime_string(self):
13561411
"""
1357-
The uptime of the device as a string.
1358-
The format is dd::hh::mm
1412+
Get uptime of the device as a string in the format is dd::hh::mm.
13591413
13601414
Returns:
13611415
str: The uptime of the device.

0 commit comments

Comments
 (0)