nautobot 2.4.0b1__py3-none-any.whl → 2.4.1__py3-none-any.whl
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.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/apps/__init__.py +1 -1
- nautobot/apps/api.py +8 -8
- nautobot/apps/change_logging.py +2 -2
- nautobot/apps/choices.py +4 -4
- nautobot/apps/events.py +3 -3
- nautobot/apps/factory.py +2 -2
- nautobot/apps/filters.py +1 -1
- nautobot/apps/forms.py +20 -20
- nautobot/apps/graphql.py +2 -2
- nautobot/apps/jobs.py +8 -8
- nautobot/apps/models.py +19 -19
- nautobot/apps/tables.py +1 -1
- nautobot/apps/testing.py +10 -10
- nautobot/apps/ui.py +2 -2
- nautobot/apps/utils.py +7 -7
- nautobot/apps/views.py +7 -7
- nautobot/circuits/api/serializers.py +1 -0
- nautobot/circuits/api/views.py +4 -8
- nautobot/circuits/tables.py +2 -1
- nautobot/circuits/templates/circuits/circuit_create.html +1 -7
- nautobot/circuits/views.py +3 -3
- nautobot/cloud/api/views.py +6 -10
- nautobot/cloud/models.py +1 -1
- nautobot/cloud/views.py +0 -16
- nautobot/core/api/constants.py +11 -0
- nautobot/core/api/fields.py +5 -5
- nautobot/core/api/filter_backends.py +3 -9
- nautobot/core/api/schema.py +13 -2
- nautobot/core/api/serializers.py +40 -34
- nautobot/core/api/views.py +56 -4
- nautobot/core/celery/log.py +4 -4
- nautobot/core/celery/schedulers.py +2 -2
- nautobot/core/choices.py +2 -2
- nautobot/core/events/__init__.py +3 -3
- nautobot/core/filters.py +67 -35
- nautobot/core/forms/__init__.py +19 -19
- nautobot/core/forms/fields.py +14 -11
- nautobot/core/forms/forms.py +33 -2
- nautobot/core/graphql/types.py +1 -1
- nautobot/core/jobs/__init__.py +28 -7
- nautobot/core/jobs/bulk_actions.py +285 -0
- nautobot/core/jobs/cleanup.py +48 -12
- nautobot/core/jobs/groups.py +1 -1
- nautobot/core/management/commands/validate_models.py +1 -1
- nautobot/core/models/__init__.py +3 -1
- nautobot/core/models/query_functions.py +2 -2
- nautobot/core/models/tree_queries.py +6 -3
- nautobot/core/settings.py +29 -2
- nautobot/core/settings.yaml +21 -0
- nautobot/core/tables.py +79 -61
- nautobot/core/templates/about.html +67 -0
- nautobot/core/templates/inc/media.html +3 -0
- nautobot/core/templates/inc/nav_menu.html +1 -0
- nautobot/core/templates/inc/tenancy_form_panel.html +9 -0
- nautobot/core/templates/inc/tenant_table_row.html +11 -0
- nautobot/core/templates/nautobot_config.py.j2 +13 -0
- nautobot/core/templates/search.html +7 -0
- nautobot/core/templates/utilities/render_jinja2.html +1 -1
- nautobot/core/templates/utilities/templatetags/tag.html +1 -1
- nautobot/core/templates/utilities/theme_preview.html +7 -0
- nautobot/core/templatetags/helpers.py +11 -2
- nautobot/core/testing/__init__.py +8 -8
- nautobot/core/testing/api.py +170 -15
- nautobot/core/testing/filters.py +45 -10
- nautobot/core/testing/forms.py +2 -0
- nautobot/core/testing/integration.py +86 -4
- nautobot/core/testing/mixins.py +7 -2
- nautobot/core/testing/views.py +44 -29
- nautobot/core/tests/integration/test_app_home.py +0 -1
- nautobot/core/tests/integration/test_app_navbar.py +0 -1
- nautobot/core/tests/integration/test_filters.py +0 -2
- nautobot/core/tests/integration/test_home.py +0 -1
- nautobot/core/tests/integration/test_navbar.py +0 -1
- nautobot/core/tests/integration/test_view_authentication.py +1 -0
- nautobot/core/tests/runner.py +1 -1
- nautobot/core/tests/test_api.py +98 -1
- nautobot/core/tests/test_csv.py +25 -3
- nautobot/core/tests/test_filters.py +209 -246
- nautobot/core/tests/test_forms.py +1 -0
- nautobot/core/tests/test_jobs.py +460 -1
- nautobot/core/tests/test_models.py +9 -0
- nautobot/core/tests/test_settings_schema.py +7 -0
- nautobot/core/tests/test_tables.py +100 -0
- nautobot/core/tests/test_utils.py +63 -1
- nautobot/core/tests/test_views.py +30 -3
- nautobot/core/ui/nav.py +1 -0
- nautobot/core/ui/object_detail.py +15 -1
- nautobot/core/urls.py +11 -0
- nautobot/core/utils/lookup.py +11 -8
- nautobot/core/utils/querysets.py +64 -0
- nautobot/core/utils/requests.py +24 -9
- nautobot/core/views/__init__.py +42 -0
- nautobot/core/views/generic.py +131 -197
- nautobot/core/views/mixins.py +126 -38
- nautobot/core/views/renderers.py +6 -6
- nautobot/dcim/api/serializers.py +56 -64
- nautobot/dcim/api/views.py +47 -113
- nautobot/dcim/constants.py +6 -13
- nautobot/dcim/factory.py +6 -1
- nautobot/dcim/filters/__init__.py +31 -2
- nautobot/dcim/forms.py +36 -17
- nautobot/dcim/graphql/types.py +2 -2
- nautobot/dcim/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
- nautobot/dcim/models/__init__.py +1 -1
- nautobot/dcim/models/device_component_templates.py +2 -2
- nautobot/dcim/models/device_components.py +22 -20
- nautobot/dcim/models/devices.py +10 -1
- nautobot/dcim/models/locations.py +3 -3
- nautobot/dcim/models/power.py +6 -5
- nautobot/dcim/models/racks.py +4 -4
- nautobot/dcim/tables/__init__.py +3 -3
- nautobot/dcim/tables/devices.py +7 -5
- nautobot/dcim/tables/devicetypes.py +2 -2
- nautobot/dcim/tables/racks.py +1 -1
- nautobot/dcim/templates/dcim/controller_create.html +1 -7
- nautobot/dcim/templates/dcim/controller_retrieve.html +1 -9
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +2 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +5 -0
- nautobot/dcim/templates/dcim/device.html +1 -9
- nautobot/dcim/templates/dcim/device_edit.html +36 -37
- nautobot/dcim/templates/dcim/location.html +1 -9
- nautobot/dcim/templates/dcim/location_edit.html +1 -7
- nautobot/dcim/templates/dcim/rack.html +1 -9
- nautobot/dcim/templates/dcim/rack_edit.html +1 -7
- nautobot/dcim/templates/dcim/rackreservation.html +1 -9
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +1 -9
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +1 -7
- nautobot/dcim/tests/integration/test_controller.py +62 -0
- nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
- nautobot/dcim/tests/integration/test_device_bulk_delete.py +189 -0
- nautobot/dcim/tests/integration/test_device_bulk_edit.py +181 -0
- nautobot/dcim/tests/test_api.py +16 -5
- nautobot/dcim/tests/test_filters.py +33 -0
- nautobot/dcim/tests/test_forms.py +51 -2
- nautobot/dcim/tests/test_graphql.py +52 -0
- nautobot/dcim/tests/test_jobs.py +118 -0
- nautobot/dcim/tests/test_models.py +52 -9
- nautobot/dcim/tests/test_views.py +21 -83
- nautobot/dcim/views.py +1 -13
- nautobot/extras/api/customfields.py +2 -2
- nautobot/extras/api/serializers.py +90 -85
- nautobot/extras/api/views.py +22 -27
- nautobot/extras/constants.py +2 -0
- nautobot/extras/filters/__init__.py +8 -6
- nautobot/extras/forms/base.py +2 -2
- nautobot/extras/forms/forms.py +139 -31
- nautobot/extras/forms/mixins.py +14 -6
- nautobot/extras/group_sync.py +3 -3
- nautobot/extras/health_checks.py +1 -2
- nautobot/extras/jobs.py +85 -18
- nautobot/extras/managers.py +3 -1
- nautobot/extras/migrations/0018_joblog_data_migration.py +7 -9
- nautobot/extras/migrations/0120_job_is_singleton_job_is_singleton_override.py +22 -0
- nautobot/extras/migrations/0121_alter_team_contacts.py +17 -0
- nautobot/extras/models/__init__.py +1 -1
- nautobot/extras/models/contacts.py +1 -1
- nautobot/extras/models/customfields.py +12 -11
- nautobot/extras/models/groups.py +11 -9
- nautobot/extras/models/jobs.py +23 -4
- nautobot/extras/models/models.py +2 -2
- nautobot/extras/plugins/__init__.py +13 -2
- nautobot/extras/plugins/marketplace_manifest.yml +84 -79
- nautobot/extras/plugins/tables.py +16 -14
- nautobot/extras/plugins/views.py +65 -69
- nautobot/extras/registry.py +1 -1
- nautobot/extras/secrets/__init__.py +2 -2
- nautobot/extras/tables.py +7 -5
- nautobot/extras/templates/extras/dynamicgroup.html +1 -9
- nautobot/extras/templates/extras/job_detail.html +16 -0
- nautobot/extras/templates/extras/job_edit.html +1 -0
- nautobot/extras/templates/extras/jobqueue_retrieve.html +1 -9
- nautobot/extras/templates/extras/marketplace.html +29 -11
- nautobot/extras/templates/extras/plugin_detail.html +32 -15
- nautobot/extras/templates/extras/plugins_tiles.html +21 -10
- nautobot/extras/templatetags/job_buttons.py +4 -4
- nautobot/extras/test_jobs/api_test_job.py +1 -1
- nautobot/extras/test_jobs/atomic_transaction.py +2 -2
- nautobot/extras/test_jobs/dry_run.py +1 -1
- nautobot/extras/test_jobs/fail.py +5 -5
- nautobot/extras/test_jobs/file_output.py +1 -1
- nautobot/extras/test_jobs/file_upload_fail.py +1 -1
- nautobot/extras/test_jobs/file_upload_pass.py +1 -1
- nautobot/extras/test_jobs/ipaddress_vars.py +3 -1
- nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +1 -1
- nautobot/extras/test_jobs/location_with_custom_field.py +1 -1
- nautobot/extras/test_jobs/log_redaction.py +1 -1
- nautobot/extras/test_jobs/log_skip_db_logging.py +1 -1
- nautobot/extras/test_jobs/modify_db.py +1 -1
- nautobot/extras/test_jobs/object_var_optional.py +1 -1
- nautobot/extras/test_jobs/object_var_required.py +1 -1
- nautobot/extras/test_jobs/object_vars.py +1 -1
- nautobot/extras/test_jobs/pass.py +3 -3
- nautobot/extras/test_jobs/profiling.py +1 -1
- nautobot/extras/test_jobs/relative_import.py +3 -3
- nautobot/extras/test_jobs/singleton.py +16 -0
- nautobot/extras/test_jobs/soft_time_limit_greater_than_time_limit.py +1 -1
- nautobot/extras/test_jobs/task_queues.py +1 -1
- nautobot/extras/tests/integration/test_plugin_banner.py +0 -2
- nautobot/extras/tests/test_api.py +13 -13
- nautobot/extras/tests/test_customfields.py +1 -1
- nautobot/extras/tests/test_datasources.py +2 -1
- nautobot/extras/tests/test_dynamicgroups.py +1 -1
- nautobot/extras/tests/test_filters.py +6 -6
- nautobot/extras/tests/test_forms.py +33 -1
- nautobot/extras/tests/test_jobs.py +178 -32
- nautobot/extras/tests/test_models.py +16 -10
- nautobot/extras/tests/test_plugins.py +62 -9
- nautobot/extras/tests/test_relationships.py +120 -9
- nautobot/extras/tests/test_views.py +56 -194
- nautobot/extras/utils.py +3 -2
- nautobot/extras/views.py +30 -98
- nautobot/ipam/api/fields.py +3 -3
- nautobot/ipam/api/serializers.py +41 -33
- nautobot/ipam/api/views.py +68 -117
- nautobot/ipam/factory.py +1 -1
- nautobot/ipam/filters.py +3 -2
- nautobot/ipam/lookups.py +101 -62
- nautobot/ipam/models.py +66 -16
- nautobot/ipam/querysets.py +2 -2
- nautobot/ipam/tables.py +23 -7
- nautobot/ipam/templates/ipam/ipaddress.html +1 -9
- nautobot/ipam/templates/ipam/ipaddress_bulk_add.html +1 -7
- nautobot/ipam/templates/ipam/ipaddress_edit.html +1 -7
- nautobot/ipam/templates/ipam/prefix.html +1 -9
- nautobot/ipam/templates/ipam/prefix_edit.html +1 -7
- nautobot/ipam/templates/ipam/vlan.html +1 -9
- nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
- nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
- nautobot/ipam/tests/test_api.py +436 -3
- nautobot/ipam/tests/test_forms.py +49 -47
- nautobot/ipam/tests/test_migrations.py +30 -30
- nautobot/ipam/tests/test_models.py +95 -34
- nautobot/ipam/tests/test_querysets.py +63 -1
- nautobot/ipam/tests/test_views.py +3 -0
- nautobot/ipam/utils/__init__.py +36 -6
- nautobot/ipam/views.py +61 -87
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css +40 -2
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css +1 -1
- nautobot/project-static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -1
- nautobot/project-static/docs/404.html +46 -4
- nautobot/project-static/docs/apps/index.html +46 -4
- nautobot/project-static/docs/apps/nautobot-apps.html +47 -6
- nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js → bundle.88dd0f4e.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.83f73b43.min.js.map → bundle.88dd0f4e.min.js.map} +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +62 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +59 -7
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +374 -122
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +90 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +95 -21
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +53 -6
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +52 -5
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +79 -17
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +102 -28
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +108 -21
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +131 -38
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +239 -65
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +581 -165
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +109 -36
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +453 -167
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +493 -211
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +60 -8
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +71 -15
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +407 -55
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +620 -205
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +858 -412
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +59 -7
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +448 -186
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +365 -147
- nautobot/project-static/docs/development/apps/api/configuration-view.html +46 -4
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +46 -4
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +46 -4
- nautobot/project-static/docs/development/apps/api/models/global-search.html +46 -4
- nautobot/project-static/docs/development/apps/api/models/graphql.html +46 -4
- nautobot/project-static/docs/development/apps/api/models/index.html +46 -4
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +46 -4
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +68 -7
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +46 -4
- nautobot/project-static/docs/development/apps/api/prometheus.html +46 -4
- nautobot/project-static/docs/development/apps/api/setup.html +46 -4
- nautobot/project-static/docs/development/apps/api/testing.html +46 -4
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +46 -4
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +46 -4
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +46 -4
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +46 -4
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/base-template.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/index.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/notes.html +46 -4
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +52 -6
- nautobot/project-static/docs/development/apps/api/views/urls.html +46 -4
- nautobot/project-static/docs/development/apps/index.html +46 -4
- nautobot/project-static/docs/development/apps/migration/code-updates.html +46 -4
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +46 -4
- nautobot/project-static/docs/development/apps/migration/from-v1.html +46 -4
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +46 -4
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +46 -4
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +46 -4
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +46 -4
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +50 -8
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +46 -4
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +211 -14
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +46 -4
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +46 -4
- nautobot/project-static/docs/development/core/application-registry.html +46 -4
- nautobot/project-static/docs/development/core/best-practices.html +46 -4
- nautobot/project-static/docs/development/core/bootstrap-ui.html +46 -4
- nautobot/project-static/docs/development/core/caching.html +46 -4
- nautobot/project-static/docs/development/core/controllers.html +46 -4
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +73 -74
- nautobot/project-static/docs/development/core/generic-views.html +46 -4
- nautobot/project-static/docs/development/core/getting-started.html +249 -224
- nautobot/project-static/docs/development/core/homepage.html +49 -7
- nautobot/project-static/docs/development/core/index.html +46 -4
- nautobot/project-static/docs/development/core/{local-k8s.html → minikube-dev-environment-for-k8s-jobs.html} +469 -168
- nautobot/project-static/docs/development/core/model-checklist.html +56 -12
- nautobot/project-static/docs/development/core/model-features.html +46 -4
- nautobot/project-static/docs/development/core/natural-keys.html +46 -4
- nautobot/project-static/docs/development/core/navigation-menu.html +46 -4
- nautobot/project-static/docs/development/core/release-checklist.html +49 -7
- nautobot/project-static/docs/development/core/role-internals.html +46 -4
- nautobot/project-static/docs/development/core/settings.html +46 -4
- nautobot/project-static/docs/development/core/style-guide.html +49 -7
- nautobot/project-static/docs/development/core/templates.html +46 -4
- nautobot/project-static/docs/development/core/testing.html +46 -4
- nautobot/project-static/docs/development/core/ui-component-framework.html +369 -273
- nautobot/project-static/docs/development/core/user-preferences.html +46 -4
- nautobot/project-static/docs/development/index.html +46 -4
- nautobot/project-static/docs/development/jobs/index.html +216 -122
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +46 -4
- nautobot/project-static/docs/index.html +54 -23
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_edit_button.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_nav.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_list_view.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_add.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_queue_config.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_completed.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_nav.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_result_pending.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_job_run_form.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_nautobot_login.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_job.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_run_scheduled_job_form.png +0 -0
- nautobot/project-static/docs/media/development/core/kubernetes/k8s_scheduled_job_result.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/buttons-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/cluster-type-before-after-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example_2.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example-code.png +0 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +47 -7
- nautobot/project-static/docs/overview/design_philosophy.html +46 -4
- nautobot/project-static/docs/release-notes/index.html +52 -12
- nautobot/project-static/docs/release-notes/version-1.0.html +234 -193
- nautobot/project-static/docs/release-notes/version-1.1.html +231 -190
- nautobot/project-static/docs/release-notes/version-1.2.html +306 -265
- nautobot/project-static/docs/release-notes/version-1.3.html +332 -291
- nautobot/project-static/docs/release-notes/version-1.4.html +417 -377
- nautobot/project-static/docs/release-notes/version-1.5.html +605 -566
- nautobot/project-static/docs/release-notes/version-1.6.html +904 -447
- nautobot/project-static/docs/release-notes/version-2.0.html +528 -489
- nautobot/project-static/docs/release-notes/version-2.1.html +363 -324
- nautobot/project-static/docs/release-notes/version-2.2.html +356 -317
- nautobot/project-static/docs/release-notes/version-2.3.html +997 -352
- nautobot/project-static/docs/release-notes/version-2.4.html +525 -101
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +295 -287
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +46 -4
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +46 -4
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +48 -6
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +46 -4
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +46 -4
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +110 -8
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +46 -4
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +48 -6
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +46 -4
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +46 -4
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +46 -4
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +66 -8
- nautobot/project-static/docs/user-guide/administration/installation/index.html +46 -4
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +47 -5
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +46 -4
- nautobot/project-static/docs/user-guide/administration/installation/services.html +46 -4
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +46 -4
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +46 -4
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +46 -4
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +49 -8
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +46 -4
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +50 -12
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +49 -7
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +46 -4
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +51 -7
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/central-mode.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-1.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/device-group-create-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/radio-profile-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/supported-data-rate-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-1.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-controller-create-2.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-add.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/images/wireless/wireless-network-create.png +0 -0
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +46 -4
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +49 -7
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9444 -0
- nautobot/project-static/docs/user-guide/index.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +50 -8
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +50 -7
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +49 -7
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/kubernetes-job-support.html +9722 -0
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +47 -5
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +94 -25
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +74 -5
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +46 -4
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +46 -4
- nautobot/project-static/js/forms.js +1 -1
- nautobot/tenancy/api/views.py +9 -13
- nautobot/tenancy/views.py +4 -2
- nautobot/users/admin.py +1 -1
- nautobot/users/api/serializers.py +5 -4
- nautobot/users/api/views.py +3 -3
- nautobot/virtualization/api/serializers.py +4 -4
- nautobot/virtualization/api/views.py +5 -24
- nautobot/virtualization/filters.py +20 -3
- nautobot/virtualization/models.py +1 -1
- nautobot/virtualization/tables.py +2 -2
- nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
- nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -9
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
- nautobot/virtualization/tests/test_filters.py +17 -0
- nautobot/wireless/filters.py +2 -2
- nautobot/wireless/forms.py +1 -1
- nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +1 -9
- nautobot/wireless/tests/integration/__init__.py +0 -0
- nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
- nautobot/wireless/tests/test_filters.py +29 -1
- nautobot/wireless/tests/test_views.py +22 -1
- nautobot/wireless/views.py +0 -10
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/METADATA +6 -6
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/RECORD +600 -550
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/WHEEL +1 -1
- nautobot/core/fixtures/user-data.json +0 -59
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/NOTICE +0 -0
- {nautobot-2.4.0b1.dist-info → nautobot-2.4.1.dist-info}/entry_points.txt +0 -0
nautobot/extras/api/views.py
CHANGED
|
@@ -17,6 +17,7 @@ from rest_framework.permissions import IsAuthenticated
|
|
|
17
17
|
from rest_framework.response import Response
|
|
18
18
|
|
|
19
19
|
from nautobot.core.api.authentication import TokenPermissions
|
|
20
|
+
from nautobot.core.api.parsers import NautobotCSVParser
|
|
20
21
|
from nautobot.core.api.utils import get_serializer_for_model
|
|
21
22
|
from nautobot.core.api.views import (
|
|
22
23
|
BulkDestroyModelMixin,
|
|
@@ -180,14 +181,7 @@ class ConfigContextQuerySetMixin:
|
|
|
180
181
|
|
|
181
182
|
|
|
182
183
|
class ConfigContextViewSet(NotesViewSetMixin, ModelViewSet):
|
|
183
|
-
queryset = ConfigContext.objects.
|
|
184
|
-
"locations",
|
|
185
|
-
"roles",
|
|
186
|
-
"device_types",
|
|
187
|
-
"platforms",
|
|
188
|
-
"tenant_groups",
|
|
189
|
-
"tenants",
|
|
190
|
-
)
|
|
184
|
+
queryset = ConfigContext.objects.all()
|
|
191
185
|
serializer_class = serializers.ConfigContextSerializer
|
|
192
186
|
filterset_class = filters.ConfigContextFilterSet
|
|
193
187
|
|
|
@@ -304,7 +298,7 @@ class DynamicGroupViewSet(NotesViewSetMixin, ModelViewSet):
|
|
|
304
298
|
Manage Dynamic Groups through DELETE, GET, POST, PUT, and PATCH requests.
|
|
305
299
|
"""
|
|
306
300
|
|
|
307
|
-
queryset = DynamicGroup.objects.
|
|
301
|
+
queryset = DynamicGroup.objects.all()
|
|
308
302
|
serializer_class = serializers.DynamicGroupSerializer
|
|
309
303
|
filterset_class = filters.DynamicGroupFilterSet
|
|
310
304
|
|
|
@@ -329,7 +323,7 @@ class DynamicGroupMembershipViewSet(ModelViewSet):
|
|
|
329
323
|
Manage Dynamic Group Memberships through DELETE, GET, POST, PUT, and PATCH requests.
|
|
330
324
|
"""
|
|
331
325
|
|
|
332
|
-
queryset = DynamicGroupMembership.objects.
|
|
326
|
+
queryset = DynamicGroupMembership.objects.all()
|
|
333
327
|
serializer_class = serializers.DynamicGroupMembershipSerializer
|
|
334
328
|
filterset_class = filters.DynamicGroupMembershipFilterSet
|
|
335
329
|
|
|
@@ -340,13 +334,13 @@ class DynamicGroupMembershipViewSet(ModelViewSet):
|
|
|
340
334
|
|
|
341
335
|
|
|
342
336
|
class SavedViewViewSet(ModelViewSet):
|
|
343
|
-
queryset = SavedView.objects.
|
|
337
|
+
queryset = SavedView.objects.all()
|
|
344
338
|
serializer_class = serializers.SavedViewSerializer
|
|
345
339
|
filterset_class = filters.SavedViewFilterSet
|
|
346
340
|
|
|
347
341
|
|
|
348
342
|
class UserSavedViewAssociationViewSet(ModelViewSet):
|
|
349
|
-
queryset = UserSavedViewAssociation.objects.
|
|
343
|
+
queryset = UserSavedViewAssociation.objects.all()
|
|
350
344
|
serializer_class = serializers.UserSavedViewAssociationSerializer
|
|
351
345
|
filterset_class = filters.UserSavedViewAssociationFilterSet
|
|
352
346
|
|
|
@@ -356,7 +350,7 @@ class StaticGroupAssociationViewSet(NautobotModelViewSet):
|
|
|
356
350
|
Manage Static Group Associations through DELETE, GET, POST, PUT, and PATCH requests.
|
|
357
351
|
"""
|
|
358
352
|
|
|
359
|
-
queryset = StaticGroupAssociation.objects.
|
|
353
|
+
queryset = StaticGroupAssociation.objects.all()
|
|
360
354
|
serializer_class = serializers.StaticGroupAssociationSerializer
|
|
361
355
|
filterset_class = filters.StaticGroupAssociationFilterSet
|
|
362
356
|
|
|
@@ -367,7 +361,7 @@ class StaticGroupAssociationViewSet(NautobotModelViewSet):
|
|
|
367
361
|
and "dynamic_group" in self.request.GET
|
|
368
362
|
and self.action in ["list", "retrieve"]
|
|
369
363
|
):
|
|
370
|
-
self.queryset = StaticGroupAssociation.all_objects.
|
|
364
|
+
self.queryset = StaticGroupAssociation.all_objects.all()
|
|
371
365
|
return super().get_queryset()
|
|
372
366
|
|
|
373
367
|
|
|
@@ -388,7 +382,7 @@ class ExportTemplateViewSet(NotesViewSetMixin, ModelViewSet):
|
|
|
388
382
|
|
|
389
383
|
|
|
390
384
|
class ExternalIntegrationViewSet(NautobotModelViewSet):
|
|
391
|
-
queryset = ExternalIntegration.objects.
|
|
385
|
+
queryset = ExternalIntegration.objects.all()
|
|
392
386
|
serializer_class = serializers.ExternalIntegrationSerializer
|
|
393
387
|
filterset_class = filters.ExternalIntegrationFilterSet
|
|
394
388
|
|
|
@@ -399,7 +393,7 @@ class ExternalIntegrationViewSet(NautobotModelViewSet):
|
|
|
399
393
|
|
|
400
394
|
|
|
401
395
|
class FileProxyViewSet(ReadOnlyModelViewSet):
|
|
402
|
-
queryset = FileProxy.objects.
|
|
396
|
+
queryset = FileProxy.objects.all()
|
|
403
397
|
serializer_class = serializers.FileProxySerializer
|
|
404
398
|
filterset_class = filters.FileProxyFilterSet
|
|
405
399
|
|
|
@@ -488,6 +482,7 @@ class ImageAttachmentViewSet(ModelViewSet):
|
|
|
488
482
|
queryset = ImageAttachment.objects.all()
|
|
489
483
|
serializer_class = serializers.ImageAttachmentSerializer
|
|
490
484
|
filterset_class = filters.ImageAttachmentFilterSet
|
|
485
|
+
parser_classes = [JSONParser, NautobotCSVParser, MultiPartParser]
|
|
491
486
|
|
|
492
487
|
|
|
493
488
|
#
|
|
@@ -766,13 +761,13 @@ class JobViewSet(
|
|
|
766
761
|
):
|
|
767
762
|
lookup_value_regex = r"[-0-9a-fA-F]+"
|
|
768
763
|
|
|
769
|
-
def perform_destroy(self,
|
|
770
|
-
if
|
|
764
|
+
def perform_destroy(self, instance):
|
|
765
|
+
if instance.module_name.startswith("nautobot."):
|
|
771
766
|
raise ProtectedError(
|
|
772
|
-
f"Unable to delete Job {
|
|
767
|
+
f"Unable to delete Job {instance}. System Job cannot be deleted",
|
|
773
768
|
[],
|
|
774
769
|
)
|
|
775
|
-
super().perform_destroy(
|
|
770
|
+
super().perform_destroy(instance)
|
|
776
771
|
|
|
777
772
|
|
|
778
773
|
@extend_schema_view(
|
|
@@ -838,7 +833,7 @@ class JobQueueAssignmentViewSet(NautobotModelViewSet):
|
|
|
838
833
|
Manage job queue assignments through DELETE, GET, POST, PUT, and PATCH requests.
|
|
839
834
|
"""
|
|
840
835
|
|
|
841
|
-
queryset = JobQueueAssignment.objects.
|
|
836
|
+
queryset = JobQueueAssignment.objects.all()
|
|
842
837
|
serializer_class = serializers.JobQueueAssignmentSerializer
|
|
843
838
|
filterset_class = filters.JobQueueAssignmentFilterSet
|
|
844
839
|
|
|
@@ -853,7 +848,7 @@ class JobLogEntryViewSet(ReadOnlyModelViewSet):
|
|
|
853
848
|
Retrieve a list of job log entries.
|
|
854
849
|
"""
|
|
855
850
|
|
|
856
|
-
queryset = JobLogEntry.objects.
|
|
851
|
+
queryset = JobLogEntry.objects.all()
|
|
857
852
|
serializer_class = serializers.JobLogEntrySerializer
|
|
858
853
|
filterset_class = filters.JobLogEntryFilterSet
|
|
859
854
|
|
|
@@ -871,7 +866,7 @@ class JobResultViewSet(
|
|
|
871
866
|
Retrieve a list of job results
|
|
872
867
|
"""
|
|
873
868
|
|
|
874
|
-
queryset = JobResult.objects.
|
|
869
|
+
queryset = JobResult.objects.all()
|
|
875
870
|
serializer_class = serializers.JobResultSerializer
|
|
876
871
|
filterset_class = filters.JobResultFilterSet
|
|
877
872
|
|
|
@@ -908,7 +903,7 @@ class ScheduledJobViewSet(ReadOnlyModelViewSet):
|
|
|
908
903
|
Retrieve a list of scheduled jobs
|
|
909
904
|
"""
|
|
910
905
|
|
|
911
|
-
queryset = ScheduledJob.objects.
|
|
906
|
+
queryset = ScheduledJob.objects.all()
|
|
912
907
|
serializer_class = serializers.ScheduledJobSerializer
|
|
913
908
|
filterset_class = filters.ScheduledJobFilterSet
|
|
914
909
|
|
|
@@ -1061,7 +1056,7 @@ class MetadataTypeViewSet(NautobotModelViewSet):
|
|
|
1061
1056
|
|
|
1062
1057
|
|
|
1063
1058
|
class MetadataChoiceViewSet(ModelViewSet):
|
|
1064
|
-
queryset = MetadataChoice.objects.
|
|
1059
|
+
queryset = MetadataChoice.objects.all()
|
|
1065
1060
|
serializer_class = serializers.MetadataChoiceSerializer
|
|
1066
1061
|
filterset_class = filters.MetadataChoiceFilterSet
|
|
1067
1062
|
|
|
@@ -1078,7 +1073,7 @@ class ObjectMetadataViewSet(NautobotModelViewSet):
|
|
|
1078
1073
|
|
|
1079
1074
|
|
|
1080
1075
|
class NoteViewSet(ModelViewSet):
|
|
1081
|
-
queryset = Note.objects.
|
|
1076
|
+
queryset = Note.objects.all()
|
|
1082
1077
|
serializer_class = serializers.NoteSerializer
|
|
1083
1078
|
filterset_class = filters.NoteFilterSet
|
|
1084
1079
|
|
|
@@ -1097,7 +1092,7 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
|
|
|
1097
1092
|
Retrieve a list of recent changes.
|
|
1098
1093
|
"""
|
|
1099
1094
|
|
|
1100
|
-
queryset = ObjectChange.objects.
|
|
1095
|
+
queryset = ObjectChange.objects.all()
|
|
1101
1096
|
serializer_class = serializers.ObjectChangeSerializer
|
|
1102
1097
|
filterset_class = filters.ObjectChangeFilterSet
|
|
1103
1098
|
|
nautobot/extras/constants.py
CHANGED
|
@@ -30,6 +30,7 @@ JOB_OVERRIDABLE_FIELDS = (
|
|
|
30
30
|
"soft_time_limit",
|
|
31
31
|
"time_limit",
|
|
32
32
|
"has_sensitive_variables",
|
|
33
|
+
"is_singleton",
|
|
33
34
|
)
|
|
34
35
|
|
|
35
36
|
|
|
@@ -52,4 +53,5 @@ JOB_RESULT_CUSTOM_CELERY_KWARGS = (
|
|
|
52
53
|
"nautobot_job_job_model_id",
|
|
53
54
|
"nautobot_job_scheduled_job_id",
|
|
54
55
|
"nautobot_job_user_id",
|
|
56
|
+
"nautobot_job_ignore_singleton_lock",
|
|
55
57
|
)
|
|
@@ -119,13 +119,13 @@ __all__ = (
|
|
|
119
119
|
"CustomFieldDateFilter",
|
|
120
120
|
"CustomFieldFilterMixin",
|
|
121
121
|
"CustomFieldJSONFilter",
|
|
122
|
+
"CustomFieldModelFilterSet",
|
|
123
|
+
"CustomFieldModelFilterSetMixin",
|
|
122
124
|
"CustomFieldMultiSelectFilter",
|
|
123
125
|
"CustomFieldMultiValueCharFilter",
|
|
124
126
|
"CustomFieldMultiValueDateFilter",
|
|
125
127
|
"CustomFieldMultiValueNumberFilter",
|
|
126
128
|
"CustomFieldNumberFilter",
|
|
127
|
-
"CustomFieldModelFilterSet",
|
|
128
|
-
"CustomFieldModelFilterSetMixin",
|
|
129
129
|
"CustomLinkFilterSet",
|
|
130
130
|
"DynamicGroupFilterSet",
|
|
131
131
|
"DynamicGroupMembershipFilterSet",
|
|
@@ -136,25 +136,25 @@ __all__ = (
|
|
|
136
136
|
"ImageAttachmentFilterSet",
|
|
137
137
|
"JobFilterSet",
|
|
138
138
|
"JobLogEntryFilterSet",
|
|
139
|
-
"JobQueueFilterSet",
|
|
140
139
|
"JobQueueAssignmentFilterSet",
|
|
140
|
+
"JobQueueFilterSet",
|
|
141
141
|
"JobResultFilterSet",
|
|
142
142
|
"LocalContextFilterSet",
|
|
143
143
|
"LocalContextModelFilterSetMixin",
|
|
144
|
-
"MetadataTypeFilterSet",
|
|
145
144
|
"MetadataChoiceFilterSet",
|
|
145
|
+
"MetadataTypeFilterSet",
|
|
146
146
|
"NautobotFilterSet",
|
|
147
147
|
"NoteFilterSet",
|
|
148
148
|
"ObjectChangeFilterSet",
|
|
149
|
+
"RelationshipAssociationFilterSet",
|
|
149
150
|
"RelationshipFilter",
|
|
150
151
|
"RelationshipFilterSet",
|
|
151
|
-
"RelationshipAssociationFilterSet",
|
|
152
152
|
"RoleFilterSet",
|
|
153
153
|
"RoleModelFilterSetMixin",
|
|
154
154
|
"ScheduledJobFilterSet",
|
|
155
155
|
"SecretFilterSet",
|
|
156
|
-
"SecretsGroupFilterSet",
|
|
157
156
|
"SecretsGroupAssociationFilterSet",
|
|
157
|
+
"SecretsGroupFilterSet",
|
|
158
158
|
"StatusFilter",
|
|
159
159
|
"StatusFilterSet",
|
|
160
160
|
"StatusModelFilterSetMixin",
|
|
@@ -874,6 +874,7 @@ class JobFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
|
|
|
874
874
|
"is_job_button_receiver",
|
|
875
875
|
"soft_time_limit",
|
|
876
876
|
"time_limit",
|
|
877
|
+
"is_singleton",
|
|
877
878
|
"grouping_override",
|
|
878
879
|
"name_override",
|
|
879
880
|
"approval_required_override",
|
|
@@ -883,6 +884,7 @@ class JobFilterSet(BaseFilterSet, CustomFieldModelFilterSetMixin):
|
|
|
883
884
|
"soft_time_limit_override",
|
|
884
885
|
"time_limit_override",
|
|
885
886
|
"has_sensitive_variables_override",
|
|
887
|
+
"is_singleton_override",
|
|
886
888
|
"tags",
|
|
887
889
|
]
|
|
888
890
|
|
nautobot/extras/forms/base.py
CHANGED
nautobot/extras/forms/forms.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import inspect
|
|
2
|
+
import logging
|
|
2
3
|
|
|
4
|
+
from celery import chain
|
|
3
5
|
from django import forms
|
|
4
6
|
from django.conf import settings
|
|
5
7
|
from django.contrib.auth import get_user_model
|
|
@@ -7,7 +9,7 @@ from django.contrib.contenttypes.models import ContentType
|
|
|
7
9
|
from django.core.exceptions import ValidationError
|
|
8
10
|
from django.core.validators import MinValueValidator
|
|
9
11
|
from django.db.models.fields import TextField
|
|
10
|
-
from django.forms import inlineformset_factory, ModelMultipleChoiceField
|
|
12
|
+
from django.forms import inlineformset_factory, ModelMultipleChoiceField, MultipleHiddenInput
|
|
11
13
|
from django.urls.base import reverse
|
|
12
14
|
from django.utils.timezone import get_current_timezone_name
|
|
13
15
|
|
|
@@ -35,6 +37,7 @@ from nautobot.core.forms import (
|
|
|
35
37
|
TagFilterField,
|
|
36
38
|
)
|
|
37
39
|
from nautobot.core.forms.constants import BOOLEAN_WITH_BLANK_CHOICES
|
|
40
|
+
from nautobot.core.forms.forms import ConfirmationForm
|
|
38
41
|
from nautobot.core.utils.deprecation import class_deprecated_in_favor_of
|
|
39
42
|
from nautobot.dcim.models import Device, DeviceRedundancyGroup, DeviceType, Location, Platform
|
|
40
43
|
from nautobot.extras.choices import (
|
|
@@ -88,9 +91,12 @@ from nautobot.extras.models import (
|
|
|
88
91
|
Webhook,
|
|
89
92
|
)
|
|
90
93
|
from nautobot.extras.registry import registry
|
|
94
|
+
from nautobot.extras.signals import change_context_state
|
|
95
|
+
from nautobot.extras.tasks import delete_custom_field_data
|
|
91
96
|
from nautobot.extras.utils import (
|
|
92
97
|
ChangeLoggedModelsQuery,
|
|
93
98
|
FeatureQuery,
|
|
99
|
+
get_worker_count,
|
|
94
100
|
RoleModelsQuery,
|
|
95
101
|
TaggableClassesQuery,
|
|
96
102
|
)
|
|
@@ -111,87 +117,90 @@ from .mixins import (
|
|
|
111
117
|
TagsBulkEditFormMixin,
|
|
112
118
|
)
|
|
113
119
|
|
|
120
|
+
logger = logging.getLogger(__name__)
|
|
121
|
+
|
|
114
122
|
__all__ = (
|
|
115
123
|
"BaseDynamicGroupMembershipFormSet",
|
|
116
|
-
"ComputedFieldForm",
|
|
117
124
|
"ComputedFieldFilterForm",
|
|
118
|
-
"
|
|
125
|
+
"ComputedFieldForm",
|
|
119
126
|
"ConfigContextBulkEditForm",
|
|
120
127
|
"ConfigContextFilterForm",
|
|
121
|
-
"
|
|
128
|
+
"ConfigContextForm",
|
|
122
129
|
"ConfigContextSchemaBulkEditForm",
|
|
123
130
|
"ConfigContextSchemaFilterForm",
|
|
124
|
-
"
|
|
125
|
-
"CustomFieldFilterForm",
|
|
126
|
-
"CustomFieldModelCSVForm",
|
|
131
|
+
"ConfigContextSchemaForm",
|
|
127
132
|
"CustomFieldBulkCreateForm", # 2.0 TODO remove this deprecated class
|
|
133
|
+
"CustomFieldBulkDeleteForm",
|
|
128
134
|
"CustomFieldChoiceFormSet",
|
|
129
|
-
"
|
|
135
|
+
"CustomFieldFilterForm",
|
|
136
|
+
"CustomFieldForm",
|
|
137
|
+
"CustomFieldModelCSVForm",
|
|
130
138
|
"CustomLinkFilterForm",
|
|
139
|
+
"CustomLinkForm",
|
|
131
140
|
"DynamicGroupBulkAssignForm",
|
|
132
|
-
"DynamicGroupForm",
|
|
133
141
|
"DynamicGroupFilterForm",
|
|
142
|
+
"DynamicGroupForm",
|
|
134
143
|
"DynamicGroupMembershipFormSet",
|
|
135
|
-
"ExportTemplateForm",
|
|
136
144
|
"ExportTemplateFilterForm",
|
|
145
|
+
"ExportTemplateForm",
|
|
146
|
+
"ExternalIntegrationBulkEditForm",
|
|
137
147
|
"ExternalIntegrationFilterForm",
|
|
138
148
|
"ExternalIntegrationForm",
|
|
139
|
-
"ExternalIntegrationBulkEditForm",
|
|
140
|
-
"GitRepositoryForm",
|
|
141
149
|
"GitRepositoryBulkEditForm",
|
|
142
150
|
"GitRepositoryFilterForm",
|
|
143
|
-
"
|
|
151
|
+
"GitRepositoryForm",
|
|
144
152
|
"GraphQLQueryFilterForm",
|
|
153
|
+
"GraphQLQueryForm",
|
|
145
154
|
"ImageAttachmentForm",
|
|
146
|
-
"JobForm",
|
|
147
155
|
"JobBulkEditForm",
|
|
148
|
-
"JobButtonForm",
|
|
149
156
|
"JobButtonBulkEditForm",
|
|
150
157
|
"JobButtonFilterForm",
|
|
158
|
+
"JobButtonForm",
|
|
151
159
|
"JobEditForm",
|
|
152
160
|
"JobFilterForm",
|
|
153
|
-
"
|
|
161
|
+
"JobForm",
|
|
154
162
|
"JobHookFilterForm",
|
|
163
|
+
"JobHookForm",
|
|
155
164
|
"JobQueueBulkEditForm",
|
|
156
165
|
"JobQueueFilterForm",
|
|
157
166
|
"JobQueueForm",
|
|
158
|
-
"JobScheduleForm",
|
|
159
167
|
"JobResultFilterForm",
|
|
168
|
+
"JobScheduleForm",
|
|
160
169
|
"LocalContextFilterForm",
|
|
161
|
-
"LocalContextModelForm",
|
|
162
170
|
"LocalContextModelBulkEditForm",
|
|
171
|
+
"LocalContextModelForm",
|
|
172
|
+
"MetadataChoiceFormSet",
|
|
163
173
|
"MetadataTypeBulkEditForm",
|
|
164
|
-
"MetadataTypeForm",
|
|
165
174
|
"MetadataTypeFilterForm",
|
|
166
|
-
"
|
|
167
|
-
"NoteForm",
|
|
175
|
+
"MetadataTypeForm",
|
|
168
176
|
"NoteFilterForm",
|
|
177
|
+
"NoteForm",
|
|
169
178
|
"ObjectChangeFilterForm",
|
|
170
179
|
"ObjectMetadataFilterForm",
|
|
171
180
|
"PasswordInputWithPlaceholder",
|
|
172
|
-
"RelationshipForm",
|
|
173
|
-
"RelationshipFilterForm",
|
|
174
181
|
"RelationshipAssociationFilterForm",
|
|
182
|
+
"RelationshipFilterForm",
|
|
183
|
+
"RelationshipForm",
|
|
175
184
|
"RoleBulkEditForm",
|
|
176
185
|
"RoleFilterForm",
|
|
177
186
|
"RoleForm",
|
|
178
187
|
"SavedViewForm",
|
|
179
188
|
"SavedViewModalForm",
|
|
180
189
|
"ScheduledJobFilterForm",
|
|
181
|
-
"SecretForm",
|
|
182
190
|
"SecretFilterForm",
|
|
183
|
-
"
|
|
184
|
-
"SecretsGroupFilterForm",
|
|
191
|
+
"SecretForm",
|
|
185
192
|
"SecretsGroupAssociationFormSet",
|
|
193
|
+
"SecretsGroupFilterForm",
|
|
194
|
+
"SecretsGroupForm",
|
|
186
195
|
"StaticGroupAssociationFilterForm",
|
|
187
|
-
"StatusForm",
|
|
188
|
-
"StatusFilterForm",
|
|
189
196
|
"StatusBulkEditForm",
|
|
190
|
-
"
|
|
191
|
-
"
|
|
197
|
+
"StatusFilterForm",
|
|
198
|
+
"StatusForm",
|
|
192
199
|
"TagBulkEditForm",
|
|
193
|
-
"
|
|
200
|
+
"TagFilterForm",
|
|
201
|
+
"TagForm",
|
|
194
202
|
"WebhookFilterForm",
|
|
203
|
+
"WebhookForm",
|
|
195
204
|
)
|
|
196
205
|
|
|
197
206
|
|
|
@@ -491,6 +500,44 @@ class CustomFieldBulkCreateForm(CustomFieldModelBulkEditFormMixin):
|
|
|
491
500
|
"""No longer needed as a separate class - use CustomFieldModelBulkEditFormMixin instead."""
|
|
492
501
|
|
|
493
502
|
|
|
503
|
+
class CustomFieldBulkDeleteForm(ConfirmationForm):
|
|
504
|
+
def __init__(self, *args, delete_all=False, **kwargs):
|
|
505
|
+
super().__init__(*args, **kwargs)
|
|
506
|
+
queryset = CustomField.objects.all()
|
|
507
|
+
self.fields["pk"] = ModelMultipleChoiceField(
|
|
508
|
+
queryset=queryset, widget=MultipleHiddenInput, required=not delete_all
|
|
509
|
+
)
|
|
510
|
+
|
|
511
|
+
def construct_custom_field_delete_tasks(self, queryset):
|
|
512
|
+
"""
|
|
513
|
+
Helper method to construct a list of celery tasks to execute when bulk deleting custom fields.
|
|
514
|
+
"""
|
|
515
|
+
change_context = change_context_state.get()
|
|
516
|
+
if change_context is None:
|
|
517
|
+
context = None
|
|
518
|
+
else:
|
|
519
|
+
context = change_context.as_dict(queryset)
|
|
520
|
+
context["context_detail"] = "bulk delete custom field data"
|
|
521
|
+
tasks = [
|
|
522
|
+
delete_custom_field_data.si(obj.key, set(obj.content_types.values_list("pk", flat=True)), context)
|
|
523
|
+
for obj in queryset
|
|
524
|
+
]
|
|
525
|
+
return tasks
|
|
526
|
+
|
|
527
|
+
def perform_pre_delete(self, queryset):
|
|
528
|
+
"""
|
|
529
|
+
Remove all Custom Field Keys/Values from _custom_field_data of the related ContentType in the background.
|
|
530
|
+
"""
|
|
531
|
+
if not get_worker_count():
|
|
532
|
+
logger.error("Celery worker process not running. Object custom fields may fail to reflect this deletion.")
|
|
533
|
+
return
|
|
534
|
+
tasks = self.construct_custom_field_delete_tasks(queryset)
|
|
535
|
+
# Executing the tasks in the background sequentially using chain() aligns with how a single
|
|
536
|
+
# CustomField object is deleted. We decided to not check the result because it needs at least one worker
|
|
537
|
+
# to be active and comes with extra performance penalty.
|
|
538
|
+
chain(*tasks).apply_async()
|
|
539
|
+
|
|
540
|
+
|
|
494
541
|
#
|
|
495
542
|
# Custom Links
|
|
496
543
|
#
|
|
@@ -990,6 +1037,8 @@ class JobEditForm(NautobotModelForm):
|
|
|
990
1037
|
"job_queues",
|
|
991
1038
|
"default_job_queue_override",
|
|
992
1039
|
"default_job_queue",
|
|
1040
|
+
"is_singleton",
|
|
1041
|
+
"is_singleton_override",
|
|
993
1042
|
"tags",
|
|
994
1043
|
]
|
|
995
1044
|
|
|
@@ -1089,6 +1138,11 @@ class JobBulkEditForm(NautobotBulkEditForm):
|
|
|
1089
1138
|
required=False,
|
|
1090
1139
|
help_text="Default Job Queue the job runs on if no Job Queue is specified",
|
|
1091
1140
|
)
|
|
1141
|
+
is_singleton = forms.NullBooleanField(
|
|
1142
|
+
required=False,
|
|
1143
|
+
widget=BulkEditNullBooleanSelect,
|
|
1144
|
+
help_text="Whether this job should fail to run if another instance of this job is already running",
|
|
1145
|
+
)
|
|
1092
1146
|
# Flags to indicate whether the above properties are inherited from the source code or overridden by the database
|
|
1093
1147
|
# Text field overrides
|
|
1094
1148
|
clear_grouping_override = forms.BooleanField(
|
|
@@ -1132,10 +1186,62 @@ class JobBulkEditForm(NautobotBulkEditForm):
|
|
|
1132
1186
|
required=False,
|
|
1133
1187
|
help_text="If checked, the values of has sensitive variables will be reverted to the default values defined in each Job's source code",
|
|
1134
1188
|
)
|
|
1189
|
+
is_singleton_override = forms.BooleanField(
|
|
1190
|
+
required=False,
|
|
1191
|
+
help_text="If checked, the values of is singleton will be reverted to the default values defined in each Job's source code",
|
|
1192
|
+
)
|
|
1135
1193
|
|
|
1136
1194
|
class Meta:
|
|
1137
1195
|
model = Job
|
|
1138
1196
|
|
|
1197
|
+
def post_save(self, obj):
|
|
1198
|
+
super().post_save(obj)
|
|
1199
|
+
|
|
1200
|
+
cleaned_data = self.cleaned_data
|
|
1201
|
+
|
|
1202
|
+
# Handle text related fields
|
|
1203
|
+
for overridable_field in JOB_OVERRIDABLE_FIELDS:
|
|
1204
|
+
override_field = overridable_field + "_override"
|
|
1205
|
+
clear_override_field = "clear_" + overridable_field + "_override"
|
|
1206
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1207
|
+
override_value = cleaned_data.get(overridable_field)
|
|
1208
|
+
if reset_override:
|
|
1209
|
+
setattr(obj, override_field, False)
|
|
1210
|
+
elif not reset_override and override_value not in [None, ""]:
|
|
1211
|
+
setattr(obj, override_field, True)
|
|
1212
|
+
setattr(obj, overridable_field, override_value)
|
|
1213
|
+
|
|
1214
|
+
# Handle job queues
|
|
1215
|
+
clear_override_field = "clear_job_queues_override"
|
|
1216
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1217
|
+
if reset_override:
|
|
1218
|
+
meta_task_queues = obj.job_class.task_queues
|
|
1219
|
+
job_queues = []
|
|
1220
|
+
for queue_name in meta_task_queues:
|
|
1221
|
+
try:
|
|
1222
|
+
job_queues.append(JobQueue.objects.get(name=queue_name))
|
|
1223
|
+
except JobQueue.DoesNotExist:
|
|
1224
|
+
# Do we want to create the Job Queue for the users here if we do not have it in the database?
|
|
1225
|
+
pass
|
|
1226
|
+
obj.job_queues_override = False
|
|
1227
|
+
obj.job_queues.set(job_queues)
|
|
1228
|
+
elif cleaned_data["job_queues"]:
|
|
1229
|
+
obj.job_queues_override = True
|
|
1230
|
+
|
|
1231
|
+
# Handle default job queue
|
|
1232
|
+
clear_override_field = "clear_default_job_queue_override"
|
|
1233
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1234
|
+
if reset_override:
|
|
1235
|
+
meta_task_queues = obj.job_class.task_queues
|
|
1236
|
+
obj.default_job_queue_override = False
|
|
1237
|
+
obj.default_job_queue, _ = JobQueue.objects.get_or_create(
|
|
1238
|
+
name=meta_task_queues[0] if meta_task_queues else settings.CELERY_TASK_DEFAULT_QUEUE
|
|
1239
|
+
)
|
|
1240
|
+
elif cleaned_data["default_job_queue"]:
|
|
1241
|
+
obj.default_job_queue_override = True
|
|
1242
|
+
|
|
1243
|
+
obj.validated_save()
|
|
1244
|
+
|
|
1139
1245
|
|
|
1140
1246
|
class JobFilterForm(BootstrapMixin, forms.Form):
|
|
1141
1247
|
model = Job
|
|
@@ -1779,6 +1885,8 @@ class RoleBulkEditForm(NautobotBulkEditForm):
|
|
|
1779
1885
|
|
|
1780
1886
|
pk = forms.ModelMultipleChoiceField(queryset=Role.objects.all(), widget=forms.MultipleHiddenInput)
|
|
1781
1887
|
color = forms.CharField(max_length=6, required=False, widget=ColorSelect())
|
|
1888
|
+
description = forms.CharField(max_length=CHARFIELD_MAX_LENGTH, required=False)
|
|
1889
|
+
weight = forms.IntegerField(required=False)
|
|
1782
1890
|
content_types = MultipleContentTypeField(
|
|
1783
1891
|
queryset=RoleModelsQuery().as_queryset(), required=False, label="Content Type(s)"
|
|
1784
1892
|
)
|
nautobot/extras/forms/mixins.py
CHANGED
|
@@ -34,7 +34,7 @@ from nautobot.extras.utils import remove_prefix_from_cf_key
|
|
|
34
34
|
logger = logging.getLogger(__name__)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
__all__ = (
|
|
37
|
+
__all__ = ( # noqa:RUF022
|
|
38
38
|
"ContactTeamModelFilterFormMixin",
|
|
39
39
|
"CustomFieldModelBulkEditFormMixin",
|
|
40
40
|
"CustomFieldModelFilterFormMixin",
|
|
@@ -327,7 +327,7 @@ class RelationshipModelBulkEditFormMixin(BulkEditForm):
|
|
|
327
327
|
field_name,
|
|
328
328
|
instance,
|
|
329
329
|
)
|
|
330
|
-
if field_name in self.nullable_fields and field_name in nullified_fields:
|
|
330
|
+
if field_name in self.nullable_fields and nullified_fields and field_name in nullified_fields:
|
|
331
331
|
logger.debug("Deleting existing relationship associations for %s on %s", relationship, instance)
|
|
332
332
|
relationshipassociation_queryset.delete()
|
|
333
333
|
elif field_name in self.cleaned_data:
|
|
@@ -673,7 +673,7 @@ class RelationshipModelFormMixin(forms.ModelForm):
|
|
|
673
673
|
for peer_id in target_peer_ids:
|
|
674
674
|
relationship = self.fields[field_name].model
|
|
675
675
|
if not relationship.symmetric:
|
|
676
|
-
association = RelationshipAssociation(
|
|
676
|
+
association = RelationshipAssociation( # pylint: disable=repeated-keyword
|
|
677
677
|
relationship=relationship,
|
|
678
678
|
**{
|
|
679
679
|
f"{side}_type": self.obj_type,
|
|
@@ -837,13 +837,21 @@ class StatusModelFilterFormMixin(forms.Form):
|
|
|
837
837
|
self.order_fields(self.field_order) # Reorder fields again
|
|
838
838
|
|
|
839
839
|
|
|
840
|
-
class TagsBulkEditFormMixin(
|
|
840
|
+
class TagsBulkEditFormMixin(BulkEditForm):
|
|
841
841
|
def __init__(self, *args, **kwargs):
|
|
842
842
|
super().__init__(*args, **kwargs)
|
|
843
843
|
|
|
844
844
|
# Add add/remove tags fields
|
|
845
|
-
self.fields["add_tags"] = DynamicModelMultipleChoiceField(
|
|
846
|
-
|
|
845
|
+
self.fields["add_tags"] = DynamicModelMultipleChoiceField(
|
|
846
|
+
queryset=Tag.objects.all(),
|
|
847
|
+
query_params={"content_types": self.model._meta.label_lower},
|
|
848
|
+
required=False,
|
|
849
|
+
)
|
|
850
|
+
self.fields["remove_tags"] = DynamicModelMultipleChoiceField(
|
|
851
|
+
queryset=Tag.objects.all(),
|
|
852
|
+
query_params={"content_types": self.model._meta.label_lower},
|
|
853
|
+
required=False,
|
|
854
|
+
)
|
|
847
855
|
|
|
848
856
|
|
|
849
857
|
# 2.2 TODO: Names below are only for backward compatibility with Nautobot 1.3 and earlier. Remove in 2.2
|
nautobot/extras/group_sync.py
CHANGED
|
@@ -8,15 +8,15 @@ from django.contrib.auth.models import Group
|
|
|
8
8
|
logger = logging.getLogger(__name__)
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
CLAIMS_GROUP_NAME = getattr(settings, "
|
|
11
|
+
CLAIMS_GROUP_NAME = getattr(settings, "SSO_CLAIMS_GROUP", "groups")
|
|
12
12
|
""" Which claim to look at in the OAuth2/OIDC response
|
|
13
13
|
|
|
14
14
|
For Okta you can look at `Okta -> Authorization Servers -> Claims`. And a reasonable
|
|
15
15
|
default is "groups". For Azure a reasonable default is "roles".
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
SUPERUSER_GROUPS = getattr(settings, "
|
|
19
|
-
STAFF_GROUPS = getattr(settings, "
|
|
18
|
+
SUPERUSER_GROUPS = getattr(settings, "SSO_SUPERUSER_GROUPS", [])
|
|
19
|
+
STAFF_GROUPS = getattr(settings, "SSO_STAFF_GROUPS", [])
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def group_sync(uid, user=None, response=None, *args, **kwargs):
|
nautobot/extras/health_checks.py
CHANGED
|
@@ -160,5 +160,4 @@ class RedisBackend(RedisHealthCheck):
|
|
|
160
160
|
elif client_class == "django_redis.client.DefaultClient":
|
|
161
161
|
self.check_redis(redis_url=location, **options.get("CONNECTION_POOL_KWARGS", {}))
|
|
162
162
|
else:
|
|
163
|
-
|
|
164
|
-
self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))
|
|
163
|
+
self.add_error(ServiceUnavailable(f"{client_class} is an unsupported CLIENT_CLASS!"))
|