Skip to content

Commit

Permalink
Merge pull request #440 from nautobot/release-v2.6.1
Browse files Browse the repository at this point in the history
Release 2.6.1
  • Loading branch information
jdrew82 authored Apr 29, 2024
2 parents bd4aa05 + 1a40602 commit cd88356
Show file tree
Hide file tree
Showing 95 changed files with 2,554 additions and 1,860 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ jobs:
fail-fast: true
matrix:
python-version: ["3.11"]
nautobot-version: ["2.1.0"]
nautobot-version: ["2.2.1"]
env:
INVOKE_NAUTOBOT_SSOT_PYTHON_VER: "${{ matrix.python-version }}"
INVOKE_NAUTOBOT_SSOT_NAUTOBOT_VER: "${{ matrix.nautobot-version }}"
Expand Down Expand Up @@ -152,7 +152,7 @@ jobs:
include:
- python-version: "3.11"
db-backend: "postgresql"
nautobot-version: "2.1.0"
nautobot-version: "2.2.1"
- python-version: "3.11"
db-backend: "mysql"
nautobot-version: "stable"
Expand Down
1 change: 0 additions & 1 deletion changes/427.housekeeping

This file was deleted.

1 change: 1 addition & 0 deletions development/app_config_schema.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""App Config Schema Generator and Validator."""

import json
from importlib import import_module
from os import getenv
Expand Down
1 change: 1 addition & 0 deletions development/nautobot_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Nautobot development configuration file."""

import os
import sys

Expand Down
23 changes: 23 additions & 0 deletions docs/admin/release_notes/version_2.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,26 @@

- [#418](https://github.com/nautobot/nautobot-app-ssot/issues/418) - Unpins multiple dependencies.
- [#421](https://github.com/nautobot/nautobot-app-ssot/issues/421) - Opened prometheus-client dependency range and removed direct drf-spectacular dependency.

## [v2.6.1 (2024-04-29)](https://github.com/nautobot/nautobot-app-ssot/releases/tag/v2.6.1)

### Added

- [#436](https://github.com/nautobot/nautobot-app-ssot/issues/436) - Added additional unit tests for Device42 integration.

### Changed

- [#437](https://github.com/nautobot/nautobot-app-ssot/issues/437) - Improved performance of the Infoblox client by using `requests.Session` for API calls instead of `requests.request`.

### Fixed

- [#435](https://github.com/nautobot/nautobot-app-ssot/issues/435) - Fixed handling of DLM App installed but not enabled throwing RuntimeError.
- [#436](https://github.com/nautobot/nautobot-app-ssot/issues/436) - Fixed IPAddress attribute to be ip_version.
- [#436](https://github.com/nautobot/nautobot-app-ssot/issues/436) - Fixed IPAddress Status incorrectly being set to Reserved when the status in Device42 showed as "available".
- [#436](https://github.com/nautobot/nautobot-app-ssot/issues/436) - Fixed multiple bugs when assigning IPAddresses to Interfaces.
- [#436](https://github.com/nautobot/nautobot-app-ssot/issues/436) - Fixed check for Building definiton when creating a VLAN.
- [#436](https://github.com/nautobot/nautobot-app-ssot/issues/436) - Fixed VLAN to use location instead of location_id in create().

### Housekeeping

- [#431](https://github.com/nautobot/nautobot-app-ssot/issues/431) - Updated note on nautobot_ssot/integrations/ipfabric/diffsync/adapter_ipfabric.py IPFabricDiffSync from Nautobot to IPFabric.
1 change: 1 addition & 0 deletions nautobot_ssot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""App declaration for nautobot_ssot."""

import os
from importlib import metadata

Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/contrib/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""SSoT Contrib."""

from nautobot_ssot.contrib.adapter import NautobotAdapter
from nautobot_ssot.contrib.model import NautobotModel
from nautobot_ssot.contrib.types import (
Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/contrib/types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Contrib type classes for interfacing with Nautobot in SSoT."""

# pylint: disable=protected-access
# Diffsync relies on underscore-prefixed attributes quite heavily, which is why we disable this here.

Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/constant.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Constants for use with the ACI SSoT app."""

from django.conf import settings


Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/diffsync/adapters/aci.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""DiffSync Adapter for Cisco ACI.""" # pylint: disable=too-many-lines, too-many-instance-attributes, too-many-arguments

# pylint: disable=duplicate-code


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""DiffSync Adapter for Nautobot."""

# pylint: disable=duplicate-code

import logging
Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/diffsync/client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""All interactions with ACI.""" # pylint: disable=too-many-lines, too-many-instance-attributes, too-many-arguments

# pylint: disable=invalid-name

import sys
Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/diffsync/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Initialize models for Nautobot and ACI."""

from .nautobot import (
NautobotTenant,
NautobotVrf,
Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/diffsync/models/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Base Shared Models for Cisco ACI integration with SSoT app."""

from typing import List, Optional
from diffsync import DiffSyncModel

Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/diffsync/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""ACI Utilities."""

# pylint: disable=invalid-name
import logging
import re
Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/jobs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Jobs for ACI SSoT app."""

from django.templatetags.static import static
from django.urls import reverse
from diffsync import DiffSyncFlags
Expand Down
1 change: 1 addition & 0 deletions nautobot_ssot/integrations/aci/signals.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Signals for ACI integration."""

# pylint: disable=logging-fstring-interpolation, invalid-name
import logging
import random
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""DiffSync adapter for Arista CloudVision."""

import distutils
import ipaddress
import re
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""DiffSync adapter for Nautobot."""

from collections import defaultdict
from django.contrib.contenttypes.models import ContentType
from django.db.models import ProtectedError
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""DiffSyncModel subclasses for Nautobot-to-AristaCV data sync."""

from uuid import UUID
from diffsync import DiffSyncModel
from typing import List, Optional
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""CloudVision DiffSync models for AristaCV SSoT."""

from nautobot_ssot.integrations.aristacv.diffsync.models.base import (
Device,
CustomField,
Expand Down
13 changes: 11 additions & 2 deletions nautobot_ssot/integrations/aristacv/diffsync/models/nautobot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Nautobot DiffSync models for AristaCV SSoT."""

import logging
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from nautobot.core.settings_funcs import is_truthy
Expand Down Expand Up @@ -31,12 +33,19 @@
from nautobot_ssot.integrations.aristacv.types import CloudVisionAppConfig
from nautobot_ssot.integrations.aristacv.utils import nautobot

logger = logging.getLogger(__name__)

try:
from nautobot_device_lifecycle_mgmt.models import SoftwareLCM
from nautobot_device_lifecycle_mgmt.models import SoftwareLCM # noqa: F401 # pylint: disable=unused-import

LIFECYCLE_MGMT = True
except ImportError:
print("Device Lifecycle app isn't installed so will revert to CustomField for OS version.")
logger.info("Device Lifecycle app isn't installed so will revert to CustomField for OS version.")
LIFECYCLE_MGMT = False
except RuntimeError:
logger.warning(
"nautobot-device-lifecycle-mgmt is installed but not enabled. Did you forget to add it to your settings.PLUGINS?"
)
LIFECYCLE_MGMT = False

MISSING_CUSTOM_FIELDS = []
Expand Down
8 changes: 5 additions & 3 deletions nautobot_ssot/integrations/aristacv/utils/cloudvision.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,9 +665,11 @@ def get_ip_interfaces(client: CloudvisionApi, dId: str):
ip_intfs.append(
{
"interface": results["intfId"],
"address": results["addrWithMask"]
if results["addrWithMask"] != "0.0.0.0/0"
else results.get("virtualAddrWithMask"),
"address": (
results["addrWithMask"]
if results["addrWithMask"] != "0.0.0.0/0"
else results.get("virtualAddrWithMask")
),
}
)
return ip_intfs
Expand Down
12 changes: 8 additions & 4 deletions nautobot_ssot/integrations/aristacv/utils/nautobot.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,20 @@
from nautobot_ssot.integrations.aristacv import constants
from nautobot_ssot.integrations.aristacv.types import CloudVisionAppConfig

logger = logging.getLogger(__name__)

try:
from nautobot_device_lifecycle_mgmt.models import SoftwareLCM # noqa: F401 # pylint: disable=unused-import

LIFECYCLE_MGMT = True
except ImportError:
print("Device Lifecycle app isn't installed so will revert to CustomField for OS version.")
logger.info("Device Lifecycle app isn't installed so will revert to CustomField for OS version.")
LIFECYCLE_MGMT = False
except RuntimeError:
logger.warning(
"nautobot-device-lifecycle-mgmt is installed but not enabled. Did you forget to add it to your settings.PLUGINS?"
)
LIFECYCLE_MGMT = False


logger = logging.getLogger(__name__)


def _get_or_create_integration(integration_name: str, config: dict) -> ExternalIntegration:
Expand Down
56 changes: 35 additions & 21 deletions nautobot_ssot/integrations/device42/diffsync/adapters/device42.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,18 +468,26 @@ def load_vendor_and_model(self, hwmodel_name: str, manuf: str):
hwmodel = self.hardware(
name=hwmodel_name,
manufacturer=manuf,
size=float(round(self.d42_hardware_map[hwmodel_name]["size"]))
if self.d42_hardware_map.get(hwmodel_name) and self.d42_hardware_map[hwmodel_name].get("size")
else 1.0,
depth=self.d42_hardware_map[hwmodel_name]["depth"]
if self.d42_hardware_map.get(hwmodel_name) and self.d42_hardware_map[hwmodel_name].get("depth")
else "Half Depth",
part_number=self.d42_hardware_map[hwmodel_name]["part_no"]
if self.d42_hardware_map.get(hwmodel_name) and self.d42_hardware_map[hwmodel_name].get("part_no")
else "",
custom_fields=get_custom_field_dict(self.d42_hardware_map[hwmodel_name]["custom_fields"])
if self.d42_hardware_map.get(hwmodel_name)
else {},
size=(
float(round(self.d42_hardware_map[hwmodel_name]["size"]))
if self.d42_hardware_map.get(hwmodel_name) and self.d42_hardware_map[hwmodel_name].get("size")
else 1.0
),
depth=(
self.d42_hardware_map[hwmodel_name]["depth"]
if self.d42_hardware_map.get(hwmodel_name) and self.d42_hardware_map[hwmodel_name].get("depth")
else "Half Depth"
),
part_number=(
self.d42_hardware_map[hwmodel_name]["part_no"]
if self.d42_hardware_map.get(hwmodel_name) and self.d42_hardware_map[hwmodel_name].get("part_no")
else ""
),
custom_fields=(
get_custom_field_dict(self.d42_hardware_map[hwmodel_name]["custom_fields"])
if self.d42_hardware_map.get(hwmodel_name)
else {}
),
uuid=None,
)
self.add(hwmodel)
Expand Down Expand Up @@ -762,9 +770,11 @@ def load_connections(self):
continue
try:
new_conn = self.conn(
src_device=self.d42_device_map[_conn["second_src_device"]]["name"]
if _conn.get("second_src_device")
else self.d42_device_map[_conn["src_device"]]["name"],
src_device=(
self.d42_device_map[_conn["second_src_device"]]["name"]
if _conn.get("second_src_device")
else self.d42_device_map[_conn["src_device"]]["name"]
),
src_port=self.d42_port_map[_conn["src_port"]]["port"],
src_port_mac=self.d42_port_map[_conn["src_port"]]["hwaddress"],
src_type="interface",
Expand Down Expand Up @@ -839,9 +849,11 @@ def load_providers_and_circuits(self):
a_side_conn = self.conn(
src_device=origin_dev,
src_port=origin_int,
src_port_mac=self.d42_port_map[_tc["origin_netport_fk"]]["hwaddress"]
if _tc["origin_type"] == "Device"
else None,
src_port_mac=(
self.d42_port_map[_tc["origin_netport_fk"]]["hwaddress"]
if _tc["origin_type"] == "Device"
else None
),
src_type="interface" if _tc["origin_type"] == "Device Port" else "patch panel",
dst_device=_tc["circuit_id"],
dst_port=_tc["circuit_id"],
Expand All @@ -859,9 +871,11 @@ def load_providers_and_circuits(self):
src_type="circuit",
dst_device=endpoint_dev,
dst_port=endpoint_int,
dst_port_mac=self.d42_port_map[_tc["end_point_netport_fk"]]["hwaddress"]
if _tc["end_point_type"] == "Device"
else None,
dst_port_mac=(
self.d42_port_map[_tc["end_point_netport_fk"]]["hwaddress"]
if _tc["end_point_type"] == "Device"
else None
),
dst_type="interface" if _tc["end_point_type"] == "Device Port" else "patch panel",
src_port_mac=None,
tags=None,
Expand Down
14 changes: 11 additions & 3 deletions nautobot_ssot/integrations/device42/diffsync/adapters/nautobot.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""DiffSync adapter class for Nautobot as source-of-truth."""
from collections import defaultdict

from collections import defaultdict
import logging
from diffsync import DiffSync
from diffsync.exceptions import ObjectAlreadyExists, ObjectNotFound
from django.db.models import ProtectedError
Expand Down Expand Up @@ -28,12 +29,19 @@
from nautobot_ssot.integrations.device42.diffsync.models.nautobot import assets, circuits, dcim, ipam
from nautobot_ssot.integrations.device42.utils import nautobot

logger = logging.getLogger(__name__)

try:
import nautobot_device_lifecycle_mgmt # noqa: F401
from nautobot_device_lifecycle_mgmt.models import SoftwareLCM # noqa: F401 # pylint: disable=unused-import

LIFECYCLE_MGMT = True
except ImportError:
print("Device Lifecycle app isn't installed so will revert to CustomField for OS version.")
logger.info("Device Lifecycle app isn't installed so will revert to CustomField for OS version.")
LIFECYCLE_MGMT = False
except RuntimeError:
logger.warning(
"nautobot-device-lifecycle-mgmt is installed but not enabled. Did you forget to add it to your settings.PLUGINS?"
)
LIFECYCLE_MGMT = False


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def create(cls, diffsync, ids, attrs):
try:
patch_panel.validated_save()
diffsync.device_map[ids["name"]] = patch_panel.id
return super().create(ids=ids, diffsync=diffsync, attrs=attrs)
return super().create(diffsync, ids=ids, attrs=attrs)
except ValidationError as err:
if diffsync.job.debug:
diffsync.job.logger.warning(f"Unable to create {ids['name']} patch panel. {err}")
Expand Down Expand Up @@ -165,7 +165,7 @@ def create(cls, diffsync, ids, attrs):
if ids["patchpanel"] not in diffsync.rp_map:
diffsync.rp_map[ids["patchpanel"]] = {}
diffsync.rp_map[ids["patchpanel"]][ids["name"]] = rear_port.id
return super().create(ids=ids, diffsync=diffsync, attrs=attrs)
return super().create(diffsync, ids=ids, attrs=attrs)
except ValidationError as err:
if diffsync.job.debug:
diffsync.job.logger.debug(f"Unable to create patch panel {ids['name']}. {err}")
Expand Down Expand Up @@ -216,7 +216,7 @@ def create(cls, diffsync, ids, attrs):
if ids["patchpanel"] not in diffsync.fp_map:
diffsync.fp_map[ids["patchpanel"]] = {}
diffsync.fp_map[ids["patchpanel"]][ids["name"]] = front_port.id
return super().create(ids=ids, diffsync=diffsync, attrs=attrs)
return super().create(diffsync, ids=ids, attrs=attrs)
except ValidationError as err:
diffsync.job.logger.debug(f"Unable to create patch panel front port {ids['name']}. {err}")
return None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def create(cls, diffsync, ids, attrs):
try:
_provider.validated_save()
diffsync.provider_map[ids["name"]] = _provider.id
return super().create(ids=ids, diffsync=diffsync, attrs=attrs)
return super().create(diffsync, ids=ids, attrs=attrs)
except ValidationError as err:
if diffsync.job.debug:
diffsync.job.logger.warning(f"Unable to create {ids['name']} provider. {err}")
Expand Down Expand Up @@ -122,7 +122,7 @@ def create(cls, diffsync, ids, attrs):
term_side="Z",
circuit=_circuit,
)
return super().create(ids=ids, diffsync=diffsync, attrs=attrs)
return super().create(diffsync, ids=ids, attrs=attrs)

def update(self, attrs):
"""Update Circuit object in Nautobot."""
Expand Down
Loading

0 comments on commit cd88356

Please sign in to comment.