Skip to content

Commit 753aec8

Browse files
committed
refactor: Minor
1 parent 7e88f30 commit 753aec8

File tree

5 files changed

+53
-35
lines changed

5 files changed

+53
-35
lines changed
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
"""DiffSync adapter and model implementation for nautobot-netbox-importer."""
1+
"""DiffSync adapter and model implementation for nautobot-netbox-importer.
2+
3+
This folder is an importer implementation specific to NetBox, in opposite to `generator` folder, that is a generic Source => Nautobot importer.
4+
"""

nautobot_netbox_importer/diffsync/adapters/netbox.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,10 @@ def __init__(self, input_ref: _FileRef, options: NetBoxImporterOptions, job=None
9494
def load(self) -> None:
9595
"""Load data from NetBox."""
9696
self.import_data()
97+
9798
if self.options.fix_powerfeed_locations:
9899
fix_power_feed_locations(self)
100+
99101
if self.options.unrack_zero_uheight_devices:
100102
unrack_zero_uheight_devices(self)
101103

nautobot_netbox_importer/diffsync/models/base.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
"""NetBox to Nautobot Base Models Mapping."""
22

3-
from diffsync.enum import DiffSyncModelFlags
4-
5-
from nautobot_netbox_importer.base import RecordData
6-
from nautobot_netbox_importer.generator import DiffSyncBaseModel, SourceAdapter, SourceField, fields
3+
from nautobot_netbox_importer.generator import SourceAdapter, fields
74

85
from .locations import define_locations
96

107

118
def setup(adapter: SourceAdapter) -> None:
129
"""Map NetBox base models to Nautobot."""
13-
adapter.disable_model("sessions.session", "Nautobot has own sessions, sessions should never cross apps.")
1410
adapter.disable_model("admin.logentry", "Not directly used in Nautobot.")
15-
adapter.disable_model("users.userconfig", "May not have a 1 to 1 translation to Nautobot.")
1611
adapter.disable_model("auth.permission", "Handled via a Nautobot model and may not be a 1 to 1.")
17-
12+
adapter.disable_model("extras.imageattachment", "Images are not imported yet.")
13+
adapter.disable_model("sessions.session", "Nautobot has own sessions, sessions should never cross apps.")
14+
adapter.disable_model("users.userconfig", "May not have a 1 to 1 translation to Nautobot.")
1815

1916
adapter.configure_model(
2017
"extras.Status",

nautobot_netbox_importer/diffsync/models/dcim.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,7 @@
44
from uuid import UUID
55

66
from nautobot_netbox_importer.base import RecordData
7-
from nautobot_netbox_importer.generator import (
8-
DiffSyncBaseModel,
9-
PreImportRecordResult,
10-
SourceAdapter,
11-
SourceField,
12-
fields,
13-
)
7+
from nautobot_netbox_importer.generator import DiffSyncBaseModel, SourceAdapter, SourceField, fields
148

159
from .locations import define_location
1610

@@ -175,7 +169,7 @@ def fix_power_feed_locations(adapter: SourceAdapter) -> None:
175169
if not isinstance(location_uid, UUID):
176170
raise TypeError(f"Location UID must be UUID, got {type(location_uid)}")
177171

178-
target.location_id = location_uid
172+
target.location_id = location_uid # type: ignore[assignment]
179173
adapter.update(target)
180174

181175
# Need to update references, to properly update `content_types` fields

tasks.py

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -627,12 +627,16 @@ def import_db(context, db_name="", input_file="dump.sql"):
627627
@task(
628628
help={
629629
"db-name": "Database name to backup (default: Nautobot database)",
630+
"format": "Database dump format (default: `sql`)",
630631
"output-file": "Ouput file, overwrite if exists (default: `dump.sql`)",
631632
"readable": "Flag to dump database data in more readable format (default: `True`)",
632633
}
633634
)
634-
def backup_db(context, db_name="", output_file="dump.sql", readable=True):
635+
def backup_db(context, db_name="", format="sql", output_file="", readable=True):
635636
"""Dump database into `output_file` file from `db` container."""
637+
if not output_file:
638+
output_file = f"dump.{format}"
639+
636640
start(context, "db")
637641
_await_healthy_service(context, "db")
638642

@@ -651,6 +655,7 @@ def backup_db(context, db_name="", output_file="dump.sql", readable=True):
651655
"pg_dump",
652656
"--username=$POSTGRES_USER",
653657
f"--dbname={db_name or '$POSTGRES_DB'}",
658+
f"--format={format}",
654659
"--inserts" if readable else "",
655660
]
656661
else:
@@ -1037,8 +1042,9 @@ def validate_app_config(context):
10371042
@task(
10381043
help={
10391044
"file": "URL or path to the JSON file to import.",
1040-
"bypass-data-validation": "Bypass as much of Nautobot's internal data validation logic as possible, allowing the import of data from NetBox that would be rejected as invalid if entered as-is through the GUI or REST API. USE WITH CAUTION: it is generally more desirable to *take note* of any data validation errors, *correct* the invalid data in NetBox, and *re-import* with the corrected data! (default: False)",
10411045
"demo-version": "Version of the demo data to import from `https://github.com/netbox-community/netbox-demo-data/json` instead of using the `--file` option (default: empty).",
1046+
"test-input": "Version of the test data to import from `nautobot_netbox_importer/tests/fixtures/nautobot-v<value>` instead of using the `--file` option (default: empty).",
1047+
"bypass-data-validation": "Bypass as much of Nautobot's internal data validation logic as possible, allowing the import of data from NetBox that would be rejected as invalid if entered as-is through the GUI or REST API. USE WITH CAUTION: it is generally more desirable to *take note* of any data validation errors, *correct* the invalid data in NetBox, and *re-import* with the corrected data! (default: False)",
10421048
"create-missing-cable-terminations": "Create missing cable terminations as Nautobot requires both cable terminations to be defined to save cable instances.",
10431049
"customizations": "Path to a Python module containing customizations to apply during the import. (default: empty)",
10441050
"deduplicate-prefixes": "Deduplicate `ipam.prefix` and `ipam.aggregate` from NetBox. `prefix` value will be unique. (default: False)",
@@ -1048,61 +1054,77 @@ def validate_app_config(context):
10481054
"save-json-summary-path": "File path to write the JSON mapping to. (default: generated-mappings.json)",
10491055
"save-text-summary-path": "File path to write the text mapping to. (default: generated-mappings.txt)",
10501056
"sitegroup-parent-always-region": "When importing `dcim.sitegroup` to `dcim.locationtype`, always set the parent of a site group, to be a `Region` location type. This is a workaround to fix validation errors `'A Location of type Location may only have a Location of the same type as its parent.'`. (default: False)",
1051-
"update-paths": "Call management command `trace_paths` to update paths after the import. (default: False)",
1052-
"unrack-zero-uheight-devices": "Cleans the `position` field in `dcim.device` instances with `u_height == 0`. (default: True)",
10531057
"tag-issues": "If specified, tag records with any importer issues. (default: '')",
10541058
"trace-issues": "Show a detailed trace of issues originated from any `Exception` found during the import.",
1059+
"unrack-zero-uheight-devices": "Cleans the `position` field in `dcim.device` instances with `u_height == 0`. (default: True)",
1060+
"update-paths": "Call management command `trace_paths` to update paths after the import. (default: False)",
10551061
}
10561062
)
10571063
def import_netbox( # noqa: PLR0913
10581064
context,
10591065
file="",
10601066
demo_version="",
1061-
save_json_summary_path="",
1062-
save_text_summary_path="",
1067+
test_input="",
10631068
bypass_data_validation=False,
10641069
create_missing_cable_terminations=False,
10651070
customizations="",
10661071
deduplicate_prefixes=False,
10671072
dry_run=True,
10681073
fix_powerfeed_locations=False,
1069-
sitegroup_parent_always_region=False,
10701074
print_summary=True,
1071-
update_paths=False,
1072-
unrack_zero_uheight_devices=True,
1075+
save_json_summary_path="",
1076+
save_text_summary_path="",
1077+
sitegroup_parent_always_region=False,
10731078
tag_issues="",
10741079
trace_issues=False,
1080+
unrack_zero_uheight_devices=True,
1081+
update_paths=False,
10751082
):
10761083
"""Import NetBox data into Nautobot."""
1077-
if demo_version:
1078-
if file:
1079-
raise ValueError("Cannot specify both, `file` and `demo` arguments")
1084+
if sum(bool(x) for x in [file, demo_version, test_input]) > 1:
1085+
raise ValueError("Cannot specify more than one of `file`, `demo`, or `test_input` arguments")
10801086

1087+
if demo_version:
10811088
file = (
10821089
"https://raw.githubusercontent.com/netbox-community/netbox-demo-data/master/json/netbox-demo-v"
10831090
+ demo_version
10841091
+ ".json"
10851092
)
10861093

1094+
if test_input:
1095+
if is_truthy(context.nautobot_netbox_importer.local):
1096+
path = Path(__file__).parent
1097+
else:
1098+
path = Path('/source')
1099+
1100+
path = path / f"nautobot_netbox_importer/tests/fixtures/nautobot-v{test_input}"
1101+
1102+
file = path / "input.json"
1103+
1104+
if not save_json_summary_path:
1105+
save_json_summary_path = path / 'summary.json'
1106+
if not save_text_summary_path:
1107+
save_text_summary_path = path / 'summary.json'
1108+
10871109
command = [
10881110
"nautobot-server",
10891111
"import_netbox",
1090-
f"--save-json-summary-path={save_json_summary_path}" if save_json_summary_path else "",
1091-
f"--save-text-summary-path={save_text_summary_path}" if save_text_summary_path else "",
10921112
"--bypass-data-validation" if bypass_data_validation else "",
10931113
"--create-missing-cable-terminations" if create_missing_cable_terminations else "",
10941114
f"--customizations={customizations}" if customizations else "",
10951115
"--deduplicate-prefixes" if deduplicate_prefixes else "",
10961116
"--dry-run" if dry_run else "",
10971117
"--fix-powerfeed-locations" if fix_powerfeed_locations else "",
1098-
"--sitegroup-parent-always-region" if sitegroup_parent_always_region else "",
1099-
"--print-summary" if print_summary else "",
1100-
"--update-paths" if update_paths else "",
11011118
"--no-color",
1102-
"" if unrack_zero_uheight_devices else "--no-unrack-zero-uheight-devices",
1119+
"--print-summary" if print_summary else "",
1120+
"--sitegroup-parent-always-region" if sitegroup_parent_always_region else "",
1121+
f"--save-json-summary-path={save_json_summary_path}" if save_json_summary_path else "",
1122+
f"--save-text-summary-path={save_text_summary_path}" if save_text_summary_path else "",
11031123
f"--tag-issues={tag_issues}" if tag_issues else "",
11041124
"--trace-issues" if trace_issues else "",
1105-
file,
1125+
"" if unrack_zero_uheight_devices else "--no-unrack-zero-uheight-devices",
1126+
"--update-paths" if update_paths else "",
1127+
f"{file}",
11061128
]
11071129

11081130
run_command(context, " ".join(command))

0 commit comments

Comments
 (0)