Skip to content

Commit

Permalink
Update legacycrypt usage and fix issues with updated linters. (#603)
Browse files Browse the repository at this point in the history
* Use legacycrypt where crypt isn't available

---------

Co-authored-by: Steve Kowalik <[email protected]>
  • Loading branch information
itdependsnetworks and s-t-e-v-e-n-k authored Dec 23, 2024
1 parent 9c7e197 commit f950e99
Show file tree
Hide file tree
Showing 11 changed files with 1,123 additions and 984 deletions.
44 changes: 22 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ env:

jobs:
black:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
env:
INVOKE_LOCAL: "True"
steps:
Expand All @@ -18,11 +18,11 @@ jobs:
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Linting: black"
run: "poetry run invoke black"
bandit:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
env:
INVOKE_LOCAL: "True"
steps:
Expand All @@ -31,13 +31,13 @@ jobs:
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Linting: bandit"
run: "poetry run invoke bandit"
needs:
- "black"
mypy:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
env:
INVOKE_LOCAL: "True"
steps:
Expand All @@ -46,13 +46,13 @@ jobs:
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Type-Hints: mypy"
run: "poetry run invoke mypy"
needs:
- "black"
pydocstyle:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
env:
INVOKE_LOCAL: "True"
steps:
Expand All @@ -61,13 +61,13 @@ jobs:
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Linting: pydocstyle"
run: "poetry run invoke pydocstyle"
needs:
- "black"
flake8:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
env:
INVOKE_LOCAL: "True"
steps:
Expand All @@ -76,13 +76,13 @@ jobs:
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Linting: flake8"
run: "poetry run invoke flake8"
needs:
- "black"
yamllint:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
env:
INVOKE_LOCAL: "True"
steps:
Expand All @@ -91,7 +91,7 @@ jobs:
- name: "Setup environment"
uses: "networktocode/gh-action-setup-poetry-environment@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Linting: yamllint"
run: "poetry run invoke yamllint"
needs:
Expand All @@ -100,8 +100,8 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
runs-on: "ubuntu-20.04"
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
runs-on: "ubuntu-24.04"
env:
PYTHON_VER: "${{ matrix.python-version }}"
steps:
Expand Down Expand Up @@ -133,11 +133,11 @@ jobs:
- "flake8"
- "yamllint"
pylint:
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
strategy:
fail-fast: true
matrix:
python-version: ["3.12"]
python-version: ["3.13"]
env:
PYTHON_VER: "${{ matrix.python-version }}"
steps:
Expand Down Expand Up @@ -173,8 +173,8 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
runs-on: "ubuntu-20.04"
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
runs-on: "ubuntu-24.04"
env:
PYTHON_VER: "${{ matrix.python-version }}"
steps:
Expand Down Expand Up @@ -212,15 +212,15 @@ jobs:
- "pylint"
publish_gh:
name: "Publish to GitHub"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
if: "startsWith(github.ref, 'refs/tags/v')"
steps:
- name: "Check out repository code"
uses: "actions/checkout@v2"
- name: "Set up Python"
uses: "actions/setup-python@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Install Python Packages"
run: "pip install poetry"
- name: "Set env"
Expand All @@ -241,15 +241,15 @@ jobs:
- "pytest"
publish_pypi:
name: "Push Package to PyPI"
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
if: "startsWith(github.ref, 'refs/tags/v')"
steps:
- name: "Check out repository code"
uses: "actions/checkout@v2"
- name: "Set up Python"
uses: "actions/setup-python@v2"
with:
python-version: "3.12"
python-version: "3.13"
- name: "Install Python Packages"
run: "pip install poetry"
- name: "Set env"
Expand Down
2 changes: 1 addition & 1 deletion docs/dev/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Pull requests are welcomed and automatically built and tested against multiple versions of Python through GitHub Actions.

Except for unit tests, testing is only supported on Python 3.9.
Except for unit tests, testing is only supported on Python 3.13.

The project is packaged with a light development environment based on `Docker` to help with the local development of the project and to run tests within GitHub Actions.

Expand Down
2 changes: 1 addition & 1 deletion netutils/config/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ def find_children_w_parents(
]
for cfg_line in self.build_config_relationship():
parents = cfg_line.parents[0] if cfg_line.parents else None
if parents in potential_parents and self._match_type_check(parents, parent_pattern, match_type):
if parents in potential_parents and self._match_type_check(parents, parent_pattern, match_type): # type: ignore[arg-type]
config.append(cfg_line.config_line)
return config

Expand Down
2 changes: 1 addition & 1 deletion netutils/ip.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def _convert_ip(ip: str) -> str:
if is_ip(ip):
if "." in ip:
mask = "32"
if ":" in ip:
else:
mask = "128"
return f"{ip}/{mask}"
return ip
Expand Down
2 changes: 2 additions & 0 deletions netutils/nist.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,13 @@ def _get_nist_urls_juniper_junos(os_platform_data: t.Dict[str, t.Any]) -> t.List
# BASE
_main = os_platform_data.get("main")
_minor = os_platform_data.get("minor")
_type = "" # Check if this is an issue as used below with potentially no definition
if os_platform_data["type"]:
_type = os_platform_data["type"].lower()
_build = os_platform_data.get("build")

# SERVICE
_service = "" # Check if this is an issue as used below with potentially no definition
if os_platform_data["service"]:
_service = os_platform_data["service"].lower()
_service_build = os_platform_data.get("service_build")
Expand Down
4 changes: 3 additions & 1 deletion netutils/os_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,12 @@ def get_upgrade_path(current_version: str, target_version: str, firmware_list: t

def _compare_version(current_version: str, comparison: str, target_version: str, version_type: str) -> bool:
# Convert version strings to Version objects for comparison
if version_type not in ["loose", "strict"]:
raise ValueError(f"Invalid version type: {version_type}, must be 'loose' or 'strict'")
if version_type == "loose":
current_ver_obj = LooseVersion(current_version)
target_ver_obj = LooseVersion(target_version)
elif version_type == "strict":
else:
current_ver_obj = StrictVersion(current_version)
target_ver_obj = StrictVersion(target_version)

Expand Down
28 changes: 23 additions & 5 deletions netutils/password.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Functions for working with Passwords."""

# TODO: Swap out crypt prior to py3.13
import crypt # pylint: disable=deprecated-module
import random
import secrets
import string
Expand All @@ -19,6 +17,19 @@
HAS_SCRYPT = False


try:
import crypt # pylint: disable=deprecated-module

HAS_CRYPT = True
except ModuleNotFoundError:
try:
import legacycrypt as crypt

HAS_CRYPT = True
except ModuleNotFoundError:
HAS_CRYPT = False


# Code example from Python docs
ALPHABET = string.ascii_letters + string.digits
DEFAULT_PASSWORD_CHARS = "".join((string.ascii_letters + string.digits + ".,:-_"))
Expand Down Expand Up @@ -128,9 +139,9 @@ def compare_cisco_type5(
Examples:
>>> from netutils.password import compare_cisco_type5
>>> compare_cisco_type5("cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.")
>>> compare_cisco_type5("cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.") # doctest: +SKIP
True
>>> compare_cisco_type5("not_cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.")
>>> compare_cisco_type5("not_cisco","$1$nTc1$Z28sUTcWfXlvVe2x.3XAa.") # doctest: +SKIP
False
>>>
"""
Expand Down Expand Up @@ -247,11 +258,18 @@ def encrypt_cisco_type5(unencrypted_password: str, salt: t.Optional[str] = None,
'$1$MHkb$v2MFmDkQX66TTxLkFF50K/'
>>>
"""
if not HAS_CRYPT:
raise ImportError(
"Your version of Python does not have crypt support built in. "
"Please install legacycrypt, such as `pip install legacycrypt` when "
"adding to your install or `pip install netutils[legacycrypt]` when installing fresh."
)

if not salt:
salt = "".join(secrets.choice(ALPHABET) for _ in range(salt_len))
elif not set(salt) <= set(ALPHABET):
raise ValueError(f"type5_pw salt used improper characters, must be one of {ALPHABET}")
return crypt.crypt(unencrypted_password, f"$1${salt}$")
return str(crypt.crypt(unencrypted_password, f"$1${salt}$"))


def encrypt_cisco_type7(unencrypted_password: str, salt: t.Optional[int] = None) -> str:
Expand Down
Loading

0 comments on commit f950e99

Please sign in to comment.