nautobot 2.3.16__py3-none-any.whl → 2.4.0b1__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/__init__.py +15 -0
- nautobot/apps/api.py +0 -2
- nautobot/apps/config.py +32 -3
- nautobot/apps/events.py +19 -0
- nautobot/apps/exceptions.py +0 -2
- nautobot/apps/ui.py +44 -9
- nautobot/apps/utils.py +0 -8
- nautobot/apps/views.py +2 -0
- nautobot/circuits/navigation.py +0 -57
- nautobot/circuits/tables.py +1 -2
- nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -71
- nautobot/circuits/templates/circuits/inc/circuit_termination.html +6 -64
- nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +40 -0
- nautobot/circuits/templates/circuits/inc/circuit_termination_header_extra_content.html +26 -0
- nautobot/circuits/templates/circuits/provider_retrieve.html +0 -76
- nautobot/circuits/tests/integration/test_relationships.py +33 -24
- nautobot/circuits/tests/test_filters.py +4 -8
- nautobot/circuits/views.py +143 -26
- nautobot/cloud/factory.py +4 -1
- nautobot/cloud/models.py +1 -1
- nautobot/cloud/tests/test_filters.py +5 -4
- nautobot/core/api/fields.py +5 -5
- nautobot/core/api/metadata.py +28 -256
- nautobot/core/api/pagination.py +3 -2
- nautobot/core/api/renderers.py +3 -0
- nautobot/core/api/serializers.py +24 -244
- nautobot/core/api/urls.py +3 -4
- nautobot/core/api/utils.py +0 -62
- nautobot/core/api/views.py +48 -158
- nautobot/core/apps/__init__.py +22 -578
- nautobot/core/celery/__init__.py +13 -0
- nautobot/core/celery/log.py +4 -4
- nautobot/core/celery/schedulers.py +48 -3
- nautobot/core/cli/__init__.py +8 -0
- nautobot/core/constants.py +7 -0
- nautobot/core/events/__init__.py +116 -0
- nautobot/core/events/base.py +27 -0
- nautobot/core/events/exceptions.py +10 -0
- nautobot/core/events/redis_broker.py +48 -0
- nautobot/core/events/syslog_broker.py +19 -0
- nautobot/core/exceptions.py +0 -6
- nautobot/core/filters.py +16 -21
- nautobot/core/fixtures/user-data.json +59 -0
- nautobot/core/forms/fields.py +53 -8
- nautobot/core/forms/utils.py +2 -1
- nautobot/core/graphql/schema.py +3 -1
- nautobot/core/graphql/types.py +1 -1
- nautobot/core/jobs/__init__.py +4 -4
- nautobot/core/jobs/cleanup.py +13 -49
- nautobot/core/jobs/groups.py +1 -1
- nautobot/core/management/commands/generate_test_data.py +21 -0
- nautobot/core/management/commands/validate_models.py +1 -1
- nautobot/core/middleware.py +16 -0
- nautobot/core/models/__init__.py +1 -1
- nautobot/core/models/fields.py +11 -7
- nautobot/core/models/query_functions.py +2 -2
- nautobot/core/models/tree_queries.py +3 -6
- nautobot/core/settings.py +44 -7
- nautobot/core/settings.yaml +86 -8
- nautobot/core/tables.py +15 -65
- nautobot/core/tasks.py +1 -1
- nautobot/core/templates/components/button/default.html +7 -0
- nautobot/core/templates/components/button/dropdown.html +20 -0
- nautobot/core/templates/components/layout/one_over_two.html +19 -0
- nautobot/core/templates/components/layout/two_over_one.html +19 -0
- nautobot/core/templates/components/panel/body_content_data_table.html +27 -0
- nautobot/core/templates/components/panel/body_content_objects_table.html +4 -0
- nautobot/core/templates/components/panel/body_content_tags.html +6 -0
- nautobot/core/templates/components/panel/body_content_text.html +12 -0
- nautobot/core/templates/components/panel/body_wrapper_generic.html +3 -0
- nautobot/core/templates/components/panel/body_wrapper_key_value_table.html +3 -0
- nautobot/core/templates/components/panel/body_wrapper_table.html +3 -0
- nautobot/core/templates/components/panel/footer_contacts_table.html +20 -0
- nautobot/core/templates/components/panel/footer_content_table.html +14 -0
- nautobot/core/templates/components/panel/grouping_toggle.html +14 -0
- nautobot/core/templates/components/panel/header_extra_content_table.html +3 -0
- nautobot/core/templates/components/panel/panel.html +16 -0
- nautobot/core/templates/components/panel/stats_panel_body.html +8 -0
- nautobot/core/templates/components/tab/content_wrapper.html +3 -0
- nautobot/core/templates/components/tab/label_wrapper.html +5 -0
- nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +3 -0
- nautobot/core/templates/generic/object_retrieve.html +28 -17
- nautobot/core/templates/inc/computed_fields/panel_data.html +4 -7
- nautobot/core/templates/inc/custom_fields/panel.html +2 -2
- nautobot/core/templates/inc/custom_fields/panel_data.html +4 -7
- nautobot/core/templates/inc/footer.html +1 -0
- nautobot/core/templates/inc/media.html +0 -3
- nautobot/core/templates/inc/nav_menu.html +1 -1
- nautobot/core/templates/inc/relationships_panel.html +1 -1
- nautobot/core/templates/nautobot_config.py.j2 +3 -3
- nautobot/core/templates/panel_table.html +12 -0
- nautobot/core/templates/search.html +0 -7
- nautobot/core/templates/utilities/render_jinja2.html +117 -0
- nautobot/core/templatetags/helpers.py +101 -12
- nautobot/core/templatetags/ui_framework.py +40 -0
- nautobot/core/testing/api.py +23 -128
- nautobot/core/testing/context.py +18 -0
- nautobot/core/testing/filters.py +41 -58
- nautobot/core/testing/mixins.py +2 -7
- nautobot/core/testing/views.py +25 -123
- nautobot/core/tests/integration/test_app_home.py +1 -0
- nautobot/core/tests/integration/test_app_navbar.py +1 -0
- nautobot/core/tests/integration/test_filters.py +2 -0
- nautobot/core/tests/integration/test_home.py +1 -0
- nautobot/core/tests/integration/test_navbar.py +1 -0
- nautobot/core/tests/integration/test_view_authentication.py +1 -2
- nautobot/core/tests/nautobot_config.py +198 -0
- nautobot/core/tests/runner.py +3 -3
- nautobot/core/tests/test_api.py +82 -201
- nautobot/core/tests/test_csv.py +3 -25
- nautobot/core/tests/test_events.py +214 -0
- nautobot/core/tests/test_jinja_filters.py +1 -0
- nautobot/core/tests/test_jobs.py +84 -13
- nautobot/core/tests/test_navigations.py +7 -241
- nautobot/core/tests/test_templatetags_helpers.py +16 -0
- nautobot/core/tests/test_ui.py +150 -0
- nautobot/core/tests/test_utils.py +0 -25
- nautobot/core/tests/test_views.py +123 -31
- nautobot/core/ui/__init__.py +0 -0
- nautobot/core/ui/base.py +11 -0
- nautobot/core/ui/choices.py +44 -0
- nautobot/core/ui/homepage.py +167 -0
- nautobot/core/ui/nav.py +279 -0
- nautobot/core/ui/object_detail.py +1841 -0
- nautobot/core/ui/utils.py +36 -0
- nautobot/core/urls.py +4 -9
- nautobot/core/utils/config.py +30 -3
- nautobot/core/utils/lookup.py +20 -13
- nautobot/core/views/__init__.py +6 -1
- nautobot/core/views/generic.py +47 -52
- nautobot/core/views/mixins.py +15 -25
- nautobot/core/views/paginator.py +8 -5
- nautobot/core/views/renderers.py +3 -3
- nautobot/core/views/utils.py +11 -0
- nautobot/core/wsgi.py +3 -3
- nautobot/dcim/api/serializers.py +80 -179
- nautobot/dcim/api/urls.py +5 -0
- nautobot/dcim/api/views.py +17 -4
- nautobot/dcim/apps.py +1 -0
- nautobot/dcim/choices.py +28 -0
- nautobot/dcim/factory.py +58 -0
- nautobot/dcim/filters/__init__.py +197 -24
- nautobot/dcim/forms.py +203 -12
- nautobot/dcim/graphql/types.py +2 -2
- nautobot/dcim/migrations/0063_interfacevdcassignment_virtualdevicecontext_and_more.py +165 -0
- nautobot/dcim/migrations/0064_virtualdevicecontext_status_data_migration.py +28 -0
- nautobot/dcim/migrations/0065_controller_capabilities_and_more.py +29 -0
- nautobot/dcim/migrations/0066_controllermanageddevicegroup_radio_profiles_and_more.py +33 -0
- nautobot/dcim/models/__init__.py +4 -0
- nautobot/dcim/models/device_component_templates.py +2 -2
- nautobot/dcim/models/device_components.py +20 -22
- nautobot/dcim/models/devices.py +173 -4
- nautobot/dcim/models/locations.py +3 -3
- nautobot/dcim/models/power.py +5 -6
- nautobot/dcim/models/racks.py +6 -6
- nautobot/dcim/navigation.py +25 -224
- nautobot/dcim/signals.py +44 -0
- nautobot/dcim/tables/__init__.py +5 -3
- nautobot/dcim/tables/devices.py +96 -2
- nautobot/dcim/tables/devicetypes.py +2 -2
- nautobot/dcim/templates/dcim/controller/base.html +10 -0
- nautobot/dcim/templates/dcim/controller_create.html +1 -0
- nautobot/dcim/templates/dcim/controller_retrieve.html +5 -1
- nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +25 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +66 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +46 -0
- nautobot/dcim/templates/dcim/device/base.html +6 -42
- nautobot/dcim/templates/dcim/device/wireless.html +73 -0
- nautobot/dcim/templates/dcim/device.html +3 -1
- nautobot/dcim/templates/dcim/interface.html +1 -0
- nautobot/dcim/templates/dcim/interface_edit.html +1 -0
- nautobot/dcim/templates/dcim/locationtype.html +0 -107
- nautobot/dcim/templates/dcim/locationtype_retrieve.html +8 -0
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +76 -0
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +34 -0
- nautobot/dcim/tests/test_api.py +172 -61
- nautobot/dcim/tests/test_filters.py +171 -109
- nautobot/dcim/tests/test_forms.py +2 -51
- nautobot/dcim/tests/test_graphql.py +0 -52
- nautobot/dcim/tests/test_models.py +126 -4
- nautobot/dcim/tests/test_signals.py +1 -0
- nautobot/dcim/tests/test_views.py +103 -11
- nautobot/dcim/urls.py +72 -27
- nautobot/dcim/utils.py +2 -2
- nautobot/dcim/views.py +369 -62
- nautobot/extras/api/customfields.py +2 -2
- nautobot/extras/api/serializers.py +91 -75
- nautobot/extras/api/urls.py +4 -0
- nautobot/extras/api/views.py +78 -15
- nautobot/extras/choices.py +13 -0
- nautobot/extras/constants.py +0 -1
- nautobot/extras/context_managers.py +23 -6
- nautobot/extras/datasources/git.py +4 -1
- nautobot/extras/factory.py +27 -0
- nautobot/extras/filters/__init__.py +59 -0
- nautobot/extras/forms/forms.py +125 -30
- nautobot/extras/forms/mixins.py +3 -11
- nautobot/extras/graphql/types.py +25 -1
- nautobot/extras/group_sync.py +3 -3
- nautobot/extras/health_checks.py +2 -1
- nautobot/extras/jobs.py +62 -26
- nautobot/extras/management/__init__.py +1 -0
- nautobot/extras/management/commands/runjob.py +7 -79
- nautobot/extras/management/commands/runjob_with_job_result.py +46 -0
- nautobot/extras/management/utils.py +87 -0
- nautobot/extras/managers.py +1 -3
- nautobot/extras/migrations/0018_joblog_data_migration.py +9 -7
- nautobot/extras/migrations/0117_create_job_queue_model.py +129 -0
- nautobot/extras/migrations/0118_task_queue_to_job_queue_migration.py +78 -0
- nautobot/extras/migrations/0119_remove_task_queues_from_job_and_queue_from_scheduled_job.py +28 -0
- nautobot/extras/models/__init__.py +4 -0
- nautobot/extras/models/change_logging.py +7 -3
- nautobot/extras/models/customfields.py +11 -12
- nautobot/extras/models/groups.py +9 -13
- nautobot/extras/models/jobs.py +218 -37
- nautobot/extras/models/models.py +2 -2
- nautobot/extras/models/relationships.py +69 -1
- nautobot/extras/models/secrets.py +5 -0
- nautobot/extras/navigation.py +20 -262
- nautobot/extras/plugins/__init__.py +56 -32
- nautobot/extras/plugins/marketplace_manifest.yml +450 -0
- nautobot/extras/plugins/urls.py +1 -0
- nautobot/extras/plugins/views.py +48 -1
- nautobot/extras/signals.py +39 -1
- nautobot/extras/tables.py +40 -6
- nautobot/extras/templates/extras/externalintegration_retrieve.html +0 -47
- nautobot/extras/templates/extras/inc/tags_panel.html +1 -5
- nautobot/extras/templates/extras/job_bulk_edit.html +2 -1
- nautobot/extras/templates/extras/job_detail.html +36 -6
- nautobot/extras/templates/extras/job_edit.html +5 -2
- nautobot/extras/templates/extras/job_list.html +2 -7
- nautobot/extras/templates/extras/jobqueue_retrieve.html +44 -0
- nautobot/extras/templates/extras/marketplace.html +278 -0
- nautobot/extras/templates/extras/plugins_list.html +35 -1
- nautobot/extras/templates/extras/plugins_tiles.html +79 -0
- nautobot/extras/templates/extras/role_retrieve.html +16 -0
- nautobot/extras/templates/extras/secret.html +0 -65
- nautobot/extras/templates/extras/secret_check.js +16 -0
- nautobot/extras/templates/extras/secret_create.html +114 -0
- nautobot/extras/templates/extras/secret_edit.html +1 -114
- nautobot/extras/templates/extras/secretsgroup_edit.html +1 -1
- nautobot/extras/templates/extras/templatetags/plugin_object_detail_tabs.html +2 -0
- nautobot/extras/templatetags/job_buttons.py +5 -4
- nautobot/extras/templatetags/plugins.py +69 -6
- 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 +1 -3
- 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/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 +2 -0
- nautobot/extras/tests/test_api.py +157 -55
- nautobot/extras/tests/test_context_managers.py +4 -1
- nautobot/extras/tests/test_customfields.py +1 -1
- nautobot/extras/tests/test_datasources.py +1 -2
- nautobot/extras/tests/test_dynamicgroups.py +1 -1
- nautobot/extras/tests/test_filters.py +219 -535
- nautobot/extras/tests/test_forms.py +1 -20
- nautobot/extras/tests/test_job_variables.py +73 -152
- nautobot/extras/tests/test_jobs.py +43 -54
- nautobot/extras/tests/test_models.py +71 -16
- nautobot/extras/tests/test_relationships.py +5 -2
- nautobot/extras/tests/test_utils.py +23 -2
- nautobot/extras/tests/test_views.py +183 -43
- nautobot/extras/tests/test_webhooks.py +2 -1
- nautobot/extras/urls.py +2 -20
- nautobot/extras/utils.py +118 -4
- nautobot/extras/views.py +203 -92
- nautobot/extras/webhooks.py +5 -2
- nautobot/ipam/api/fields.py +3 -3
- nautobot/ipam/api/serializers.py +36 -137
- nautobot/ipam/api/views.py +93 -62
- nautobot/ipam/lookups.py +62 -101
- nautobot/ipam/models.py +11 -63
- nautobot/ipam/navigation.py +0 -90
- nautobot/ipam/querysets.py +2 -2
- nautobot/ipam/tables.py +6 -20
- nautobot/ipam/templates/ipam/routetarget.html +0 -28
- nautobot/ipam/templates/ipam/vrf.html +0 -47
- nautobot/ipam/tests/test_api.py +8 -419
- nautobot/ipam/tests/test_filters.py +39 -119
- nautobot/ipam/tests/test_forms.py +47 -51
- nautobot/ipam/tests/test_migrations.py +30 -30
- nautobot/ipam/tests/test_models.py +0 -41
- nautobot/ipam/tests/test_querysets.py +1 -63
- nautobot/ipam/urls.py +3 -69
- nautobot/ipam/utils/__init__.py +0 -24
- nautobot/ipam/views.py +153 -198
- nautobot/project-static/css/base.css +38 -3
- nautobot/project-static/docs/404.html +421 -19
- nautobot/project-static/docs/apps/index.html +421 -19
- nautobot/project-static/docs/apps/nautobot-apps.html +421 -19
- nautobot/project-static/docs/assets/extra.css +5 -1
- nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js → bundle.83f73b43.min.js} +2 -2
- nautobot/project-static/docs/assets/javascripts/{bundle.88dd0f4e.min.js.map → bundle.83f73b43.min.js.map} +2 -2
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +421 -172
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +425 -21
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +424 -22
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9809 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +424 -63
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +457 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +425 -25
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +457 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +425 -215
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +430 -342
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +5799 -1054
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +421 -19
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +447 -176
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +460 -21
- nautobot/project-static/docs/development/apps/api/configuration-view.html +421 -19
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +421 -19
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +421 -19
- nautobot/project-static/docs/development/apps/api/models/global-search.html +421 -19
- nautobot/project-static/docs/development/apps/api/models/graphql.html +421 -19
- nautobot/project-static/docs/development/apps/api/models/index.html +421 -19
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +421 -19
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +424 -41
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +421 -19
- nautobot/project-static/docs/development/apps/api/prometheus.html +421 -19
- nautobot/project-static/docs/development/apps/api/setup.html +425 -155
- nautobot/project-static/docs/development/apps/api/testing.html +421 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +421 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +421 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +421 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +421 -19
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +701 -130
- nautobot/project-static/docs/development/apps/api/views/base-template.html +421 -19
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +421 -19
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +421 -19
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +421 -19
- nautobot/project-static/docs/development/apps/api/views/index.html +423 -20
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +425 -19
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +451 -19
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +421 -19
- nautobot/project-static/docs/development/apps/api/views/notes.html +421 -19
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +421 -19
- nautobot/project-static/docs/development/apps/api/views/urls.html +421 -19
- nautobot/project-static/docs/development/apps/index.html +421 -19
- nautobot/project-static/docs/development/apps/migration/code-updates.html +422 -52
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +422 -20
- nautobot/project-static/docs/development/apps/migration/from-v1.html +421 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +421 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +421 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +421 -19
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +424 -22
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9219 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +9333 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +9474 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +9517 -0
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +424 -22
- nautobot/project-static/docs/development/core/application-registry.html +421 -19
- nautobot/project-static/docs/development/core/best-practices.html +421 -19
- nautobot/project-static/docs/development/core/bootstrap-ui.html +421 -19
- nautobot/project-static/docs/development/core/caching.html +421 -19
- nautobot/project-static/docs/development/core/controllers.html +423 -19
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +490 -45
- nautobot/project-static/docs/development/core/generic-views.html +421 -19
- nautobot/project-static/docs/development/core/getting-started.html +566 -179
- nautobot/project-static/docs/development/core/homepage.html +432 -30
- nautobot/project-static/docs/development/core/index.html +421 -19
- nautobot/project-static/docs/development/core/local-k8s.html +9453 -0
- nautobot/project-static/docs/development/core/model-checklist.html +424 -22
- nautobot/project-static/docs/development/core/model-features.html +421 -19
- nautobot/project-static/docs/development/core/natural-keys.html +421 -19
- nautobot/project-static/docs/development/core/navigation-menu.html +438 -26
- nautobot/project-static/docs/development/core/release-checklist.html +435 -45
- nautobot/project-static/docs/development/core/role-internals.html +421 -19
- nautobot/project-static/docs/development/core/settings.html +421 -19
- nautobot/project-static/docs/development/core/style-guide.html +421 -19
- nautobot/project-static/docs/development/core/templates.html +431 -22
- nautobot/project-static/docs/development/core/testing.html +421 -19
- nautobot/project-static/docs/development/core/ui-component-framework.html +11020 -0
- nautobot/project-static/docs/development/core/user-preferences.html +424 -22
- nautobot/project-static/docs/development/index.html +421 -19
- nautobot/project-static/docs/development/jobs/index.html +546 -160
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +421 -19
- nautobot/project-static/docs/index.html +421 -19
- nautobot/project-static/docs/media/development/core/ui-component-framework/basic-panel-layout.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/button-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/dropdown-button-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-1.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/grouped-key-value-table-panel-example-2.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/object-fields-panel-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/stats-panel-example.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/table-panels-family.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/text-panels-family.png +0 -0
- nautobot/project-static/docs/media/development/core/ui-component-framework/ui-framework-example.png +0 -0
- nautobot/project-static/docs/media/models/virtual_device_context_overview.drawio +73 -0
- nautobot/project-static/docs/media/models/virtual_device_context_overview.png +0 -0
- nautobot/project-static/docs/models/dcim/virtualdevicecontext.html +14 -0
- nautobot/project-static/docs/models/extras/jobqueue.html +14 -0
- nautobot/project-static/docs/models/wireless/radioprofile.html +14 -0
- nautobot/project-static/docs/models/wireless/supporteddatarate.html +14 -0
- nautobot/project-static/docs/models/wireless/wirelessnetwork.html +14 -0
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +426 -20
- nautobot/project-static/docs/overview/design_philosophy.html +421 -19
- nautobot/project-static/docs/release-notes/index.html +445 -22
- nautobot/project-static/docs/release-notes/version-1.0.html +421 -19
- nautobot/project-static/docs/release-notes/version-1.1.html +421 -19
- nautobot/project-static/docs/release-notes/version-1.2.html +421 -19
- nautobot/project-static/docs/release-notes/version-1.3.html +421 -19
- nautobot/project-static/docs/release-notes/version-1.4.html +421 -19
- nautobot/project-static/docs/release-notes/version-1.5.html +421 -19
- nautobot/project-static/docs/release-notes/version-1.6.html +634 -667
- nautobot/project-static/docs/release-notes/version-2.0.html +421 -19
- nautobot/project-static/docs/release-notes/version-2.1.html +421 -19
- nautobot/project-static/docs/release-notes/version-2.2.html +421 -19
- nautobot/project-static/docs/release-notes/version-2.3.html +684 -886
- nautobot/project-static/docs/release-notes/version-2.4.html +10007 -0
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +334 -270
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +421 -19
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +421 -19
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +423 -21
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +433 -32
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +421 -19
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +765 -180
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +434 -29
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +421 -19
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +421 -19
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +421 -19
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +421 -19
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +421 -19
- nautobot/project-static/docs/user-guide/administration/installation/index.html +426 -20
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +421 -19
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +421 -19
- nautobot/project-static/docs/user-guide/administration/installation/services.html +421 -19
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +421 -19
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +442 -41
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +435 -66
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +435 -66
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-nautobot-app-location.yaml +0 -16
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +421 -19
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +427 -21
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +457 -20
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +447 -22
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9333 -0
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +424 -22
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +421 -19
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +424 -22
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9271 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9175 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9169 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9235 -0
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +421 -19
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +421 -19
- nautobot/project-static/docs/user-guide/index.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +424 -22
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +9575 -0
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +424 -22
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +426 -20
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +424 -22
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9182 -0
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +424 -22
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +424 -22
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9250 -0
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +424 -22
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +424 -22
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +489 -56
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +421 -19
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +421 -19
- nautobot/project-static/img/jinja_logo.svg +97 -0
- nautobot/project-static/js/forms.js +5 -0
- nautobot/project-static/js/nav_menu.js +2 -1
- nautobot/tenancy/api/serializers.py +0 -2
- nautobot/tenancy/factory.py +1 -1
- nautobot/tenancy/navigation.py +0 -29
- nautobot/tenancy/templates/tenancy/tenant.html +4 -91
- nautobot/tenancy/tests/test_filters.py +29 -134
- nautobot/tenancy/views.py +32 -23
- nautobot/users/admin.py +3 -1
- nautobot/users/api/serializers.py +4 -5
- nautobot/users/api/views.py +1 -1
- nautobot/users/forms.py +19 -0
- nautobot/users/templates/users/preferences.html +22 -0
- nautobot/users/tests/test_filters.py +1 -19
- nautobot/users/tests/test_views.py +57 -0
- nautobot/users/utils.py +8 -0
- nautobot/users/views.py +48 -11
- nautobot/virtualization/api/serializers.py +4 -4
- nautobot/virtualization/filters.py +2 -20
- nautobot/virtualization/navigation.py +0 -48
- nautobot/virtualization/templates/virtualization/clustertype.html +0 -39
- nautobot/virtualization/tests/test_filters.py +57 -183
- nautobot/virtualization/views.py +18 -15
- nautobot/wireless/__init__.py +0 -0
- nautobot/wireless/api/__init__.py +0 -0
- nautobot/wireless/api/serializers.py +44 -0
- nautobot/wireless/api/urls.py +20 -0
- nautobot/wireless/api/views.py +34 -0
- nautobot/wireless/apps.py +8 -0
- nautobot/wireless/choices.py +345 -0
- nautobot/wireless/factory.py +138 -0
- nautobot/wireless/filters.py +167 -0
- nautobot/wireless/forms.py +283 -0
- nautobot/wireless/homepage.py +19 -0
- nautobot/wireless/migrations/0001_initial.py +223 -0
- nautobot/wireless/migrations/__init__.py +0 -0
- nautobot/wireless/models.py +207 -0
- nautobot/wireless/navigation.py +105 -0
- nautobot/wireless/tables.py +244 -0
- nautobot/wireless/templates/wireless/radioprofile_retrieve.html +81 -0
- nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +26 -0
- nautobot/wireless/templates/wireless/wirelessnetwork_create.html +88 -0
- nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +64 -0
- nautobot/wireless/tests/__init__.py +0 -0
- nautobot/wireless/tests/test_api.py +247 -0
- nautobot/wireless/tests/test_filters.py +54 -0
- nautobot/wireless/tests/test_models.py +22 -0
- nautobot/wireless/tests/test_views.py +378 -0
- nautobot/wireless/urls.py +13 -0
- nautobot/wireless/views.py +129 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/METADATA +11 -14
- {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/RECORD +674 -551
- {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/WHEEL +1 -1
- nautobot/core/utils/navigation.py +0 -54
- {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/NOTICE +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0b1.dist-info}/entry_points.txt +0 -0
nautobot/extras/views.py
CHANGED
|
@@ -18,21 +18,21 @@ from django.utils import timezone
|
|
|
18
18
|
from django.utils.encoding import iri_to_uri
|
|
19
19
|
from django.utils.html import format_html
|
|
20
20
|
from django.utils.http import url_has_allowed_host_and_scheme
|
|
21
|
+
from django.utils.timezone import get_current_timezone
|
|
21
22
|
from django.views.generic import View
|
|
22
23
|
from django_tables2 import RequestConfig
|
|
23
24
|
from jsonschema.validators import Draft7Validator
|
|
24
25
|
from rest_framework.decorators import action
|
|
25
26
|
from rest_framework.permissions import IsAuthenticated
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
except ImportError: # python 3.8
|
|
30
|
-
from backports.zoneinfo import ZoneInfo
|
|
31
|
-
|
|
28
|
+
from nautobot.core.constants import PAGINATE_COUNT_DEFAULT
|
|
29
|
+
from nautobot.core.events import publish_event
|
|
32
30
|
from nautobot.core.forms import restrict_form_fields
|
|
33
31
|
from nautobot.core.models.querysets import count_related
|
|
34
|
-
from nautobot.core.models.utils import pretty_print_query
|
|
32
|
+
from nautobot.core.models.utils import pretty_print_query, serialize_object_v2
|
|
35
33
|
from nautobot.core.tables import ButtonsColumn
|
|
34
|
+
from nautobot.core.ui import object_detail
|
|
35
|
+
from nautobot.core.ui.choices import SectionChoices
|
|
36
36
|
from nautobot.core.utils.config import get_settings_or_config
|
|
37
37
|
from nautobot.core.utils.lookup import (
|
|
38
38
|
get_filterset_for_model,
|
|
@@ -45,6 +45,7 @@ from nautobot.core.utils.requests import normalize_querydict
|
|
|
45
45
|
from nautobot.core.views import generic, viewsets
|
|
46
46
|
from nautobot.core.views.mixins import (
|
|
47
47
|
GetReturnURLMixin,
|
|
48
|
+
ObjectBulkCreateViewMixin,
|
|
48
49
|
ObjectBulkDestroyViewMixin,
|
|
49
50
|
ObjectBulkUpdateViewMixin,
|
|
50
51
|
ObjectChangeLogViewMixin,
|
|
@@ -52,18 +53,26 @@ from nautobot.core.views.mixins import (
|
|
|
52
53
|
ObjectDetailViewMixin,
|
|
53
54
|
ObjectEditViewMixin,
|
|
54
55
|
ObjectListViewMixin,
|
|
56
|
+
ObjectNotesViewMixin,
|
|
55
57
|
ObjectPermissionRequiredMixin,
|
|
56
58
|
)
|
|
57
59
|
from nautobot.core.views.paginator import EnhancedPaginator, get_paginate_count
|
|
58
60
|
from nautobot.core.views.utils import prepare_cloned_fields
|
|
59
61
|
from nautobot.core.views.viewsets import NautobotUIViewSet
|
|
60
|
-
from nautobot.dcim.models import Controller, Device, Interface, Module, Rack
|
|
61
|
-
from nautobot.dcim.tables import
|
|
62
|
+
from nautobot.dcim.models import Controller, Device, Interface, Module, Rack, VirtualDeviceContext
|
|
63
|
+
from nautobot.dcim.tables import (
|
|
64
|
+
ControllerTable,
|
|
65
|
+
DeviceTable,
|
|
66
|
+
InterfaceTable,
|
|
67
|
+
ModuleTable,
|
|
68
|
+
RackTable,
|
|
69
|
+
VirtualDeviceContextTable,
|
|
70
|
+
)
|
|
62
71
|
from nautobot.extras.constants import JOB_OVERRIDABLE_FIELDS
|
|
63
72
|
from nautobot.extras.context_managers import deferred_change_logging_for_bulk_operation
|
|
64
73
|
from nautobot.extras.signals import change_context_state
|
|
65
74
|
from nautobot.extras.tasks import delete_custom_field_data
|
|
66
|
-
from nautobot.extras.utils import get_base_template, get_worker_count
|
|
75
|
+
from nautobot.extras.utils import get_base_template, get_job_queue, get_worker_count
|
|
67
76
|
from nautobot.ipam.models import IPAddress, Prefix, VLAN
|
|
68
77
|
from nautobot.ipam.tables import IPAddressTable, PrefixTable, VLANTable
|
|
69
78
|
from nautobot.virtualization.models import VirtualMachine, VMInterface
|
|
@@ -71,7 +80,13 @@ from nautobot.virtualization.tables import VirtualMachineTable, VMInterfaceTable
|
|
|
71
80
|
|
|
72
81
|
from . import filters, forms, tables
|
|
73
82
|
from .api import serializers
|
|
74
|
-
from .choices import
|
|
83
|
+
from .choices import (
|
|
84
|
+
DynamicGroupTypeChoices,
|
|
85
|
+
JobExecutionType,
|
|
86
|
+
JobQueueTypeChoices,
|
|
87
|
+
JobResultStatusChoices,
|
|
88
|
+
LogLevelChoices,
|
|
89
|
+
)
|
|
75
90
|
from .datasources import (
|
|
76
91
|
enqueue_git_repository_diff_origin_and_local,
|
|
77
92
|
enqueue_pull_git_repository_and_refresh_data,
|
|
@@ -96,6 +111,7 @@ from .models import (
|
|
|
96
111
|
JobButton,
|
|
97
112
|
JobHook,
|
|
98
113
|
JobLogEntry,
|
|
114
|
+
JobQueue,
|
|
99
115
|
JobResult,
|
|
100
116
|
MetadataType,
|
|
101
117
|
Note,
|
|
@@ -1006,6 +1022,27 @@ class ExternalIntegrationUIViewSet(NautobotUIViewSet):
|
|
|
1006
1022
|
serializer_class = serializers.ExternalIntegrationSerializer
|
|
1007
1023
|
table_class = tables.ExternalIntegrationTable
|
|
1008
1024
|
|
|
1025
|
+
object_detail_content = object_detail.ObjectDetailContent(
|
|
1026
|
+
panels=(
|
|
1027
|
+
object_detail.ObjectFieldsPanel(
|
|
1028
|
+
section=SectionChoices.LEFT_HALF,
|
|
1029
|
+
weight=100,
|
|
1030
|
+
# Default ordering with __all__ leaves something to be desired
|
|
1031
|
+
fields=[
|
|
1032
|
+
"name",
|
|
1033
|
+
"remote_url",
|
|
1034
|
+
"http_method",
|
|
1035
|
+
"headers",
|
|
1036
|
+
"verify_ssl",
|
|
1037
|
+
"ca_file_path",
|
|
1038
|
+
"secrets_group",
|
|
1039
|
+
"timeout",
|
|
1040
|
+
"extra_config",
|
|
1041
|
+
],
|
|
1042
|
+
),
|
|
1043
|
+
),
|
|
1044
|
+
)
|
|
1045
|
+
|
|
1009
1046
|
|
|
1010
1047
|
#
|
|
1011
1048
|
# Git repositories
|
|
@@ -1060,10 +1097,10 @@ class GitRepositoryEditView(generic.ObjectEditView):
|
|
|
1060
1097
|
obj.user = request.user
|
|
1061
1098
|
return super().alter_obj(obj, request, url_args, url_kwargs)
|
|
1062
1099
|
|
|
1063
|
-
def get_return_url(self, request, obj
|
|
1100
|
+
def get_return_url(self, request, obj):
|
|
1064
1101
|
if request.method == "POST":
|
|
1065
1102
|
return reverse("extras:gitrepository_result", kwargs={"pk": obj.pk})
|
|
1066
|
-
return super().get_return_url(request, obj
|
|
1103
|
+
return super().get_return_url(request, obj)
|
|
1067
1104
|
|
|
1068
1105
|
|
|
1069
1106
|
class GitRepositoryDeleteView(generic.ObjectDeleteView):
|
|
@@ -1211,27 +1248,27 @@ class ImageAttachmentEditView(generic.ObjectEditView):
|
|
|
1211
1248
|
return get_object_or_404(self.queryset, pk=kwargs["pk"])
|
|
1212
1249
|
return self.queryset.model()
|
|
1213
1250
|
|
|
1214
|
-
def alter_obj(self,
|
|
1215
|
-
if not
|
|
1251
|
+
def alter_obj(self, imageattachment, request, args, kwargs):
|
|
1252
|
+
if not imageattachment.present_in_database:
|
|
1216
1253
|
# Assign the parent object based on URL kwargs
|
|
1217
|
-
model =
|
|
1218
|
-
if "object_id" in
|
|
1219
|
-
|
|
1220
|
-
elif "slug" in
|
|
1221
|
-
|
|
1254
|
+
model = kwargs.get("model")
|
|
1255
|
+
if "object_id" in kwargs:
|
|
1256
|
+
imageattachment.parent = get_object_or_404(model, pk=kwargs["object_id"])
|
|
1257
|
+
elif "slug" in kwargs:
|
|
1258
|
+
imageattachment.parent = get_object_or_404(model, slug=kwargs["slug"])
|
|
1222
1259
|
else:
|
|
1223
1260
|
raise RuntimeError("Neither object_id nor slug were provided?")
|
|
1224
|
-
return
|
|
1261
|
+
return imageattachment
|
|
1225
1262
|
|
|
1226
|
-
def get_return_url(self, request,
|
|
1227
|
-
return
|
|
1263
|
+
def get_return_url(self, request, imageattachment):
|
|
1264
|
+
return imageattachment.parent.get_absolute_url()
|
|
1228
1265
|
|
|
1229
1266
|
|
|
1230
1267
|
class ImageAttachmentDeleteView(generic.ObjectDeleteView):
|
|
1231
1268
|
queryset = ImageAttachment.objects.all()
|
|
1232
1269
|
|
|
1233
|
-
def get_return_url(self, request,
|
|
1234
|
-
return
|
|
1270
|
+
def get_return_url(self, request, imageattachment):
|
|
1271
|
+
return imageattachment.parent.get_absolute_url()
|
|
1235
1272
|
|
|
1236
1273
|
|
|
1237
1274
|
#
|
|
@@ -1319,9 +1356,14 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1319
1356
|
# for example "?kwargs_from_job_result=<UUID>&integervar=22"
|
|
1320
1357
|
explicit_initial = initial
|
|
1321
1358
|
initial = job_result.task_kwargs.copy()
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1359
|
+
job_queue = job_result.celery_kwargs.get("queue", None)
|
|
1360
|
+
jq = None
|
|
1361
|
+
if job_queue is not None:
|
|
1362
|
+
try:
|
|
1363
|
+
jq = JobQueue.objects.get(name=job_queue, queue_type=JobQueueTypeChoices.TYPE_CELERY)
|
|
1364
|
+
except JobQueue.DoesNotExist:
|
|
1365
|
+
pass
|
|
1366
|
+
initial["_job_queue"] = jq
|
|
1325
1367
|
initial["_profile"] = job_result.celery_kwargs.get("nautobot_job_profile", False)
|
|
1326
1368
|
initial.update(explicit_initial)
|
|
1327
1369
|
except JobResult.DoesNotExist:
|
|
@@ -1337,9 +1379,7 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1337
1379
|
get_template(job_class.template_name)
|
|
1338
1380
|
template_name = job_class.template_name
|
|
1339
1381
|
except TemplateDoesNotExist as err:
|
|
1340
|
-
messages.error(
|
|
1341
|
-
request, f'Unable to render requested custom job template "{job_class.template_name}": {err}'
|
|
1342
|
-
)
|
|
1382
|
+
messages.error(request, f'Unable to render requested custom job template "{template_name}": {err}')
|
|
1343
1383
|
except RuntimeError as err:
|
|
1344
1384
|
messages.error(request, f"Unable to run or schedule '{job_model}': {err}")
|
|
1345
1385
|
return redirect("extras:job_list")
|
|
@@ -1362,7 +1402,7 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1362
1402
|
job_class = get_job(job_model.class_path, reload=True)
|
|
1363
1403
|
job_form = job_class.as_form(request.POST, request.FILES) if job_class is not None else None
|
|
1364
1404
|
schedule_form = forms.JobScheduleForm(request.POST)
|
|
1365
|
-
|
|
1405
|
+
job_queue = request.POST.get("_job_queue")
|
|
1366
1406
|
|
|
1367
1407
|
return_url = request.POST.get("_return_url")
|
|
1368
1408
|
if return_url is not None and url_has_allowed_host_and_scheme(url=return_url, allowed_hosts=request.get_host()):
|
|
@@ -1370,8 +1410,11 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1370
1410
|
else:
|
|
1371
1411
|
return_url = None
|
|
1372
1412
|
|
|
1373
|
-
|
|
1374
|
-
if
|
|
1413
|
+
queue = get_job_queue(job_queue)
|
|
1414
|
+
if queue is None:
|
|
1415
|
+
queue = job_model.default_job_queue
|
|
1416
|
+
# Allow execution only if a worker process is running on a celery queue and the job is runnable.
|
|
1417
|
+
if queue.queue_type == JobQueueTypeChoices.TYPE_CELERY and not get_worker_count(queue=job_queue):
|
|
1375
1418
|
messages.error(request, "Unable to run or schedule job: Celery worker process not running.")
|
|
1376
1419
|
elif not job_model.installed or job_class is None:
|
|
1377
1420
|
messages.error(request, "Unable to run or schedule job: Job is not presently installed.")
|
|
@@ -1390,7 +1433,17 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1390
1433
|
"One of these two flags must be removed before this job can be scheduled or run.",
|
|
1391
1434
|
)
|
|
1392
1435
|
elif job_form is not None and job_form.is_valid() and schedule_form.is_valid():
|
|
1393
|
-
|
|
1436
|
+
job_queue = job_form.cleaned_data.pop("_job_queue", None)
|
|
1437
|
+
jq = None
|
|
1438
|
+
if job_queue is not None:
|
|
1439
|
+
try:
|
|
1440
|
+
jq = JobQueue.objects.get(pk=job_queue)
|
|
1441
|
+
except (ValidationError, JobQueue.DoesNotExist):
|
|
1442
|
+
try:
|
|
1443
|
+
jq = JobQueue.objects.get(name=job_queue)
|
|
1444
|
+
except JobQueue.DoesNotExist:
|
|
1445
|
+
pass
|
|
1446
|
+
|
|
1394
1447
|
dryrun = job_form.cleaned_data.get("dryrun", False)
|
|
1395
1448
|
# Run the job. A new JobResult is created.
|
|
1396
1449
|
profile = job_form.cleaned_data.pop("_profile")
|
|
@@ -1405,7 +1458,7 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1405
1458
|
interval=schedule_type,
|
|
1406
1459
|
crontab=schedule_form.cleaned_data.get("_recurrence_custom_time"),
|
|
1407
1460
|
approval_required=job_model.approval_required,
|
|
1408
|
-
task_queue=
|
|
1461
|
+
task_queue=jq.name if jq else None,
|
|
1409
1462
|
profile=profile,
|
|
1410
1463
|
**job_class.serialize_data(job_form.cleaned_data),
|
|
1411
1464
|
)
|
|
@@ -1424,7 +1477,7 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1424
1477
|
job_model,
|
|
1425
1478
|
request.user,
|
|
1426
1479
|
profile=profile,
|
|
1427
|
-
task_queue=
|
|
1480
|
+
task_queue=jq.name if jq else None,
|
|
1428
1481
|
**job_class.serialize_data(job_kwargs),
|
|
1429
1482
|
)
|
|
1430
1483
|
|
|
@@ -1449,9 +1502,7 @@ class JobRunView(ObjectPermissionRequiredMixin, View):
|
|
|
1449
1502
|
get_template(job_class.template_name)
|
|
1450
1503
|
template_name = job_class.template_name
|
|
1451
1504
|
except TemplateDoesNotExist as err:
|
|
1452
|
-
messages.error(
|
|
1453
|
-
request, f'Unable to render requested custom job template "{job_class.template_name}": {err}'
|
|
1454
|
-
)
|
|
1505
|
+
messages.error(request, f'Unable to render requested custom job template "{template_name}": {err}')
|
|
1455
1506
|
|
|
1456
1507
|
return render(
|
|
1457
1508
|
request,
|
|
@@ -1497,6 +1548,35 @@ class JobBulkEditView(generic.BulkEditView):
|
|
|
1497
1548
|
setattr(obj, override_field, True)
|
|
1498
1549
|
setattr(obj, overridable_field, override_value)
|
|
1499
1550
|
|
|
1551
|
+
# Handle job queues
|
|
1552
|
+
clear_override_field = "clear_job_queues_override"
|
|
1553
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1554
|
+
if reset_override:
|
|
1555
|
+
meta_task_queues = obj.job_class.task_queues
|
|
1556
|
+
job_queues = []
|
|
1557
|
+
for queue_name in meta_task_queues:
|
|
1558
|
+
try:
|
|
1559
|
+
job_queues.append(JobQueue.objects.get(name=queue_name))
|
|
1560
|
+
except JobQueue.DoesNotExist:
|
|
1561
|
+
# Do we want to create the Job Queue for the users here if we do not have it in the database?
|
|
1562
|
+
pass
|
|
1563
|
+
obj.job_queues_override = False
|
|
1564
|
+
obj.job_queues.set(job_queues)
|
|
1565
|
+
elif cleaned_data["job_queues"]:
|
|
1566
|
+
obj.job_queues_override = True
|
|
1567
|
+
|
|
1568
|
+
# Handle default job queue
|
|
1569
|
+
clear_override_field = "clear_default_job_queue_override"
|
|
1570
|
+
reset_override = cleaned_data.get(clear_override_field, False)
|
|
1571
|
+
if reset_override:
|
|
1572
|
+
meta_task_queues = obj.job_class.task_queues
|
|
1573
|
+
obj.default_job_queue_override = False
|
|
1574
|
+
obj.default_job_queue, _ = JobQueue.objects.get_or_create(
|
|
1575
|
+
name=meta_task_queues[0] if meta_task_queues else settings.CELERY_TASK_DEFAULT_QUEUE
|
|
1576
|
+
)
|
|
1577
|
+
elif cleaned_data["default_job_queue"]:
|
|
1578
|
+
obj.default_job_queue_override = True
|
|
1579
|
+
|
|
1500
1580
|
obj.validated_save()
|
|
1501
1581
|
|
|
1502
1582
|
|
|
@@ -1538,7 +1618,7 @@ class JobApprovalRequestView(generic.ObjectView):
|
|
|
1538
1618
|
if job_class is not None:
|
|
1539
1619
|
# Render the form with all fields disabled
|
|
1540
1620
|
initial = instance.kwargs
|
|
1541
|
-
initial["
|
|
1621
|
+
initial["_job_queue"] = instance.queue
|
|
1542
1622
|
initial["_profile"] = instance.celery_kwargs.get("profile", False)
|
|
1543
1623
|
job_form = job_class().as_form(initial=initial, approval_view=True)
|
|
1544
1624
|
else:
|
|
@@ -1597,12 +1677,15 @@ class JobApprovalRequestView(generic.ObjectView):
|
|
|
1597
1677
|
messages.error(request, "You do not have permission to deny this request.")
|
|
1598
1678
|
else:
|
|
1599
1679
|
# Delete the scheduled_job instance
|
|
1680
|
+
publish_event_payload = {"data": serialize_object_v2(scheduled_job)}
|
|
1600
1681
|
scheduled_job.delete()
|
|
1601
1682
|
if request.user == scheduled_job.user:
|
|
1602
1683
|
messages.error(request, f"Approval request for {scheduled_job.name} was revoked")
|
|
1603
1684
|
else:
|
|
1604
1685
|
messages.error(request, f"Approval of {scheduled_job.name} was denied")
|
|
1605
1686
|
|
|
1687
|
+
publish_event(topic="nautobot.jobs.approval.denied", payload=publish_event_payload)
|
|
1688
|
+
|
|
1606
1689
|
return redirect("extras:scheduledjob_approval_queue_list")
|
|
1607
1690
|
|
|
1608
1691
|
elif approve or force_approve:
|
|
@@ -1624,6 +1707,9 @@ class JobApprovalRequestView(generic.ObjectView):
|
|
|
1624
1707
|
scheduled_job.approved_at = timezone.now()
|
|
1625
1708
|
scheduled_job.save()
|
|
1626
1709
|
|
|
1710
|
+
publish_event_payload = {"data": serialize_object_v2(scheduled_job)}
|
|
1711
|
+
publish_event(topic="nautobot.jobs.approval.approved", payload=publish_event_payload)
|
|
1712
|
+
|
|
1627
1713
|
messages.success(request, f"{scheduled_job.name} was approved and will now begin execution")
|
|
1628
1714
|
|
|
1629
1715
|
return redirect("extras:scheduledjob_approval_queue_list")
|
|
@@ -1638,6 +1724,28 @@ class JobApprovalRequestView(generic.ObjectView):
|
|
|
1638
1724
|
)
|
|
1639
1725
|
|
|
1640
1726
|
|
|
1727
|
+
class JobQueueUIViewSet(NautobotUIViewSet):
|
|
1728
|
+
bulk_update_form_class = forms.JobQueueBulkEditForm
|
|
1729
|
+
filterset_form_class = forms.JobQueueFilterForm
|
|
1730
|
+
queryset = JobQueue.objects.all()
|
|
1731
|
+
form_class = forms.JobQueueForm
|
|
1732
|
+
filterset_class = filters.JobQueueFilterSet
|
|
1733
|
+
serializer_class = serializers.JobQueueSerializer
|
|
1734
|
+
table_class = tables.JobQueueTable
|
|
1735
|
+
|
|
1736
|
+
def get_extra_context(self, request, instance):
|
|
1737
|
+
context = super().get_extra_context(request, instance)
|
|
1738
|
+
|
|
1739
|
+
if self.action == "retrieve":
|
|
1740
|
+
jobs = instance.jobs.restrict(request.user, "view")
|
|
1741
|
+
jobs_table = tables.JobTable(jobs, orderable=False)
|
|
1742
|
+
paginate = {"paginator_class": EnhancedPaginator, "per_page": get_paginate_count(request)}
|
|
1743
|
+
RequestConfig(request, paginate).configure(jobs_table)
|
|
1744
|
+
context["jobs_table"] = jobs_table
|
|
1745
|
+
|
|
1746
|
+
return context
|
|
1747
|
+
|
|
1748
|
+
|
|
1641
1749
|
#
|
|
1642
1750
|
# Saved Views
|
|
1643
1751
|
#
|
|
@@ -1837,7 +1945,7 @@ class SavedViewUIViewSet(
|
|
|
1837
1945
|
if derived_instance and derived_instance.config.get("pagination_count", None):
|
|
1838
1946
|
pagination_count = derived_instance.config["pagination_count"]
|
|
1839
1947
|
else:
|
|
1840
|
-
pagination_count = get_settings_or_config("PAGINATE_COUNT")
|
|
1948
|
+
pagination_count = get_settings_or_config("PAGINATE_COUNT", fallback=PAGINATE_COUNT_DEFAULT)
|
|
1841
1949
|
sv.config["pagination_count"] = int(pagination_count)
|
|
1842
1950
|
sort_order = param_dict.get("sort", [])
|
|
1843
1951
|
if not sort_order:
|
|
@@ -1931,7 +2039,7 @@ class ScheduledJobView(generic.ObjectView):
|
|
|
1931
2039
|
return {
|
|
1932
2040
|
"labels": labels,
|
|
1933
2041
|
"job_class_found": (job_class is not None),
|
|
1934
|
-
"default_time_zone":
|
|
2042
|
+
"default_time_zone": get_current_timezone(),
|
|
1935
2043
|
**super().get_extra_context(request, instance),
|
|
1936
2044
|
}
|
|
1937
2045
|
|
|
@@ -2469,6 +2577,12 @@ class RoleUIViewSet(viewsets.NautobotUIViewSet):
|
|
|
2469
2577
|
module_table.columns.hide("role")
|
|
2470
2578
|
RequestConfig(request, paginate).configure(module_table)
|
|
2471
2579
|
context["module_table"] = module_table
|
|
2580
|
+
if ContentType.objects.get_for_model(VirtualDeviceContext) in context["content_types"]:
|
|
2581
|
+
vdcs = instance.virtual_device_contexts.restrict(request.user, "view")
|
|
2582
|
+
vdc_table = VirtualDeviceContextTable(vdcs)
|
|
2583
|
+
vdc_table.columns.hide("role")
|
|
2584
|
+
RequestConfig(request, paginate).configure(vdc_table)
|
|
2585
|
+
context["vdc_table"] = vdc_table
|
|
2472
2586
|
return context
|
|
2473
2587
|
|
|
2474
2588
|
|
|
@@ -2477,38 +2591,56 @@ class RoleUIViewSet(viewsets.NautobotUIViewSet):
|
|
|
2477
2591
|
#
|
|
2478
2592
|
|
|
2479
2593
|
|
|
2480
|
-
class
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2594
|
+
class SecretUIViewSet(
|
|
2595
|
+
ObjectDetailViewMixin,
|
|
2596
|
+
ObjectListViewMixin,
|
|
2597
|
+
ObjectEditViewMixin,
|
|
2598
|
+
ObjectDestroyViewMixin,
|
|
2599
|
+
ObjectBulkCreateViewMixin, # 3.0 TODO: remove, unused
|
|
2600
|
+
ObjectBulkDestroyViewMixin,
|
|
2601
|
+
# no ObjectBulkUpdateViewMixin here yet
|
|
2602
|
+
ObjectChangeLogViewMixin,
|
|
2603
|
+
ObjectNotesViewMixin,
|
|
2604
|
+
):
|
|
2488
2605
|
queryset = Secret.objects.all()
|
|
2606
|
+
form_class = forms.SecretForm
|
|
2607
|
+
filterset_class = filters.SecretFilterSet
|
|
2608
|
+
filterset_form_class = forms.SecretFilterForm
|
|
2609
|
+
table_class = tables.SecretTable
|
|
2610
|
+
|
|
2611
|
+
object_detail_content = object_detail.ObjectDetailContent(
|
|
2612
|
+
panels=[
|
|
2613
|
+
object_detail.ObjectFieldsPanel(
|
|
2614
|
+
weight=100, section=SectionChoices.LEFT_HALF, fields="__all__", exclude_fields=["parameters"]
|
|
2615
|
+
),
|
|
2616
|
+
object_detail.KeyValueTablePanel(
|
|
2617
|
+
weight=200, section=SectionChoices.LEFT_HALF, label="Parameters", context_data_key="parameters"
|
|
2618
|
+
),
|
|
2619
|
+
object_detail.ObjectsTablePanel(
|
|
2620
|
+
weight=100,
|
|
2621
|
+
section=SectionChoices.RIGHT_HALF,
|
|
2622
|
+
table_title="Groups containing this secret",
|
|
2623
|
+
table_class=tables.SecretsGroupTable,
|
|
2624
|
+
table_attribute="secrets_groups",
|
|
2625
|
+
footer_content_template_path=None,
|
|
2626
|
+
),
|
|
2627
|
+
],
|
|
2628
|
+
extra_buttons=[
|
|
2629
|
+
object_detail.Button(
|
|
2630
|
+
weight=100,
|
|
2631
|
+
label="Check Secret",
|
|
2632
|
+
icon="mdi-test-tube",
|
|
2633
|
+
javascript_template_path="extras/secret_check.js",
|
|
2634
|
+
attributes={"onClick": "checkSecret()"},
|
|
2635
|
+
),
|
|
2636
|
+
],
|
|
2637
|
+
)
|
|
2489
2638
|
|
|
2490
2639
|
def get_extra_context(self, request, instance):
|
|
2491
|
-
|
|
2492
|
-
if
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
request.user.set_config("extras.configcontext.format", format_, commit=True)
|
|
2496
|
-
elif request.user.is_authenticated:
|
|
2497
|
-
format_ = request.user.get_config("extras.configcontext.format", "json")
|
|
2498
|
-
else:
|
|
2499
|
-
format_ = "json"
|
|
2500
|
-
|
|
2501
|
-
provider = registry["secrets_providers"].get(instance.provider)
|
|
2502
|
-
|
|
2503
|
-
groups = instance.secrets_groups.distinct()
|
|
2504
|
-
groups_table = tables.SecretsGroupTable(groups, orderable=False)
|
|
2505
|
-
|
|
2506
|
-
return {
|
|
2507
|
-
"format": format_,
|
|
2508
|
-
"provider_name": provider.name if provider else instance.provider,
|
|
2509
|
-
"groups_table": groups_table,
|
|
2510
|
-
**super().get_extra_context(request, instance),
|
|
2511
|
-
}
|
|
2640
|
+
ctx = super().get_extra_context(request, instance)
|
|
2641
|
+
if self.action == "retrieve":
|
|
2642
|
+
ctx["parameters"] = instance.parameters
|
|
2643
|
+
return ctx
|
|
2512
2644
|
|
|
2513
2645
|
|
|
2514
2646
|
class SecretProviderParametersFormView(generic.GenericView):
|
|
@@ -2527,27 +2659,6 @@ class SecretProviderParametersFormView(generic.GenericView):
|
|
|
2527
2659
|
)
|
|
2528
2660
|
|
|
2529
2661
|
|
|
2530
|
-
class SecretEditView(generic.ObjectEditView):
|
|
2531
|
-
queryset = Secret.objects.all()
|
|
2532
|
-
model_form = forms.SecretForm
|
|
2533
|
-
template_name = "extras/secret_edit.html"
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
class SecretDeleteView(generic.ObjectDeleteView):
|
|
2537
|
-
queryset = Secret.objects.all()
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
class SecretBulkImportView(generic.BulkImportView): # 3.0 TODO: remove, unused
|
|
2541
|
-
queryset = Secret.objects.all()
|
|
2542
|
-
table = tables.SecretTable
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
class SecretBulkDeleteView(generic.BulkDeleteView):
|
|
2546
|
-
queryset = Secret.objects.all()
|
|
2547
|
-
filterset = filters.SecretFilterSet
|
|
2548
|
-
table = tables.SecretTable
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
2662
|
class SecretsGroupListView(generic.ObjectListView):
|
|
2552
2663
|
queryset = SecretsGroup.objects.all()
|
|
2553
2664
|
filterset = filters.SecretsGroupFilterSet
|
nautobot/extras/webhooks.py
CHANGED
|
@@ -6,12 +6,13 @@ from nautobot.extras.registry import registry
|
|
|
6
6
|
from nautobot.extras.tasks import process_webhook
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
def enqueue_webhooks(object_change, webhook_queryset=None):
|
|
9
|
+
def enqueue_webhooks(object_change, snapshots=None, webhook_queryset=None):
|
|
10
10
|
"""
|
|
11
11
|
Find Webhook(s) assigned to this instance + action and enqueue them to be processed.
|
|
12
12
|
|
|
13
13
|
Args:
|
|
14
14
|
object_change (ObjectChange): The change that may trigger Webhooks to be sent.
|
|
15
|
+
snapshots (list): The before/after data snapshots corresponding to the object_change.
|
|
15
16
|
webhook_queryset (QuerySet): Previously retrieved set of Webhooks to potentially send.
|
|
16
17
|
|
|
17
18
|
Returns:
|
|
@@ -34,6 +35,8 @@ def enqueue_webhooks(object_change, webhook_queryset=None):
|
|
|
34
35
|
webhook_queryset = Webhook.objects.filter(content_types=content_type, enabled=True, **{action_flag: True})
|
|
35
36
|
|
|
36
37
|
if webhook_queryset: # not .exists() as we *want* to populate the queryset cache
|
|
38
|
+
if snapshots is None:
|
|
39
|
+
snapshots = object_change.get_snapshots()
|
|
37
40
|
# fall back to object_data if object_data_v2 is not available
|
|
38
41
|
serialized_data = object_change.object_data_v2
|
|
39
42
|
if serialized_data is None:
|
|
@@ -49,7 +52,7 @@ def enqueue_webhooks(object_change, webhook_queryset=None):
|
|
|
49
52
|
str(timezone.now()),
|
|
50
53
|
object_change.user_name,
|
|
51
54
|
object_change.request_id,
|
|
52
|
-
|
|
55
|
+
snapshots,
|
|
53
56
|
]
|
|
54
57
|
process_webhook.apply_async(args=args)
|
|
55
58
|
|
nautobot/ipam/api/fields.py
CHANGED
|
@@ -7,11 +7,11 @@ class IPFieldSerializer(serializers.CharField):
|
|
|
7
7
|
"""Convert internal (IPNetwork) representation to API (string) representation."""
|
|
8
8
|
return str(value)
|
|
9
9
|
|
|
10
|
-
def to_internal_value(self,
|
|
10
|
+
def to_internal_value(self, value):
|
|
11
11
|
"""Convert API (string) representation to internal (IPNetwork) representation."""
|
|
12
12
|
try:
|
|
13
|
-
return netaddr.IPNetwork(
|
|
13
|
+
return netaddr.IPNetwork(value)
|
|
14
14
|
except netaddr.AddrFormatError:
|
|
15
|
-
raise serializers.ValidationError(f"Invalid IP address format: {
|
|
15
|
+
raise serializers.ValidationError(f"Invalid IP address format: {value}")
|
|
16
16
|
except (TypeError, ValueError) as e:
|
|
17
17
|
raise serializers.ValidationError(e)
|