pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/pheus/netbox-aci-plugin/commit/eb94843b81dcfe47cc84d37a686d357fa97b891a

/> feat(models): Add ACINode model and related tests · pheus/netbox-aci-plugin@eb94843 · GitHub
Skip to content

Commit eb94843

Browse files
committed
feat(models): Add ACINode model and related tests
Introduces the ACINode model to represent nodes within an ACI Fabric. Adds functionality for role and node type assignments, scoped validations, and TEP IP address handling. Includes comprehensive test cases and validation logic to ensure consistency and accuracy.
1 parent cc97b2f commit eb94843

File tree

7 files changed

+947
-7
lines changed

7 files changed

+947
-7
lines changed

netbox_aci_plugin/choices.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,42 @@ class ContractSubjectFilterPriorityChoices(ChoiceSet):
323323
)
324324

325325

326+
#
327+
# Node
328+
#
329+
330+
331+
class NodeRoleChoices(ChoiceSet):
332+
"""Choice set of Node roles."""
333+
334+
ROLE_LEAF = "leaf"
335+
ROLE_SPINE = "spine"
336+
ROLE_APIC = "apic"
337+
338+
CHOICES = (
339+
(ROLE_LEAF, _("Leaf"), "blue"),
340+
(ROLE_SPINE, _("Spine"), "teal"),
341+
(ROLE_APIC, _("APIC"), "purple"),
342+
)
343+
344+
345+
class NodeTypeChoices(ChoiceSet):
346+
"""Choice set of Node types."""
347+
348+
# default "unknown"
349+
TYPE_UNKNOWN = "unknown"
350+
TYPE_TIER_2_LEAF = "tier-2-leaf"
351+
TYPE_REMOTE_LEAF_WAN = "remote-leaf-wan"
352+
TYPE_VIRTUAL = "virtual"
353+
354+
CHOICES = (
355+
(TYPE_UNKNOWN, _("Unknown"), "gray"),
356+
(TYPE_TIER_2_LEAF, _("Tier 2 Leaf"), "blue"),
357+
(TYPE_REMOTE_LEAF_WAN, _("Remote Leaf WAN"), "teal"),
358+
(TYPE_VIRTUAL, _("Virtual"), "purple"),
359+
)
360+
361+
326362
#
327363
# Quality of Service (QoS)
328364
#

netbox_aci_plugin/constants.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
POD_ID_MIN = 1
2626
POD_ID_MAX = 255
2727

28+
NODE_ID_MIN = 1
29+
NODE_ID_MAX = 4000
2830

2931
#
3032
# Contract Relation
@@ -84,3 +86,13 @@
8486
)
8587
| Q(app_label="dcim", model="macaddress")
8688
)
89+
90+
#
91+
# Node
92+
#
93+
94+
# Node assignment to possible object types
95+
NODE_OBJECT_TYPES = Q(
96+
Q(app_label="dcim", model="device")
97+
| Q(app_label="virtualization", model="virtualmachine")
98+
)
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
import django.core.validators
2+
import django.db.models.deletion
3+
import netbox.models.deletion
4+
import taggit.managers
5+
import utilities.json
6+
from django.db import migrations, models
7+
8+
import netbox_aci_plugin.models.mixins
9+
10+
11+
class Migration(migrations.Migration):
12+
dependencies = [
13+
("netbox_aci_plugin", "0012_fabric_pod"),
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name="ACINode",
19+
fields=[
20+
(
21+
"id",
22+
models.BigAutoField(
23+
auto_created=True, primary_key=True, serialize=False
24+
),
25+
),
26+
("created", models.DateTimeField(auto_now_add=True, null=True)),
27+
("last_updated", models.DateTimeField(auto_now=True, null=True)),
28+
(
29+
"custom_field_data",
30+
models.JSONField(
31+
blank=True,
32+
default=dict,
33+
encoder=utilities.json.CustomFieldJSONEncoder,
34+
),
35+
),
36+
(
37+
"name",
38+
models.CharField(
39+
max_length=64,
40+
validators=[
41+
django.core.validators.RegexValidator(
42+
code="invalid",
43+
message="Only alphanumeric characters, periods, underscores, colons and hyphens are allowed.",
44+
regex="^[A-Za-z0-9_.:-]+$",
45+
)
46+
],
47+
),
48+
),
49+
(
50+
"name_alias",
51+
models.CharField(
52+
blank=True,
53+
max_length=64,
54+
validators=[
55+
django.core.validators.RegexValidator(
56+
code="invalid",
57+
message="Only alphanumeric characters, periods, underscores, colons and hyphens are allowed.",
58+
regex="^[A-Za-z0-9_.:-]*$",
59+
)
60+
],
61+
),
62+
),
63+
(
64+
"description",
65+
models.CharField(
66+
blank=True,
67+
max_length=128,
68+
validators=[
69+
django.core.validators.RegexValidator(
70+
code="invalid",
71+
message="Only alphanumeric characters and !#$%%()*,-./:;@ _{|}~?&+ are allowed.",
72+
regex="^[A-Za-z0-9!#$%()*,-./:;@ _{|}~?&+]*$",
73+
)
74+
],
75+
),
76+
),
77+
("comments", models.TextField(blank=True)),
78+
(
79+
"node_id",
80+
models.PositiveSmallIntegerField(
81+
validators=[
82+
django.core.validators.MinValueValidator(1),
83+
django.core.validators.MaxValueValidator(4000),
84+
]
85+
),
86+
),
87+
(
88+
"node_object_id",
89+
models.PositiveBigIntegerField(blank=True, null=True),
90+
),
91+
("role", models.CharField(default="leaf", max_length=6)),
92+
("node_type", models.CharField(default="unknown", max_length=16)),
93+
(
94+
"_device",
95+
models.ForeignKey(
96+
blank=True,
97+
null=True,
98+
on_delete=django.db.models.deletion.CASCADE,
99+
related_name="_aci_nodes",
100+
to="dcim.device",
101+
),
102+
),
103+
(
104+
"_virtual_machine",
105+
models.ForeignKey(
106+
blank=True,
107+
null=True,
108+
on_delete=django.db.models.deletion.CASCADE,
109+
related_name="_aci_nodes",
110+
to="virtualization.virtualmachine",
111+
),
112+
),
113+
(
114+
"aci_pod",
115+
models.ForeignKey(
116+
on_delete=django.db.models.deletion.PROTECT,
117+
related_name="aci_nodes",
118+
to="netbox_aci_plugin.acipod",
119+
),
120+
),
121+
(
122+
"nb_tenant",
123+
models.ForeignKey(
124+
blank=True,
125+
null=True,
126+
on_delete=django.db.models.deletion.SET_NULL,
127+
related_name="%(class)ss",
128+
to="tenancy.tenant",
129+
),
130+
),
131+
(
132+
"node_object_type",
133+
models.ForeignKey(
134+
blank=True,
135+
limit_choices_to=models.Q(
136+
models.Q(
137+
models.Q(("app_label", "dcim"), ("model", "device")),
138+
models.Q(
139+
("app_label", "virtualization"),
140+
("model", "virtualmachine"),
141+
),
142+
_connector="OR",
143+
)
144+
),
145+
null=True,
146+
on_delete=django.db.models.deletion.PROTECT,
147+
related_name="+",
148+
to="contenttypes.contenttype",
149+
),
150+
),
151+
(
152+
"tags",
153+
taggit.managers.TaggableManager(
154+
through="extras.TaggedItem", to="extras.Tag"
155+
),
156+
),
157+
(
158+
"tep_ip_address",
159+
models.ForeignKey(
160+
blank=True,
161+
null=True,
162+
on_delete=django.db.models.deletion.SET_NULL,
163+
related_name="aci_nodes",
164+
to="ipam.ipaddress",
165+
),
166+
),
167+
],
168+
options={
169+
"verbose_name": "ACI Node",
170+
"ordering": ("aci_pod", "node_id"),
171+
"constraints": [
172+
models.UniqueConstraint(
173+
fields=("aci_pod", "node_id"),
174+
name="netbox_aci_plugin_acinode_unique_nodeid_per_pod",
175+
),
176+
models.UniqueConstraint(
177+
fields=("aci_pod", "name"),
178+
name="netbox_aci_plugin_acinode_unique_nodename_per_pod",
179+
),
180+
models.UniqueConstraint(
181+
fields=("node_object_id", "node_object_type"),
182+
name="netbox_aci_plugin_acinode_unique_node_object",
183+
violation_error_message="ACI Node must be unique per ACI Fabric.",
184+
),
185+
],
186+
},
187+
bases=(
188+
netbox.models.deletion.DeleteMixin,
189+
models.Model,
190+
netbox_aci_plugin.models.mixins.UniqueGenericForeignKeyMixin,
191+
),
192+
),
193+
]

netbox_aci_plugin/models/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .fabric.fabrics import ACIFabric
2+
from .fabric.nodes import ACINode
23
from .fabric.pods import ACIPod
34
from .tenant.app_profiles import ACIAppProfile
45
from .tenant.bridge_domains import ACIBridgeDomain, ACIBridgeDomainSubnet
@@ -25,6 +26,7 @@
2526
__all__ = (
2627
# Fabric
2728
"ACIFabric",
29+
"ACINode",
2830
"ACIPod",
2931
# Tenant
3032
"ACIAppProfile",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy