openwisp-controller 1.1__tar.gz → 1.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (327) hide show
  1. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/CHANGES.rst +59 -7
  2. {openwisp_controller-1.1/openwisp_controller.egg-info → openwisp_controller-1.1.2}/PKG-INFO +30 -17
  3. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/README.rst +16 -15
  4. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/__init__.py +1 -1
  5. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/admin.py +50 -18
  6. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/views.py +4 -0
  7. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/apps.py +27 -1
  8. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/base.py +79 -1
  9. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/config.py +103 -50
  10. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/device.py +1 -0
  11. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/template.py +23 -14
  12. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/vpn.py +9 -7
  13. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/controller/views.py +37 -6
  14. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/handlers.py +2 -2
  15. openwisp_controller-1.1.2/openwisp_controller/config/static/config/css/device-delete-confirmation.css +11 -0
  16. openwisp_controller-1.1.2/openwisp_controller/config/static/config/js/device-delete-confirmation.js +12 -0
  17. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tasks.py +31 -2
  18. openwisp_controller-1.1.2/openwisp_controller/config/templates/admin/config/device/delete_confirmation.html +81 -0
  19. openwisp_controller-1.1.2/openwisp_controller/config/templates/admin/config/device/delete_selected_confirmation.html +87 -0
  20. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_admin.py +266 -10
  21. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_api.py +86 -0
  22. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_config.py +65 -5
  23. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_controller.py +92 -12
  24. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_device.py +8 -0
  25. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_handlers.py +1 -1
  26. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_selenium.py +74 -0
  27. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_template.py +15 -0
  28. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_vpn.py +55 -14
  29. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/utils.py +1 -1
  30. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/utils.py +2 -1
  31. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/validators.py +4 -4
  32. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/admin.py +9 -1
  33. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/api/serializer.py +13 -0
  34. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/base/models.py +30 -8
  35. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/channels/consumers.py +4 -2
  36. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/commands.py +1 -1
  37. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/openwrt/ssh.py +5 -2
  38. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/pytest.py +42 -9
  39. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_api.py +38 -2
  40. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_models.py +18 -3
  41. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/admin.py +34 -1
  42. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/views.py +2 -3
  43. openwisp_controller-1.1.2/openwisp_controller/geo/static/leaflet/draw/leaflet.draw.i18n.js +116 -0
  44. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_api.py +48 -18
  45. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/utils.py +7 -0
  46. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/utils.py +5 -5
  47. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/mixins.py +2 -2
  48. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/admin.py +1 -1
  49. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/test_selenium.py +20 -5
  50. {openwisp_controller-1.1 → openwisp_controller-1.1.2/openwisp_controller.egg-info}/PKG-INFO +30 -17
  51. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/SOURCES.txt +4 -0
  52. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/pyproject.toml +1 -1
  53. openwisp_controller-1.1/openwisp_controller/config/templates/admin/config/device/delete_selected_confirmation.html +0 -36
  54. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/LICENSE +0 -0
  55. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/MANIFEST.in +0 -0
  56. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/admin.py +0 -0
  57. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/base.py +0 -0
  58. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/checks.py +0 -0
  59. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/__init__.py +0 -0
  60. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/__init__.py +0 -0
  61. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/download_views.py +0 -0
  62. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/filters.py +0 -0
  63. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/serializers.py +0 -0
  64. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/urls.py +0 -0
  65. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/zerotier_service.py +0 -0
  66. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/__init__.py +0 -0
  67. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/channels_consumer.py +0 -0
  68. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/device_group.py +0 -0
  69. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/multitenancy.py +0 -0
  70. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/tag.py +0 -0
  71. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/controller/__init__.py +0 -0
  72. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/controller/urls.py +0 -0
  73. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/crypto.py +0 -0
  74. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/exceptions.py +0 -0
  75. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/exportable.py +0 -0
  76. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/filters.py +0 -0
  77. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/fixtures/test_templates.json +0 -0
  78. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0001_squashed_0002_config_settings_uuid.py +0 -0
  79. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0003_template_tags.py +0 -0
  80. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0004_add_device_model.py +0 -0
  81. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0005_populate_device.py +0 -0
  82. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0006_config_device_not_null.py +0 -0
  83. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0007_simplify_config.py +0 -0
  84. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0008_update_indexes.py +0 -0
  85. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0009_device_system.py +0 -0
  86. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0010_auto_20180106_1814.py +0 -0
  87. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0011_update_device_mac_address.py +0 -0
  88. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0012_auto_20180219_1501.py +0 -0
  89. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0013_last_ip_management_ip_and_status_applied.py +0 -0
  90. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0014_device_hardware_id.py +0 -0
  91. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0015_default_groups_permissions.py +0 -0
  92. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0016_default_organization_config_settings.py +0 -0
  93. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0017_template_name_organization_unique_together.py +0 -0
  94. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0018_config_context.py +0 -0
  95. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0019_organization_mac_add_hardware_id_name_unique_together.py +0 -0
  96. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0020_remove_config_organization.py +0 -0
  97. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0021_vpn_key.py +0 -0
  98. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0022_vpn_format_dh.py +0 -0
  99. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0023_update_context.py +0 -0
  100. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0024_update_context_data.py +0 -0
  101. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0025_update_device_key.py +0 -0
  102. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0026_hardware_id_not_unique.py +0 -0
  103. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0027_add_indexes_on_ip_fields.py +0 -0
  104. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0028_template_default_values.py +0 -0
  105. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0029_merge_django_netjsonconfig.py +0 -0
  106. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0030_django_taggit_update.py +0 -0
  107. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0031_update_vpn_dh_param.py +0 -0
  108. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0032_update_legacy_vpn_backend.py +0 -0
  109. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0033_name_unique_per_organization.py +0 -0
  110. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0034_template_required.py +0 -0
  111. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0035_device_name_unique_optional.py +0 -0
  112. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0036_device_group.py +0 -0
  113. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0037_alter_taggedtemplate.py +0 -0
  114. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0038_vpn_subnet.py +0 -0
  115. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0039_wireguard_vxlan_ipam.py +0 -0
  116. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0040_vpnclient_ip_setnull.py +0 -0
  117. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0041_default_groups_organizationconfigsettings_permission.py +0 -0
  118. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0042_multiple_wireguard_tunnels.py +0 -0
  119. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0043_devicegroup_templates.py +0 -0
  120. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0044_config_error_reason.py +0 -0
  121. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0045_alter_vpn_webhook_endpoint.py +0 -0
  122. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0046_organizationlimits.py +0 -0
  123. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0047_add_organizationlimits.py +0 -0
  124. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0048_wifi_radio_band_migration.py +0 -0
  125. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0049_devicegroup_context.py +0 -0
  126. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0050_alter_vpnclient_unique_together.py +0 -0
  127. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0051_organizationconfigsettings_context.py +0 -0
  128. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0052_vpn_node_network_id.py +0 -0
  129. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0053_vpnclient_secret.py +0 -0
  130. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0054_device__is_deactivated.py +0 -0
  131. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0055_alter_config_status.py +0 -0
  132. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/__init__.py +0 -0
  133. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/models.py +0 -0
  134. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/settings.py +0 -0
  135. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/signals.py +0 -0
  136. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/sortedm2m/__init__.py +0 -0
  137. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/sortedm2m/fields.py +0 -0
  138. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/sortedm2m/forms.py +0 -0
  139. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/admin.css +0 -0
  140. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/devicegroup.css +0 -0
  141. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/lib/advanced-mode.css +0 -0
  142. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/lib/img/jsoneditor-icons.svg +0 -0
  143. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/lib/jsonschema-ui.css +0 -0
  144. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/lib/advanced-mode.js +0 -0
  145. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/lib/jsonschema-ui.js +0 -0
  146. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/lib/tomorrow_night_bright.js +0 -0
  147. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/management_ip.js +0 -0
  148. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/preview.js +0 -0
  149. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/relevant_templates.js +0 -0
  150. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/switcher.js +0 -0
  151. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/tabs.js +0 -0
  152. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/unsaved_changes.js +0 -0
  153. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/utils.js +0 -0
  154. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/vpn.js +0 -0
  155. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/widget.js +0 -0
  156. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/import_export/import-openwisp.css +0 -0
  157. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/sortedm2m/patch_sortedm2m.js +0 -0
  158. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/support.css +0 -0
  159. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tasks_zerotier.py +0 -0
  160. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/change_device_group.html +0 -0
  161. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/change_form.html +0 -0
  162. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/change_list_device.html +0 -0
  163. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/clone_template_form.html +0 -0
  164. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/device/change_form.html +0 -0
  165. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/device_recover_form.html +0 -0
  166. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/jsonschema-widget.html +0 -0
  167. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/preview.html +0 -0
  168. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/system_context.html +0 -0
  169. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/device_group/change_form.html +0 -0
  170. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/import_export/import.html +0 -0
  171. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/reversion/config/revision_form.html +0 -0
  172. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/__init__.py +0 -0
  173. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/pytest.py +0 -0
  174. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_apps.py +0 -0
  175. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_device_group.py +0 -0
  176. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_notifications.py +0 -0
  177. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_tag.py +0 -0
  178. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_views.py +0 -0
  179. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/urls.py +0 -0
  180. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/views.py +0 -0
  181. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/widgets.py +0 -0
  182. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/__init__.py +0 -0
  183. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/api/urls.py +0 -0
  184. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/api/views.py +0 -0
  185. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/apps.py +0 -0
  186. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/base/__init__.py +0 -0
  187. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/channels/routing.py +0 -0
  188. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/__init__.py +0 -0
  189. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/airos/snmp.py +0 -0
  190. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/exceptions.py +0 -0
  191. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/openwrt/__init__.py +0 -0
  192. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/openwrt/snmp.py +0 -0
  193. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/snmp.py +0 -0
  194. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/ssh.py +0 -0
  195. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/exceptions.py +0 -0
  196. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0001_initial.py +0 -0
  197. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0002_credentials_auto_add.py +0 -0
  198. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0003_default_group_permissions.py +0 -0
  199. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0004_django3_1_upgrade.py +0 -0
  200. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0005_device_connection_failure_reason.py +0 -0
  201. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0006_name_unique_per_organization.py +0 -0
  202. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0007_command.py +0 -0
  203. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0008_remove_conflicting_deviceconnections.py +0 -0
  204. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0009_alter_deviceconnection_unique_together.py +0 -0
  205. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/__init__.py +0 -0
  206. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/models.py +0 -0
  207. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/schema.py +0 -0
  208. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/settings.py +0 -0
  209. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/signals.py +0 -0
  210. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/css/command-inline.css +0 -0
  211. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/css/credentials.css +0 -0
  212. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/js/commands.js +0 -0
  213. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/js/credentials.js +0 -0
  214. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/js/lib/reconnecting-websocket.min.js +0 -0
  215. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tasks.py +0 -0
  216. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/__init__.py +0 -0
  217. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/base.py +0 -0
  218. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test-key.ed25519 +0 -0
  219. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test-key.rsa +0 -0
  220. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_admin.py +0 -0
  221. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_command_utilities.py +0 -0
  222. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_notifications.py +0 -0
  223. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_selenium.py +0 -0
  224. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_snmp.py +0 -0
  225. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_ssh.py +0 -0
  226. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_tasks.py +0 -0
  227. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/utils.py +0 -0
  228. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/utils.py +0 -0
  229. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/widgets.py +0 -0
  230. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/context_processors.py +0 -0
  231. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/__init__.py +0 -0
  232. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/__init__.py +0 -0
  233. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/filters.py +0 -0
  234. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/serializers.py +0 -0
  235. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/urls.py +0 -0
  236. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/apps.py +0 -0
  237. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/base/__init__.py +0 -0
  238. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/base/models.py +0 -0
  239. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/channels/__init__.py +0 -0
  240. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/channels/consumers.py +0 -0
  241. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/channels/routing.py +0 -0
  242. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/exportable.py +0 -0
  243. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/0001_initial.py +0 -0
  244. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/0002_default_groups_permissions.py +0 -0
  245. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/0003_alter_devicelocation_floorplan_location.py +0 -0
  246. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/__init__.py +0 -0
  247. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/models.py +0 -0
  248. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/templates/admin/widgets/foreign_key_raw_id.html +0 -0
  249. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/__init__.py +0 -0
  250. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/pytest.py +0 -0
  251. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_admin.py +0 -0
  252. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_admin_inline.py +0 -0
  253. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_apps.py +0 -0
  254. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_models.py +0 -0
  255. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/migrations.py +0 -0
  256. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/__init__.py +0 -0
  257. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/admin.py +0 -0
  258. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/api/serializers.py +0 -0
  259. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/api/urls.py +0 -0
  260. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/api/views.py +0 -0
  261. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/apps.py +0 -0
  262. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/base/__init__.py +0 -0
  263. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/base/models.py +0 -0
  264. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0001_initial.py +0 -0
  265. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0002_add_organization_name.py +0 -0
  266. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0003_fill_organization_name.py +0 -0
  267. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0004_auto_20180106_1814.py +0 -0
  268. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0005_organizational_unit_name.py +0 -0
  269. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0006_add_x509_passphrase_field.py +0 -0
  270. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0007_default_groups_permissions.py +0 -0
  271. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0008_serial_number_length.py +0 -0
  272. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0009_common_name_maxlength_64.py +0 -0
  273. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0010_common_name_organization_unique.py +0 -0
  274. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0011_disallowed_blank_key_length_or_digest.py +0 -0
  275. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/__init__.py +0 -0
  276. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/models.py +0 -0
  277. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/static/admin/pki/js/show-org-field.js +0 -0
  278. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/templates/admin/pki/change_form.html +0 -0
  279. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/__init__.py +0 -0
  280. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/test_admin.py +0 -0
  281. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/test_api.py +0 -0
  282. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/test_models.py +0 -0
  283. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/utils.py +0 -0
  284. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/urls.py +0 -0
  285. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/utils.py +0 -0
  286. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/routing.py +0 -0
  287. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/settings.py +0 -0
  288. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/__init__.py +0 -0
  289. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/apps.py +0 -0
  290. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/base/models.py +0 -0
  291. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/filters.py +0 -0
  292. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0001_initial.py +0 -0
  293. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0002_default_group_migration.py +0 -0
  294. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0003_related_field_allow_blank.py +0 -0
  295. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0004_index_rule_on_delete.py +0 -0
  296. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0005_number_of_subnets_and_ips.py +0 -0
  297. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/__init__.py +0 -0
  298. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/models.py +0 -0
  299. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/__init__.py +0 -0
  300. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/base.py +0 -0
  301. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/device.py +0 -0
  302. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/vpn.py +0 -0
  303. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/settings.py +0 -0
  304. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/signals.py +0 -0
  305. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/static/subnet-division/css/subnet-division.css +0 -0
  306. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/static/subnet-division/js/subnet-division.js +0 -0
  307. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tasks.py +0 -0
  308. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/__init__.py +0 -0
  309. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/helpers.py +0 -0
  310. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/test_admin.py +0 -0
  311. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/test_models.py +0 -0
  312. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/test_rule.py +0 -0
  313. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/utils.py +0 -0
  314. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/__init__.py +0 -0
  315. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/mixins.py +0 -0
  316. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/test_users_integration.py +0 -0
  317. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/test_utilities.py +0 -0
  318. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/utils.py +0 -0
  319. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/urls.py +0 -0
  320. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/vpn_backends.py +0 -0
  321. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/dependency_links.txt +0 -0
  322. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/not-zip-safe +0 -0
  323. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/requires.txt +0 -0
  324. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/top_level.txt +0 -0
  325. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/requirements.txt +0 -0
  326. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/setup.cfg +0 -0
  327. {openwisp_controller-1.1 → openwisp_controller-1.1.2}/setup.py +0 -0
@@ -1,6 +1,58 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ Version 1.1.2 [2025-08-01]
5
+ --------------------------
6
+
7
+ Bugfixes
8
+ ~~~~~~~~
9
+
10
+ - Fixed `compatibility of OpenWrt.update_config with openwisp-config >=
11
+ 1.1.0 <https://github.com/openwisp/openwisp-controller/issues/964>`__.
12
+ - Fixed `VPN-client template switch issue when switching between VPN
13
+ servers with the same address
14
+ <https://github.com/openwisp/openwisp-controller/issues/973>`__.
15
+ - Fixed `missing config_changed signal when reverting a template
16
+ <https://github.com/openwisp/openwisp-controller/issues/836>`__.
17
+ - Fixed `Zerotier network name being set to "ow_zt" instead of "global"
18
+ <https://github.com/openwisp/openwisp-controller/issues/982>`__.
19
+ - Fixed error in preview when device has no name set.
20
+ - Fixed live updates for "Send commands" when multiple websocket
21
+ connections are open for the same device.
22
+ - Limited command results in the device admin to 30 entries to avoid
23
+ loading issues.
24
+ - Fixed uncaught exception in ``leaflet.draw.i18n.js``.
25
+ - Fixed `handling of devices without a DeviceConnection when creating
26
+ commands
27
+ <https://github.com/openwisp/openwisp-controller/issues/1016>`__.
28
+ - Prevented `adding multiple VPN client templates pointing to the same VPN
29
+ server <https://github.com/openwisp/openwisp-controller/issues/832>`__.
30
+ - Fixed timeout issues in VPN checksum and download configuration views
31
+ for large VPN setups (e.g., 2000+ WireGuard peers) by caching the
32
+ checksum and generated configuration.
33
+ - Fixed an issue where enforcing required templates was accidentally
34
+ deleting `VpnClient` objects, causing them to be recreated whenever
35
+ device templates were modified in the Django admin.
36
+ - Fixed ``HTTP 500 Server Error`` when geographic REST API endpoints
37
+ receive a malformed resource ID.
38
+
39
+ Version 1.1.1 [2025-01-31]
40
+ --------------------------
41
+
42
+ Bugfixes
43
+ ~~~~~~~~
44
+
45
+ - Fixed `recovering deleted device with related location
46
+ <https://github.com/openwisp/openwisp-controller/issues/936>`__.
47
+ - Fixed `deleting device with "deactivating" config status
48
+ <https://github.com/openwisp/openwisp-controller/issues/949>`__.
49
+ - Fixed `conversion of MAC address to uppercase format
50
+ <https://github.com/openwisp/openwisp-controller/issues/922>`__ with the
51
+ openwisp-config agent.
52
+ - Fixed `updating templates with invalid configurations to prevent
53
+ ValidationError due to cache invalidation mechanism
54
+ <https://github.com/openwisp/openwisp-controller/pull/948>`__.
55
+
4
56
  Version 1.1.0 [2024-11-22]
5
57
  --------------------------
6
58
 
@@ -8,14 +60,14 @@ Features
8
60
  ~~~~~~~~
9
61
 
10
62
  - Added `support for ZeroTier
11
- <https://openwisp.io/docs/dev/controller/user/zerotier.html>`_.
63
+ <https://openwisp.io/docs/stable/controller/user/zerotier.html>`_.
12
64
  - Added support for adding `configuration templates
13
- <https://openwisp.io/docs/dev/controller/user/device-groups.html#group-templates>`_
65
+ <https://openwisp.io/docs/stable/controller/user/device-groups.html#group-templates>`_
14
66
  and `configuration variables
15
- <https://openwisp.io/docs/dev/controller/user/device-groups.html#group-configuration-variables>`_
67
+ <https://openwisp.io/docs/stable/controller/user/device-groups.html#group-configuration-variables>`_
16
68
  to device groups.
17
69
  - Implemented support for `SNMP credentials
18
- <https://openwisp.io/docs/dev/controller/user/intro.html#snmp>`_.
70
+ <https://openwisp.io/docs/stable/controller/user/intro.html#snmp>`_.
19
71
  - Added support for device deactivation and reactivation.
20
72
  - Introduced an admin action to quickly move devices between groups.
21
73
  - Added autocomplete support for filters in the admin interface.
@@ -23,13 +75,13 @@ Features
23
75
  config agent.
24
76
  - Enabled filtering of subnets by Subnet Division Rule type.
25
77
  - Allowed `limiting the number of devices per organization
26
- <https://openwisp.io/docs/dev/controller/user/organization-limits.html>`_.
78
+ <https://openwisp.io/docs/stable/controller/user/organization-limits.html>`_.
27
79
  - Added support for defining organization-level variables.
28
80
  - Enabled `bulk import and export of devices
29
- <https://openwisp.io/docs/dev/controller/user/import-export.html>`_.
81
+ <https://openwisp.io/docs/stable/controller/user/import-export.html>`_.
30
82
  - Added `functionality to configure available commands for each
31
83
  organization
32
- <https://openwisp.io/docs/dev/controller/user/settings.html#openwisp-controller-organization-enabled-commands>`_.
84
+ <https://openwisp.io/docs/stable/controller/user/settings.html#openwisp-controller-organization-enabled-commands>`_.
33
85
  - Added a dashboard chart showing the distribution of devices across
34
86
  different groups.
35
87
  - Added filters to the REST API.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: openwisp-controller
3
- Version: 1.1
3
+ Version: 1.1.2
4
4
  Summary: OpenWISP Controller
5
5
  Home-page: http://openwisp.org
6
6
  Download-URL: https://github.com/openwisp/openwisp-controller/releases
@@ -37,6 +37,18 @@ Requires-Dist: django-cache-memoize~=0.2.0
37
37
  Requires-Dist: shortuuid~=1.0.13
38
38
  Requires-Dist: netaddr~=1.3.0
39
39
  Requires-Dist: django-import-export~=3.3.0
40
+ Dynamic: author
41
+ Dynamic: author-email
42
+ Dynamic: classifier
43
+ Dynamic: description
44
+ Dynamic: download-url
45
+ Dynamic: home-page
46
+ Dynamic: keywords
47
+ Dynamic: license
48
+ Dynamic: license-file
49
+ Dynamic: platform
50
+ Dynamic: requires-dist
51
+ Dynamic: summary
40
52
 
41
53
  openwisp-controller
42
54
  ===================
@@ -89,30 +101,31 @@ built on top of its building blocks.
89
101
 
90
102
  Other popular building blocks that are part of the OpenWISP ecosystem are:
91
103
 
92
- - `openwisp-monitoring <https://openwisp.io/docs/dev/monitoring/>`_:
104
+ - `openwisp-monitoring <https://openwisp.io/docs/stable/monitoring/>`_:
93
105
  provides device status monitoring, collection of metrics, charts,
94
106
  alerts, possibility to define custom checks
95
107
  - `openwisp-firmware-upgrader
96
- <https://openwisp.io/docs/dev/firmware-upgrader/>`_: automated firmware
97
- upgrades (single devices or mass network upgrades)
98
- - `openwisp-radius <https://openwisp.io/docs/dev/user/radius.html>`_:
99
- based on FreeRADIUS, allows to implement network access authentication
100
- systems like 802.1x WPA2 Enterprise, captive portal authentication,
101
- Hotspot 2.0 (802.11u)
108
+ <https://openwisp.io/docs/stable/firmware-upgrader/>`_: automated
109
+ firmware upgrades (single devices or mass network upgrades)
110
+ - `openwisp-radius <https://openwisp.io/docs/stable/radius/>`_: based on
111
+ FreeRADIUS, allows to implement network access authentication systems
112
+ like 802.1x WPA2 Enterprise, captive portal authentication, Hotspot 2.0
113
+ (802.11u)
102
114
  - `openwisp-network-topology
103
- <https://openwisp.io/docs/dev/network-topology/>`_: provides way to
115
+ <https://openwisp.io/docs/stable/network-topology/>`_: provides way to
104
116
  collect and visualize network topology data from dynamic mesh routing
105
117
  daemons or other network software (e.g.: OpenVPN); it can be used in
106
118
  conjunction with openwisp-monitoring to get a better idea of the state
107
119
  of the network
108
- - `openwisp-ipam <https://openwisp.io/docs/dev/ipam/>`_: allows to manage
109
- the assignment of IP addresses used in the network
110
- - `openwisp-notifications <https://openwisp.io/docs/dev/notifications/>`_:
111
- allows users to be aware of important events happening in the network.
120
+ - `openwisp-ipam <https://openwisp.io/docs/stable/ipam/>`_: allows to
121
+ manage the assignment of IP addresses used in the network
122
+ - `openwisp-notifications
123
+ <https://openwisp.io/docs/stable/notifications/>`_: allows users to be
124
+ aware of important events happening in the network.
112
125
 
113
126
  **For a more complete overview of the OpenWISP modules and architecture**,
114
127
  see the `OpenWISP Architecture Overview
115
- <https://openwisp.io/docs/dev/general/architecture.html>`_.
128
+ <https://openwisp.io/docs/stable/general/architecture.html>`_.
116
129
 
117
130
  .. image:: https://raw.githubusercontent.com/openwisp/openwisp2-docs/master/assets/design/openwisp-logo-black.svg
118
131
  :target: http://openwisp.org
@@ -121,9 +134,9 @@ see the `OpenWISP Architecture Overview
121
134
  Documentation
122
135
  -------------
123
136
 
124
- - `Usage documentation <https://openwisp.io/docs/dev/controller/>`_
137
+ - `Usage documentation <https://openwisp.io/docs/stable/controller/>`_
125
138
  - `Developer documentation
126
- <https://openwisp.io/docs/dev/controller/developer/>`_
139
+ <https://openwisp.io/docs/stable/controller/developer/>`_
127
140
 
128
141
  Contributing
129
142
  ------------
@@ -49,30 +49,31 @@ built on top of its building blocks.
49
49
 
50
50
  Other popular building blocks that are part of the OpenWISP ecosystem are:
51
51
 
52
- - `openwisp-monitoring <https://openwisp.io/docs/dev/monitoring/>`_:
52
+ - `openwisp-monitoring <https://openwisp.io/docs/stable/monitoring/>`_:
53
53
  provides device status monitoring, collection of metrics, charts,
54
54
  alerts, possibility to define custom checks
55
55
  - `openwisp-firmware-upgrader
56
- <https://openwisp.io/docs/dev/firmware-upgrader/>`_: automated firmware
57
- upgrades (single devices or mass network upgrades)
58
- - `openwisp-radius <https://openwisp.io/docs/dev/user/radius.html>`_:
59
- based on FreeRADIUS, allows to implement network access authentication
60
- systems like 802.1x WPA2 Enterprise, captive portal authentication,
61
- Hotspot 2.0 (802.11u)
56
+ <https://openwisp.io/docs/stable/firmware-upgrader/>`_: automated
57
+ firmware upgrades (single devices or mass network upgrades)
58
+ - `openwisp-radius <https://openwisp.io/docs/stable/radius/>`_: based on
59
+ FreeRADIUS, allows to implement network access authentication systems
60
+ like 802.1x WPA2 Enterprise, captive portal authentication, Hotspot 2.0
61
+ (802.11u)
62
62
  - `openwisp-network-topology
63
- <https://openwisp.io/docs/dev/network-topology/>`_: provides way to
63
+ <https://openwisp.io/docs/stable/network-topology/>`_: provides way to
64
64
  collect and visualize network topology data from dynamic mesh routing
65
65
  daemons or other network software (e.g.: OpenVPN); it can be used in
66
66
  conjunction with openwisp-monitoring to get a better idea of the state
67
67
  of the network
68
- - `openwisp-ipam <https://openwisp.io/docs/dev/ipam/>`_: allows to manage
69
- the assignment of IP addresses used in the network
70
- - `openwisp-notifications <https://openwisp.io/docs/dev/notifications/>`_:
71
- allows users to be aware of important events happening in the network.
68
+ - `openwisp-ipam <https://openwisp.io/docs/stable/ipam/>`_: allows to
69
+ manage the assignment of IP addresses used in the network
70
+ - `openwisp-notifications
71
+ <https://openwisp.io/docs/stable/notifications/>`_: allows users to be
72
+ aware of important events happening in the network.
72
73
 
73
74
  **For a more complete overview of the OpenWISP modules and architecture**,
74
75
  see the `OpenWISP Architecture Overview
75
- <https://openwisp.io/docs/dev/general/architecture.html>`_.
76
+ <https://openwisp.io/docs/stable/general/architecture.html>`_.
76
77
 
77
78
  .. image:: https://raw.githubusercontent.com/openwisp/openwisp2-docs/master/assets/design/openwisp-logo-black.svg
78
79
  :target: http://openwisp.org
@@ -81,9 +82,9 @@ see the `OpenWISP Architecture Overview
81
82
  Documentation
82
83
  -------------
83
84
 
84
- - `Usage documentation <https://openwisp.io/docs/dev/controller/>`_
85
+ - `Usage documentation <https://openwisp.io/docs/stable/controller/>`_
85
86
  - `Developer documentation
86
- <https://openwisp.io/docs/dev/controller/developer/>`_
87
+ <https://openwisp.io/docs/stable/controller/developer/>`_
87
88
 
88
89
  Contributing
89
90
  ------------
@@ -1,4 +1,4 @@
1
- VERSION = (1, 1, 0, 'final')
1
+ VERSION = (1, 1, 2, 'final')
2
2
  __version__ = VERSION # alias
3
3
 
4
4
 
@@ -1,11 +1,13 @@
1
1
  import json
2
2
  import logging
3
+ from collections.abc import Iterable
3
4
 
4
5
  import reversion
5
6
  from django import forms
6
7
  from django.conf import settings
7
8
  from django.contrib import admin, messages
8
9
  from django.contrib.admin import helpers
10
+ from django.contrib.admin.actions import delete_selected
9
11
  from django.contrib.admin.models import ADDITION, LogEntry
10
12
  from django.contrib.contenttypes.models import ContentType
11
13
  from django.core.exceptions import (
@@ -309,7 +311,8 @@ class BaseConfigAdmin(BaseAdmin):
309
311
  config = instance.config
310
312
  else:
311
313
  raise Http404()
312
- config_archive = config.generate()
314
+ get_configuration = getattr(config, "get_cached_configuration", config.generate)
315
+ config_archive = get_configuration()
313
316
  return send_file(
314
317
  filename='{0}.tar.gz'.format(config.name),
315
318
  contents=config_archive.getvalue(),
@@ -566,8 +569,6 @@ class DeviceAdmin(MultitenantAdminMixin, BaseConfigAdmin, UUIDAdmin):
566
569
  perm = super().has_delete_permission(request)
567
570
  if not obj:
568
571
  return perm
569
- if obj._has_config():
570
- perm = perm and obj.config.is_deactivated()
571
572
  return perm and obj.is_deactivated()
572
573
 
573
574
  def save_form(self, request, form, change):
@@ -765,22 +766,42 @@ class DeviceAdmin(MultitenantAdminMixin, BaseConfigAdmin, UUIDAdmin):
765
766
  def activate_device(self, request, queryset):
766
767
  self._change_device_status(request, queryset, 'activate')
767
768
 
768
- def get_deleted_objects(self, objs, request, *args, **kwargs):
769
- # Ensure that all selected devices can be deleted, i.e.
770
- # the device should be flagged as deactivated and if it has
771
- # a config object, it's status should be "deactivated".
772
- active_devices = []
773
- for obj in objs:
774
- if not self.has_delete_permission(request, obj):
775
- active_devices.append(obj)
776
- if active_devices:
777
- return (
778
- active_devices,
779
- {self.model._meta.verbose_name_plural: len(active_devices)},
780
- ['active_devices'],
781
- [],
769
+ @admin.action(description=delete_selected.short_description, permissions=['delete'])
770
+ def delete_selected(self, request, queryset):
771
+ response = delete_selected(self, request, queryset)
772
+ if not response:
773
+ return response
774
+ if 'active_devices' in response.context_data.get('perms_lacking', {}):
775
+ active_devices = []
776
+ for device in queryset.iterator():
777
+ if not device.is_deactivated() or (
778
+ device._has_config() and not device.config.is_deactivated()
779
+ ):
780
+ active_devices.append(self._get_device_path(device))
781
+ response.context_data.update(
782
+ {
783
+ 'active_devices': active_devices,
784
+ 'perms_lacking': set(),
785
+ 'title': _('Are you sure?'),
786
+ }
782
787
  )
783
- return super().get_deleted_objects(objs, request, *args, **kwargs)
788
+ return response
789
+
790
+ def get_deleted_objects(self, objs, request, *args, **kwargs):
791
+ to_delete, model_count, perms_needed, protected = super().get_deleted_objects(
792
+ objs, request, *args, **kwargs
793
+ )
794
+ if (
795
+ isinstance(perms_needed, Iterable)
796
+ and len(perms_needed) == 1
797
+ and list(perms_needed)[0] == self.model._meta.verbose_name
798
+ and objs.filter(_is_deactivated=False).exists()
799
+ ):
800
+ if request.POST.get("post"):
801
+ perms_needed = set()
802
+ else:
803
+ perms_needed = {'active_devices'}
804
+ return to_delete, model_count, perms_needed, protected
784
805
 
785
806
  def get_fields(self, request, obj=None):
786
807
  """
@@ -900,6 +921,17 @@ class DeviceAdmin(MultitenantAdminMixin, BaseConfigAdmin, UUIDAdmin):
900
921
  request._recover_view = True
901
922
  return super().recover_view(request, version_id, extra_context)
902
923
 
924
+ def delete_view(self, request, object_id, extra_context=None):
925
+ extra_context = extra_context or {}
926
+ obj = self.get_object(request, object_id)
927
+ if obj and obj._has_config() and not obj.config.is_deactivated():
928
+ extra_context['deactivating_warning'] = True
929
+ return super().delete_view(request, object_id, extra_context)
930
+
931
+ def delete_model(self, request, obj):
932
+ force_delete = request.POST.get('force_delete') == 'true'
933
+ obj.delete(check_deactivated=not force_delete)
934
+
903
935
  def get_inlines(self, request, obj):
904
936
  inlines = super().get_inlines(request, obj)
905
937
  # this only makes sense in existing devices
@@ -107,6 +107,10 @@ class DeviceDetailView(ProtectedAPIMixin, RetrieveUpdateDestroyAPIView):
107
107
  queryset = Device.objects.select_related('config', 'group', 'organization')
108
108
  permission_classes = ProtectedAPIMixin.permission_classes + (DevicePermission,)
109
109
 
110
+ def perform_destroy(self, instance):
111
+ force_deletion = self.request.query_params.get('force', None) == 'true'
112
+ instance.delete(check_deactivated=(not force_deletion))
113
+
110
114
 
111
115
  class DeviceActivateView(ProtectedAPIMixin, GenericAPIView):
112
116
  serializer_class = serializers.Serializer
@@ -55,6 +55,7 @@ class ConfigConfig(AppConfig):
55
55
 
56
56
  def __setmodels__(self):
57
57
  self.device_model = load_model('config', 'Device')
58
+ self.template_model = load_model('config', 'Template')
58
59
  self.devicegroup_model = load_model('config', 'DeviceGroup')
59
60
  self.config_model = load_model('config', 'Config')
60
61
  self.vpn_model = load_model('config', 'Vpn')
@@ -135,11 +136,21 @@ class ConfigConfig(AppConfig):
135
136
  sender=self.config_model,
136
137
  dispatch_uid='devicegroup_templates_change_handler.backend_changed',
137
138
  )
139
+ pre_save.connect(
140
+ self.template_model.pre_save_handler,
141
+ sender=self.template_model,
142
+ dispatch_uid='template_pre_save_handler',
143
+ )
138
144
  pre_save.connect(
139
145
  handlers.organization_disabled_handler,
140
146
  sender=self.org_model,
141
147
  dispatch_uid='organization_disabled_pre_save_clear_device_checksum_cache',
142
148
  )
149
+ post_save.connect(
150
+ self.template_model.post_save_handler,
151
+ sender=self.template_model,
152
+ dispatch_uid='template_post_save_handler',
153
+ )
143
154
  post_save.connect(
144
155
  self.org_limits.post_save_handler,
145
156
  sender=self.org_model,
@@ -294,7 +305,7 @@ class ConfigConfig(AppConfig):
294
305
  Triggers the cache invalidation for the
295
306
  device config checksum (view and model method)
296
307
  """
297
- from .controller.views import DeviceChecksumView
308
+ from .controller.views import DeviceChecksumView, GetVpnView
298
309
  from .handlers import (
299
310
  device_cache_invalidation_handler,
300
311
  devicegroup_change_handler,
@@ -323,6 +334,21 @@ class ConfigConfig(AppConfig):
323
334
  DeviceChecksumView.invalidate_checksum_cache,
324
335
  dispatch_uid='invalidate_checksum_cache',
325
336
  )
337
+ # VPN cache invalidation
338
+ post_save.connect(
339
+ GetVpnView.invalidate_get_vpn_cache,
340
+ sender=self.vpn_model,
341
+ dispatch_uid="invalidate_get_vpn_cache",
342
+ )
343
+ pre_delete.connect(
344
+ GetVpnView.invalidate_get_vpn_cache,
345
+ sender=self.vpn_model,
346
+ dispatch_uid="vpn_server_pre_delete_invalidate_get_vpn_cache",
347
+ )
348
+ vpn_server_modified.connect(
349
+ GetVpnView.invalidate_get_vpn_cache,
350
+ dispatch_uid="vpn_server_modified_invalidate_get_vpn_cache",
351
+ )
326
352
  device_group_changed.connect(
327
353
  devicegroup_change_handler,
328
354
  sender=self.device_model,
@@ -1,8 +1,10 @@
1
1
  import collections
2
2
  import hashlib
3
3
  import json
4
+ import logging
4
5
  from copy import deepcopy
5
6
 
7
+ from cache_memoize import cache_memoize
6
8
  from django.core.exceptions import ValidationError
7
9
  from django.db import models
8
10
  from django.utils.functional import cached_property
@@ -15,6 +17,82 @@ from openwisp_utils.base import TimeStampedEditableModel
15
17
 
16
18
  from .. import settings as app_settings
17
19
 
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ def get_cached_args_rewrite(instance):
24
+ """
25
+ Use only the PK parameter for calculating the cache key
26
+ """
27
+ return instance.pk.hex
28
+
29
+
30
+ class ChecksumCacheMixin:
31
+ """
32
+ Mixin that provides caching for checksum.
33
+ """
34
+
35
+ _CHECKSUM_CACHE_TIMEOUT = 60 * 60 * 24 * 30 # 30 days
36
+
37
+ @cache_memoize(
38
+ timeout=_CHECKSUM_CACHE_TIMEOUT, args_rewrite=get_cached_args_rewrite
39
+ )
40
+ def get_cached_checksum(self):
41
+ """
42
+ Handles caching,
43
+ timeout=None means value is cached indefinitely
44
+ (invalidation handled on post_save/post_delete signal)
45
+ """
46
+ logger.debug(f"calculating checksum for {self.__class__.__name__} ID {self.pk}")
47
+ return self.checksum
48
+
49
+ @classmethod
50
+ def bulk_invalidate_get_cached_checksum(cls, query_params):
51
+ """
52
+ Bulk invalidate checksum cache for multiple instances
53
+ """
54
+ for instance in cls.objects.only("id").filter(**query_params).iterator():
55
+ instance.get_cached_checksum.invalidate(instance)
56
+
57
+ def invalidate_checksum_cache(self):
58
+ """
59
+ Invalidate the checksum cache for this instance
60
+ """
61
+ self.get_cached_checksum.invalidate(self)
62
+ logger.debug(
63
+ f"invalidated checksum cache for {self.__class__.__name__} ID {self.pk}"
64
+ )
65
+
66
+
67
+ class ConfigChecksumCacheMixin(ChecksumCacheMixin):
68
+ """
69
+ Mixin that provides caching for both checksum and configuration.
70
+ """
71
+
72
+ @cache_memoize(
73
+ timeout=ChecksumCacheMixin._CHECKSUM_CACHE_TIMEOUT,
74
+ args_rewrite=get_cached_args_rewrite,
75
+ )
76
+ def get_cached_configuration(self):
77
+ """
78
+ Returns cached configuration
79
+ """
80
+ return self.generate()
81
+
82
+ def invalidate_configuration_cache(self):
83
+ """
84
+ Invalidate the configuration cache for this instance
85
+ """
86
+ self.get_cached_configuration.invalidate(self)
87
+ logger.debug(
88
+ f"invalidated configuration cache for {self.__class__.__name__}"
89
+ f" ID {self.pk}"
90
+ )
91
+
92
+ def invalidate_checksum_cache(self):
93
+ super().invalidate_checksum_cache()
94
+ self.invalidate_configuration_cache()
95
+
18
96
 
19
97
  class BaseModel(TimeStampedEditableModel):
20
98
  """
@@ -89,7 +167,7 @@ class BaseConfig(BaseModel):
89
167
  return config
90
168
  c = deepcopy(config)
91
169
  is_config = not any([self.__template__, self.__vpn__])
92
- if 'hostname' not in c.get('general', {}) and is_config:
170
+ if all(('hostname' not in c.get('general', {}), is_config, self.name)):
93
171
  c.setdefault('general', {})
94
172
  c['general']['hostname'] = self.name.replace(':', '-')
95
173
  return c