Skip to content

Commit bd4aa05

Browse files
authored
Merge pull request #429 from nautobot/develop
Release v2.6.0
2 parents fd32997 + a9c2123 commit bd4aa05

39 files changed

+1568
-635
lines changed

changes/427.housekeeping

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Created release for 2.6.0

development/run_example_job.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"""Executes a job locally for testing purposes.
2+
3+
To run this script use the following command:
4+
5+
```
6+
invoke nbshell \
7+
--plain \
8+
--file development/run_example_job.py \
9+
--env RUN_SSOT_TARGET_JOB=False \
10+
--env RUN_SSOT_JOB_DRY_RUN=True
11+
```
12+
13+
Passing environment variables to the script is optional. The script will default to running the data source job with a dry run enabled.
14+
"""
15+
16+
import json
17+
import os
18+
19+
from django.core.management import call_command
20+
from nautobot.core.settings_funcs import is_truthy
21+
from nautobot.extras.choices import SecretsGroupAccessTypeChoices
22+
from nautobot.extras.choices import SecretsGroupSecretTypeChoices
23+
from nautobot.extras.models import ExternalIntegration
24+
from nautobot.extras.models import Job
25+
from nautobot.extras.models import Secret
26+
from nautobot.extras.models import SecretsGroup
27+
from nautobot.extras.models import SecretsGroupAssociation
28+
29+
_TOKEN = 40 * "a"
30+
os.environ["NAUTOBOT_DEMO_TOKEN"] = _TOKEN
31+
32+
_NAUTOBOT_DEMO_URL = "https://demo.nautobot.com"
33+
_DRY_RUN = is_truthy(os.getenv("RUN_SSOT_JOB_DRY_RUN", "True"))
34+
35+
module_name = "nautobot_ssot.jobs.examples"
36+
is_target_job = is_truthy(os.getenv("RUN_SSOT_TARGET_JOB", "False"))
37+
job_class_name = "ExampleDataTarget" if is_target_job else "ExampleDataSource"
38+
39+
job = Job.objects.get(module_name=module_name, job_class_name=job_class_name)
40+
if not job.enabled:
41+
job.enabled = True
42+
job.validated_save()
43+
44+
nautobot_demo, created = ExternalIntegration.objects.get_or_create(
45+
name="Nautobot Demo",
46+
defaults={
47+
"remote_url": _NAUTOBOT_DEMO_URL,
48+
"verify_ssl": False,
49+
},
50+
)
51+
52+
if created:
53+
secret = Secret.objects.create(
54+
name="nautobot-demo-token",
55+
provider="environment-variable",
56+
parameters={"variable": "NAUTOBOT_DEMO_TOKEN"},
57+
)
58+
secrets_group = SecretsGroup.objects.create(name="Nautobot Demo Group")
59+
SecretsGroupAssociation.objects.create(
60+
secret=secret,
61+
secrets_group=secrets_group,
62+
access_type=SecretsGroupAccessTypeChoices.TYPE_HTTP,
63+
secret_type=SecretsGroupSecretTypeChoices.TYPE_TOKEN,
64+
)
65+
nautobot_demo.secrets_group = secrets_group
66+
nautobot_demo.validated_save()
67+
68+
data: dict = {
69+
"debug": True,
70+
"dryrun": _DRY_RUN,
71+
"memory_profiling": False,
72+
}
73+
74+
if is_target_job:
75+
data["target"] = str(nautobot_demo.pk)
76+
data["target_url"] = _NAUTOBOT_DEMO_URL
77+
data["target_token"] = _TOKEN
78+
else:
79+
data["source"] = str(nautobot_demo.pk)
80+
data["source_url"] = _NAUTOBOT_DEMO_URL
81+
data["source_token"] = _TOKEN
82+
83+
call_command(
84+
"runjob",
85+
f"{module_name}.{job_class_name}",
86+
data=json.dumps(data),
87+
username="admin",
88+
local=True, # Enable to run the job locally (not as a celery task)
89+
)

docs/admin/install.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ sudo systemctl restart nautobot nautobot-worker nautobot-scheduler
7979

8080
The app behavior can be controlled with the following list of settings:
8181

82-
| Key | Example | Default | Description |
83-
| ------------------- | ------- | ------- | ---------------------------------------------------------- |
84-
| `hide_example_jobs` | `True` | `False` | A boolean to represent whether or display the example job. |
82+
| Key | Example | Default | Description |
83+
| ------------------- | ------- | ------- | ----------------------------------------------------------------- |
84+
| `hide_example_jobs` | `True` | `False` | A boolean to represent whether or not to display the example job. |
8585

8686
## Integrations Configuration
8787

docs/admin/release_notes/version_1.6.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,58 @@
1717
- [161](https://github.com/nautobot/nautobot-app-ssot/pull/161) - Reverts ChatOps dependency removal by @snaselj
1818
- [213](https://github.com/nautobot/nautobot-app-ssot/pull/213) - fix: :bug: Several fixes in the ACI integration by @chadell
1919
- [205](https://github.com/nautobot/nautobot-app-ssot/pull/205) - Migrate PR #164 from Arista Child Repo by @qduk
20+
21+
## v1.6.1 - 2024-02-21
22+
23+
## Fixed
24+
25+
- [243](https://github.com/nautobot/nautobot-app-ssot/pull/243) - Fix Infoblox import_subnet for ltm-1.6 by @jdrew82
26+
- [261](https://github.com/nautobot/nautobot-app-ssot/pull/261) - Fix Device42 documentation. by @jdrew82
27+
28+
## Changed
29+
30+
- [245](https://github.com/nautobot/nautobot-app-ssot/pull/245) - IPFabric integration settings updates by @alhogan
31+
32+
- [357](https://github.com/nautobot/nautobot-app-ssot/pull/357) - Backport contrib changes to LTM by @Kircheneer
33+
- [361](https://github.com/nautobot/nautobot-app-ssot/pull/361) - Backport of #350 by @Kircheneer
34+
- [363](https://github.com/nautobot/nautobot-app-ssot/pull/363) - Backport #362 by @Kircheneer
35+
36+
## v1.6.2 - 2024-03-12
37+
38+
## Fixed
39+
40+
- [386](https://github.com/nautobot/nautobot-app-ssot/pull/386) - Fixes bug in backport of contrib custom relationship handling
41+
42+
## Changed
43+
44+
- [386](https://github.com/nautobot/nautobot-app-ssot/pull/386) - Improves error handling in contrib (backport of #374)
45+
- [373](https://github.com/nautobot/nautobot-app-ssot/pull/373) - Change contrib.NautobotModel.get_from_db to use a PK (backport of #371)
46+
47+
## v1.6.3 - 2024-03-20
48+
49+
## Fixed
50+
51+
- [396](https://github.com/nautobot/nautobot-app-ssot/pull/396) - Fix custom one-to-many relationships (backport of #393)
52+
- [396](https://github.com/nautobot/nautobot-app-ssot/pull/396) - Use `typing.get_args` in favor of accessing `__args__` directly (backport of #390)
53+
- [396](https://github.com/nautobot/nautobot-app-ssot/pull/396) - Fixed issue with generic relationships and `NautobotAdapter.load` (backport of #388)
54+
- [396](https://github.com/nautobot/nautobot-app-ssot/pull/396) - Allow foreign keys inside of many to many relationships (backport of #377)
55+
56+
## Housekeeping
57+
58+
- Replicate module and test module structure for contrib code in LTM branch
59+
60+
## v1.6.4 - 2024-04-16
61+
62+
## Fixed
63+
64+
- [243](https://github.com/nautobot/nautobot-app-ssot/pull/243) - Fix Infoblox import_subnet for ltm-1.6 by @jdrew82
65+
- [261](https://github.com/nautobot/nautobot-app-ssot/pull/261) - Fix Device42 documentation. by @jdrew82
66+
- [419](https://github.com/nautobot/nautobot-app-ssot/pull/419) - Fix Device42 Plugin Settings for LTM by @jdrew82
67+
68+
## Changed
69+
70+
- [245](https://github.com/nautobot/nautobot-app-ssot/pull/245) - IPFabric integration settings updates by @alhogan
71+
- [357](https://github.com/nautobot/nautobot-app-ssot/pull/357) - backport contrib changes to LTM by @Kircheneer
72+
- [361](https://github.com/nautobot/nautobot-app-ssot/pull/361) - Backport of #350 by @Kircheneer
73+
- [363](https://github.com/nautobot/nautobot-app-ssot/pull/363) - Backport #362 by @Kircheneer
74+
- [373](https://github.com/nautobot/nautobot-app-ssot/pull/373) - change contrib.NautobotModel.get_from_db to use a PK by @Kircheneer
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
# v2.6 Release Notes
3+
4+
## [v2.6.0 (2024-04-16)](https://github.com/nautobot/nautobot-app-ssot/releases/tag/v2.6.0)
5+
6+
### Added
7+
8+
- [#367](https://github.com/nautobot/nautobot-app-ssot/issues/367) - Added support of Roles, Platforms, Manufacturers, DeviceTypes, and Devices to example Jobs.
9+
10+
### Changed
11+
12+
- [#398](https://github.com/nautobot/nautobot-app-ssot/issues/398) - Changed Arista Cloud Vision jobs to optionally use ExternalIntegration.
13+
- [#414](https://github.com/nautobot/nautobot-app-ssot/issues/414) - Changed IPFabric interface media matching to fall back on interface names.
14+
15+
### Fixed
16+
17+
- [#367](https://github.com/nautobot/nautobot-app-ssot/issues/367) - Fixed issues with example Jobs.
18+
- [#407](https://github.com/nautobot/nautobot-app-ssot/issues/407) - Fixed logic check for 'hide_example_jobs' when defined, and also set to False.
19+
- [#409](https://github.com/nautobot/nautobot-app-ssot/issues/409) - Fixed tagging and custom field updates for Nautobot objects synced to/from Infoblox.
20+
- [#413](https://github.com/nautobot/nautobot-app-ssot/issues/413) - Fixed method of retrieving objects from IPFabric's technology categories.
21+
22+
### Housekeeping
23+
24+
- [#418](https://github.com/nautobot/nautobot-app-ssot/issues/418) - Unpins multiple dependencies.
25+
- [#421](https://github.com/nautobot/nautobot-app-ssot/issues/421) - Opened prometheus-client dependency range and removed direct drf-spectacular dependency.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ nav:
132132
- Compatibility Matrix: "admin/compatibility_matrix.md"
133133
- Release Notes:
134134
- "admin/release_notes/index.md"
135+
- v2.6: "admin/release_notes/version_2.6.md"
135136
- v2.5: "admin/release_notes/version_2.5.md"
136137
- v2.4: "admin/release_notes/version_2.4.md"
137138
- v2.3: "admin/release_notes/version_2.3.md"

nautobot_ssot/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class NautobotSSOTAppConfig(NautobotAppConfig):
7474
"aristacv_from_cloudvision_default_site": "",
7575
"aristacv_hostname_patterns": [],
7676
"aristacv_import_active": False,
77+
"aristacv_external_integration_name": "",
7778
"aristacv_role_mappings": {},
7879
"aristacv_site_mappings": {},
7980
"aristacv_verify": True,

nautobot_ssot/integrations/aristacv/constant.py renamed to nautobot_ssot/integrations/aristacv/constants.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
"""Storage of data that will not change throughout the life cycle of the application."""
22

3-
from django.conf import settings
4-
5-
6-
def _read_settings() -> dict:
7-
config = settings.PLUGINS_CONFIG["nautobot_ssot"]
8-
return config
9-
10-
11-
APP_SETTINGS = _read_settings()
3+
ARISTA_PLATFORM = "arista.eos.eos"
4+
CLOUDVISION_PLATFORM = "Arista EOS-CloudVision"
5+
DEFAULT_APPLY_IMPORT_TAG = False
6+
DEFAULT_CREATE_CONTROLLER = False
7+
DEFAULT_CVAAS_URL = "https://www.arista.io"
8+
DEFAULT_DELETE_DEVICES_ON_SYNC = False
9+
DEFAULT_DEVICE_ROLE = "network"
10+
DEFAULT_DEVICE_ROLE_COLOR = "ff0000"
11+
DEFAULT_DEVICE_STATUS = "cloudvision_imported"
12+
DEFAULT_DEVICE_STATUS_COLOR = "ff0000"
13+
DEFAULT_IMPORT_ACTIVE = False
14+
DEFAULT_SITE = "cloudvision_imported"
15+
DEFAULT_VERIFY_SSL = True
1216

1317
PORT_TYPE_MAP = {
1418
"xcvr1000BaseT": "1000base-t",
@@ -83,7 +87,3 @@ def _read_settings() -> dict:
8387
"400GBASE-2FR4": "400gbase-x-osfp",
8488
"400GBASE-ZR": "400gbase-x-qsfpdd",
8589
}
86-
87-
CLOUDVISION_PLATFORM = "Arista EOS-CloudVision"
88-
89-
ARISTA_PLATFORM = "arista.eos.eos"

nautobot_ssot/integrations/aristacv/diffsync/adapters/cloudvision.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from diffsync import DiffSync
88
from diffsync.exceptions import ObjectAlreadyExists, ObjectNotFound
99

10-
from nautobot_ssot.integrations.aristacv.constant import APP_SETTINGS
1110
from nautobot_ssot.integrations.aristacv.diffsync.models.cloudvision import (
1211
CloudvisionCustomField,
1312
CloudvisionDevice,
@@ -17,6 +16,7 @@
1716
CloudvisionIPAddress,
1817
CloudvisionIPAssignment,
1918
)
19+
from nautobot_ssot.integrations.aristacv.types import CloudVisionAppConfig
2020
from nautobot_ssot.integrations.aristacv.utils import cloudvision
2121

2222

@@ -41,8 +41,13 @@ def __init__(self, *args, job=None, conn: cloudvision.CloudvisionApi, **kwargs):
4141

4242
def load_devices(self):
4343
"""Load devices from CloudVision."""
44-
if APP_SETTINGS.get("aristacv_create_controller"):
45-
cvp_version = cloudvision.get_cvp_version()
44+
config: CloudVisionAppConfig = self.job.app_config
45+
if config.hostname_patterns and not (config.site_mappings and config.role_mappings):
46+
self.job.logger.warning(
47+
"Configuration found for aristacv_hostname_patterns but no aristacv_site_mappings or aristacv_role_mappings. Please ensure your mappings are defined."
48+
)
49+
if config.create_controller:
50+
cvp_version = cloudvision.get_cvp_version(config)
4651
cvp_ver_cf = self.cf(name="arista_eos", value=cvp_version, device_name="CloudVision")
4752
try:
4853
self.add(cvp_ver_cf)
@@ -258,10 +263,4 @@ def load_device_tags(self, device):
258263

259264
def load(self):
260265
"""Load devices and associated data from CloudVision."""
261-
if APP_SETTINGS.get("aristacv_hostname_patterns") and not (
262-
APP_SETTINGS.get("aristacv_site_mappings") and APP_SETTINGS.get("aristacv_role_mappings")
263-
):
264-
self.job.logger.warning(
265-
"Configuration found for aristacv_hostname_patterns but no aristacv_site_mappings or aristacv_role_mappings. Please ensure your mappings are defined."
266-
)
267266
self.load_devices()

nautobot_ssot/integrations/aristacv/diffsync/adapters/nautobot.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from diffsync import DiffSync
1212
from diffsync.exceptions import ObjectNotFound, ObjectAlreadyExists
1313

14-
from nautobot_ssot.integrations.aristacv.constant import APP_SETTINGS
1514
from nautobot_ssot.integrations.aristacv.diffsync.models.nautobot import (
1615
NautobotDevice,
1716
NautobotCustomField,
@@ -21,6 +20,7 @@
2120
NautobotIPAssignment,
2221
NautobotPort,
2322
)
23+
from nautobot_ssot.integrations.aristacv.types import CloudVisionAppConfig
2424
from nautobot_ssot.integrations.aristacv.utils import nautobot
2525

2626

@@ -166,8 +166,9 @@ def sync_complete(self, source: DiffSync, *args, **kwargs):
166166
self.job.logger.warning(f"Deletion failed for protected object: {nautobot_object}. {err}")
167167
self.objects_to_delete[grouping] = []
168168

169+
config: CloudVisionAppConfig = self.job.app_config # type: ignore
169170
# if Controller is created we need to ensure all imported Devices have RelationshipAssociation to it.
170-
if APP_SETTINGS.get("aristacv_create_controller"):
171+
if config.create_controller:
171172
self.job.logger.info("Creating Relationships between CloudVision and connected Devices.")
172173
controller_relation = OrmRelationship.objects.get(label="Controller -> Device")
173174
device_ct = ContentType.objects.get_for_model(OrmDevice)

0 commit comments

Comments
 (0)