netbox-interface-name-rules 1.1.2__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/PKG-INFO +7 -1
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/README.md +6 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/__init__.py +4 -1
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/api/serializers.py +17 -1
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/api/views.py +2 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/engine.py +417 -192
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/filters.py +7 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/forms.py +13 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/jobs.py +1 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/migrations/0009_interfacenamerule_enabled.py +19 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/migrations/0010_interfacenamerule_applies_to_device_interfaces.py +19 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/migrations/0011_remove_interfacenamerule_interfacenamerule_module_type_mode_check_and_more.py +39 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/migrations/0012_remove_interfacenamerule_interfacenamerule_unique_exact_and_more.py +39 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/models.py +68 -14
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/signals.py +241 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/tables.py +56 -2
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/tests/test_device_rules.py +285 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/tests/test_engine_advanced.py +680 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/tests/test_misc.py +466 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/tests/test_regex.py +10 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/tests/test_rules.py +26 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/tests/test_signals.py +258 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/tests/test_views.py +328 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/urls.py +1 -0
- netbox_interface_name_rules-1.2.0/netbox_interface_name_rules/utils.py +17 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/views.py +181 -107
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules.egg-info/PKG-INFO +7 -1
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules.egg-info/SOURCES.txt +10 -1
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/pyproject.toml +25 -2
- netbox_interface_name_rules-1.1.2/netbox_interface_name_rules/signals.py +0 -78
- netbox_interface_name_rules-1.1.2/netbox_interface_name_rules/utils.py +0 -19
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/LICENSE +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/api/__init__.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/api/urls.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0001_initial.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0002_regex_pattern_matching.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0003_constraints.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0004_nulls_distinct.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0005_platform.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0006_alter_interfacenamerule_options.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0007_alter_optional_fks_set_null.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/0008_constraint_nonempty_pattern.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/migrations/__init__.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/navigation.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/tests/__init__.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/tests/test_api.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/tests/test_e2e.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules/tests/test_engine.py +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules.egg-info/dependency_links.txt +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/netbox_interface_name_rules.egg-info/top_level.txt +0 -0
- {netbox_interface_name_rules-1.1.2 → netbox_interface_name_rules-1.2.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: netbox-interface-name-rules
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: NetBox plugin for automatic interface renaming when modules are installed
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -17,6 +17,7 @@ Dynamic: license-file
|
|
|
17
17
|
[](https://pypi.org/project/netbox-interface-name-rules/)
|
|
18
18
|
[](https://pypi.org/project/netbox-interface-name-rules/)
|
|
19
19
|
[](https://github.com/marcinpsk/netbox-InterfaceNameRules-plugin/actions/workflows/test.yaml)
|
|
20
|
+
[](https://marcinpsk.github.io/netbox-InterfaceNameRules-plugin/coverage/)
|
|
20
21
|
[](LICENSE)
|
|
21
22
|
[](https://pypi.org/project/netbox-interface-name-rules/)
|
|
22
23
|
[](https://github.com/netbox-community/netbox)
|
|
@@ -71,6 +72,11 @@ PLUGINS = ['netbox_interface_name_rules']
|
|
|
71
72
|
|
|
72
73
|
Apache 2.0
|
|
73
74
|
|
|
75
|
+
## Documentation
|
|
76
|
+
|
|
77
|
+
- [Full documentation](https://marcinpsk.github.io/netbox-InterfaceNameRules-plugin/) — installation, configuration, examples
|
|
78
|
+
- [DeepWiki](https://deepwiki.com/marcinpsk/netbox-InterfaceNameRules-plugin) — AI-generated codebase overview
|
|
79
|
+
|
|
74
80
|
## Contributing
|
|
75
81
|
|
|
76
82
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for how to submit code or interface name rules.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
[](https://pypi.org/project/netbox-interface-name-rules/)
|
|
4
4
|
[](https://pypi.org/project/netbox-interface-name-rules/)
|
|
5
5
|
[](https://github.com/marcinpsk/netbox-InterfaceNameRules-plugin/actions/workflows/test.yaml)
|
|
6
|
+
[](https://marcinpsk.github.io/netbox-InterfaceNameRules-plugin/coverage/)
|
|
6
7
|
[](LICENSE)
|
|
7
8
|
[](https://pypi.org/project/netbox-interface-name-rules/)
|
|
8
9
|
[](https://github.com/netbox-community/netbox)
|
|
@@ -57,6 +58,11 @@ PLUGINS = ['netbox_interface_name_rules']
|
|
|
57
58
|
|
|
58
59
|
Apache 2.0
|
|
59
60
|
|
|
61
|
+
## Documentation
|
|
62
|
+
|
|
63
|
+
- [Full documentation](https://marcinpsk.github.io/netbox-InterfaceNameRules-plugin/) — installation, configuration, examples
|
|
64
|
+
- [DeepWiki](https://deepwiki.com/marcinpsk/netbox-InterfaceNameRules-plugin) — AI-generated codebase overview
|
|
65
|
+
|
|
60
66
|
## Contributing
|
|
61
67
|
|
|
62
68
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for how to submit code or interface name rules.
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
# Copyright (C) 2025 Marcin Zieba <marcinpsk@gmail.com>
|
|
3
3
|
from netbox.plugins import PluginConfig
|
|
4
4
|
|
|
5
|
-
__version__ = "1.
|
|
5
|
+
__version__ = "1.2.0"
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class InterfaceNameRulesConfig(PluginConfig):
|
|
9
|
+
"""NetBox plugin configuration for Interface Name Rules."""
|
|
10
|
+
|
|
9
11
|
name = "netbox_interface_name_rules"
|
|
10
12
|
verbose_name = "Interface Name Rules"
|
|
11
13
|
description = "Automatic interface renaming when modules are installed into bays."
|
|
@@ -16,6 +18,7 @@ class InterfaceNameRulesConfig(PluginConfig):
|
|
|
16
18
|
default_settings = {}
|
|
17
19
|
|
|
18
20
|
def ready(self):
|
|
21
|
+
"""Connect signal handlers after all apps are loaded."""
|
|
19
22
|
super().ready()
|
|
20
23
|
from . import signals # noqa: F401 — registers post_save handler
|
|
21
24
|
|
|
@@ -24,18 +24,30 @@ class InterfaceNameRuleSerializer(NetBoxModelSerializer):
|
|
|
24
24
|
"channel_count",
|
|
25
25
|
"channel_start",
|
|
26
26
|
"description",
|
|
27
|
+
"enabled",
|
|
28
|
+
"applies_to_device_interfaces",
|
|
27
29
|
]
|
|
28
30
|
|
|
29
31
|
def validate(self, attrs):
|
|
32
|
+
"""Ensure module_type XOR module_type_pattern depending on regex mode."""
|
|
30
33
|
attrs = super().validate(attrs)
|
|
31
34
|
instance = self.instance
|
|
32
35
|
|
|
33
36
|
# For PATCH requests, fall back to existing instance values for fields not in attrs
|
|
37
|
+
is_device_level = attrs.get(
|
|
38
|
+
"applies_to_device_interfaces", getattr(instance, "applies_to_device_interfaces", False)
|
|
39
|
+
)
|
|
34
40
|
is_regex = attrs.get("module_type_is_regex", getattr(instance, "module_type_is_regex", False))
|
|
35
41
|
module_type = attrs.get("module_type", getattr(instance, "module_type", None))
|
|
36
42
|
pattern = attrs.get("module_type_pattern", getattr(instance, "module_type_pattern", ""))
|
|
37
43
|
|
|
38
|
-
if
|
|
44
|
+
if is_device_level:
|
|
45
|
+
# Device-level rules must not have a module_type FK
|
|
46
|
+
if module_type:
|
|
47
|
+
raise serializers.ValidationError(
|
|
48
|
+
{"module_type": "Module type must be empty for device-level interface rules."}
|
|
49
|
+
)
|
|
50
|
+
elif is_regex:
|
|
39
51
|
if not pattern:
|
|
40
52
|
raise serializers.ValidationError(
|
|
41
53
|
{"module_type_pattern": "Regex pattern is required when regex mode is enabled."}
|
|
@@ -49,4 +61,8 @@ class InterfaceNameRuleSerializer(NetBoxModelSerializer):
|
|
|
49
61
|
raise serializers.ValidationError(
|
|
50
62
|
{"module_type": "module_type is required when regex mode is disabled."}
|
|
51
63
|
)
|
|
64
|
+
if pattern:
|
|
65
|
+
raise serializers.ValidationError(
|
|
66
|
+
{"module_type_pattern": "Cannot set module_type_pattern when regex mode is disabled."}
|
|
67
|
+
)
|
|
52
68
|
return attrs
|