Skip to content

Commit

Permalink
[fix] Allow updating templates with invalid configurations
Browse files Browse the repository at this point in the history
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.

(cherry picked from commit bd3d11a)
  • Loading branch information
pandafy committed Dec 4, 2024
1 parent 00cb542 commit bd44dd1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
10 changes: 9 additions & 1 deletion openwisp_controller/config/base/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from django.db import models, transaction
from django.utils.translation import gettext_lazy as _
from jsonfield import JSONField
from netjsonconfig.exceptions import ValidationError as NetjsonconfigValidationError
from swapper import get_model_name
from taggit.managers import TaggableManager

Expand Down Expand Up @@ -115,7 +116,14 @@ def save(self, *args, **kwargs):
if hasattr(self, 'backend_instance'):
del self.backend_instance
current = self.__class__.objects.get(pk=self.pk)
update_related_config_status = self.checksum != current.checksum
try:
current_checksum = current.checksum
except NetjsonconfigValidationError:
# If the Netjsonconfig library upgrade changes the schema,
# the old configuration may become invalid, raising an exception.
# Setting the checksum to None forces related configurations to update.
current_checksum = None
update_related_config_status = self.checksum != current_checksum
# save current changes
super().save(*args, **kwargs)
# update relations
Expand Down
16 changes: 16 additions & 0 deletions openwisp_controller/config/tests/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.db import transaction
from django.test import TestCase, TransactionTestCase
from netjsonconfig import OpenWrt
from netjsonconfig.exceptions import ValidationError as NetjsonconfigValidationError
from swapper import load_model

from openwisp_utils.tests import catch_signal
Expand Down Expand Up @@ -733,3 +734,18 @@ def test_task_timeout(self, mocked_update_related_config_status):
template.save()
mocked_error.assert_called_once()
mocked_update_related_config_status.assert_called_once()

def test_fixing_wrong_configuration(self):
template = self._create_template()
# create a wrong configuration
Template.objects.update(config={'interfaces': [{'name': 'eth0', 'type': ''}]})
# Ensure the configuration raises ValidationError
with self.assertRaises(NetjsonconfigValidationError):
template.refresh_from_db()
del template.backend_instance
template.checksum

del template.backend_instance
template.config = {'interfaces': [{'name': 'eth0', 'type': 'ethernet'}]}
template.full_clean()
template.save()

0 comments on commit bd44dd1

Please sign in to comment.