Skip to content

Commit

Permalink
Merge pull request #14 from networktocode/develop
Browse files Browse the repository at this point in the history
Release 0.2.0
  • Loading branch information
itdependsnetworks authored Jun 3, 2021
2 parents a542a61 + 2d7f1d0 commit 0aef341
Show file tree
Hide file tree
Showing 17 changed files with 232 additions and 244 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ before_script:
- "poetry config virtualenvs.create false"
- "poetry install --no-interaction"
script:
- "invoke coverage"
- "invoke pytest"

jobs:
include:
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## v0.2.0 - 2021-06

### Fixed

- Enable docsting tests
- Fix docstring tests
- Fix wording and links on README

### Changed

- Changed name of is_fqdn_valid to is_fqdn_resolvable, prepare to deprecate is_fqdn_valid
- Removed automatic import of all functions on initiation of package
- Moved interface mappings from variables to constants

## v0.1.1 - 2021-05

### Added

- Update travis configuration to release a new version from CI/CD pipeline

## v0.1.0 - 2021-03-19

Initial release
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This library intends to keep the following tenets:

* Must not be any dependencies required to run the library.
* May be some optional dependencies, to be managed by the user in opt in fashion.
* Shall prefer functional programming over object oriented programming.
* Shall prefer functions over classes.
* Shall prefer a folder and file structure that is flat.
* Shall leverage docstrings as the primary documentation mechanism.
* Must provide examples in every public function.
Expand Down Expand Up @@ -174,5 +174,5 @@ Each command can be executed with `invoke <command>`. Each command also has its

## Questions

For any questions or comments, please check the [FAQ](FAQ.md) first and feel free to swing by the [Network to Code slack channel](https://networktocode.slack.com/) (channel #networktocode).
For any questions or comments, feel free to swing by the [Network to Code slack channel](https://networktocode.slack.com/) (channel #networktocode).
Sign up [here](http://slack.networktocode.com/)
31 changes: 1 addition & 30 deletions netutils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,3 @@
"""Initialization file for library."""

from . import asn
from . import dns
from . import constants
from . import interface
from . import ip
from . import lib_mapper
from . import mac
from . import password
from . import ping
from . import protocol_mapper
from . import route
from . import variables
from . import vlan

__all__ = [
"asn",
"constants",
"dns",
"interface",
"ip",
"lib_mapper",
"mac",
"password",
"ping",
"protocol_mapper",
"route",
"variables",
"vlan",
]
__version__ = "0.1.2"
__version__ = "0.2.0"
6 changes: 0 additions & 6 deletions netutils/config/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
"""Initialization file for config methods."""

from . import clean
from . import compliance
from . import parser

__all__ = ["clean", "compliance", "parser"]
7 changes: 3 additions & 4 deletions netutils/config/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@


import re
from ..variables import CLEAN_FILTERS, SANITIZE_FILTERS # pylint: disable=relative-beyond-top-level


def clean_config(config, filters=CLEAN_FILTERS): # pylint: disable=dangerous-default-value
def clean_config(config, filters):
r"""Given a list of regex patterns, delete those lines that match.
Args:
config (str): A string representation of a device configuration.
filters (list, optional): A list of regex patterns used to delete remove configuration. Defaults to an empty list.
filters (list): A list of regex patterns used to delete remove configuration.
Returns:
str: Stripped down configuration.
Expand Down Expand Up @@ -53,7 +52,7 @@ def clean_config(config, filters=CLEAN_FILTERS): # pylint: disable=dangerous-de
return config


def sanitize_config(config, filters=SANITIZE_FILTERS): # pylint: disable=dangerous-default-value
def sanitize_config(config, filters):
r"""Given a dictionary of filters, remove sensitive data from the provided config.
Args:
Expand Down
173 changes: 173 additions & 0 deletions netutils/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,134 @@
"""Constant definitions used in project."""

# This variable provides mapping for known interface variants, to the associated long form.
BASE_INTERFACES = {
"ATM": "ATM",
"AT": "ATM",
"B": "Bdi",
"Bd": "Bdi",
"Bdi": "Bdi",
"EOBC": "EOBC",
"EO": "EOBC",
"Ethernet": "Ethernet",
"Eth": "Ethernet",
"eth": "Ethernet",
"Et": "Ethernet",
"et": "Ethernet",
"FastEthernet": "FastEthernet",
"FastEth": "FastEthernet",
"FastE": "FastEthernet",
"Fast": "FastEthernet",
"Fas": "FastEthernet",
"FE": "FastEthernet",
"Fa": "FastEthernet",
"fa": "FastEthernet",
"Fddi": "Fddi",
"FD": "Fddi",
"FortyGigabitEthernet": "FortyGigabitEthernet",
"FortyGigEthernet": "FortyGigabitEthernet",
"FortyGigEth": "FortyGigabitEthernet",
"FortyGigE": "FortyGigabitEthernet",
"FortyGig": "FortyGigabitEthernet",
"FGE": "FortyGigabitEthernet",
"FO": "FortyGigabitEthernet",
"Fo": "FortyGigabitEthernet",
"FiftyGigabitEthernet": "FiftyGigabitEthernet",
"FiftyGigEthernet": "FiftyGigabitEthernet",
"FiftyGigEth": "FiftyGigabitEthernet",
"FiftyGigE": "FiftyGigabitEthernet",
"FI": "FiftyGigabitEthernet",
"Fi": "FiftyGigabitEthernet",
"fi": "FiftyGigabitEthernet",
"GigabitEthernet": "GigabitEthernet",
"GigEthernet": "GigabitEthernet",
"GigEth": "GigabitEthernet",
"GigE": "GigabitEthernet",
"Gig": "GigabitEthernet",
"GE": "GigabitEthernet",
"Ge": "GigabitEthernet",
"ge": "GigabitEthernet",
"Gi": "GigabitEthernet",
"gi": "GigabitEthernet",
"HundredGigabitEthernet": "HundredGigabitEthernet",
"HundredGigEthernet": "HundredGigabitEthernet",
"HundredGigEth": "HundredGigabitEthernet",
"HundredGigE": "HundredGigabitEthernet",
"HundredGig": "HundredGigabitEthernet",
"Hu": "HundredGigabitEthernet",
"TwentyFiveGigabitEthernet": "TwentyFiveGigE",
"TwentyFiveGigEthernet": "TwentyFiveGigE",
"TwentyFiveGigEth": "TwentyFiveGigE",
"TwentyFiveGigE": "TwentyFiveGigE",
"TwentyFiveGig": "TwentyFiveGigE",
"TF": "TwentyFiveGigE",
"Tf": "TwentyFiveGigE",
"tf": "TwentyFiveGigE",
"TwoHundredGigabitEthernet": "TwoHundredGigabitEthernet",
"TwoHundredGigEthernet": "TwoHundredGigabitEthernet",
"TwoHundredGigEth": "TwoHundredGigabitEthernet",
"TwoHundredGigE": "TwoHundredGigabitEthernet",
"TwoHundredGig": "TwoHundredGigabitEthernet",
"TH": "TwoHundredGigabitEthernet",
"Th": "TwoHundredGigabitEthernet",
"th": "TwoHundredGigabitEthernet",
"FourHundredGigabitEthernet": "FourHundredGigabitEthernet",
"FourHundredGigEthernet": "FourHundredGigabitEthernet",
"FourHundredGigEth": "FourHundredGigabitEthernet",
"FourHundredGigE": "FourHundredGigabitEthernet",
"FourHundredGig": "FourHundredGigabitEthernet",
"F": "FourHundredGigabitEthernet",
"f": "FourHundredGigabitEthernet",
"Loopback": "Loopback",
"loopback": "Loopback",
"Lo": "Loopback",
"lo": "Loopback",
"Management": "Management",
"Mgmt": "Management",
"mgmt": "Management",
"Ma": "Management",
"Management_short": "Ma",
"MFR": "MFR",
"Multilink": "Multilink",
"Mu": "Multilink",
"n": "nve",
"nv": "nve",
"nve": "nve",
"PortChannel": "Port-channel",
"Port-channel": "Port-channel",
"Port-Channel": "Port-channel",
"port-channel": "Port-channel",
"po": "Port-channel",
"Po": "Port-channel",
"POS": "POS",
"PO": "POS",
"Serial": "Serial",
"Se": "Serial",
"S": "Serial",
"TenGigabitEthernet": "TenGigabitEthernet",
"TenGigEthernet": "TenGigabitEthernet",
"TenGigEth": "TenGigabitEthernet",
"TenGig": "TenGigabitEthernet",
"TeGig": "TenGigabitEthernet",
"Ten": "TenGigabitEthernet",
"T": "TenGigabitEthernet",
"Te": "TenGigabitEthernet",
"te": "TenGigabitEthernet",
"Tunnel": "Tunnel",
"Tun": "Tunnel",
"Tu": "Tunnel",
"Twe": "TwentyFiveGigE",
"Tw": "TwoGigabitEthernet",
"Two": "TwoGigabitEthernet",
"Virtual-Access": "Virtual-Access",
"Vi": "Virtual-Access",
"Virtual-Template": "Virtual-Template",
"Vt": "Virtual-Template",
"VLAN": "VLAN",
"V": "VLAN",
"Vl": "VLAN",
"Wlan-GigabitEthernet": "Wlan-GigabitEthernet",
}

# The default mac format
DEFAULT_MAC_FORMAT = "MAC_DOT_FOUR"

Expand All @@ -24,3 +153,47 @@
MAC_DOT_FOUR=r"([a-fA-F0-9]{4}[\.]){2}([a-fA-F0-9]{4})",
MAC_NO_SPECIAL=r"([a-fA-F0-9]{12})",
)

"""Variable definitions used in project, purposely not constants to signal to use these variables can be overridden."""

# This variable maps a full interface name, to an opinionated shortened name.
REVERSE_MAPPING = {
"ATM": "At",
"EOBC": "EO",
"Ethernet": "Et",
"FastEthernet": "Fa",
"Fddi": "FD",
"FortyGigabitEthernet": "Fo",
"GigabitEthernet": "Gi",
"HundredGigabitEthernet": "Hu",
"Loopback": "Lo",
"Management": "Ma",
"MFR": "MFR",
"Multilink": "Mu",
"Port-channel": "Po",
"POS": "PO",
"Serial": "Se",
"TenGigabitEthernet": "Te",
"Tunnel": "Tu",
"TwoGigabitEthernet": "Two",
"TwentyFiveGigE": "Twe",
"Virtual-Access": "Vi",
"Virtual-Template": "Vt",
"VLAN": "Vl",
"Wlan-GigabitEthernet": "Wl-Gi",
}

# These are base level filters to provide documentation of how a CLEAN_FILTER can be used, This is a private variable, and subject
# to change without notice between revisions.
_PROVIDED_CLEAN_FILTERS = [
{"regex": r"^Current\s+configuration.*\n"},
{"regex": r"^Building\s+configuration.*\n"},
{"regex": r"^ntp\s+clock-period.*\n"},
]

# These are base level filters to provide documentation of how a SANITIZE_FILTERS can be used, This is a private variable, and subject
# to change without notice between revisions.
_PROVIDED_SANITIZE_FILTERS = [
{"regex": r"(username\s+\S+\spassword\s+5\s+)\S+(\s+role\s+\S+)", "replace": "\\1<redacted_config>\\2"},
{"regex": r"(username\s+\S+\s+privilege\s+15\s+password\s+0\s+)\S+", "replace": "\\1<redacted_config>"},
]
29 changes: 20 additions & 9 deletions netutils/dns.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@


def fqdn_to_ip(hostname):
"""Provides the IP address of a resolvable name.
"""Provides the IP address of a resolvable name on the machine it is running from.
There are many reasons that a valid FQDN may not be resolvable, such as a network error
from your machine to the DNS server, an upstream DNS issue, etc.
Args:
hostname (str): An FQDN that may or may not be resolvable.
Expand All @@ -19,13 +22,17 @@ def fqdn_to_ip(hostname):
>>>
Raises:
socket.gaierror: If FQDN is not resolvable, leverage is_fqdn_valid to check first.
socket.gaierror: If FQDN is not resolvable, leverage is_fqdn_resolvable to check first.
"""
return socket.gethostbyname(hostname)
# The data structure is complex, only require the first item, and drill down from there.
return socket.getaddrinfo(hostname, 0)[0][4][0]


def is_fqdn_resolvable(hostname):
"""Verifies whether a hostname is resolvable on the machine it is running from.
def is_fqdn_valid(hostname):
"""Verifies whether a hostname is resolvable.
There are many reasons that a valid FQDN may not be resolvable, such as a network error
from your machine to the DNS server, an upstream DNS issue, etc.
Args:
hostname (str): A FQDN that may or may not be resolvable.
Expand All @@ -34,15 +41,19 @@ def is_fqdn_valid(hostname):
bool: The result as to whether or not the domain was valid.
Example:
>>> from netutils.dns import is_fqdn_valid
>>> is_fqdn_valid("google.com")
>>> from netutils.dns import is_fqdn_resolvable
>>> is_fqdn_resolvable("google.com")
True
>>> is_fqdn_valid("nevergonnagiveyouup.pizza")
>>> is_fqdn_resolvable("nevergonnagiveyouup.pizza")
False
>>>
"""
try:
socket.gethostbyname(hostname)
socket.getaddrinfo(hostname, 0)
return True
except socket.error:
return False


# Provide until transition to 1.0
is_fqdn_valid = is_fqdn_resolvable
2 changes: 1 addition & 1 deletion netutils/interface.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Functions for working with interface."""

from .variables import BASE_INTERFACES, REVERSE_MAPPING
from .constants import BASE_INTERFACES, REVERSE_MAPPING


def split_interface(interface):
Expand Down
4 changes: 2 additions & 2 deletions netutils/ip.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def is_netmask(netmask):
True
>>> is_netmask('24')
False
>>> is_netmask('255.255.266.0)
>>> is_netmask('255.255.266.0')
False
"""
try:
Expand Down Expand Up @@ -158,7 +158,7 @@ def cidr_to_netmask(cidr):
Example:
>>> from netutils.ip import netmask_to_cidr
>>> cidr_to_netmask(24)
'255.255.255.0
'255.255.255.0'
>>> cidr_to_netmask(17)
'255.255.128.0'
"""
Expand Down
2 changes: 1 addition & 1 deletion netutils/ping.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def tcp_ping(ip, port, timeout=1): # pylint: disable=invalid-name
>>> from netutils.ping import tcp_ping
>>> tcp_ping("1.1.1.1", 443)
True
>>> tcp_ping("1.0.100.0", 443)
>>> tcp_ping("1.0.100.0", 27)
False
>>>
"""
Expand Down
Loading

0 comments on commit 0aef341

Please sign in to comment.