Skip to content

Commit 2375cd8

Browse files
authored
Merge pull request #128 from tobiasge/netbox-4.5
Compatibility with NetBox 4.5.*
2 parents bf4a0ca + 080d1b0 commit 2375cd8

18 files changed

Lines changed: 92 additions & 105 deletions

File tree

.github/workflows/linter.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,23 @@ jobs:
1717
# list of changed files within `super-linter`
1818
fetch-depth: 0
1919
- name: Lint Code Base
20-
uses: github/super-linter@v7
20+
uses: super-linter/super-linter@v8
2121
env:
2222
DEFAULT_BRANCH: main
2323
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2424
SUPPRESS_POSSUM: true
2525
VALIDATE_ALL_CODEBASE: false
2626
VALIDATE_CHECKOV: false
27+
VALIDATE_GITHUB_ACTIONS_ZIZMOR: false
28+
VALIDATE_GITLEAKS: false
2729
VALIDATE_JSCPD: false
2830
VALIDATE_PYTHON_BLACK: false
2931
VALIDATE_PYTHON_ISORT: false
3032
VALIDATE_PYTHON_MYPY: false
3133
VALIDATE_PYTHON_PYINK: false
3234
VALIDATE_PYTHON_PYLINT: false
35+
VALIDATE_PYTHON_RUFF_FORMAT: false
36+
VALIDATE_TRIVY: false
3337
LINTER_RULES_PATH: /
3438
FILTER_REGEX_EXCLUDE: (.*/)?(LICENSE)
3539
YAML_CONFIG_FILE: .yamllint.yaml

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ readme = "README.md"
1212
license = "Apache-2.0"
1313
dynamic = ["version"]
1414

15-
requires-python = ">=3.10"
15+
requires-python = ">=3.12"
1616
dependencies = ["ruamel-yaml>=0.18.10"]
1717

1818
[project.urls]
@@ -27,8 +27,8 @@ build-backend = "hatchling.build"
2727
[tool.hatch.version]
2828
path = "src/netbox_initializers/version.py"
2929

30-
[tool.uv]
31-
dev-dependencies = ["ruff==0.12"]
30+
[dependency-groups]
31+
dev = ["ruff==0.15.12"]
3232

3333
[tool.ruff]
3434
line-length = 100

src/netbox_initializers/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ class NetBoxInitializersConfig(PluginConfig):
99
description = "Load initial data into Netbox"
1010
version = VERSION
1111
base_url = "initializers"
12-
min_version = "4.4.0"
13-
max_version = "4.4.99"
12+
min_version = "4.5.0"
13+
max_version = "4.5.99"
1414

1515

1616
config = NetBoxInitializersConfig

src/netbox_initializers/initializers/base.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ def set_mac_addresses(self, entity, mac_addresses):
100100

101101
save = False
102102
for mac_address in MACAddress.objects.filter(mac_address__in=mac_addresses):
103-
104103
entity.mac_addresses.add(mac_address)
105104
save = True
106105

src/netbox_initializers/initializers/cables.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import Tuple
2+
23
from circuits.constants import CIRCUIT_TERMINATION_TERMINATION_TYPES
34
from circuits.models import Circuit, CircuitTermination
45
from dcim.models import (
@@ -61,8 +62,7 @@ def get_termination_object(params: dict, side: str):
6162
circuit_params["termination_id"] = scope_id
6263
else:
6364
raise ValueError(
64-
f"⚠️ Missing required parameter: 'scope'"
65-
f"for side {term_side} of circuit {circuit}"
65+
f"⚠️ Missing required parameter: 'scope'for side {term_side} of circuit {circuit}"
6666
)
6767

6868
termination, created = CircuitTermination.objects.get_or_create(

src/netbox_initializers/initializers/custom_fields.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1+
import importlib
2+
3+
from core.models import ObjectType
14
from extras.models import CustomField, CustomFieldChoiceSet
25

36
from netbox_initializers.initializers.base import BaseInitializer, register_initializer
47

58

69
def get_class_for_class_path(class_path):
7-
import importlib
8-
9-
from core.models import ObjectType
1010

1111
module_name, class_name = class_path.rsplit(".", 1)
1212
module = importlib.import_module(module_name)

src/netbox_initializers/initializers/device_types.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
DeviceBayTemplate,
88
FrontPortTemplate,
99
InterfaceTemplate,
10+
PortTemplateMapping,
1011
PowerOutletTemplate,
1112
PowerPortTemplate,
1213
RearPortTemplate,
@@ -129,6 +130,18 @@ def load_data(self):
129130
c_param[n_assoc] = n_model.objects.get(**n_query)
130131

131132
for new_param in expanded_c_params:
133+
# FrontPortTemplate: rear_port/rear_port_position moved to PortTemplateMapping
134+
port_mapping_params = {}
135+
if c_model is FrontPortTemplate:
136+
rear_port = new_param.pop("rear_port", None)
137+
if rear_port is not None:
138+
port_mapping_params = {
139+
"rear_port": rear_port,
140+
"rear_port_position": new_param.pop("rear_port_position", 1),
141+
"front_port_position": new_param.pop("front_port_position", 1),
142+
"device_type": device_type,
143+
}
144+
132145
new_matching_params, new_defaults = self.split_params(new_param, c_match_params)
133146
new_obj, new_obj_created = c_model.objects.get_or_create(
134147
**new_matching_params, defaults=new_defaults
@@ -138,5 +151,13 @@ def load_data(self):
138151
f"🧷 Created {c_model._meta} {new_obj} component for device type {device_type}"
139152
)
140153

154+
if port_mapping_params:
155+
front_port_position = port_mapping_params.pop("front_port_position")
156+
PortTemplateMapping.objects.get_or_create(
157+
front_port=new_obj,
158+
front_port_position=front_port_position,
159+
defaults=port_mapping_params,
160+
)
161+
141162

142163
register_initializer("device_types", DeviceTypeInitializer)

src/netbox_initializers/initializers/prefixes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ def load_data(self):
3030
params["prefix"] = IPNetwork(params["prefix"])
3131

3232
if scope := params.pop("scope"):
33-
params["scope_type"], params["scope_id"] = get_scope_details(scope, LOCATION_SCOPE_TYPES)
33+
params["scope_type"], params["scope_id"] = get_scope_details(
34+
scope, LOCATION_SCOPE_TYPES
35+
)
3436

3537
for assoc, details in OPTIONAL_ASSOCS.items():
3638
if assoc in params:

src/netbox_initializers/initializers/services.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from ipam.models import Service
21
from django.contrib.contenttypes.models import ContentType
2+
from ipam.models import Service
33

44
from netbox_initializers.initializers.base import BaseInitializer, register_initializer
55

@@ -19,9 +19,7 @@ def load_data(self):
1919
# Get model from Contenttype
2020
scope_type = params.pop("parent_type", None)
2121
if not scope_type:
22-
print(
23-
f"Services '{params['name']}': parent_type is missing from Services"
24-
)
22+
print(f"Services '{params['name']}': parent_type is missing from Services")
2523
app_label, model = str(scope_type).split(".")
2624
parent_model = ContentType.objects.get(app_label=app_label, model=model).model_class()
2725
parent = parent_model.objects.get(name=params.pop("parent_name"))

src/netbox_initializers/initializers/users.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ def load_data(self):
1313
return
1414

1515
for username, user_details in users.items():
16-
api_token = user_details.pop("api_token", Token.generate_key())
16+
token_data = user_details.pop("token", Token.generate_key())
1717
password = user_details.pop("password", get_random_string(length=25))
1818
user, created = User.objects.get_or_create(username=username, defaults=user_details)
1919
if created:
2020
user.set_password(password)
2121
user.save()
22-
if api_token:
23-
Token.objects.get_or_create(user=user, key=api_token)
22+
if token_data and "key" in token_data and "value" in token_data:
23+
Token.objects.create(
24+
user=user, key=token_data["key"], token=token_data["value"]
25+
)
2426
print("👤 Created user", username)
2527

2628

0 commit comments

Comments
 (0)