diff --git a/.cookiecutter.json b/.cookiecutter.json index a5d8a4ac..21fa6220 100644 --- a/.cookiecutter.json +++ b/.cookiecutter.json @@ -21,7 +21,7 @@ "_drift_manager": { "template": "https://github.com/nautobot/cookiecutter-nautobot-app.git", "template_dir": "nautobot-app", - "template_ref": "refs/tags/nautobot-app-v2.2.1", + "template_ref": "refs/tags/nautobot-app-v2.3.0", "cookie_dir": "", "branch_prefix": "drift-manager", "pull_request_strategy": "create", @@ -29,7 +29,7 @@ "black" ], "draft": true, - "baked_commit_ref": "e99ba259e45876cf5a3432b7b02f95feac3ae6ad" + "baked_commit_ref": "32dbed28878e65887bfd9bd5601a0d4c5b5220e8" } } } \ No newline at end of file diff --git a/.dockerignore b/.dockerignore index 2270f496..a0bf06f4 100644 --- a/.dockerignore +++ b/.dockerignore @@ -19,7 +19,6 @@ FAQ.md .git/ .gitignore .github -tasks.py LICENSE **/*.log **/.vscode/ diff --git a/.flake8 b/.flake8 deleted file mode 100644 index c9f5e84d..00000000 --- a/.flake8 +++ /dev/null @@ -1,10 +0,0 @@ -[flake8] -ignore = - E501, # Line length is enforced by Black, so flake8 doesn't need to check it - W503 # Black disagrees with this rule, as does PEP 8; Black wins -exclude = - migrations, - __pycache__, - manage.py, - settings.py, - .venv diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fb5ff9fa..4848f39e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,7 @@ env: APP_NAME: "nautobot-app-device-onboarding" jobs: - black: + ruff-format: runs-on: "ubuntu-22.04" env: INVOKE_NAUTOBOT_DEVICE_ONBOARDING_LOCAL: "True" @@ -25,20 +25,9 @@ jobs: uses: "actions/checkout@v4" - name: "Setup environment" uses: "networktocode/gh-action-setup-poetry-environment@v6" - - name: "Linting: black" - run: "poetry run invoke black" - bandit: - runs-on: "ubuntu-22.04" - env: - INVOKE_NAUTOBOT_DEVICE_ONBOARDING_LOCAL: "True" - steps: - - name: "Check out repository code" - uses: "actions/checkout@v4" - - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v6" - - name: "Linting: bandit" - run: "poetry run invoke bandit" - ruff: + - name: "Linting: ruff format" + run: "poetry run invoke ruff --action format" + ruff-lint: runs-on: "ubuntu-22.04" env: INVOKE_NAUTOBOT_DEVICE_ONBOARDING_LOCAL: "True" @@ -60,17 +49,6 @@ jobs: uses: "networktocode/gh-action-setup-poetry-environment@v6" - name: "Check Docs Build" run: "poetry run invoke build-and-check-docs" - flake8: - runs-on: "ubuntu-22.04" - env: - INVOKE_NAUTOBOT_DEVICE_ONBOARDING_LOCAL: "True" - steps: - - name: "Check out repository code" - uses: "actions/checkout@v4" - - name: "Setup environment" - uses: "networktocode/gh-action-setup-poetry-environment@v6" - - name: "Linting: flake8" - run: "poetry run invoke flake8" poetry: runs-on: "ubuntu-22.04" env: @@ -95,12 +73,10 @@ jobs: run: "poetry run invoke yamllint" check-in-docker: needs: - - "bandit" - - "ruff" - - "flake8" + - "ruff-format" + - "ruff-lint" - "poetry" - "yamllint" - - "black" runs-on: "ubuntu-22.04" strategy: fail-fast: true diff --git a/README.md b/README.md index cf95926c..9c7f9d05 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@
- A plugin for Nautobot to easily onboard new devices. + An App for Nautobot.

## Overview @@ -21,44 +21,44 @@ Regardless, the Onboarding App greatly simplifies the onboarding process by allo | Data Attribute | Cisco IOS | Cisco XE | Cisco NXOS | Cisco WLC | Juniper Junos | Arista EOS | F5 | | ----------------------- | :----------------: | :--------------: | :--------------: | :--------------: | :--------------: | :--------------: | :-: | -| Hostname | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | -| Platform | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | -| Manufacturer | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | -| Serial Number | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | -| Device Type | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | -| Mgmt Interface | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | -| Mgmt IP Address | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | +| Hostname | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Platform | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Manufacturer | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Serial Number | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Device Type | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Mgmt Interface | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | +| Mgmt IP Address | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ### Support Matrix (Sync Data From Network) | Interfaces | Cisco IOS | Cisco XE | Cisco NXOS | Cisco WLC | Juniper Junos | Arista EOS | F5 | | ----------------------- | :----------------: | :--------------: | :--------------: | :--------------: | :--------------: | :--------------: | :-: | -| Name | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| IP Address | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| Type | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| MTU | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| Description | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| Mac Address | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| Link Status | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| 802.1Q mode | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| Lag Member | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| Vrf Membership | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | +| Name | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| IP Address | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| Type | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| MTU | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| Description | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| Mac Address | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| Link Status | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| 802.1Q mode | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| Lag Member | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| Vrf Membership | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | | VLANS | Cisco IOS | Cisco XE | Cisco NXOS | Cisco WLC | Juniper Junos | Arista EOS | F5 | | ----------------------- | :----------------: | :--------------: | :--------------: | :--------------: | :--------------: | :--------------: | :-: | -| Untagged VLANs | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | -| Tagged VLANs | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :white_check_mark: | :white_check_mark: | :x: | +| Untagged VLANs | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | +| Tagged VLANs | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | | Cabling | Cisco IOS | Cisco XE | Cisco NXOS | Cisco WLC | Juniper Junos | Arista EOS | F5 | | ----------------------- | :----------------: | :--------------: | :--------------: | :--------------: | :--------------: | :--------------: | :-: | -| Terminations A | :test_tube: | :test_tube: | :test_tube: | :x: | :test_tube: | :x: | :x: | -| Terminations B | :test_tube: | :test_tube: | :test_tube: | :x: | :test_tube: | :x: | :x: | +| Terminations A | 🧪 | 🧪 | 🧪 | ❌ | 🧪 | ❌ | ❌ | +| Terminations B | 🧪 | 🧪 | 🧪 | ❌ | 🧪 | ❌ | ❌ | | Legend | | :---- | -| :white_check_mark: - Supported and stable. | -| :x: - No current support. | -| :test_tube: - Supported, but has limited testing. | +| ✅ - Supported and stable. | +| ❌ - No current support. | +| 🧪 - Supported, but has limited testing. | ### Screenshots diff --git a/changes/216.housekeeping b/changes/216.housekeeping new file mode 100644 index 00000000..b60b1318 --- /dev/null +++ b/changes/216.housekeeping @@ -0,0 +1 @@ +Rebake using 2.3 Nautobot-App-Cookiecutter. \ No newline at end of file diff --git a/changes/217.fixed b/changes/217.fixed new file mode 100644 index 00000000..5aff1ecc --- /dev/null +++ b/changes/217.fixed @@ -0,0 +1,2 @@ +Removed secrets-provider app dependency. +Removed python-tss-sdk dependency. \ No newline at end of file diff --git a/changes/218.fixed b/changes/218.fixed new file mode 100644 index 00000000..3c12ecd5 --- /dev/null +++ b/changes/218.fixed @@ -0,0 +1 @@ +Replaced all instances of emoji shortcodes with the unicode characters so they render correctly in docs. diff --git a/development/docker-compose.mysql.yml b/development/docker-compose.mysql.yml index a8fe3129..dbe31cba 100644 --- a/development/docker-compose.mysql.yml +++ b/development/docker-compose.mysql.yml @@ -17,7 +17,6 @@ services: db: image: "mysql:8" command: - - "--default-authentication-plugin=mysql_native_password" - "--max_connections=1000" env_file: - "development.env" diff --git a/development/nautobot_config.py b/development/nautobot_config.py index 4f29792d..d77b1133 100644 --- a/development/nautobot_config.py +++ b/development/nautobot_config.py @@ -10,7 +10,7 @@ # Debug # -DEBUG = is_truthy(os.getenv("NAUTOBOT_DEBUG", False)) +DEBUG = is_truthy(os.getenv("NAUTOBOT_DEBUG", "false")) _TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" if DEBUG and not _TESTING: @@ -48,9 +48,10 @@ "PASSWORD": os.getenv("NAUTOBOT_DB_PASSWORD", ""), # Database password "HOST": os.getenv("NAUTOBOT_DB_HOST", "localhost"), # Database server "PORT": os.getenv( - "NAUTOBOT_DB_PORT", default_db_settings[nautobot_db_engine]["NAUTOBOT_DB_PORT"] + "NAUTOBOT_DB_PORT", + default_db_settings[nautobot_db_engine]["NAUTOBOT_DB_PORT"], ), # Database port, default to postgres - "CONN_MAX_AGE": int(os.getenv("NAUTOBOT_DB_TIMEOUT", 300)), # Database timeout + "CONN_MAX_AGE": int(os.getenv("NAUTOBOT_DB_TIMEOUT", "300")), # Database timeout "ENGINE": nautobot_db_engine, } } diff --git a/docs/assets/extra.css b/docs/assets/extra.css index 1eff1192..3f3931a0 100644 --- a/docs/assets/extra.css +++ b/docs/assets/extra.css @@ -96,7 +96,7 @@ a.autorefs-external:hover::after { } -/* Customization for mkdocs-version-annotations */ +/* Customization for markdown-version-annotations */ :root { /* Icon for "version-added" admonition: Material Design Icons "plus-box-outline" */ --md-admonition-icon--version-added: url('data:image/svg+xml;charset=utf-8,'); diff --git a/docs/dev/contributing.md b/docs/dev/contributing.md index a3d41d71..b26279a7 100644 --- a/docs/dev/contributing.md +++ b/docs/dev/contributing.md @@ -6,7 +6,7 @@ The project is packaged with a light [development environment](dev_environment.m The project is following Network to Code software development guidelines and is leveraging the following: -- Python linting and formatting: `black`, `pylint`, `bandit`, `flake8`, and `ruff`. +- Python linting and formatting: `pylint` and `ruff`. - YAML linting is done with `yamllint`. - Django unit test to ensure the app is working properly. diff --git a/docs/dev/dev_environment.md b/docs/dev/dev_environment.md index b1aad192..48b8337d 100644 --- a/docs/dev/dev_environment.md +++ b/docs/dev/dev_environment.md @@ -123,10 +123,7 @@ Each command can be executed with `invoke `. All commands support the a #### Testing ``` - bandit Run bandit to validate basic static code security analysis. - black Run black to check that Python files adhere to its style standards. - flake8 Run flake8 to check that Python files adhere to its style standards. - ruff Run ruff to validate docstring formatting adheres to NTC defined standards. + ruff Run ruff to perform code formatting and/or linting. pylint Run pylint code analysis. tests Run all tests for this app. unittest Run Django unit tests for the app. @@ -457,7 +454,7 @@ This is the same as running: ### Tests -To run tests against your code, you can run all of the tests that TravisCI runs against any new PR with: +To run tests against your code, you can run all of the tests that the CI runs against any new PR with: ```bash ➜ invoke tests @@ -467,9 +464,6 @@ To run an individual test, you can run any or all of the following: ```bash ➜ invoke unittest -➜ invoke bandit -➜ invoke black -➜ invoke flake8 ➜ invoke ruff ➜ invoke pylint ``` diff --git a/docs/requirements.txt b/docs/requirements.txt index d168c88f..1d89ad0d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ mkdocs==1.5.2 mkdocs-material==9.1.15 -mkdocs-version-annotations==1.0.0 +markdown-version-annotations==1.0.1 mkdocstrings-python==1.5.2 mkdocstrings==0.22.0 diff --git a/mkdocs.yml b/mkdocs.yml index 2fa3f308..8381ae16 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -72,6 +72,8 @@ extra: link: "https://twitter.com/networktocode" name: "Network to Code Twitter" markdown_extensions: + - "markdown_version_annotations": + admonition_tag: "???" - "admonition" - "toc": permalink: true @@ -85,7 +87,6 @@ markdown_extensions: - "footnotes" plugins: - "search" - - "mkdocs-version-annotations" - "mkdocstrings": default_handler: "python" handlers: diff --git a/nautobot_device_onboarding/__init__.py b/nautobot_device_onboarding/__init__.py index 3af1124b..3d4a53d1 100644 --- a/nautobot_device_onboarding/__init__.py +++ b/nautobot_device_onboarding/__init__.py @@ -1,7 +1,6 @@ """App declaration for nautobot_device_onboarding.""" -# Metadata is inherited from Nautobot -# If not including Nautobot in the environment, this should be added +# Metadata is inherited from Nautobot. If not including Nautobot in the environment, this should be added from importlib import metadata from nautobot.apps import NautobotAppConfig diff --git a/nautobot_device_onboarding/jobs.py b/nautobot_device_onboarding/jobs.py index 8521d104..1edac236 100755 --- a/nautobot_device_onboarding/jobs.py +++ b/nautobot_device_onboarding/jobs.py @@ -383,9 +383,9 @@ def _process_csv_data(self, csv_file): processed_csv_data[row["ip_address_host"]]["port"] = int(row["port"].strip()) processed_csv_data[row["ip_address_host"]]["timeout"] = int(row["timeout"].strip()) processed_csv_data[row["ip_address_host"]]["set_mgmt_only"] = set_mgmgt_only - processed_csv_data[row["ip_address_host"]][ - "update_devices_without_primary_ip" - ] = update_devices_without_primary_ip + processed_csv_data[row["ip_address_host"]]["update_devices_without_primary_ip"] = ( + update_devices_without_primary_ip + ) processed_csv_data[row["ip_address_host"]]["device_role"] = device_role processed_csv_data[row["ip_address_host"]]["device_status"] = device_status processed_csv_data[row["ip_address_host"]]["interface_status"] = interface_status diff --git a/nautobot_device_onboarding/tests/test_api.py b/nautobot_device_onboarding/tests/test_api.py new file mode 100644 index 00000000..9f2d62b9 --- /dev/null +++ b/nautobot_device_onboarding/tests/test_api.py @@ -0,0 +1,28 @@ +"""Unit tests for nautobot_device_onboarding.""" + +from django.contrib.auth import get_user_model +from django.test import TestCase +from django.urls import reverse +from nautobot.users.models import Token +from rest_framework import status +from rest_framework.test import APIClient + +User = get_user_model() + + +class PlaceholderAPITest(TestCase): + """Test the NautobotDeviceOnboarding API.""" + + def setUp(self): + """Create a superuser and token for API calls.""" + self.user = User.objects.create(username="testuser", is_superuser=True) + self.token = Token.objects.create(user=self.user) + self.client = APIClient() + self.client.credentials(HTTP_AUTHORIZATION=f"Token {self.token.key}") + + def test_placeholder(self): + """Verify that devices can be listed.""" + url = reverse("dcim-api:device-list") + response = self.client.get(url) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data["count"], 0) diff --git a/nautobot_device_onboarding/tests/test_basic.py b/nautobot_device_onboarding/tests/test_basic.py index 2e5df1de..d72f2d02 100644 --- a/nautobot_device_onboarding/tests/test_basic.py +++ b/nautobot_device_onboarding/tests/test_basic.py @@ -17,8 +17,9 @@ def test_version(self): with open(f"{parent_path}/docs/requirements.txt", "r", encoding="utf-8") as file: requirements = [line for line in file.read().splitlines() if (len(line) > 0 and not line.startswith("#"))] for pkg in requirements: - if len(pkg.split("==")) == 2: - pkg, version = pkg.split("==") + package_name = pkg + if len(pkg.split("==")) == 2: # noqa: PLR2004 + package_name, version = pkg.split("==") else: version = "*" - self.assertEqual(poetry_details[pkg], version) + self.assertEqual(poetry_details[package_name], version) diff --git a/nautobot_device_onboarding/tests/test_formatter.py b/nautobot_device_onboarding/tests/test_formatter.py index 44096ec2..abf85f1f 100755 --- a/nautobot_device_onboarding/tests/test_formatter.py +++ b/nautobot_device_onboarding/tests/test_formatter.py @@ -10,8 +10,8 @@ from nautobot_device_onboarding.nornir_plays.formatter import ( extract_and_post_process, - perform_data_extraction, normalize_processed_data, + perform_data_extraction, ) from nautobot_device_onboarding.nornir_plays.transform import add_platform_parsing_info diff --git a/nautobot_device_onboarding/tests/test_jinja_filters.py b/nautobot_device_onboarding/tests/test_jinja_filters.py index 42fb0a0b..4dcd3faf 100755 --- a/nautobot_device_onboarding/tests/test_jinja_filters.py +++ b/nautobot_device_onboarding/tests/test_jinja_filters.py @@ -2,6 +2,7 @@ import unittest import unittest.mock + from nautobot_device_onboarding.jinja_filters import ( extract_prefix, flatten_dict_from_value, diff --git a/nautobot_device_onboarding/tests/test_transform.py b/nautobot_device_onboarding/tests/test_transform.py index 2cc0dbaf..67e620ef 100755 --- a/nautobot_device_onboarding/tests/test_transform.py +++ b/nautobot_device_onboarding/tests/test_transform.py @@ -77,9 +77,7 @@ def test_git_repo_was_created(self, MockGitRepo): # pylint:disable=invalid-name self.assertEqual(1, repo_count) @mock.patch("nautobot_device_onboarding.nornir_plays.transform.load_command_mappers_from_dir") - def test_pull_git_repository_and_refresh_data_with_valid_data( - self, mock_load_command_mappers, MockGitRepo - ): # pylint:disable=invalid-name + def test_pull_git_repository_and_refresh_data_with_valid_data(self, mock_load_command_mappers, MockGitRepo): # pylint:disable=invalid-name """ The test_pull_git_repository_and_refresh_data job should succeed if valid data is present in the repo. """ diff --git a/poetry.lock b/poetry.lock index 321e2a51..75cb3361 100755 --- a/poetry.lock +++ b/poetry.lock @@ -209,30 +209,6 @@ tzdata = {version = "*", optional = true, markers = "extra == \"tzdata\""} [package.extras] tzdata = ["tzdata"] -[[package]] -name = "bandit" -version = "1.7.8" -description = "Security oriented static analyser for python code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "bandit-1.7.8-py3-none-any.whl", hash = "sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381"}, - {file = "bandit-1.7.8.tar.gz", hash = "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b"}, -] - -[package.dependencies] -colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} -PyYAML = ">=5.3.1" -rich = "*" -stevedore = ">=1.20.0" - -[package.extras] -baseline = ["GitPython (>=3.1.30)"] -sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"] -test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"] -toml = ["tomli (>=1.1.0)"] -yaml = ["PyYAML"] - [[package]] name = "bcrypt" version = "4.1.3" @@ -284,52 +260,6 @@ files = [ {file = "billiard-4.2.0.tar.gz", hash = "sha256:9a3c3184cb275aa17a732f93f65b20c525d3d9f253722d26a82194803ade5a2c"}, ] -[[package]] -name = "black" -version = "24.4.2" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.8" -files = [ - {file = "black-24.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce"}, - {file = "black-24.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021"}, - {file = "black-24.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063"}, - {file = "black-24.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96"}, - {file = "black-24.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474"}, - {file = "black-24.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c"}, - {file = "black-24.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb"}, - {file = "black-24.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1"}, - {file = "black-24.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d"}, - {file = "black-24.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04"}, - {file = "black-24.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc"}, - {file = "black-24.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0"}, - {file = "black-24.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7"}, - {file = "black-24.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94"}, - {file = "black-24.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8"}, - {file = "black-24.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c"}, - {file = "black-24.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1"}, - {file = "black-24.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741"}, - {file = "black-24.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"}, - {file = "black-24.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7"}, - {file = "black-24.4.2-py3-none-any.whl", hash = "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c"}, - {file = "black-24.4.2.tar.gz", hash = "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -packaging = ">=22.0" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - [[package]] name = "celery" version = "5.3.6" @@ -1304,22 +1234,6 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] -[[package]] -name = "flake8" -version = "5.0.4" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.6.1" -files = [ - {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, - {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.9.0,<2.10.0" -pyflakes = ">=2.5.0,<2.6.0" - [[package]] name = "future" version = "1.0.0" @@ -1930,9 +1844,13 @@ files = [ {file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"}, {file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"}, {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6"}, {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c"}, {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184"}, {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f"}, {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"}, {file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"}, {file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"}, @@ -2022,28 +1940,18 @@ docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-li testing = ["coverage", "pyyaml"] [[package]] -name = "markdown-it-py" -version = "3.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" +name = "markdown-version-annotations" +version = "1.0.1" +description = "Markdown plugin to add custom admonitions for documenting version differences" optional = false -python-versions = ">=3.8" +python-versions = "<4.0,>=3.7" files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, + {file = "markdown_version_annotations-1.0.1-py3-none-any.whl", hash = "sha256:6df0b2ac08bab906c8baa425f59fc0fe342fbe8b3917c144fb75914266b33200"}, + {file = "markdown_version_annotations-1.0.1.tar.gz", hash = "sha256:620aade507ef175ccfb2059db152a34c6a1d2add28c2be16ea4de38d742e6132"}, ] [package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] +markdown = ">=3.3.7,<4.0.0" [[package]] name = "markupsafe" @@ -2139,17 +2047,6 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - [[package]] name = "mergedeep" version = "1.3.4" @@ -2241,17 +2138,6 @@ files = [ {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, ] -[[package]] -name = "mkdocs-version-annotations" -version = "1.0.0" -description = "MkDocs plugin to add custom admonitions for documenting version differences" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "mkdocs-version-annotations-1.0.0.tar.gz", hash = "sha256:6786024b37d27b330fda240b76ebec8e7ce48bd5a9d7a66e99804559d088dffa"}, - {file = "mkdocs_version_annotations-1.0.0-py3-none-any.whl", hash = "sha256:385004eb4a7530dd87a227e08cd907ce7a8fe21fdf297720a4149c511bcf05f5"}, -] - [[package]] name = "mkdocstrings" version = "0.22.0" @@ -2416,24 +2302,6 @@ nautobot = ">=2.0.0,<3.0.0" netutils = ">=1.6.0" nornir-nautobot = ">=3.0.0,<4.0.0" -[[package]] -name = "nautobot-secrets-providers" -version = "2.0.1" -description = "Nautobot Secrets Providers App" -optional = false -python-versions = ">=3.8,<3.12" -files = [ - {file = "nautobot_secrets_providers-2.0.1-py3-none-any.whl", hash = "sha256:67d671fccf1fbe4c62e4771ec17306ac4531b1ada65b0359390a762378661bfc"}, - {file = "nautobot_secrets_providers-2.0.1.tar.gz", hash = "sha256:f3bb1a2986dc4c9b5b40a5756d4025a9cffdcb4f0e7a6214ee610a3e527f789b"}, -] - -[package.extras] -all = ["boto3 (>=1.19.5,<1.20.0)", "hvac (>=0.11.0,<1.1.0)", "python-tss-sdk (>=1.2.0,<1.3.0)"] -aws = ["boto3 (>=1.19.5,<1.20.0)"] -hashicorp = ["hvac (>=0.11.0,<1.1.0)"] -nautobot = ["nautobot (>=2.0.0,<3.0.0)"] -thycotic = ["python-tss-sdk (>=1.2.0,<1.3.0)"] - [[package]] name = "nautobot-ssot" version = "2.6.1" @@ -2750,17 +2618,6 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] -[[package]] -name = "pbr" -version = "6.0.0" -description = "Python Build Reasonableness" -optional = false -python-versions = ">=2.6" -files = [ - {file = "pbr-6.0.0-py2.py3-none-any.whl", hash = "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda"}, - {file = "pbr-6.0.0.tar.gz", hash = "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"}, -] - [[package]] name = "pexpect" version = "4.9.0" @@ -3140,17 +2997,6 @@ netaddr = "*" dev = ["check-manifest", "pep8", "pyflakes", "twine"] test = ["coverage", "mock"] -[[package]] -name = "pyflakes" -version = "2.5.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, - {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, -] - [[package]] name = "pygments" version = "2.18.0" @@ -3396,20 +3242,6 @@ text-unidecode = ">=1.3" [package.extras] unidecode = ["Unidecode (>=1.1.1)"] -[[package]] -name = "python-tss-sdk" -version = "1.2.2" -description = "The Delinea Secret Server Python SDK" -optional = false -python-versions = ">=3.8" -files = [ - {file = "python_tss_sdk-1.2.2-py3-none-any.whl", hash = "sha256:f69e5d9fba75b5835b9182402f8520294dd8e8abc4b4e0409080121bc06b5186"}, - {file = "python_tss_sdk-1.2.2.tar.gz", hash = "sha256:2620d0002d794d4407f85b7521d69d73f865f348238e43f61418754a6aeb520e"}, -] - -[package.dependencies] -requests = ">=2.12.5" - [[package]] name = "python3-openid" version = "3.2.0" @@ -3516,7 +3348,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -3725,25 +3556,6 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] -[[package]] -name = "rich" -version = "13.7.1" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, -] - -[package.dependencies] -markdown-it-py = ">=2.2.0" -pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] - [[package]] name = "rpds-py" version = "0.18.1" @@ -3931,28 +3743,29 @@ files = [ [[package]] name = "ruff" -version = "0.4.6" +version = "0.5.5" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ef995583a038cd4a7edf1422c9e19118e2511b8ba0b015861b4abd26ec5367c5"}, - {file = "ruff-0.4.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:602ebd7ad909eab6e7da65d3c091547781bb06f5f826974a53dbe563d357e53c"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f9ced5cbb7510fd7525448eeb204e0a22cabb6e99a3cb160272262817d49786"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04a80acfc862e0e1630c8b738e70dcca03f350bad9e106968a8108379e12b31f"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be47700ecb004dfa3fd4dcdddf7322d4e632de3c06cd05329d69c45c0280e618"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1ff930d6e05f444090a0139e4e13e1e2e1f02bd51bb4547734823c760c621e79"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f13410aabd3b5776f9c5699f42b37a3a348d65498c4310589bc6e5c548dc8a2f"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0cf5cc02d3ae52dfb0c8a946eb7a1d6ffe4d91846ffc8ce388baa8f627e3bd50"}, - {file = "ruff-0.4.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea3424793c29906407e3cf417f28fc33f689dacbbadfb52b7e9a809dd535dcef"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1fa8561489fadf483ffbb091ea94b9c39a00ed63efacd426aae2f197a45e67fc"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4d5b914818d8047270308fe3e85d9d7f4a31ec86c6475c9f418fbd1624d198e0"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4f02284335c766678778475e7698b7ab83abaf2f9ff0554a07b6f28df3b5c259"}, - {file = "ruff-0.4.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3a6a0a4f4b5f54fff7c860010ab3dd81425445e37d35701a965c0248819dde7a"}, - {file = "ruff-0.4.6-py3-none-win32.whl", hash = "sha256:9018bf59b3aa8ad4fba2b1dc0299a6e4e60a4c3bc62bbeaea222679865453062"}, - {file = "ruff-0.4.6-py3-none-win_amd64.whl", hash = "sha256:a769ae07ac74ff1a019d6bd529426427c3e30d75bdf1e08bb3d46ac8f417326a"}, - {file = "ruff-0.4.6-py3-none-win_arm64.whl", hash = "sha256:735a16407a1a8f58e4c5b913ad6102722e80b562dd17acb88887685ff6f20cf6"}, - {file = "ruff-0.4.6.tar.gz", hash = "sha256:a797a87da50603f71e6d0765282098245aca6e3b94b7c17473115167d8dfb0b7"}, + {file = "ruff-0.5.5-py3-none-linux_armv6l.whl", hash = "sha256:605d589ec35d1da9213a9d4d7e7a9c761d90bba78fc8790d1c5e65026c1b9eaf"}, + {file = "ruff-0.5.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00817603822a3e42b80f7c3298c8269e09f889ee94640cd1fc7f9329788d7bf8"}, + {file = "ruff-0.5.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:187a60f555e9f865a2ff2c6984b9afeffa7158ba6e1eab56cb830404c942b0f3"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe26fc46fa8c6e0ae3f47ddccfbb136253c831c3289bba044befe68f467bfb16"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad25dd9c5faac95c8e9efb13e15803cd8bbf7f4600645a60ffe17c73f60779b"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f70737c157d7edf749bcb952d13854e8f745cec695a01bdc6e29c29c288fc36e"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:cfd7de17cef6ab559e9f5ab859f0d3296393bc78f69030967ca4d87a541b97a0"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a09b43e02f76ac0145f86a08e045e2ea452066f7ba064fd6b0cdccb486f7c3e7"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0b856cb19c60cd40198be5d8d4b556228e3dcd545b4f423d1ad812bfdca5884"}, + {file = "ruff-0.5.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3687d002f911e8a5faf977e619a034d159a8373514a587249cc00f211c67a091"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ac9dc814e510436e30d0ba535f435a7f3dc97f895f844f5b3f347ec8c228a523"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:af9bdf6c389b5add40d89b201425b531e0a5cceb3cfdcc69f04d3d531c6be74f"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d40a8533ed545390ef8315b8e25c4bb85739b90bd0f3fe1280a29ae364cc55d8"}, + {file = "ruff-0.5.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cab904683bf9e2ecbbe9ff235bfe056f0eba754d0168ad5407832928d579e7ab"}, + {file = "ruff-0.5.5-py3-none-win32.whl", hash = "sha256:696f18463b47a94575db635ebb4c178188645636f05e934fdf361b74edf1bb2d"}, + {file = "ruff-0.5.5-py3-none-win_amd64.whl", hash = "sha256:50f36d77f52d4c9c2f1361ccbfbd09099a1b2ea5d2b2222c586ab08885cf3445"}, + {file = "ruff-0.5.5-py3-none-win_arm64.whl", hash = "sha256:3191317d967af701f1b73a31ed5788795936e423b7acce82a2b63e26eb3e89d6"}, + {file = "ruff-0.5.5.tar.gz", hash = "sha256:cc5516bdb4858d972fbc31d246bdb390eab8df1a26e2353be2dbc0c2d7f5421a"}, ] [[package]] @@ -4117,20 +3930,6 @@ pure-eval = "*" [package.extras] tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] -[[package]] -name = "stevedore" -version = "5.2.0" -description = "Manage dynamic plugins for Python applications" -optional = false -python-versions = ">=3.8" -files = [ - {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"}, - {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"}, -] - -[package.dependencies] -pbr = ">=2.0.0,<2.1.0 || >2.1.0" - [[package]] name = "structlog" version = "22.3.0" @@ -4487,4 +4286,4 @@ all = [] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.12" -content-hash = "34f02489b251692fdf52e61cd635a6d417cd443bf078ea752d0be7049c3a0224" +content-hash = "8ac22c9e70d945661feae6f306ede76e1c65e716b20fbbcba1337029f53148f1" diff --git a/pyproject.toml b/pyproject.toml index fe122739..bd4deff9 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,32 +34,27 @@ nautobot-ssot = "^2.6.0" nautobot-plugin-nornir = "^2.0.0" jdiff = "^0.0.6" ntc-templates = "^6.0.0" -nautobot-secrets-providers = "^2.0.1" -python-tss-sdk = "*" # Netutils pin is needed for https://github.com/networktocode/netutils/pull/553 netutils = "^1.9.1" [tool.poetry.group.dev.dependencies] -bandit = "*" -black = "*" coverage = "*" django-debug-toolbar = "*" -flake8 = "*" invoke = "*" ipython = "*" pylint = "*" pylint-django = "*" pylint-nautobot = "*" -ruff = "*" +ruff = "0.5.5" yamllint = "*" toml = "*" Markdown = "*" +# Render custom markdown for version added/changed/remove notes +markdown-version-annotations = "1.0.1" # Rendering docs to HTML mkdocs = "1.5.2" # Material for MkDocs theme mkdocs-material = "9.1.15" -# Render custom markdown for version added/changed/remove notes -mkdocs-version-annotations = "1.0.0" # Automatic documentation from sources, for MkDocs mkdocstrings = "0.22.0" mkdocstrings-python = "1.5.2" @@ -69,32 +64,6 @@ towncrier = "~23.6.0" all = [ ] -[tool.black] -line-length = 120 -target-version = ['py38', 'py39', 'py310', 'py311'] -include = '\.pyi?$' -exclude = ''' -( - /( - \.eggs # exclude a few common directories in the - | \.git # root of the project - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist - )/ - | settings.py # This is where you define files that should not be stylized by black - # the root of the project -) -''' - -[tool.coverage.report] -show_missing = true - [tool.pylint.master] # Include the pylint_django plugin to avoid spurious warnings about Django patterns load-plugins="pylint_django, pylint_nautobot" @@ -105,8 +74,6 @@ ignore=".venv" no-docstring-rgx="^(_|test_|Meta$)" [tool.pylint.messages_control] -# Line length is enforced by Black, so pylint doesn't need to check it. -# Pylint and Black disagree about how to format multi-line arrays; Black wins. disable = """, arguments-differ, line-too-long, @@ -143,6 +110,9 @@ target-version = "py38" [tool.ruff.lint] select = [ "D", # pydocstyle + "F", "E", "W", # flake8 + "S", # bandit + "I", # isort ] ignore = [ # warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. @@ -160,17 +130,19 @@ ignore = [ "D401", # First line of docstring should be in imperative mood "D407", # Missing dashed underline after section "D416", # Section name ends in colon + "E501", # Line too long ] [tool.ruff.lint.pydocstyle] convention = "google" -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "nautobot_device_onboarding/migrations/*" = [ - "D", # pydocstyle + "D", ] "nautobot_device_onboarding/tests/*" = [ - "D", # pydocstyle + "D", + "S" ] [build-system] diff --git a/tasks.py b/tasks.py index c5b4be23..37342758 100644 --- a/tasks.py +++ b/tasks.py @@ -159,17 +159,17 @@ def run_command(context, command, **kwargs): # Check if nautobot is running, no need to start another nautobot container to run a command docker_compose_status = "ps --services --filter status=running" results = docker_compose(context, docker_compose_status, hide="out") - if "nautobot" in results.stdout: - compose_command = "exec" - else: - compose_command = "run --rm --entrypoint=''" + command_env_args = "" if "command_env" in kwargs: command_env = kwargs.pop("command_env") for key, value in command_env.items(): - compose_command += f' --env="{key}={value}"' + command_env_args += f' --env="{key}={value}"' - compose_command += f" -- nautobot {command}" + if "nautobot" in results.stdout: + compose_command = f"exec{command_env_args} nautobot {command}" + else: + compose_command = f"run{command_env_args} --rm --entrypoint='{command}' nautobot" pty = kwargs.pop("pty", True) @@ -494,7 +494,12 @@ def dbshell(context, db_name="", input_file="", output_file="", query=""): f"> '{output_file}'" if output_file else "", ] - docker_compose(context, " ".join(command), env=env, pty=not (input_file or output_file or query)) + docker_compose( + context, + " ".join(command), + env=env, + pty=not (input_file or output_file or query), + ) @task( @@ -649,28 +654,6 @@ def generate_release_notes(context, version=""): # ------------------------------------------------------------------------------ # TESTS # ------------------------------------------------------------------------------ -@task( - help={ - "autoformat": "Apply formatting recommendations automatically, rather than failing if formatting is incorrect.", - } -) -def black(context, autoformat=False): - """Check Python code style with Black.""" - if autoformat: - black_command = "black" - else: - black_command = "black --check --diff" - - command = f"{black_command} ." - - run_command(context, command) - - -@task -def flake8(context): - """Check for PEP8 compliance and other style issues.""" - command = "flake8 . --config .flake8" - run_command(context, command) @task @@ -692,38 +675,39 @@ def pylint(context): @task(aliases=("a",)) def autoformat(context): """Run code autoformatting.""" - black(context, autoformat=True) - ruff(context, fix=True) + ruff(context, action=["format"], fix=True) @task( help={ - "action": "One of 'lint', 'format', or 'both'", - "fix": "Automatically fix selected action. May not be able to fix all.", - "output_format": "see https://docs.astral.sh/ruff/settings/#output-format", + "action": "Available values are `['lint', 'format']`. Can be used multiple times. (default: `['lint', 'format']`)", + "target": "File or directory to inspect, repeatable (default: all files in the project will be inspected)", + "fix": "Automatically fix selected actions. May not be able to fix all issues found. (default: False)", + "output_format": "See https://docs.astral.sh/ruff/settings/#output-format for details. (default: `concise`)", }, + iterable=["action", "target"], ) -def ruff(context, action="lint", fix=False, output_format="full"): +def ruff(context, action=None, target=None, fix=False, output_format="concise"): """Run ruff to perform code formatting and/or linting.""" - if action != "lint": - command = "ruff format" - if not fix: - command += " --check" - command += " ." - run_command(context, command) - if action != "format": - command = "ruff check" - if fix: - command += " --fix" - command += f" --output-format {output_format} ." - run_command(context, command) + if not action: + action = ["lint", "format"] + if not target: + target = ["."] + if "format" in action: + command = "ruff format " + if not fix: + command += "--check " + command += " ".join(target) + run_command(context, command, warn=True) -@task -def bandit(context): - """Run bandit to validate basic static code security analysis.""" - command = "bandit --recursive . --configfile .bandit.yml" - run_command(context, command) + if "lint" in action: + command = "ruff check " + if fix: + command += "--fix " + command += f"--output-format {output_format} " + command += " ".join(target) + run_command(context, command, warn=True) @task @@ -755,7 +739,7 @@ def check_migrations(context): "verbose": "Enable verbose test output.", } ) -def unittest( +def unittest( # noqa: PLR0913 context, keepdb=False, label="nautobot_device_onboarding", @@ -805,14 +789,8 @@ def tests(context, failfast=False, keepdb=False, lint_only=False): print("Starting Docker Containers...") start(context) # Sorted loosely from fastest to slowest - print("Running black...") - black(context) print("Running ruff...") ruff(context) - print("Running flake8...") - flake8(context) - print("Running bandit...") - bandit(context) print("Running yamllint...") yamllint(context) print("Running poetry check...") @@ -845,11 +823,20 @@ def generate_app_config_schema(context): - `NautobotAppConfig.required_settings` """ start(context, service="nautobot") - nbshell(context, file="development/app_config_schema.py", env={"APP_CONFIG_SCHEMA_COMMAND": "generate"}) + nbshell( + context, + file="development/app_config_schema.py", + env={"APP_CONFIG_SCHEMA_COMMAND": "generate"}, + ) @task def validate_app_config(context): """Validate the app config based on the app config schema.""" start(context, service="nautobot") - nbshell(context, plain=True, file="development/app_config_schema.py", env={"APP_CONFIG_SCHEMA_COMMAND": "validate"}) + nbshell( + context, + plain=True, + file="development/app_config_schema.py", + env={"APP_CONFIG_SCHEMA_COMMAND": "validate"}, + )