Skip to content

Commit 0160cb5

Browse files
committed
fix: add backwards compatible support for mac_address field
1 parent 440fe8b commit 0160cb5

File tree

2 files changed

+133
-1
lines changed

2 files changed

+133
-1
lines changed

Diff for: netbox_diode_plugin/api/views.py

+19
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,18 @@ def _handle_ipaddress_assigned_object(
472472
object_data["assigned_object_type"] = assigned_object_type
473473
object_data["assigned_object_id"] = assigned_object_instance.id
474474
return None
475+
476+
def _handle_interface_mac_address_compat(self, instance, object_type: str, object_data: dict) -> Optional[Dict[str, Any]]:
477+
"""Handle interface mac address backward compatibility"""
478+
# TODO(ltucker): deprecate.
479+
if object_data.get("mac_address"):
480+
mac_address_value = object_data.pop("mac_address")
481+
mac_address_instance, _ = instance.mac_addresses.get_or_create(
482+
mac_address=mac_address_value,
483+
)
484+
instance.primary_mac_address = mac_address_instance
485+
instance.save()
486+
return None
475487

476488
def post(self, request, *args, **kwargs):
477489
"""
@@ -534,6 +546,13 @@ def post(self, request, *args, **kwargs):
534546
serializer_errors.append(
535547
{"change_id": change_id, **errors_dict}
536548
)
549+
continue
550+
551+
if object_type == "dcim.interface" or object_type == "virtualization.vminterface":
552+
errors = self._handle_interface_mac_address_compat(serializer.instance, object_type, object_data)
553+
if errors is not None:
554+
serializer_errors.append({"change_id": change_id, **errors})
555+
continue
537556
if len(serializer_errors) > 0:
538557
raise ApplyChangeSetException
539558
except ApplyChangeSetException:

Diff for: netbox_diode_plugin/tests/test_api_apply_change_set.py

+114-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
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 Cluster, ClusterType, VMInterface, VirtualMachine
2323

2424
User = get_user_model()
2525

@@ -145,6 +145,12 @@ def setUp(self):
145145
)
146146
IPAddress.objects.bulk_create(self.ip_addresses)
147147

148+
self.virtual_machines = (
149+
VirtualMachine(name="Virtual Machine 1"),
150+
VirtualMachine(name="Virtual Machine 2"),
151+
)
152+
VirtualMachine.objects.bulk_create(self.virtual_machines)
153+
148154
self.url = "/netbox/api/plugins/diode/apply-change-set/"
149155

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

0 commit comments

Comments
 (0)