diff --git a/django_netjsonconfig/migrations/0001_initial.py b/django_netjsonconfig/migrations/0001_initial.py index 1310aba..2745b99 100644 --- a/django_netjsonconfig/migrations/0001_initial.py +++ b/django_netjsonconfig/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9c1 on 2015-12-01 18:00 +# Generated by Django 1.9 on 2015-12-14 15:01 from __future__ import unicode_literals from django.db import migrations, models @@ -27,6 +27,7 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=63)), ('backend', models.CharField(choices=[('netjsonconfig.OpenWrt', 'OpenWRT'), ('netjsonconfig.OpenWisp', 'OpenWISP')], help_text='Select netjsonconfig backend', max_length=128, verbose_name='backend')), ('config', jsonfield.fields.JSONField(default=dict, help_text='configuration in NetJSON DeviceConfiguration format', verbose_name='configuration')), + ('key', models.CharField(db_index=True, help_text='unique key that will be used to build the download URL', max_length=64, unique=True)), ], options={ 'abstract': False, diff --git a/django_netjsonconfig/models/device.py b/django_netjsonconfig/models/device.py index 8c68329..1daa704 100644 --- a/django_netjsonconfig/models/device.py +++ b/django_netjsonconfig/models/device.py @@ -97,6 +97,10 @@ class BaseDevice(AbstractConfig): Abstract model implementing the NetJSON DeviceConfiguration object """ + key = models.CharField(max_length=64, unique=True, db_index=True, + help_text=_('unique key that will be used to ' + 'build the download URL')) + class Meta: abstract = True diff --git a/django_netjsonconfig/tests/test_device.py b/django_netjsonconfig/tests/test_device.py index a55e426..3596ab7 100644 --- a/django_netjsonconfig/tests/test_device.py +++ b/django_netjsonconfig/tests/test_device.py @@ -14,6 +14,7 @@ class TestDevice(TestCase): """ fixtures = ['test_templates'] maxDiff = None + TEST_KEY = '00:11:22:33:44:55' def test_str(self): d = Device(name='test') @@ -30,7 +31,10 @@ def test_backend_instance(self): def test_validation(self): config = {'interfaces': {'invalid': True}} - d = Device(name='test', backend='netjsonconfig.OpenWrt', config=config) + d = Device(name='test', + backend='netjsonconfig.OpenWrt', + config=config, + key=self.TEST_KEY) # ensure django ValidationError is raised with self.assertRaises(ValidationError): d.full_clean() @@ -40,7 +44,8 @@ def test_json(self): radio = Template.objects.get(name='radio0') d = Device(name='test', backend='netjsonconfig.OpenWrt', - config={'general':{'hostname':'json-test'}}) + config={'general':{'hostname':'json-test'}}, + key=self.TEST_KEY) d.full_clean() d.save() d.templates.add(dhcp) @@ -99,7 +104,7 @@ def test_m2m_validation(self): t = Template(name='files', **kwargs) t.full_clean() t.save() - d = Device(name='test', **kwargs) + d = Device(name='test', key=self.TEST_KEY, **kwargs) d.full_clean() d.save() with atomic(): diff --git a/django_netjsonconfig/tests/test_device_admin.py b/django_netjsonconfig/tests/test_device_admin.py index 31f15be..ec6ba8d 100644 --- a/django_netjsonconfig/tests/test_device_admin.py +++ b/django_netjsonconfig/tests/test_device_admin.py @@ -10,27 +10,29 @@ class TestDeviceAdmin(TestCase): """ fixtures = ['test_templates', 'test_users'] maxDiff = None + TEST_KEY = '00:11:22:33:44:55' def setUp(self): self.client.login(username='admin', password='tester') def test_clean_templates(self): t = Template.objects.first() - d = Device(name='test', backend=t.backend, config=t.config) + d = Device(name='test', backend=t.backend, config=t.config, key=self.TEST_KEY) d.full_clean() d.save() path = reverse('admin:django_netjsonconfig_device_change', args=[d.pk]) # ensure it fails with error - response = self.client.post(path, {'templates': str(t.pk)}) + response = self.client.post(path, {'templates': str(t.pk), 'key': self.TEST_KEY}) self.assertIn('errors field-templates', str(response.content)) # remove conflicting template and ensure doesn't error - response = self.client.post(path, {'templates': ''}) + response = self.client.post(path, {'templates': '', 'key': self.TEST_KEY}) self.assertNotIn('errors field-templates', str(response.content)) def test_download_config(self): d = Device(name='download', backend='netjsonconfig.OpenWrt', - config={'general':{'hostname':'device'}}) + config={'general':{'hostname':'device'}}, + key=self.TEST_KEY) d.full_clean() d.save() path = reverse('admin:django_netjsonconfig_device_download', args=[d.pk]) @@ -40,7 +42,8 @@ def test_download_config(self): def test_visualize_config(self): d = Device(name='download', backend='netjsonconfig.OpenWrt', - config={'general':{'hostname':'device'}}) + config={'general':{'hostname':'device'}}, + key=self.TEST_KEY) d.full_clean() d.save() path = reverse('admin:django_netjsonconfig_device_visualize', args=[d.pk])