Skip to content

Commit 04a69b9

Browse files
committed
[fix] Allow updating templates with invalid configurations
Previously, fixing an invalid template configuration via the UI was blocked due to the cache invalidation mechanism. This mechanism attempted to evaluate the existing configuration, triggering a ValidationError and preventing updates.
1 parent 3a5643d commit 04a69b9

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

openwisp_controller/config/base/template.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from django.db import models, transaction
77
from django.utils.translation import gettext_lazy as _
88
from jsonfield import JSONField
9+
from netjsonconfig.exceptions import ValidationError as NetjsonconfigValidationError
910
from swapper import get_model_name
1011
from taggit.managers import TaggableManager
1112

@@ -115,7 +116,14 @@ def save(self, *args, **kwargs):
115116
if hasattr(self, 'backend_instance'):
116117
del self.backend_instance
117118
current = self.__class__.objects.get(pk=self.pk)
118-
update_related_config_status = self.checksum != current.checksum
119+
try:
120+
current_checksum = current.checksum
121+
except NetjsonconfigValidationError:
122+
# If the Netjsonconfig library upgrade changes the schema,
123+
# the old configuration may become invalid, raising an exception.
124+
# Setting the checksum to None forces related configurations to update.
125+
current_checksum = None
126+
update_related_config_status = self.checksum != current_checksum
119127
# save current changes
120128
super().save(*args, **kwargs)
121129
# update relations

openwisp_controller/config/tests/test_template.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from django.db import transaction
88
from django.test import TestCase, TransactionTestCase
99
from netjsonconfig import OpenWrt
10+
from netjsonconfig.exceptions import ValidationError as NetjsonconfigValidationError
1011
from swapper import load_model
1112

1213
from openwisp_utils.tests import catch_signal
@@ -733,3 +734,18 @@ def test_task_timeout(self, mocked_update_related_config_status):
733734
template.save()
734735
mocked_error.assert_called_once()
735736
mocked_update_related_config_status.assert_called_once()
737+
738+
def test_fixing_wrong_configuration(self):
739+
template = self._create_template()
740+
# create a wrong configuration
741+
Template.objects.update(config={'interfaces': [{'name': 'eth0', 'type': ''}]})
742+
# Ensure the configuration raises ValidationError
743+
with self.assertRaises(NetjsonconfigValidationError):
744+
template.refresh_from_db()
745+
del template.backend_instance
746+
template.checksum
747+
748+
del template.backend_instance
749+
template.config = {'interfaces': [{'name': 'eth0', 'type': 'ethernet'}]}
750+
template.full_clean()
751+
template.save()

0 commit comments

Comments
 (0)