openwisp-controller 1.1__tar.gz → 1.1.1__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.1}/CHANGES.rst +24 -7
- {openwisp_controller-1.1/openwisp_controller.egg-info → openwisp_controller-1.1.1}/PKG-INFO +26 -14
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/README.rst +13 -12
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/__init__.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/admin.py +48 -17
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/api/views.py +4 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/device.py +1 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/template.py +9 -1
- openwisp_controller-1.1.1/openwisp_controller/config/static/config/css/device-delete-confirmation.css +11 -0
- openwisp_controller-1.1.1/openwisp_controller/config/static/config/js/device-delete-confirmation.js +12 -0
- openwisp_controller-1.1.1/openwisp_controller/config/templates/admin/config/device/delete_confirmation.html +81 -0
- openwisp_controller-1.1.1/openwisp_controller/config/templates/admin/config/device/delete_selected_confirmation.html +87 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_admin.py +1 -2
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_api.py +16 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_device.py +8 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_selenium.py +74 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_template.py +15 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/admin.py +34 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/test_api.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/admin.py +1 -1
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/tests/test_selenium.py +20 -5
- {openwisp_controller-1.1 → openwisp_controller-1.1.1/openwisp_controller.egg-info}/PKG-INFO +26 -14
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller.egg-info/SOURCES.txt +3 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/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.1}/LICENSE +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/MANIFEST.in +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/base.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/checks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/api/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/api/download_views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/api/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/api/serializers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/api/zerotier_service.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/base.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/channels_consumer.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/config.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/device_group.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/multitenancy.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/tag.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/vpn.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/controller/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/controller/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/controller/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/crypto.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/exceptions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/exportable.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/fixtures/test_templates.json +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/handlers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0001_squashed_0002_config_settings_uuid.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0003_template_tags.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0004_add_device_model.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0005_populate_device.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0006_config_device_not_null.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0007_simplify_config.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0008_update_indexes.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0009_device_system.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0010_auto_20180106_1814.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0011_update_device_mac_address.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0012_auto_20180219_1501.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0013_last_ip_management_ip_and_status_applied.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0014_device_hardware_id.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0015_default_groups_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0016_default_organization_config_settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0017_template_name_organization_unique_together.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0018_config_context.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0019_organization_mac_add_hardware_id_name_unique_together.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0020_remove_config_organization.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0021_vpn_key.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0022_vpn_format_dh.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0023_update_context.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0024_update_context_data.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0025_update_device_key.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0026_hardware_id_not_unique.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0027_add_indexes_on_ip_fields.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0028_template_default_values.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0029_merge_django_netjsonconfig.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0030_django_taggit_update.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0031_update_vpn_dh_param.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0032_update_legacy_vpn_backend.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0033_name_unique_per_organization.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0034_template_required.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0035_device_name_unique_optional.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0036_device_group.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0037_alter_taggedtemplate.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0038_vpn_subnet.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0039_wireguard_vxlan_ipam.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0040_vpnclient_ip_setnull.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0041_default_groups_organizationconfigsettings_permission.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0042_multiple_wireguard_tunnels.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0043_devicegroup_templates.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0044_config_error_reason.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0045_alter_vpn_webhook_endpoint.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0046_organizationlimits.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0047_add_organizationlimits.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0048_wifi_radio_band_migration.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0049_devicegroup_context.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0050_alter_vpnclient_unique_together.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0051_organizationconfigsettings_context.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0052_vpn_node_network_id.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0053_vpnclient_secret.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0054_device__is_deactivated.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/0055_alter_config_status.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/signals.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/sortedm2m/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/sortedm2m/fields.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/sortedm2m/forms.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/css/admin.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/css/devicegroup.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/css/lib/advanced-mode.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/css/lib/img/jsoneditor-icons.svg +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/css/lib/jsonschema-ui.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/lib/advanced-mode.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/lib/jsonschema-ui.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/lib/tomorrow_night_bright.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/management_ip.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/preview.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/relevant_templates.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/switcher.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/tabs.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/unsaved_changes.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/utils.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/vpn.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/config/js/widget.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/import_export/import-openwisp.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/sortedm2m/patch_sortedm2m.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/static/support.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tasks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tasks_zerotier.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/change_device_group.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/change_list_device.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/clone_template_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/device/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/device_recover_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/jsonschema-widget.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/preview.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/config/system_context.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/device_group/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/admin/import_export/import.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/templates/reversion/config/revision_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/pytest.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_config.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_controller.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_device_group.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_handlers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_notifications.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_tag.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_vpn.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/validators.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/widgets.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/api/serializer.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/api/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/base/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/channels/consumers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/channels/routing.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/commands.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/airos/snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/exceptions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/openwrt/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/openwrt/snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/openwrt/ssh.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/connectors/ssh.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/exceptions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0002_credentials_auto_add.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0003_default_group_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0004_django3_1_upgrade.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0005_device_connection_failure_reason.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0006_name_unique_per_organization.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0007_command.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0008_remove_conflicting_deviceconnections.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/0009_alter_deviceconnection_unique_together.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/schema.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/signals.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/static/connection/css/command-inline.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/static/connection/css/credentials.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/static/connection/js/commands.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/static/connection/js/credentials.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/static/connection/js/lib/reconnecting-websocket.min.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tasks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/base.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/pytest.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test-key.ed25519 +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test-key.rsa +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_api.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_command_utilities.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_notifications.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_selenium.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_snmp.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_ssh.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/test_tasks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/connection/widgets.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/context_processors.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/api/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/api/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/api/serializers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/api/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/base/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/channels/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/channels/consumers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/channels/routing.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/exportable.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/migrations/0002_default_groups_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/migrations/0003_alter_devicelocation_floorplan_location.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/templates/admin/widgets/foreign_key_raw_id.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/pytest.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/test_admin_inline.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/test_apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/test_models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/geo/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/migrations.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/mixins.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/api/serializers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/api/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/api/views.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/base/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/base/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0002_add_organization_name.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0003_fill_organization_name.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0004_auto_20180106_1814.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0005_organizational_unit_name.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0006_add_x509_passphrase_field.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0007_default_groups_permissions.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0008_serial_number_length.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0009_common_name_maxlength_64.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0010_common_name_organization_unique.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/0011_disallowed_blank_key_length_or_digest.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/static/admin/pki/js/show-org-field.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/templates/admin/pki/change_form.html +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/tests/test_api.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/tests/test_models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/pki/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/routing.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/apps.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/base/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/filters.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/migrations/0001_initial.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/migrations/0002_default_group_migration.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/migrations/0003_related_field_allow_blank.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/migrations/0004_index_rule_on_delete.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/migrations/0005_number_of_subnets_and_ips.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/migrations/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/rule_types/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/rule_types/base.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/rule_types/device.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/rule_types/vpn.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/settings.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/signals.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/static/subnet-division/css/subnet-division.css +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/static/subnet-division/js/subnet-division.js +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/tasks.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/tests/helpers.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/tests/test_admin.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/tests/test_models.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/tests/test_rule.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/subnet_division/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/tests/__init__.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/tests/mixins.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/tests/test_users_integration.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/tests/test_utilities.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/tests/utils.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/urls.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/vpn_backends.py +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller.egg-info/dependency_links.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller.egg-info/not-zip-safe +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller.egg-info/requires.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller.egg-info/top_level.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/requirements.txt +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/setup.cfg +0 -0
- {openwisp_controller-1.1 → openwisp_controller-1.1.1}/setup.py +0 -0
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
Version 1.1.1 [2025-01-31]
|
|
5
|
+
--------------------------
|
|
6
|
+
|
|
7
|
+
Bugfixes
|
|
8
|
+
~~~~~~~~
|
|
9
|
+
|
|
10
|
+
- Fixed `recovering deleted device with related location
|
|
11
|
+
<https://github.com/openwisp/openwisp-controller/issues/936>`__.
|
|
12
|
+
- Fixed `deleting device with “deactivating” config status
|
|
13
|
+
<https://github.com/openwisp/openwisp-controller/issues/949>`__.
|
|
14
|
+
- Fixed `conversion of MAC address to uppercase format
|
|
15
|
+
<https://github.com/openwisp/openwisp-controller/issues/922>`__ with the
|
|
16
|
+
openwisp-config agent.
|
|
17
|
+
- Fixed `updating templates with invalid configurations to prevent
|
|
18
|
+
ValidationError due to cache invalidation mechanism
|
|
19
|
+
<https://github.com/openwisp/openwisp-controller/pull/948>`__.
|
|
20
|
+
|
|
4
21
|
Version 1.1.0 [2024-11-22]
|
|
5
22
|
--------------------------
|
|
6
23
|
|
|
@@ -8,14 +25,14 @@ Features
|
|
|
8
25
|
~~~~~~~~
|
|
9
26
|
|
|
10
27
|
- Added `support for ZeroTier
|
|
11
|
-
<https://openwisp.io/docs/
|
|
28
|
+
<https://openwisp.io/docs/stable/controller/user/zerotier.html>`_.
|
|
12
29
|
- Added support for adding `configuration templates
|
|
13
|
-
<https://openwisp.io/docs/
|
|
30
|
+
<https://openwisp.io/docs/stable/controller/user/device-groups.html#group-templates>`_
|
|
14
31
|
and `configuration variables
|
|
15
|
-
<https://openwisp.io/docs/
|
|
32
|
+
<https://openwisp.io/docs/stable/controller/user/device-groups.html#group-configuration-variables>`_
|
|
16
33
|
to device groups.
|
|
17
34
|
- Implemented support for `SNMP credentials
|
|
18
|
-
<https://openwisp.io/docs/
|
|
35
|
+
<https://openwisp.io/docs/stable/controller/user/intro.html#snmp>`_.
|
|
19
36
|
- Added support for device deactivation and reactivation.
|
|
20
37
|
- Introduced an admin action to quickly move devices between groups.
|
|
21
38
|
- Added autocomplete support for filters in the admin interface.
|
|
@@ -23,13 +40,13 @@ Features
|
|
|
23
40
|
config agent.
|
|
24
41
|
- Enabled filtering of subnets by Subnet Division Rule type.
|
|
25
42
|
- Allowed `limiting the number of devices per organization
|
|
26
|
-
<https://openwisp.io/docs/
|
|
43
|
+
<https://openwisp.io/docs/stable/controller/user/organization-limits.html>`_.
|
|
27
44
|
- Added support for defining organization-level variables.
|
|
28
45
|
- Enabled `bulk import and export of devices
|
|
29
|
-
<https://openwisp.io/docs/
|
|
46
|
+
<https://openwisp.io/docs/stable/controller/user/import-export.html>`_.
|
|
30
47
|
- Added `functionality to configure available commands for each
|
|
31
48
|
organization
|
|
32
|
-
<https://openwisp.io/docs/
|
|
49
|
+
<https://openwisp.io/docs/stable/controller/user/settings.html#openwisp-controller-organization-enabled-commands>`_.
|
|
33
50
|
- Added a dashboard chart showing the distribution of devices across
|
|
34
51
|
different groups.
|
|
35
52
|
- Added filters to the REST API.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: openwisp-controller
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.1.1
|
|
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,17 @@ 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: platform
|
|
49
|
+
Dynamic: requires-dist
|
|
50
|
+
Dynamic: summary
|
|
40
51
|
|
|
41
52
|
openwisp-controller
|
|
42
53
|
===================
|
|
@@ -89,30 +100,31 @@ built on top of its building blocks.
|
|
|
89
100
|
|
|
90
101
|
Other popular building blocks that are part of the OpenWISP ecosystem are:
|
|
91
102
|
|
|
92
|
-
- `openwisp-monitoring <https://openwisp.io/docs/
|
|
103
|
+
- `openwisp-monitoring <https://openwisp.io/docs/stable/monitoring/>`_:
|
|
93
104
|
provides device status monitoring, collection of metrics, charts,
|
|
94
105
|
alerts, possibility to define custom checks
|
|
95
106
|
- `openwisp-firmware-upgrader
|
|
96
|
-
<https://openwisp.io/docs/
|
|
97
|
-
upgrades (single devices or mass network upgrades)
|
|
98
|
-
- `openwisp-radius <https://openwisp.io/docs/
|
|
107
|
+
<https://openwisp.io/docs/stable/firmware-upgrader/>`_: automated
|
|
108
|
+
firmware upgrades (single devices or mass network upgrades)
|
|
109
|
+
- `openwisp-radius <https://openwisp.io/docs/stable/user/radius.html>`_:
|
|
99
110
|
based on FreeRADIUS, allows to implement network access authentication
|
|
100
111
|
systems like 802.1x WPA2 Enterprise, captive portal authentication,
|
|
101
112
|
Hotspot 2.0 (802.11u)
|
|
102
113
|
- `openwisp-network-topology
|
|
103
|
-
<https://openwisp.io/docs/
|
|
114
|
+
<https://openwisp.io/docs/stable/network-topology/>`_: provides way to
|
|
104
115
|
collect and visualize network topology data from dynamic mesh routing
|
|
105
116
|
daemons or other network software (e.g.: OpenVPN); it can be used in
|
|
106
117
|
conjunction with openwisp-monitoring to get a better idea of the state
|
|
107
118
|
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
|
|
119
|
+
- `openwisp-ipam <https://openwisp.io/docs/stable/ipam/>`_: allows to
|
|
120
|
+
manage the assignment of IP addresses used in the network
|
|
121
|
+
- `openwisp-notifications
|
|
122
|
+
<https://openwisp.io/docs/stable/notifications/>`_: allows users to be
|
|
123
|
+
aware of important events happening in the network.
|
|
112
124
|
|
|
113
125
|
**For a more complete overview of the OpenWISP modules and architecture**,
|
|
114
126
|
see the `OpenWISP Architecture Overview
|
|
115
|
-
<https://openwisp.io/docs/
|
|
127
|
+
<https://openwisp.io/docs/stable/general/architecture.html>`_.
|
|
116
128
|
|
|
117
129
|
.. image:: https://raw.githubusercontent.com/openwisp/openwisp2-docs/master/assets/design/openwisp-logo-black.svg
|
|
118
130
|
:target: http://openwisp.org
|
|
@@ -121,9 +133,9 @@ see the `OpenWISP Architecture Overview
|
|
|
121
133
|
Documentation
|
|
122
134
|
-------------
|
|
123
135
|
|
|
124
|
-
- `Usage documentation <https://openwisp.io/docs/
|
|
136
|
+
- `Usage documentation <https://openwisp.io/docs/stable/controller/>`_
|
|
125
137
|
- `Developer documentation
|
|
126
|
-
<https://openwisp.io/docs/
|
|
138
|
+
<https://openwisp.io/docs/stable/controller/developer/>`_
|
|
127
139
|
|
|
128
140
|
Contributing
|
|
129
141
|
------------
|
|
@@ -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/
|
|
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/user/radius.html>`_:
|
|
59
59
|
based on FreeRADIUS, allows to implement network access authentication
|
|
60
60
|
systems like 802.1x WPA2 Enterprise, captive portal authentication,
|
|
61
61
|
Hotspot 2.0 (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 (
|
|
@@ -566,8 +568,6 @@ class DeviceAdmin(MultitenantAdminMixin, BaseConfigAdmin, UUIDAdmin):
|
|
|
566
568
|
perm = super().has_delete_permission(request)
|
|
567
569
|
if not obj:
|
|
568
570
|
return perm
|
|
569
|
-
if obj._has_config():
|
|
570
|
-
perm = perm and obj.config.is_deactivated()
|
|
571
571
|
return perm and obj.is_deactivated()
|
|
572
572
|
|
|
573
573
|
def save_form(self, request, form, change):
|
|
@@ -765,22 +765,42 @@ class DeviceAdmin(MultitenantAdminMixin, BaseConfigAdmin, UUIDAdmin):
|
|
|
765
765
|
def activate_device(self, request, queryset):
|
|
766
766
|
self._change_device_status(request, queryset, 'activate')
|
|
767
767
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
768
|
+
@admin.action(description=delete_selected.short_description, permissions=['delete'])
|
|
769
|
+
def delete_selected(self, request, queryset):
|
|
770
|
+
response = delete_selected(self, request, queryset)
|
|
771
|
+
if not response:
|
|
772
|
+
return response
|
|
773
|
+
if 'active_devices' in response.context_data.get('perms_lacking', {}):
|
|
774
|
+
active_devices = []
|
|
775
|
+
for device in queryset.iterator():
|
|
776
|
+
if not device.is_deactivated() or (
|
|
777
|
+
device._has_config() and not device.config.is_deactivated()
|
|
778
|
+
):
|
|
779
|
+
active_devices.append(self._get_device_path(device))
|
|
780
|
+
response.context_data.update(
|
|
781
|
+
{
|
|
782
|
+
'active_devices': active_devices,
|
|
783
|
+
'perms_lacking': set(),
|
|
784
|
+
'title': _('Are you sure?'),
|
|
785
|
+
}
|
|
782
786
|
)
|
|
783
|
-
return
|
|
787
|
+
return response
|
|
788
|
+
|
|
789
|
+
def get_deleted_objects(self, objs, request, *args, **kwargs):
|
|
790
|
+
to_delete, model_count, perms_needed, protected = super().get_deleted_objects(
|
|
791
|
+
objs, request, *args, **kwargs
|
|
792
|
+
)
|
|
793
|
+
if (
|
|
794
|
+
isinstance(perms_needed, Iterable)
|
|
795
|
+
and len(perms_needed) == 1
|
|
796
|
+
and list(perms_needed)[0] == self.model._meta.verbose_name
|
|
797
|
+
and objs.filter(_is_deactivated=False).exists()
|
|
798
|
+
):
|
|
799
|
+
if request.POST.get("post"):
|
|
800
|
+
perms_needed = set()
|
|
801
|
+
else:
|
|
802
|
+
perms_needed = {'active_devices'}
|
|
803
|
+
return to_delete, model_count, perms_needed, protected
|
|
784
804
|
|
|
785
805
|
def get_fields(self, request, obj=None):
|
|
786
806
|
"""
|
|
@@ -900,6 +920,17 @@ class DeviceAdmin(MultitenantAdminMixin, BaseConfigAdmin, UUIDAdmin):
|
|
|
900
920
|
request._recover_view = True
|
|
901
921
|
return super().recover_view(request, version_id, extra_context)
|
|
902
922
|
|
|
923
|
+
def delete_view(self, request, object_id, extra_context=None):
|
|
924
|
+
extra_context = extra_context or {}
|
|
925
|
+
obj = self.get_object(request, object_id)
|
|
926
|
+
if obj and obj._has_config() and not obj.config.is_deactivated():
|
|
927
|
+
extra_context['deactivating_warning'] = True
|
|
928
|
+
return super().delete_view(request, object_id, extra_context)
|
|
929
|
+
|
|
930
|
+
def delete_model(self, request, obj):
|
|
931
|
+
force_delete = request.POST.get('force_delete') == 'true'
|
|
932
|
+
obj.delete(check_deactivated=not force_delete)
|
|
933
|
+
|
|
903
934
|
def get_inlines(self, request, obj):
|
|
904
935
|
inlines = super().get_inlines(request, obj)
|
|
905
936
|
# this only makes sense in existing devices
|
{openwisp_controller-1.1 → openwisp_controller-1.1.1}/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
|
{openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/device.py
RENAMED
|
@@ -262,6 +262,7 @@ class AbstractDevice(OrgMixin, BaseModel):
|
|
|
262
262
|
|
|
263
263
|
def clean(self, *args, **kwargs):
|
|
264
264
|
super().clean(*args, **kwargs)
|
|
265
|
+
self.mac_address = self.mac_address.upper()
|
|
265
266
|
self._validate_unique_name()
|
|
266
267
|
self._validate_org_relation('group', field_error='group')
|
|
267
268
|
self._validate_org_device_limit()
|
{openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/base/template.py
RENAMED
|
@@ -6,6 +6,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
|
|
6
6
|
from django.db import models, transaction
|
|
7
7
|
from django.utils.translation import gettext_lazy as _
|
|
8
8
|
from jsonfield import JSONField
|
|
9
|
+
from netjsonconfig.exceptions import ValidationError as NetjsonconfigValidationError
|
|
9
10
|
from swapper import get_model_name
|
|
10
11
|
from taggit.managers import TaggableManager
|
|
11
12
|
|
|
@@ -115,7 +116,14 @@ class AbstractTemplate(ShareableOrgMixinUniqueName, BaseConfig):
|
|
|
115
116
|
if hasattr(self, 'backend_instance'):
|
|
116
117
|
del self.backend_instance
|
|
117
118
|
current = self.__class__.objects.get(pk=self.pk)
|
|
118
|
-
|
|
119
|
+
try:
|
|
120
|
+
current_checksum = current.checksum
|
|
121
|
+
except NetjsonconfigValidationError:
|
|
122
|
+
# If the Netjsonconfig library upgrade changes the schema,
|
|
123
|
+
# the old configuration may become invalid, raising an exception.
|
|
124
|
+
# Setting the checksum to None forces related configurations to update.
|
|
125
|
+
current_checksum = None
|
|
126
|
+
update_related_config_status = self.checksum != current_checksum
|
|
119
127
|
# save current changes
|
|
120
128
|
super().save(*args, **kwargs)
|
|
121
129
|
# update relations
|
openwisp_controller-1.1.1/openwisp_controller/config/static/config/js/device-delete-confirmation.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
(function ($) {
|
|
4
|
+
$(document).ready(function () {
|
|
5
|
+
$("#warning-ack").click(function (event) {
|
|
6
|
+
event.preventDefault();
|
|
7
|
+
$("#deactivating-warning").slideUp("fast");
|
|
8
|
+
$("#delete-confirm-container").slideDown("fast");
|
|
9
|
+
$('input[name="force_delete"]').val("true");
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
})(django.jQuery);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{% extends "admin/delete_confirmation.html" %}
|
|
2
|
+
{% load i18n static %}
|
|
3
|
+
|
|
4
|
+
{% block extrastyle %}
|
|
5
|
+
{{ block.super }}
|
|
6
|
+
<link rel="stylesheet" type="text/css" href="{% static 'config/css/device-delete-confirmation.css' %}" />
|
|
7
|
+
{% endblock extrastyle %}
|
|
8
|
+
|
|
9
|
+
{% block content %}
|
|
10
|
+
{% if perms_lacking %}
|
|
11
|
+
<p>{% blocktranslate with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktranslate %}</p>
|
|
12
|
+
<ul>
|
|
13
|
+
{% for obj in perms_lacking %}
|
|
14
|
+
<li>{{ obj }}</li>
|
|
15
|
+
{% endfor %}
|
|
16
|
+
</ul>
|
|
17
|
+
{% elif protected %}
|
|
18
|
+
<p>{% blocktranslate with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would require deleting the following protected related objects:{% endblocktranslate %}</p>
|
|
19
|
+
<ul>
|
|
20
|
+
{% for obj in protected %}
|
|
21
|
+
<li>{{ obj }}</li>
|
|
22
|
+
{% endfor %}
|
|
23
|
+
</ul>
|
|
24
|
+
{% else %}
|
|
25
|
+
{% if deactivating_warning %}
|
|
26
|
+
<div id="deactivating-warning">
|
|
27
|
+
<ul class="messagelist">
|
|
28
|
+
<li class="warning">
|
|
29
|
+
<p>
|
|
30
|
+
<strong>
|
|
31
|
+
{% translate 'Warning: Device is not fully deactivated.' %}
|
|
32
|
+
</strong>
|
|
33
|
+
</p>
|
|
34
|
+
<p>
|
|
35
|
+
{% blocktranslate %}
|
|
36
|
+
This device is still in the process of being deactivated,
|
|
37
|
+
meaning its configuration is still present on the device.
|
|
38
|
+
{% endblocktranslate %}
|
|
39
|
+
</p>
|
|
40
|
+
<p>
|
|
41
|
+
{% blocktranslate %}
|
|
42
|
+
To ensure its configuration is removed, please
|
|
43
|
+
wait until its status changes to
|
|
44
|
+
<strong>"deactivated"</strong>.<br>
|
|
45
|
+
If you proceed now, the device will be deleted,
|
|
46
|
+
but its configuration will remain active.
|
|
47
|
+
{% endblocktranslate %}
|
|
48
|
+
</p>
|
|
49
|
+
<form>
|
|
50
|
+
<input type="submit" class="button danger-btn" id="warning-ack"
|
|
51
|
+
value="{% translate 'I understand the risks, delete the device' %}">
|
|
52
|
+
<a class="button cancel-link">{% translate 'No, take me back' %}</a>
|
|
53
|
+
</form>
|
|
54
|
+
</li>
|
|
55
|
+
</ul>
|
|
56
|
+
</div>
|
|
57
|
+
{% endif %}
|
|
58
|
+
<div id="delete-confirm-container" {% if deactivating_warning %}style="display:none;"{% endif %}>
|
|
59
|
+
<p>{% blocktranslate with escaped_object=object %}Are you sure you want to delete the {{ object_name }}
|
|
60
|
+
"{{ escaped_object }}"? All of the following related items will be deleted:{% endblocktranslate %}</p>
|
|
61
|
+
{% include "admin/includes/object_delete_summary.html" %}
|
|
62
|
+
<h2>{% translate "Objects" %}</h2>
|
|
63
|
+
<ul id="deleted-objects">{{ deleted_objects|unordered_list }}</ul>
|
|
64
|
+
<form method="post">{% csrf_token %}
|
|
65
|
+
<div>
|
|
66
|
+
<input type="hidden" name="post" value="yes">
|
|
67
|
+
{% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
|
|
68
|
+
{% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
|
|
69
|
+
<input type="submit" value="{% translate 'Yes, I’m sure' %}">
|
|
70
|
+
{% if deactivating_warning %}<input type="hidden" name="force_delete" value="false">{% endif %}
|
|
71
|
+
<a href="#" class="button cancel-link">{% translate "No, take me back" %}</a>
|
|
72
|
+
</div>
|
|
73
|
+
</form>
|
|
74
|
+
</div>
|
|
75
|
+
{% endif %}
|
|
76
|
+
{% endblock %}
|
|
77
|
+
|
|
78
|
+
{% block footer %}
|
|
79
|
+
{{ block.super }}
|
|
80
|
+
<script type="text/javascript" src="{% static 'config/js/device-delete-confirmation.js' %}"></script>
|
|
81
|
+
{% endblock %}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{% extends "admin/delete_selected_confirmation.html" %}
|
|
2
|
+
{% load i18n l10n admin_urls static %}
|
|
3
|
+
|
|
4
|
+
{% block extrastyle %}
|
|
5
|
+
{{ block.super }}
|
|
6
|
+
<link rel="stylesheet" type="text/css" href="{% static 'config/css/device-delete-confirmation.css' %}" />
|
|
7
|
+
{% endblock extrastyle %}
|
|
8
|
+
|
|
9
|
+
{% block content %}
|
|
10
|
+
{% if perms_lacking %}
|
|
11
|
+
<p>{% blocktranslate %}Deleting the selected {{ objects_name }} would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktranslate %}</p>
|
|
12
|
+
<ul>{{ perms_lacking|unordered_list }}</ul>
|
|
13
|
+
{% elif protected %}
|
|
14
|
+
<p>{% blocktranslate %}Deleting the selected {{ objects_name }} would require deleting the following protected related objects:{% endblocktranslate %}</p>
|
|
15
|
+
<ul>{{ protected|unordered_list }}</ul>
|
|
16
|
+
{% else %}
|
|
17
|
+
{% if active_devices %}
|
|
18
|
+
<div id="deactivating-warning">
|
|
19
|
+
<ul class="messagelist">
|
|
20
|
+
<li class="warning">
|
|
21
|
+
<p>
|
|
22
|
+
<strong>
|
|
23
|
+
{% blocktranslate count counter=active_devices|length %}
|
|
24
|
+
Warning: Device is not fully deactivated.
|
|
25
|
+
{% plural %}
|
|
26
|
+
Warning: Some devices are not fully deactivated.
|
|
27
|
+
{% endblocktranslate %}
|
|
28
|
+
</strong>
|
|
29
|
+
</p>
|
|
30
|
+
<p>
|
|
31
|
+
{% blocktranslate count counter=active_devices|length %}
|
|
32
|
+
The device below is either still active or
|
|
33
|
+
in the process of being deactivated:
|
|
34
|
+
{% plural %}
|
|
35
|
+
The devices listed below are either still active
|
|
36
|
+
or in the process of being deactivated:
|
|
37
|
+
{% endblocktranslate %}
|
|
38
|
+
</p>
|
|
39
|
+
<ul>{{ active_devices|unordered_list }}</ul>
|
|
40
|
+
<p>
|
|
41
|
+
{% blocktranslate count counter=active_devices|length %}
|
|
42
|
+
To ensure its configuration is removed, please
|
|
43
|
+
wait until its status changes to <strong>"deactivated"</strong>.<br>
|
|
44
|
+
If you proceed now, the device will be deleted,
|
|
45
|
+
but its configuration will remain active.
|
|
46
|
+
{% plural %}
|
|
47
|
+
To ensure their configurations are removed, please
|
|
48
|
+
wait until their status changes to <strong>"deactivated"</strong>.<br>
|
|
49
|
+
If you proceed now, the devices will be deleted,
|
|
50
|
+
but their configurations will remain active.
|
|
51
|
+
{% endblocktranslate %}
|
|
52
|
+
</p>
|
|
53
|
+
<form>
|
|
54
|
+
<input type="submit" class="button danger-btn" id="warning-ack"
|
|
55
|
+
value="{% blocktranslate count counter=active_devices|length %}I understand the risks, delete the device{% plural %}I understand the risks, delete the devices{% endblocktranslate %}">
|
|
56
|
+
<a class="button cancel-link">{% translate 'No, take me back' %}</a>
|
|
57
|
+
</form>
|
|
58
|
+
</li>
|
|
59
|
+
</ul>
|
|
60
|
+
</div>
|
|
61
|
+
{% endif %}
|
|
62
|
+
<div id="delete-confirm-container" {% if active_devices %}style="display:none;"{% endif %}>
|
|
63
|
+
<p>{% blocktranslate %}Are you sure you want to delete the selected {{ objects_name }}? All of the following objects and their related items will be deleted:{% endblocktranslate %}</p>
|
|
64
|
+
{% include "admin/includes/object_delete_summary.html" %}
|
|
65
|
+
<h2>{% translate "Objects" %}</h2>
|
|
66
|
+
{% for deletable_object in deletable_objects %}
|
|
67
|
+
<ul>{{ deletable_object|unordered_list }}</ul>
|
|
68
|
+
{% endfor %}
|
|
69
|
+
<form method="post">{% csrf_token %}
|
|
70
|
+
<div>
|
|
71
|
+
{% for obj in queryset %}
|
|
72
|
+
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}">
|
|
73
|
+
{% endfor %}
|
|
74
|
+
<input type="hidden" name="action" value="delete_selected">
|
|
75
|
+
<input type="hidden" name="post" value="yes">
|
|
76
|
+
<input type="submit" value="{% translate 'Yes, I’m sure' %}">
|
|
77
|
+
<a href="#" class="button cancel-link">{% translate "No, take me back" %}</a>
|
|
78
|
+
</div>
|
|
79
|
+
</form>
|
|
80
|
+
</div>
|
|
81
|
+
{% endif %}
|
|
82
|
+
{% endblock %}
|
|
83
|
+
|
|
84
|
+
{% block footer %}
|
|
85
|
+
{{ block.super }}
|
|
86
|
+
<script type="text/javascript" src="{% static 'config/js/device-delete-confirmation.js' %}"></script>
|
|
87
|
+
{% endblock %}
|
{openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_admin.py
RENAMED
|
@@ -2120,9 +2120,8 @@ class TestTransactionAdmin(
|
|
|
2120
2120
|
)
|
|
2121
2121
|
# Save buttons are absent on deactivated device
|
|
2122
2122
|
self.assertNotContains(response, self._save_btn_html)
|
|
2123
|
-
# Delete button is not present if config status is deactivating
|
|
2124
2123
|
self.assertEqual(device.config.status, 'deactivating')
|
|
2125
|
-
self.
|
|
2124
|
+
self.assertContains(response, delete_btn_html)
|
|
2126
2125
|
self.assertNotContains(response, self._deactivate_btn_html)
|
|
2127
2126
|
self.assertContains(response, self._activate_btn_html)
|
|
2128
2127
|
# Verify adding a new DeviceLocation and DeviceConnection is not allowed
|
{openwisp_controller-1.1 → openwisp_controller-1.1.1}/openwisp_controller/config/tests/test_api.py
RENAMED
|
@@ -539,6 +539,22 @@ class TestConfigApi(
|
|
|
539
539
|
self.assertEqual(response.status_code, 204)
|
|
540
540
|
self.assertEqual(Device.objects.count(), 0)
|
|
541
541
|
|
|
542
|
+
def test_deactivating_device_force_deletion(self):
|
|
543
|
+
self._create_template(required=True)
|
|
544
|
+
device = self._create_device()
|
|
545
|
+
config = self._create_config(device=device)
|
|
546
|
+
device.deactivate()
|
|
547
|
+
path = reverse('config_api:device_detail', args=[device.pk])
|
|
548
|
+
|
|
549
|
+
with self.subTest(
|
|
550
|
+
'Test force deleting device with config in deactivating state'
|
|
551
|
+
):
|
|
552
|
+
self.assertEqual(device.is_deactivated(), True)
|
|
553
|
+
self.assertEqual(config.is_deactivating(), True)
|
|
554
|
+
response = self.client.delete(f'{path}?force=true')
|
|
555
|
+
self.assertEqual(response.status_code, 204)
|
|
556
|
+
self.assertEqual(Device.objects.count(), 0)
|
|
557
|
+
|
|
542
558
|
def test_template_create_no_org_api(self):
|
|
543
559
|
self.assertEqual(Template.objects.count(), 0)
|
|
544
560
|
path = reverse('config_api:template_list')
|
|
@@ -69,6 +69,14 @@ class TestDevice(
|
|
|
69
69
|
else:
|
|
70
70
|
self.fail('ValidationError not raised for "{0}"'.format(mac_address))
|
|
71
71
|
|
|
72
|
+
def test_device_mac_address_uppercase(self):
|
|
73
|
+
device = self._create_device(mac_address='00:1a:2b:3c:4d:5e')
|
|
74
|
+
device.full_clean()
|
|
75
|
+
self.assertEqual(device.mac_address, '00:1A:2B:3C:4D:5E')
|
|
76
|
+
device.save()
|
|
77
|
+
device.refresh_from_db()
|
|
78
|
+
self.assertEqual(device.mac_address, '00:1A:2B:3C:4D:5E')
|
|
79
|
+
|
|
72
80
|
def test_config_status_modified(self):
|
|
73
81
|
c = self._create_config(device=self._create_device(), status='applied')
|
|
74
82
|
self.assertEqual(c.status, 'applied')
|