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.
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/CHANGES.rst +59 -7
- {openwisp_controller-1.1/openwisp_controller.egg-info → openwisp_controller-1.1.2}/PKG-INFO +30 -17
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/README.rst +16 -15
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/__init__.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/admin.py +50 -18
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/views.py +4 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/apps.py +27 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/base.py +79 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/config.py +103 -50
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/device.py +1 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/template.py +23 -14
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/vpn.py +9 -7
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/controller/views.py +37 -6
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/handlers.py +2 -2
- openwisp_controller-1.1.2/openwisp_controller/config/static/config/css/device-delete-confirmation.css +11 -0
- openwisp_controller-1.1.2/openwisp_controller/config/static/config/js/device-delete-confirmation.js +12 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tasks.py +31 -2
- openwisp_controller-1.1.2/openwisp_controller/config/templates/admin/config/device/delete_confirmation.html +81 -0
- openwisp_controller-1.1.2/openwisp_controller/config/templates/admin/config/device/delete_selected_confirmation.html +87 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_admin.py +266 -10
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_api.py +86 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_config.py +65 -5
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_controller.py +92 -12
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_device.py +8 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_handlers.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_selenium.py +74 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_template.py +15 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_vpn.py +55 -14
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/utils.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/utils.py +2 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/validators.py +4 -4
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/admin.py +9 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/api/serializer.py +13 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/base/models.py +30 -8
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/channels/consumers.py +4 -2
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/commands.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/openwrt/ssh.py +5 -2
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/pytest.py +42 -9
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_api.py +38 -2
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_models.py +18 -3
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/admin.py +34 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/views.py +2 -3
- openwisp_controller-1.1.2/openwisp_controller/geo/static/leaflet/draw/leaflet.draw.i18n.js +116 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_api.py +48 -18
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/utils.py +7 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/utils.py +5 -5
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/mixins.py +2 -2
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/admin.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/test_selenium.py +20 -5
- {openwisp_controller-1.1 → openwisp_controller-1.1.2/openwisp_controller.egg-info}/PKG-INFO +30 -17
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/SOURCES.txt +4 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/pyproject.toml +1 -1
- openwisp_controller-1.1/openwisp_controller/config/templates/admin/config/device/delete_selected_confirmation.html +0 -36
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/LICENSE +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/MANIFEST.in +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/base.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/checks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/download_views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/serializers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/zerotier_service.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/channels_consumer.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/device_group.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/multitenancy.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/tag.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/controller/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/controller/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/crypto.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/exceptions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/exportable.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/fixtures/test_templates.json +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0001_squashed_0002_config_settings_uuid.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0003_template_tags.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0004_add_device_model.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0005_populate_device.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0006_config_device_not_null.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0007_simplify_config.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0008_update_indexes.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0009_device_system.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0010_auto_20180106_1814.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0011_update_device_mac_address.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0012_auto_20180219_1501.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0013_last_ip_management_ip_and_status_applied.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0014_device_hardware_id.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0015_default_groups_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0016_default_organization_config_settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0017_template_name_organization_unique_together.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0018_config_context.py +0 -0
- {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
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0020_remove_config_organization.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0021_vpn_key.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0022_vpn_format_dh.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0023_update_context.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0024_update_context_data.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0025_update_device_key.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0026_hardware_id_not_unique.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0027_add_indexes_on_ip_fields.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0028_template_default_values.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0029_merge_django_netjsonconfig.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0030_django_taggit_update.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0031_update_vpn_dh_param.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0032_update_legacy_vpn_backend.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0033_name_unique_per_organization.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0034_template_required.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0035_device_name_unique_optional.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0036_device_group.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0037_alter_taggedtemplate.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0038_vpn_subnet.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0039_wireguard_vxlan_ipam.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0040_vpnclient_ip_setnull.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0041_default_groups_organizationconfigsettings_permission.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0042_multiple_wireguard_tunnels.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0043_devicegroup_templates.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0044_config_error_reason.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0045_alter_vpn_webhook_endpoint.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0046_organizationlimits.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0047_add_organizationlimits.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0048_wifi_radio_band_migration.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0049_devicegroup_context.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0050_alter_vpnclient_unique_together.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0051_organizationconfigsettings_context.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0052_vpn_node_network_id.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0053_vpnclient_secret.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0054_device__is_deactivated.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/0055_alter_config_status.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/signals.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/sortedm2m/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/sortedm2m/fields.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/sortedm2m/forms.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/admin.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/devicegroup.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/lib/advanced-mode.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/lib/img/jsoneditor-icons.svg +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/css/lib/jsonschema-ui.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/lib/advanced-mode.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/lib/jsonschema-ui.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/lib/tomorrow_night_bright.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/management_ip.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/preview.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/relevant_templates.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/switcher.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/tabs.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/unsaved_changes.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/utils.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/vpn.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/config/js/widget.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/import_export/import-openwisp.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/sortedm2m/patch_sortedm2m.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/static/support.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tasks_zerotier.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/change_device_group.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/change_list_device.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/clone_template_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/device/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/device_recover_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/jsonschema-widget.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/preview.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/config/system_context.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/device_group/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/admin/import_export/import.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/templates/reversion/config/revision_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/pytest.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_device_group.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_notifications.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_tag.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/tests/test_views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/widgets.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/api/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/channels/routing.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/airos/snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/exceptions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/openwrt/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/openwrt/snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/connectors/ssh.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/exceptions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0002_credentials_auto_add.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0003_default_group_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0004_django3_1_upgrade.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0005_device_connection_failure_reason.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0006_name_unique_per_organization.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0007_command.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0008_remove_conflicting_deviceconnections.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/0009_alter_deviceconnection_unique_together.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/schema.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/signals.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/css/command-inline.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/css/credentials.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/js/commands.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/js/credentials.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/static/connection/js/lib/reconnecting-websocket.min.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tasks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/base.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test-key.ed25519 +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test-key.rsa +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_command_utilities.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_notifications.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_selenium.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_ssh.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/test_tasks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/connection/widgets.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/context_processors.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/serializers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/base/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/channels/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/channels/consumers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/channels/routing.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/exportable.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/0002_default_groups_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/0003_alter_devicelocation_floorplan_location.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/templates/admin/widgets/foreign_key_raw_id.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/pytest.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_admin_inline.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/geo/tests/test_models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/migrations.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/api/serializers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/api/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/base/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0002_add_organization_name.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0003_fill_organization_name.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0004_auto_20180106_1814.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0005_organizational_unit_name.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0006_add_x509_passphrase_field.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0007_default_groups_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0008_serial_number_length.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0009_common_name_maxlength_64.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0010_common_name_organization_unique.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/0011_disallowed_blank_key_length_or_digest.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/static/admin/pki/js/show-org-field.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/templates/admin/pki/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/test_api.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/test_models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/pki/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/routing.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/base/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0002_default_group_migration.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0003_related_field_allow_blank.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0004_index_rule_on_delete.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/0005_number_of_subnets_and_ips.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/base.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/device.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/rule_types/vpn.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/signals.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/static/subnet-division/css/subnet-division.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/static/subnet-division/js/subnet-division.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tasks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/helpers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/test_models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/tests/test_rule.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/subnet_division/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/mixins.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/test_users_integration.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/test_utilities.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/vpn_backends.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/dependency_links.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/not-zip-safe +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/requires.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller.egg-info/top_level.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/requirements.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.2}/setup.cfg +0 -0
- {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/
|
|
63
|
+
<https://openwisp.io/docs/stable/controller/user/zerotier.html>`_.
|
|
12
64
|
- Added support for adding `configuration templates
|
|
13
|
-
<https://openwisp.io/docs/
|
|
65
|
+
<https://openwisp.io/docs/stable/controller/user/device-groups.html#group-templates>`_
|
|
14
66
|
and `configuration variables
|
|
15
|
-
<https://openwisp.io/docs/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
+
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/
|
|
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/
|
|
97
|
-
upgrades (single devices or mass network upgrades)
|
|
98
|
-
- `openwisp-radius <https://openwisp.io/docs/
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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/
|
|
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/
|
|
109
|
-
the assignment of IP addresses used in the network
|
|
110
|
-
- `openwisp-notifications
|
|
111
|
-
allows users to be
|
|
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/
|
|
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/
|
|
137
|
+
- `Usage documentation <https://openwisp.io/docs/stable/controller/>`_
|
|
125
138
|
- `Developer documentation
|
|
126
|
-
<https://openwisp.io/docs/
|
|
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/
|
|
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/
|
|
57
|
-
upgrades (single devices or mass network upgrades)
|
|
58
|
-
- `openwisp-radius <https://openwisp.io/docs/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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/
|
|
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/
|
|
69
|
-
the assignment of IP addresses used in the network
|
|
70
|
-
- `openwisp-notifications
|
|
71
|
-
allows users to be
|
|
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/
|
|
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/
|
|
85
|
+
- `Usage documentation <https://openwisp.io/docs/stable/controller/>`_
|
|
85
86
|
- `Developer documentation
|
|
86
|
-
<https://openwisp.io/docs/
|
|
87
|
+
<https://openwisp.io/docs/stable/controller/developer/>`_
|
|
87
88
|
|
|
88
89
|
Contributing
|
|
89
90
|
------------
|
|
@@ -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
|
-
|
|
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
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
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
|
|
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
|
{openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/api/views.py
RENAMED
|
@@ -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,
|
{openwisp_controller-1.1 → openwisp_controller-1.1.2}/openwisp_controller/config/base/base.py
RENAMED
|
@@ -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', {})
|
|
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
|