Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Commit

Permalink
Merge pull request #102 from nautobot/release-v0.10.0
Browse files Browse the repository at this point in the history
Release v0.10.0
  • Loading branch information
chadell authored Jun 8, 2022
2 parents 33a081b + 830e09f commit 55c1115
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## v0.10.0 - 2022-06-08

### Added

- #100 - Add a Job option to select the reference snapshot to sync from.

## v0.9.6 - 2022-05-31

### Fixed
Expand Down
5 changes: 4 additions & 1 deletion development/creds.example.env
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ POSTGRES_USER=nautobot
REDIS_PASSWORD=notverysecurepwd
# NAUTOBOT_DB_HOST=localhost
# NAUTOBOT_REDIS_HOST=localhost
# NAUTOBOT_ROOT=./development
# NAUTOBOT_ROOT=./development

IPFABRIC_HOST=http://yoururl
IPFABRIC_API_TOKEN=secrettoken
2 changes: 1 addition & 1 deletion nautobot_ssot_ipfabric/diffsync/diffsync_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def update(self, attrs):
device_tags = _device.tags.filter(pk=safe_delete_tag.pk)
if device_tags.exists():
_device.tags.remove(safe_delete_tag)

# TODO: If only the "model" is changing, the "vendor" is not available
if attrs.get("model"):
device_type_object = tonb_nbutils.create_device_type_object(
device_type=attrs["model"], vendor_name=attrs["vendor"]
Expand Down
57 changes: 51 additions & 6 deletions nautobot_ssot_ipfabric/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
# pylint: disable=too-few-public-methods
# pylint: disable=too-many-locals
"""IP Fabric Data Target Job."""
import uuid
from diffsync.enum import DiffSyncFlags
from diffsync.exceptions import ObjectNotCreated
from django.conf import settings
from django.templatetags.static import static
from django.urls import reverse
from httpx import ConnectError
from ipfabric import IPFClient
from nautobot.dcim.models import Site
from nautobot.extras.jobs import BooleanVar, Job, ScriptVariable
from nautobot.extras.jobs import BooleanVar, Job, ScriptVariable, ChoiceVar
from nautobot.utilities.forms import DynamicModelChoiceField
from nautobot_ssot.jobs.base import DataMapping, DataSource

Expand All @@ -28,6 +30,15 @@
name = "SSoT - IPFabric" # pylint: disable=invalid-name


def is_valid_uuid(identifier):
"""Return true if the identifier it's a valid UUID."""
try:
uuid.UUID(str(identifier))
return True
except ValueError:
return False


class OptionalObjectVar(ScriptVariable):
"""Custom implementation of an Optional ObjectVar.
Expand Down Expand Up @@ -62,10 +73,24 @@ def __init__(
)


try:
CLIENT = IPFClient(
IPFABRIC_HOST,
token=IPFABRIC_API_TOKEN,
verify=IPFABRIC_SSL_VERIFY,
timeout=IPFABRIC_TIMEOUT,
)
snapshots = CLIENT.get_snapshots()
except ConnectError:
CLIENT = None
snapshots = []


# pylint:disable=too-few-public-methods
class IpFabricDataSource(DataSource, Job):
"""Job syncing data from IP Fabric to Nautobot."""

client = CLIENT
debug = BooleanVar(description="Enable for more verbose debug logging")
safe_delete_mode = BooleanVar(
description="Records are not deleted. Status fields are updated as necessary.",
Expand All @@ -82,6 +107,23 @@ class IpFabricDataSource(DataSource, Job):
model=Site,
required=False,
)
snapshot = ChoiceVar(
description="IPFabric snapshot to sync from. Defaults to $latest",
default="$last",
choices=[
(
snapshot_id,
snapshot_id
if not is_valid_uuid(snapshot_id)
else snapshots[snapshot_id].name
if snapshots[snapshot_id].name
else snapshot_id,
)
for snapshot_id in snapshots
if snapshots[snapshot_id].locked
],
required=False,
)

class Meta:
"""Metadata about this Job."""
Expand All @@ -92,6 +134,7 @@ class Meta:
description = "Sync data from IP Fabric into Nautobot."
field_order = (
"debug",
"snapshot",
"safe_delete_mode",
"sync_ipfabric_tagged_only",
"dry_run",
Expand Down Expand Up @@ -139,9 +182,11 @@ def load_target_adapter(self):

def sync_data(self):
"""Sync a device data from IP Fabric into Nautobot."""
client = IPFClient(
IPFABRIC_HOST, token=IPFABRIC_API_TOKEN, verify=IPFABRIC_SSL_VERIFY, timeout=IPFABRIC_TIMEOUT
)
if self.client is None:
self.log_failure(message="IPFabric client is not ready. Check your config.")
return

self.client.snapshot_id = self.kwargs["snapshot"]
dry_run = self.kwargs["dry_run"]
safe_mode = self.kwargs["safe_delete_mode"]
tagged_only = self.kwargs["sync_ipfabric_tagged_only"]
Expand All @@ -152,10 +197,10 @@ def sync_data(self):
site_filter_object = Site.objects.get(pk=site_filter)
else:
site_filter_object = None
options = f"`Debug`: {debug_mode}, `Dry Run`: {dry_run}, `Safe Delete Mode`: {safe_mode}, `Sync Tagged Only`: {tagged_only}, `Site Filter`: {site_filter_object}"
options = f"`Snapshot_id`: {self.client.snapshot_id}.`Debug`: {debug_mode}, `Dry Run`: {dry_run}, `Safe Delete Mode`: {safe_mode}, `Sync Tagged Only`: {tagged_only}, `Site Filter`: {site_filter_object}"
self.log_info(message=f"Starting job with the following options: {options}")

ipfabric_source = IPFabricDiffSync(job=self, sync=self.sync, client=client)
ipfabric_source = IPFabricDiffSync(job=self, sync=self.sync, client=self.client)
self.log_info(message="Loading current data from IP Fabric...")
ipfabric_source.load()

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "nautobot-ssot-ipfabric"
version = "0.9.6"
version = "0.10.0"
description = "Nautobot SSoT IPFabric"
authors = ["Network to Code, LLC <[email protected]>"]
license = "Apache-2.0"
Expand Down

0 comments on commit 55c1115

Please sign in to comment.