Skip to content

Commit 04fdc42

Browse files
authored
fix: add backwards compatible support for mac_address field (#62)
* fix: add backwards compatible support for mac_address field
1 parent f21d283 commit 04fdc42

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed

Diff for: netbox_diode_plugin/api/views.py

+21
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,21 @@ def _handle_ipaddress_assigned_object(
472472
object_data["assigned_object_id"] = assigned_object_instance.id
473473
return None
474474

475+
def _handle_interface_mac_address_compat(self, instance, object_type: str, object_data: dict) -> Optional[Dict[str, Any]]:
476+
"""Handle interface mac address backward compatibility."""
477+
# TODO(ltucker): deprecate.
478+
if object_type != "dcim.interface" and object_type != "virtualization.vminterface":
479+
return None
480+
481+
if object_data.get("mac_address"):
482+
mac_address_value = object_data.pop("mac_address")
483+
mac_address_instance, _ = instance.mac_addresses.get_or_create(
484+
mac_address=mac_address_value,
485+
)
486+
instance.primary_mac_address = mac_address_instance
487+
instance.save()
488+
return None
489+
475490
def post(self, request, *args, **kwargs):
476491
"""
477492
Create a new change set and apply it to the current state.
@@ -533,6 +548,12 @@ def post(self, request, *args, **kwargs):
533548
serializer_errors.append(
534549
{"change_id": change_id, **errors_dict}
535550
)
551+
continue
552+
553+
errors = self._handle_interface_mac_address_compat(serializer.instance, object_type, object_data)
554+
if errors is not None:
555+
serializer_errors.append({"change_id": change_id, **errors})
556+
continue
536557
if len(serializer_errors) > 0:
537558
raise ApplyChangeSetException
538559
except ApplyChangeSetException:

Diff for: netbox_diode_plugin/tests/test_api_apply_change_set.py

+119-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,12 @@
1919
from rest_framework import status
2020
from users.models import Token
2121
from utilities.testing import APITestCase
22-
from virtualization.models import Cluster, ClusterType
22+
from virtualization.models import (
23+
Cluster,
24+
ClusterType,
25+
VirtualMachine,
26+
VMInterface,
27+
)
2328

2429
User = get_user_model()
2530

@@ -145,6 +150,12 @@ def setUp(self):
145150
)
146151
IPAddress.objects.bulk_create(self.ip_addresses)
147152

153+
self.virtual_machines = (
154+
VirtualMachine(name="Virtual Machine 1"),
155+
VirtualMachine(name="Virtual Machine 2"),
156+
)
157+
VirtualMachine.objects.bulk_create(self.virtual_machines)
158+
148159
self.url = "/netbox/api/plugins/diode/apply-change-set/"
149160

150161
def send_request(self, payload, status_code=status.HTTP_200_OK):
@@ -982,3 +993,110 @@ def test_add_primary_ip_address_to_device(self):
982993
self.assertEqual(response.json().get("result"), "success")
983994
self.assertEqual(device_updated.name, self.devices[0].name)
984995
self.assertEqual(device_updated.primary_ip4, self.ip_addresses[0])
996+
997+
def test_create_and_update_interface_with_compat_mac_address_field(self):
998+
"""Test create interface using backward compatible mac_address field."""
999+
payload = {
1000+
"change_set_id": str(uuid.uuid4()),
1001+
"change_set": [
1002+
{
1003+
"change_id": str(uuid.uuid4()),
1004+
"change_type": "create",
1005+
"object_version": None,
1006+
"object_type": "dcim.interface",
1007+
"object_id": None,
1008+
"data": {
1009+
"name": "Interface 6",
1010+
"type": "virtual",
1011+
"mac_address": "00:00:00:00:00:01",
1012+
"device": {
1013+
"id": self.devices[1].pk,
1014+
},
1015+
},
1016+
},
1017+
],
1018+
}
1019+
1020+
response = self.send_request(payload)
1021+
self.assertEqual(response.json().get("result"), "success")
1022+
self.assertEqual(Interface.objects.count(), 6)
1023+
interface_id = Interface.objects.order_by('-id').first().id
1024+
self.assertEqual(Interface.objects.get(id=interface_id).mac_address, "00:00:00:00:00:01")
1025+
1026+
payload = {
1027+
"change_set_id": str(uuid.uuid4()),
1028+
"change_set": [
1029+
{
1030+
"change_id": str(uuid.uuid4()),
1031+
"change_type": "update",
1032+
"object_version": None,
1033+
"object_type": "dcim.interface",
1034+
"object_id": interface_id,
1035+
"data": {
1036+
"name": "Interface 6",
1037+
"mac_address": "00:00:00:00:00:02",
1038+
"type": "virtual",
1039+
"device": {
1040+
"id": self.devices[1].pk,
1041+
},
1042+
},
1043+
},
1044+
],
1045+
}
1046+
response = self.send_request(payload)
1047+
self.assertEqual(response.json().get("result"), "success")
1048+
self.assertEqual(response.json().get("result"), "success")
1049+
self.assertEqual(Interface.objects.count(), 6)
1050+
self.assertEqual(Interface.objects.get(id=interface_id).mac_address, "00:00:00:00:00:02")
1051+
1052+
def test_create_and_update_vminterface_with_compat_mac_address_field(self):
1053+
"""Test create vminterface using backward compatible mac_address field."""
1054+
payload = {
1055+
"change_set_id": str(uuid.uuid4()),
1056+
"change_set": [
1057+
{
1058+
"change_id": str(uuid.uuid4()),
1059+
"change_type": "create",
1060+
"object_version": None,
1061+
"object_type": "virtualization.vminterface",
1062+
"object_id": None,
1063+
"data": {
1064+
"name": "VM Interface 1",
1065+
"mac_address": "00:00:00:00:00:01",
1066+
"virtual_machine": {
1067+
"id": self.virtual_machines[0].pk,
1068+
},
1069+
},
1070+
},
1071+
],
1072+
}
1073+
1074+
response = self.send_request(payload)
1075+
self.assertEqual(response.json().get("result"), "success")
1076+
self.assertEqual(VMInterface.objects.count(), 1)
1077+
interface_id = VMInterface.objects.order_by('-id').first().id
1078+
self.assertEqual(VMInterface.objects.get(id=interface_id).mac_address, "00:00:00:00:00:01")
1079+
1080+
payload = {
1081+
"change_set_id": str(uuid.uuid4()),
1082+
"change_set": [
1083+
{
1084+
"change_id": str(uuid.uuid4()),
1085+
"change_type": "update",
1086+
"object_version": None,
1087+
"object_type": "virtualization.vminterface",
1088+
"object_id": interface_id,
1089+
"data": {
1090+
"name": "VM Interface 1",
1091+
"mac_address": "00:00:00:00:00:02",
1092+
"virtual_machine": {
1093+
"id": self.virtual_machines[0].pk,
1094+
},
1095+
},
1096+
},
1097+
],
1098+
}
1099+
response = self.send_request(payload)
1100+
self.assertEqual(response.json().get("result"), "success")
1101+
self.assertEqual(VMInterface.objects.count(), 1)
1102+
self.assertEqual(VMInterface.objects.get(id=interface_id).mac_address, "00:00:00:00:00:02")

0 commit comments

Comments
 (0)