nautobot 2.3.16__py3-none-any.whl → 2.4.0__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/__init__.py +1 -1
- nautobot/apps/api.py +8 -10
- nautobot/apps/change_logging.py +2 -2
- nautobot/apps/choices.py +4 -4
- nautobot/apps/config.py +32 -3
- nautobot/apps/events.py +19 -0
- nautobot/apps/exceptions.py +0 -2
- 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 +44 -9
- nautobot/apps/utils.py +7 -15
- nautobot/apps/views.py +8 -6
- nautobot/circuits/api/serializers.py +1 -0
- nautobot/circuits/api/views.py +4 -8
- nautobot/circuits/navigation.py +0 -57
- nautobot/circuits/templates/circuits/circuit_create.html +1 -7
- 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 +140 -23
- nautobot/cloud/api/views.py +6 -10
- nautobot/cloud/factory.py +4 -1
- nautobot/cloud/tests/test_filters.py +5 -4
- nautobot/cloud/views.py +0 -16
- nautobot/core/api/constants.py +11 -0
- nautobot/core/api/filter_backends.py +3 -9
- nautobot/core/api/metadata.py +28 -256
- nautobot/core/api/pagination.py +3 -2
- nautobot/core/api/renderers.py +3 -0
- nautobot/core/api/schema.py +13 -2
- nautobot/core/api/serializers.py +45 -259
- nautobot/core/api/urls.py +3 -4
- nautobot/core/api/utils.py +0 -62
- nautobot/core/api/views.py +99 -157
- nautobot/core/apps/__init__.py +22 -578
- nautobot/core/celery/__init__.py +13 -0
- nautobot/core/celery/schedulers.py +47 -2
- nautobot/core/choices.py +2 -2
- 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/forms/__init__.py +19 -19
- nautobot/core/forms/fields.py +57 -9
- nautobot/core/forms/forms.py +33 -2
- nautobot/core/forms/utils.py +2 -1
- nautobot/core/graphql/schema.py +3 -1
- nautobot/core/jobs/__init__.py +24 -3
- nautobot/core/jobs/bulk_actions.py +248 -0
- nautobot/core/jobs/cleanup.py +1 -1
- nautobot/core/management/commands/generate_test_data.py +21 -0
- nautobot/core/middleware.py +16 -0
- nautobot/core/models/fields.py +11 -7
- nautobot/core/settings.py +68 -4
- nautobot/core/settings.yaml +99 -0
- nautobot/core/tables.py +10 -46
- nautobot/core/tasks.py +1 -1
- nautobot/core/templates/about.html +67 -0
- 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/nav_menu.html +2 -1
- nautobot/core/templates/inc/relationships_panel.html +1 -1
- 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/panel_table.html +12 -0
- nautobot/core/templates/utilities/render_jinja2.html +117 -0
- nautobot/core/templates/utilities/templatetags/tag.html +1 -1
- nautobot/core/templates/utilities/theme_preview.html +7 -0
- nautobot/core/templatetags/helpers.py +104 -6
- nautobot/core/templatetags/ui_framework.py +40 -0
- nautobot/core/testing/__init__.py +8 -8
- nautobot/core/testing/api.py +187 -137
- nautobot/core/testing/context.py +18 -0
- nautobot/core/testing/filters.py +41 -35
- nautobot/core/testing/forms.py +2 -0
- nautobot/core/testing/views.py +65 -148
- nautobot/core/tests/integration/test_view_authentication.py +1 -1
- nautobot/core/tests/nautobot_config.py +198 -0
- nautobot/core/tests/runner.py +2 -2
- nautobot/core/tests/test_api.py +154 -176
- nautobot/core/tests/test_events.py +214 -0
- nautobot/core/tests/test_forms.py +1 -0
- nautobot/core/tests/test_jinja_filters.py +1 -0
- nautobot/core/tests/test_jobs.py +387 -14
- nautobot/core/tests/test_navigations.py +7 -241
- nautobot/core/tests/test_settings_schema.py +7 -0
- nautobot/core/tests/test_tables.py +100 -0
- nautobot/core/tests/test_templatetags_helpers.py +16 -0
- nautobot/core/tests/test_ui.py +150 -0
- nautobot/core/tests/test_utils.py +55 -18
- nautobot/core/tests/test_views.py +124 -5
- 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 +280 -0
- nautobot/core/ui/object_detail.py +1855 -0
- nautobot/core/ui/utils.py +36 -0
- nautobot/core/urls.py +6 -0
- nautobot/core/utils/config.py +30 -3
- nautobot/core/utils/lookup.py +12 -2
- nautobot/core/utils/querysets.py +64 -0
- nautobot/core/utils/requests.py +24 -9
- nautobot/core/views/__init__.py +48 -1
- nautobot/core/views/generic.py +37 -140
- nautobot/core/views/mixins.py +82 -32
- nautobot/core/views/paginator.py +8 -5
- nautobot/core/views/renderers.py +9 -9
- nautobot/core/views/utils.py +11 -0
- nautobot/core/wsgi.py +3 -3
- nautobot/dcim/api/serializers.py +34 -141
- nautobot/dcim/api/urls.py +5 -0
- nautobot/dcim/api/views.py +57 -110
- nautobot/dcim/apps.py +1 -0
- nautobot/dcim/choices.py +28 -0
- nautobot/dcim/factory.py +58 -0
- nautobot/dcim/filters/__init__.py +204 -2
- nautobot/dcim/forms.py +219 -9
- 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/migrations/0067_controllermanageddevicegroup_tenant.py +25 -0
- nautobot/dcim/models/__init__.py +5 -1
- nautobot/dcim/models/devices.py +180 -2
- nautobot/dcim/models/racks.py +2 -2
- nautobot/dcim/navigation.py +25 -224
- nautobot/dcim/signals.py +44 -0
- nautobot/dcim/tables/__init__.py +2 -0
- nautobot/dcim/tables/devices.py +103 -7
- nautobot/dcim/tables/racks.py +1 -1
- nautobot/dcim/templates/dcim/controller/base.html +10 -0
- nautobot/dcim/templates/dcim/controller_create.html +2 -7
- nautobot/dcim/templates/dcim/controller_retrieve.html +6 -10
- nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +25 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_create.html +68 -0
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +51 -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 +4 -10
- nautobot/dcim/templates/dcim/device_edit.html +36 -37
- nautobot/dcim/templates/dcim/interface.html +1 -0
- nautobot/dcim/templates/dcim/interface_edit.html +1 -0
- nautobot/dcim/templates/dcim/location.html +1 -9
- nautobot/dcim/templates/dcim/location_edit.html +1 -7
- nautobot/dcim/templates/dcim/locationtype.html +0 -107
- nautobot/dcim/templates/dcim/locationtype_retrieve.html +8 -0
- 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 +68 -0
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +28 -0
- nautobot/dcim/tests/integration/test_controller.py +62 -0
- nautobot/dcim/tests/integration/test_controller_managed_device_group.py +71 -0
- nautobot/dcim/tests/test_api.py +188 -64
- nautobot/dcim/tests/test_filters.py +171 -76
- nautobot/dcim/tests/test_jobs.py +118 -0
- nautobot/dcim/tests/test_models.py +157 -6
- nautobot/dcim/tests/test_signals.py +1 -0
- nautobot/dcim/tests/test_views.py +118 -88
- nautobot/dcim/urls.py +72 -27
- nautobot/dcim/utils.py +2 -2
- nautobot/dcim/views.py +356 -61
- nautobot/extras/api/serializers.py +39 -18
- nautobot/extras/api/urls.py +4 -0
- nautobot/extras/api/views.py +89 -31
- nautobot/extras/choices.py +13 -0
- nautobot/extras/constants.py +2 -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 +66 -5
- nautobot/extras/forms/base.py +2 -2
- nautobot/extras/forms/forms.py +262 -59
- nautobot/extras/forms/mixins.py +2 -2
- nautobot/extras/graphql/types.py +25 -1
- nautobot/extras/jobs.py +109 -15
- 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/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/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 +5 -1
- nautobot/extras/models/change_logging.py +7 -3
- nautobot/extras/models/contacts.py +1 -1
- nautobot/extras/models/groups.py +0 -2
- nautobot/extras/models/jobs.py +233 -33
- 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 +54 -19
- nautobot/extras/plugins/marketplace_manifest.yml +455 -0
- nautobot/extras/plugins/tables.py +16 -14
- nautobot/extras/plugins/urls.py +1 -0
- nautobot/extras/plugins/views.py +103 -60
- nautobot/extras/registry.py +1 -1
- nautobot/extras/secrets/__init__.py +2 -2
- nautobot/extras/signals.py +39 -1
- nautobot/extras/tables.py +37 -1
- nautobot/extras/templates/extras/dynamicgroup.html +1 -9
- 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 +52 -6
- nautobot/extras/templates/extras/job_edit.html +6 -2
- nautobot/extras/templates/extras/job_list.html +2 -7
- nautobot/extras/templates/extras/jobqueue_retrieve.html +36 -0
- nautobot/extras/templates/extras/marketplace.html +296 -0
- nautobot/extras/templates/extras/plugin_detail.html +32 -15
- nautobot/extras/templates/extras/plugins_list.html +35 -1
- nautobot/extras/templates/extras/plugins_tiles.html +90 -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/singleton.py +16 -0
- nautobot/extras/tests/test_api.py +145 -43
- nautobot/extras/tests/test_context_managers.py +4 -1
- nautobot/extras/tests/test_filters.py +213 -529
- nautobot/extras/tests/test_job_variables.py +73 -152
- nautobot/extras/tests/test_jobs.py +181 -51
- nautobot/extras/tests/test_models.py +61 -6
- nautobot/extras/tests/test_plugins.py +62 -9
- nautobot/extras/tests/test_relationships.py +123 -9
- nautobot/extras/tests/test_utils.py +23 -2
- nautobot/extras/tests/test_views.py +146 -145
- nautobot/extras/tests/test_webhooks.py +2 -1
- nautobot/extras/urls.py +2 -20
- nautobot/extras/utils.py +119 -4
- nautobot/extras/views.py +168 -125
- nautobot/extras/webhooks.py +5 -2
- nautobot/ipam/api/serializers.py +10 -103
- nautobot/ipam/api/views.py +31 -49
- nautobot/ipam/factory.py +1 -1
- nautobot/ipam/filters.py +3 -2
- nautobot/ipam/models.py +10 -12
- nautobot/ipam/navigation.py +0 -90
- nautobot/ipam/tables.py +3 -1
- 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/routetarget.html +0 -28
- nautobot/ipam/templates/ipam/vlan.html +1 -9
- nautobot/ipam/templates/ipam/vlan_edit.html +1 -7
- nautobot/ipam/templates/ipam/vrf.html +0 -47
- nautobot/ipam/templates/ipam/vrf_edit.html +1 -7
- nautobot/ipam/tests/test_api.py +7 -5
- nautobot/ipam/tests/test_filters.py +39 -119
- nautobot/ipam/tests/test_forms.py +0 -2
- nautobot/ipam/tests/test_models.py +56 -36
- nautobot/ipam/tests/test_views.py +3 -0
- nautobot/ipam/urls.py +3 -69
- nautobot/ipam/utils/__init__.py +16 -10
- nautobot/ipam/views.py +91 -162
- 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/css/base.css +38 -3
- nautobot/project-static/docs/404.html +461 -17
- nautobot/project-static/docs/apps/index.html +461 -17
- nautobot/project-static/docs/apps/nautobot-apps.html +462 -19
- nautobot/project-static/docs/assets/_mkdocstrings.css +25 -1
- nautobot/project-static/docs/assets/extra.css +5 -1
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +477 -23
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +474 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +790 -289
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +505 -31
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +510 -34
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +471 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +467 -18
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +497 -33
- nautobot/project-static/docs/code-reference/nautobot/apps/events.html +9883 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +523 -75
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +546 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +670 -94
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +1030 -177
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +524 -49
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +874 -188
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +955 -235
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +475 -21
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +486 -28
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +661 -99
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +947 -479
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +6425 -1234
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +474 -20
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +877 -344
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +828 -171
- nautobot/project-static/docs/development/apps/api/configuration-view.html +461 -17
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/global-search.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/graphql.html +461 -17
- nautobot/project-static/docs/development/apps/api/models/index.html +461 -17
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/table-extensions.html +461 -17
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +461 -17
- nautobot/project-static/docs/development/apps/api/prometheus.html +461 -17
- nautobot/project-static/docs/development/apps/api/setup.html +465 -153
- nautobot/project-static/docs/development/apps/api/testing.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +461 -17
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +741 -128
- nautobot/project-static/docs/development/apps/api/views/base-template.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/index.html +463 -18
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +465 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +491 -17
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/notes.html +461 -17
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +467 -19
- nautobot/project-static/docs/development/apps/api/views/urls.html +461 -17
- nautobot/project-static/docs/development/apps/index.html +461 -17
- nautobot/project-static/docs/development/apps/migration/code-updates.html +462 -50
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +462 -18
- nautobot/project-static/docs/development/apps/migration/from-v1.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +461 -17
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +464 -20
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/best-practices.html +9261 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/custom-content.html +9375 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/index.html +9671 -0
- nautobot/project-static/docs/development/apps/migration/ui-component-framework/migration-steps.html +9559 -0
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +464 -20
- nautobot/project-static/docs/development/core/application-registry.html +461 -17
- nautobot/project-static/docs/development/core/best-practices.html +461 -17
- nautobot/project-static/docs/development/core/bootstrap-ui.html +461 -17
- nautobot/project-static/docs/development/core/caching.html +461 -17
- nautobot/project-static/docs/development/core/controllers.html +463 -17
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +464 -20
- nautobot/project-static/docs/development/core/generic-views.html +461 -17
- nautobot/project-static/docs/development/core/getting-started.html +539 -127
- nautobot/project-static/docs/development/core/homepage.html +472 -28
- nautobot/project-static/docs/development/core/index.html +461 -17
- nautobot/project-static/docs/development/core/minikube-dev-environment-for-k8s-jobs.html +9754 -0
- nautobot/project-static/docs/development/core/model-checklist.html +471 -25
- nautobot/project-static/docs/development/core/model-features.html +461 -17
- nautobot/project-static/docs/development/core/natural-keys.html +461 -17
- nautobot/project-static/docs/development/core/navigation-menu.html +478 -24
- nautobot/project-static/docs/development/core/release-checklist.html +478 -46
- nautobot/project-static/docs/development/core/role-internals.html +461 -17
- nautobot/project-static/docs/development/core/settings.html +461 -17
- nautobot/project-static/docs/development/core/style-guide.html +464 -20
- nautobot/project-static/docs/development/core/templates.html +471 -20
- nautobot/project-static/docs/development/core/testing.html +461 -17
- nautobot/project-static/docs/development/core/ui-component-framework.html +11116 -0
- nautobot/project-static/docs/development/core/user-preferences.html +464 -20
- nautobot/project-static/docs/development/index.html +461 -17
- nautobot/project-static/docs/development/jobs/index.html +499 -19
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +461 -17
- nautobot/project-static/docs/index.html +469 -36
- 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/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/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/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/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/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 +467 -21
- nautobot/project-static/docs/overview/design_philosophy.html +461 -17
- nautobot/project-static/docs/release-notes/index.html +483 -20
- nautobot/project-static/docs/release-notes/version-1.0.html +649 -206
- nautobot/project-static/docs/release-notes/version-1.1.html +646 -203
- nautobot/project-static/docs/release-notes/version-1.2.html +721 -278
- nautobot/project-static/docs/release-notes/version-1.3.html +747 -304
- nautobot/project-static/docs/release-notes/version-1.4.html +832 -390
- nautobot/project-static/docs/release-notes/version-1.5.html +1020 -579
- nautobot/project-static/docs/release-notes/version-1.6.html +940 -516
- nautobot/project-static/docs/release-notes/version-2.0.html +943 -502
- nautobot/project-static/docs/release-notes/version-2.1.html +778 -337
- nautobot/project-static/docs/release-notes/version-2.2.html +771 -330
- nautobot/project-static/docs/release-notes/version-2.3.html +914 -471
- nautobot/project-static/docs/release-notes/version-2.4.html +10323 -0
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +342 -270
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +473 -30
- nautobot/project-static/docs/user-guide/administration/configuration/redis.html +461 -17
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +842 -155
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +474 -27
- nautobot/project-static/docs/user-guide/administration/guides/health-checks.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +461 -17
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +463 -19
- nautobot/project-static/docs/user-guide/administration/guides/selinux-troubleshooting.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +481 -21
- nautobot/project-static/docs/user-guide/administration/installation/index.html +466 -18
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +462 -18
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +461 -17
- nautobot/project-static/docs/user-guide/administration/installation/services.html +461 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +461 -17
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +482 -39
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +475 -64
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +475 -64
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +464 -21
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +461 -17
- 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 +461 -17
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +467 -19
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloud.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudaccount.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetwork.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudnetworkprefixassignment.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudresourcetype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservice.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/cloud/cloudservicenetworkassignment.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +497 -18
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +487 -20
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/module.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebay.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/modulebaytemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/moduletype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualdevicecontext.html +9375 -0
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +468 -28
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +464 -20
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +461 -17
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +464 -20
- nautobot/project-static/docs/user-guide/core-data-model/wireless/index.html +9313 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/radioprofile.html +9217 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/supporteddatarate.html +9211 -0
- nautobot/project-static/docs/user-guide/core-data-model/wireless/wirelessnetwork.html +9277 -0
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +466 -20
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +461 -17
- 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 +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +461 -17
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +464 -20
- nautobot/project-static/docs/user-guide/feature-guides/wireless-networks-and-controllers.html +9444 -0
- nautobot/project-static/docs/user-guide/index.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +465 -21
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/events.html +9617 -0
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +470 -21
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobqueue.html +9224 -0
- 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 +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/objectmetadata.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +465 -21
- nautobot/project-static/docs/user-guide/platform-functionality/rendering-jinja-templates.html +9292 -0
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +509 -38
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +492 -21
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/savedview.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/staticgroupassociation.html +464 -20
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +529 -54
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +461 -17
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +461 -17
- nautobot/project-static/img/jinja_logo.svg +97 -0
- nautobot/project-static/js/forms.js +6 -1
- nautobot/project-static/js/nav_menu.js +2 -1
- nautobot/tenancy/api/serializers.py +0 -2
- nautobot/tenancy/api/views.py +9 -13
- 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 +35 -24
- nautobot/users/admin.py +2 -0
- nautobot/users/api/views.py +2 -2
- 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/views.py +5 -24
- nautobot/virtualization/filters.py +1 -2
- nautobot/virtualization/models.py +1 -1
- nautobot/virtualization/navigation.py +0 -48
- nautobot/virtualization/tables.py +2 -2
- nautobot/virtualization/templates/virtualization/cluster_edit.html +1 -7
- nautobot/virtualization/templates/virtualization/clustertype.html +0 -39
- nautobot/virtualization/templates/virtualization/virtualmachine.html +1 -9
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +2 -8
- nautobot/virtualization/tests/test_filters.py +57 -166
- 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 +56 -0
- nautobot/wireless/tests/__init__.py +0 -0
- nautobot/wireless/tests/integration/__init__.py +0 -0
- nautobot/wireless/tests/integration/test_radio_profile.py +42 -0
- nautobot/wireless/tests/test_api.py +247 -0
- nautobot/wireless/tests/test_filters.py +82 -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 +119 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/METADATA +9 -12
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/RECORD +720 -549
- nautobot/core/utils/navigation.py +0 -54
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/NOTICE +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/WHEEL +0 -0
- {nautobot-2.3.16.dist-info → nautobot-2.4.0.dist-info}/entry_points.txt +0 -0
nautobot/core/apps/__init__.py
CHANGED
|
@@ -1,29 +1,42 @@
|
|
|
1
|
-
from abc import ABC, abstractmethod
|
|
2
1
|
from collections import OrderedDict
|
|
3
2
|
import logging
|
|
4
3
|
import os
|
|
5
4
|
|
|
6
5
|
from constance.apps import ConstanceConfig
|
|
7
6
|
from django.apps import AppConfig, apps as global_apps
|
|
8
|
-
from django.contrib.admin.sites import NotRegistered
|
|
9
7
|
from django.db.models import BigIntegerField, BinaryField, JSONField
|
|
10
8
|
from django.db.models.signals import post_migrate
|
|
11
9
|
from django.urls import reverse
|
|
12
10
|
from django.urls.exceptions import NoReverseMatch
|
|
11
|
+
from django.utils.http import urlencode
|
|
13
12
|
from django.utils.module_loading import import_string
|
|
14
13
|
from graphene.types import generic, String
|
|
15
14
|
|
|
16
|
-
from nautobot.core.choices import ButtonActionColorChoices, ButtonActionIconChoices
|
|
17
15
|
from nautobot.core.signals import nautobot_database_ready
|
|
18
|
-
from nautobot.core.
|
|
16
|
+
from nautobot.core.ui.base import PermissionsMixin # noqa: F401
|
|
17
|
+
|
|
18
|
+
from nautobot.core.ui.homepage import ( # isort: skip # noqa: F401
|
|
19
|
+
HomePageBase,
|
|
20
|
+
HomePageGroup,
|
|
21
|
+
HomePageItem,
|
|
22
|
+
HomePagePanel,
|
|
23
|
+
)
|
|
24
|
+
from nautobot.core.ui.nav import ( # isort: skip # noqa: F401
|
|
25
|
+
NavMenuAddButton,
|
|
26
|
+
NavMenuBase,
|
|
27
|
+
NavMenuButton,
|
|
28
|
+
NavMenuGroup,
|
|
29
|
+
NavMenuImportButton,
|
|
30
|
+
NavMenuItem,
|
|
31
|
+
NavMenuTab,
|
|
32
|
+
NAV_CONTEXT_NAMES,
|
|
33
|
+
)
|
|
34
|
+
|
|
19
35
|
from nautobot.extras.registry import registry
|
|
20
36
|
|
|
21
37
|
logger = logging.getLogger(__name__)
|
|
22
38
|
registry["nav_menu"] = {"tabs": {}}
|
|
23
|
-
registry["new_ui_nav_menu"] = {}
|
|
24
39
|
registry["homepage_layout"] = {"panels": {}}
|
|
25
|
-
registry["new_ui_ready_routes"] = set()
|
|
26
|
-
NAV_CONTEXT_NAMES = ("Inventory", "Networks", "Security", "Automation", "Platform")
|
|
27
40
|
|
|
28
41
|
|
|
29
42
|
class NautobotConfig(AppConfig):
|
|
@@ -59,19 +72,6 @@ class NautobotConfig(AppConfig):
|
|
|
59
72
|
except ImportError:
|
|
60
73
|
pass
|
|
61
74
|
|
|
62
|
-
# TODO we should remove this because it is no longer relevant.
|
|
63
|
-
try:
|
|
64
|
-
navigation = import_string(f"{self.name}.{self.navigation}")
|
|
65
|
-
register_new_ui_menu_items(navigation)
|
|
66
|
-
except ImportError:
|
|
67
|
-
pass
|
|
68
|
-
|
|
69
|
-
try:
|
|
70
|
-
registry["new_ui_ready_routes"].update(get_all_new_ui_ready_routes())
|
|
71
|
-
except NotRegistered:
|
|
72
|
-
# NOTE: Catch this error: The "Tag" model is not registered, which may be related to the admin not registering Tags. Further research is needed on this.
|
|
73
|
-
pass
|
|
74
|
-
|
|
75
75
|
|
|
76
76
|
def create_or_check_entry(grouping, record, key, path):
|
|
77
77
|
"""
|
|
@@ -96,14 +96,6 @@ def create_or_check_entry(grouping, record, key, path):
|
|
|
96
96
|
if grouping[key][attr] != value:
|
|
97
97
|
logger.error("Unable to redefine %s on %s from %s to %s", attr, path, grouping[key][attr], value)
|
|
98
98
|
|
|
99
|
-
# TODO: remove?
|
|
100
|
-
# React-UI specific: recursive population/validation of `data` for NavContext -> NavGrouping -> NavItem records
|
|
101
|
-
if isinstance(record, (NavContext, NavGrouping)):
|
|
102
|
-
groups = record.groups if isinstance(record, NavContext) else record.items
|
|
103
|
-
for item in groups:
|
|
104
|
-
create_or_check_entry(grouping[key]["data"], item, item.name, f"{path} -> {item.name}")
|
|
105
|
-
grouping[key]["data"] = dict(sorted(grouping[key]["data"].items(), key=lambda x: x[1]["weight"]))
|
|
106
|
-
|
|
107
99
|
|
|
108
100
|
def register_menu_items(tab_list):
|
|
109
101
|
"""
|
|
@@ -174,6 +166,8 @@ def register_menu_items(tab_list):
|
|
|
174
166
|
# Instead of passing the reverse url strings, we pass in the url itself initialized with args and kwargs.
|
|
175
167
|
try:
|
|
176
168
|
item.link = reverse(item.link, args=item.args, kwargs=item.kwargs)
|
|
169
|
+
if item.query_params:
|
|
170
|
+
item.link += f"?{urlencode(item.query_params)}"
|
|
177
171
|
except NoReverseMatch as e:
|
|
178
172
|
# Catch the invalid link here and render the link name as an error message in the template
|
|
179
173
|
logger.debug("%s", e)
|
|
@@ -234,11 +228,6 @@ def register_menu_items(tab_list):
|
|
|
234
228
|
)
|
|
235
229
|
|
|
236
230
|
|
|
237
|
-
def register_new_ui_menu_items(context_list):
|
|
238
|
-
for nav_context in context_list:
|
|
239
|
-
create_or_check_entry(registry["new_ui_nav_menu"], nav_context, nav_context.name, nav_context.name)
|
|
240
|
-
|
|
241
|
-
|
|
242
231
|
def register_homepage_panels(path, label, homepage_layout):
|
|
243
232
|
"""
|
|
244
233
|
Register homepage panels using `homepage.py`.
|
|
@@ -316,551 +305,6 @@ def register_homepage_panels(path, label, homepage_layout):
|
|
|
316
305
|
)
|
|
317
306
|
|
|
318
307
|
|
|
319
|
-
class HomePageBase(ABC):
|
|
320
|
-
"""Base class for homepage layout classes."""
|
|
321
|
-
|
|
322
|
-
@property
|
|
323
|
-
@abstractmethod
|
|
324
|
-
def initial_dict(self): # to be implemented by each subclass
|
|
325
|
-
return {}
|
|
326
|
-
|
|
327
|
-
@property
|
|
328
|
-
@abstractmethod
|
|
329
|
-
def fixed_fields(self): # to be implemented by subclass
|
|
330
|
-
return ()
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
class NavMenuBase(ABC): # replaces PermissionsMixin
|
|
334
|
-
"""Base class for navigation classes."""
|
|
335
|
-
|
|
336
|
-
@property
|
|
337
|
-
@abstractmethod
|
|
338
|
-
def initial_dict(self) -> dict: # to be implemented by each subclass
|
|
339
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
340
|
-
return {}
|
|
341
|
-
|
|
342
|
-
@property
|
|
343
|
-
@abstractmethod
|
|
344
|
-
def fixed_fields(self) -> tuple: # to be implemented by subclass
|
|
345
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
346
|
-
return ()
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
class PermissionsMixin:
|
|
350
|
-
"""Ensure permissions through init."""
|
|
351
|
-
|
|
352
|
-
def __init__(self, permissions=None):
|
|
353
|
-
"""Ensure permissions."""
|
|
354
|
-
if permissions is not None and not isinstance(permissions, (list, tuple)):
|
|
355
|
-
raise TypeError("Permissions must be passed as a tuple or list.")
|
|
356
|
-
self.permissions = set(permissions) if permissions else None
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
class HomePagePanel(HomePageBase, PermissionsMixin):
|
|
360
|
-
"""Defines properties that can be used for a panel."""
|
|
361
|
-
|
|
362
|
-
items = None
|
|
363
|
-
template_path = None
|
|
364
|
-
|
|
365
|
-
@property
|
|
366
|
-
def initial_dict(self):
|
|
367
|
-
return {
|
|
368
|
-
"custom_template": self.custom_template,
|
|
369
|
-
"custom_data": self.custom_data,
|
|
370
|
-
"weight": self.weight,
|
|
371
|
-
"items": {},
|
|
372
|
-
"permissions": self.permissions,
|
|
373
|
-
"template_path": self.template_path,
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
@property
|
|
377
|
-
def fixed_fields(self):
|
|
378
|
-
return ()
|
|
379
|
-
|
|
380
|
-
def __init__(self, name, permissions=None, custom_data=None, custom_template=None, items=None, weight=1000):
|
|
381
|
-
"""
|
|
382
|
-
Ensure panel properties.
|
|
383
|
-
|
|
384
|
-
Args:
|
|
385
|
-
name (str): The name of the panel.
|
|
386
|
-
permissions (list): The permissions required to view this panel.
|
|
387
|
-
custom_data (dict): Custom data to be passed to the custom template.
|
|
388
|
-
custom_template (str): Name of custom template.
|
|
389
|
-
items (list): List of items to be rendered in this panel.
|
|
390
|
-
weight (int): The weight of this panel.
|
|
391
|
-
"""
|
|
392
|
-
super().__init__(permissions)
|
|
393
|
-
self.custom_data = custom_data
|
|
394
|
-
self.custom_template = custom_template
|
|
395
|
-
self.name = name
|
|
396
|
-
self.weight = weight
|
|
397
|
-
|
|
398
|
-
if items is not None and custom_template is not None:
|
|
399
|
-
raise ValueError("Cannot specify items and custom_template at the same time.")
|
|
400
|
-
if items is not None:
|
|
401
|
-
if not isinstance(items, (list, tuple)):
|
|
402
|
-
raise TypeError("Items must be passed as a tuple or list.")
|
|
403
|
-
elif not all(isinstance(item, (HomePageGroup, HomePageItem)) for item in items):
|
|
404
|
-
raise TypeError("All items defined in a panel must be an instance of HomePageGroup or HomePageItem")
|
|
405
|
-
self.items = items
|
|
406
|
-
else:
|
|
407
|
-
self.items = []
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
class HomePageGroup(HomePageBase, PermissionsMixin):
|
|
411
|
-
"""Defines properties that can be used for a panel group."""
|
|
412
|
-
|
|
413
|
-
items = []
|
|
414
|
-
|
|
415
|
-
@property
|
|
416
|
-
def initial_dict(self):
|
|
417
|
-
return {
|
|
418
|
-
"items": {},
|
|
419
|
-
"permissions": self.permissions,
|
|
420
|
-
"weight": self.weight,
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
@property
|
|
424
|
-
def fixed_fields(self):
|
|
425
|
-
return ()
|
|
426
|
-
|
|
427
|
-
def __init__(self, name, permissions=None, items=None, weight=1000):
|
|
428
|
-
"""
|
|
429
|
-
Ensure group properties.
|
|
430
|
-
|
|
431
|
-
Args:
|
|
432
|
-
name (str): The name of the group.
|
|
433
|
-
permissions (list): The permissions required to view this group.
|
|
434
|
-
items (list): List of items to be rendered in this group.
|
|
435
|
-
weight (int): The weight of this group.
|
|
436
|
-
"""
|
|
437
|
-
super().__init__(permissions)
|
|
438
|
-
self.name = name
|
|
439
|
-
self.weight = weight
|
|
440
|
-
|
|
441
|
-
if items is not None:
|
|
442
|
-
if not isinstance(items, (list, tuple)):
|
|
443
|
-
raise TypeError("Items must be passed as a tuple or list.")
|
|
444
|
-
elif not all(isinstance(item, HomePageItem) for item in items):
|
|
445
|
-
raise TypeError("All items defined in a group must be an instance of HomePageItem")
|
|
446
|
-
self.items = items
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
class HomePageItem(HomePageBase, PermissionsMixin):
|
|
450
|
-
"""Defines properties that can be used for a panel item."""
|
|
451
|
-
|
|
452
|
-
items = []
|
|
453
|
-
template_path = None
|
|
454
|
-
|
|
455
|
-
@property
|
|
456
|
-
def initial_dict(self):
|
|
457
|
-
return {
|
|
458
|
-
"custom_template": self.custom_template,
|
|
459
|
-
"custom_data": self.custom_data,
|
|
460
|
-
"description": self.description,
|
|
461
|
-
"link": self.link,
|
|
462
|
-
"model": self.model,
|
|
463
|
-
"permissions": self.permissions,
|
|
464
|
-
"template_path": self.template_path,
|
|
465
|
-
"weight": self.weight,
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
@property
|
|
469
|
-
def fixed_fields(self):
|
|
470
|
-
return ()
|
|
471
|
-
|
|
472
|
-
def __init__(
|
|
473
|
-
self,
|
|
474
|
-
name,
|
|
475
|
-
link=None,
|
|
476
|
-
model=None,
|
|
477
|
-
custom_template=None,
|
|
478
|
-
custom_data=None,
|
|
479
|
-
description=None,
|
|
480
|
-
permissions=None,
|
|
481
|
-
weight=1000,
|
|
482
|
-
):
|
|
483
|
-
"""
|
|
484
|
-
Ensure item properties.
|
|
485
|
-
|
|
486
|
-
Args:
|
|
487
|
-
name (str): The name of the item.
|
|
488
|
-
link (str): The link to be used for this item.
|
|
489
|
-
model (str): The model to being used for this item to calculate the total count of objects.
|
|
490
|
-
custom_template (str): Name of custom template.
|
|
491
|
-
custom_data (dict): Custom data to be passed to the custom template.
|
|
492
|
-
"""
|
|
493
|
-
super().__init__(permissions)
|
|
494
|
-
|
|
495
|
-
self.name = name
|
|
496
|
-
self.custom_template = custom_template
|
|
497
|
-
self.custom_data = custom_data
|
|
498
|
-
self.description = description
|
|
499
|
-
self.link = link
|
|
500
|
-
self.model = model
|
|
501
|
-
self.weight = weight
|
|
502
|
-
|
|
503
|
-
if model is not None and custom_template is not None:
|
|
504
|
-
raise ValueError("Cannot specify model and custom_template at the same time.")
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
class NavMenuTab(NavMenuBase, PermissionsMixin):
|
|
508
|
-
"""
|
|
509
|
-
Ths class represents a navigation menu tab. This is built up from a name and a weight value. The name is
|
|
510
|
-
the display text and the weight defines its position in the navbar.
|
|
511
|
-
|
|
512
|
-
Groups are each specified as a list of NavMenuGroup instances.
|
|
513
|
-
"""
|
|
514
|
-
|
|
515
|
-
permissions = []
|
|
516
|
-
groups = []
|
|
517
|
-
|
|
518
|
-
@property
|
|
519
|
-
def initial_dict(self) -> dict:
|
|
520
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
521
|
-
return {
|
|
522
|
-
"weight": self.weight,
|
|
523
|
-
"groups": {},
|
|
524
|
-
"permissions": set(),
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
@property
|
|
528
|
-
def fixed_fields(self) -> tuple:
|
|
529
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
530
|
-
return ()
|
|
531
|
-
|
|
532
|
-
def __init__(self, name, permissions=None, groups=None, weight=1000):
|
|
533
|
-
"""
|
|
534
|
-
Ensure tab properties.
|
|
535
|
-
|
|
536
|
-
Args:
|
|
537
|
-
name (str): The name of the tab.
|
|
538
|
-
permissions (list): The permissions required to view this tab.
|
|
539
|
-
groups (list): List of groups to be rendered in this tab.
|
|
540
|
-
weight (int): The weight of this tab.
|
|
541
|
-
"""
|
|
542
|
-
super().__init__(permissions)
|
|
543
|
-
self.name = name
|
|
544
|
-
self.weight = weight
|
|
545
|
-
if groups is not None:
|
|
546
|
-
if not isinstance(groups, (list, tuple)):
|
|
547
|
-
raise TypeError("Groups must be passed as a tuple or list.")
|
|
548
|
-
elif not all(isinstance(group, NavMenuGroup) for group in groups):
|
|
549
|
-
raise TypeError("All groups defined in a tab must be an instance of NavMenuGroup")
|
|
550
|
-
self.groups = groups
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
class NavMenuGroup(NavMenuBase, PermissionsMixin):
|
|
554
|
-
"""
|
|
555
|
-
Ths class represents a navigation menu group. This is built up from a name and a weight value. The name is
|
|
556
|
-
the display text and the weight defines its position in the navbar.
|
|
557
|
-
|
|
558
|
-
Items are each specified as a list of NavMenuItem instances.
|
|
559
|
-
"""
|
|
560
|
-
|
|
561
|
-
permissions = []
|
|
562
|
-
items = []
|
|
563
|
-
|
|
564
|
-
@property
|
|
565
|
-
def initial_dict(self) -> dict:
|
|
566
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
567
|
-
return {
|
|
568
|
-
"weight": self.weight,
|
|
569
|
-
"items": {},
|
|
570
|
-
"permissions": set(),
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
@property
|
|
574
|
-
def fixed_fields(self) -> tuple:
|
|
575
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
576
|
-
return ()
|
|
577
|
-
|
|
578
|
-
def __init__(self, name, items=None, weight=1000):
|
|
579
|
-
"""
|
|
580
|
-
Ensure group properties.
|
|
581
|
-
|
|
582
|
-
Args:
|
|
583
|
-
name (str): The name of the group.
|
|
584
|
-
items (list): List of items to be rendered in this group.
|
|
585
|
-
weight (int): The weight of this group.
|
|
586
|
-
"""
|
|
587
|
-
self.name = name
|
|
588
|
-
self.weight = weight
|
|
589
|
-
|
|
590
|
-
if items is not None and not isinstance(items, (list, tuple)):
|
|
591
|
-
raise TypeError("Items must be passed as a tuple or list.")
|
|
592
|
-
elif not all(isinstance(item, NavMenuItem) for item in items):
|
|
593
|
-
raise TypeError("All items defined in a group must be an instance of NavMenuItem")
|
|
594
|
-
self.items = items
|
|
595
|
-
super().__init__(permissions=self.permissions)
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
class NavMenuItem(NavMenuBase, PermissionsMixin):
|
|
599
|
-
"""
|
|
600
|
-
This class represents a navigation menu item. This constitutes primary link and its text, but also allows for
|
|
601
|
-
specifying additional link buttons that appear to the right of the item in the nav menu.
|
|
602
|
-
|
|
603
|
-
Links are specified as Django reverse URL strings.
|
|
604
|
-
Buttons are each specified as a list of NavMenuButton instances.
|
|
605
|
-
"""
|
|
606
|
-
|
|
607
|
-
@property
|
|
608
|
-
def initial_dict(self) -> dict:
|
|
609
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
610
|
-
return {
|
|
611
|
-
"name": self.name,
|
|
612
|
-
"weight": self.weight,
|
|
613
|
-
"buttons": {},
|
|
614
|
-
"permissions": self.permissions,
|
|
615
|
-
"args": [],
|
|
616
|
-
"kwargs": {},
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
@property
|
|
620
|
-
def fixed_fields(self) -> tuple:
|
|
621
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
622
|
-
return (
|
|
623
|
-
("name", self.name),
|
|
624
|
-
("permissions", self.permissions),
|
|
625
|
-
)
|
|
626
|
-
|
|
627
|
-
permissions = []
|
|
628
|
-
buttons = []
|
|
629
|
-
args = []
|
|
630
|
-
kwargs = {}
|
|
631
|
-
|
|
632
|
-
def __init__(self, link, name, args=None, kwargs=None, permissions=None, buttons=(), weight=1000):
|
|
633
|
-
"""
|
|
634
|
-
Ensure item properties.
|
|
635
|
-
|
|
636
|
-
Args:
|
|
637
|
-
link (str): The link to be used for this item.
|
|
638
|
-
name (str): The name of the item.
|
|
639
|
-
args (list): Arguments that are being passed to the url with reverse() method
|
|
640
|
-
kwargs (dict): Keyword arguments are are being passed to the url with reverse() method
|
|
641
|
-
permissions (list): The permissions required to view this item.
|
|
642
|
-
buttons (list): List of buttons to be rendered in this item.
|
|
643
|
-
weight (int): The weight of this item.
|
|
644
|
-
"""
|
|
645
|
-
super().__init__(permissions)
|
|
646
|
-
self.link = link
|
|
647
|
-
self.name = name
|
|
648
|
-
self.weight = weight
|
|
649
|
-
self.args = args
|
|
650
|
-
self.kwargs = kwargs
|
|
651
|
-
|
|
652
|
-
if not isinstance(buttons, (list, tuple)):
|
|
653
|
-
raise TypeError("Buttons must be passed as a tuple or list.")
|
|
654
|
-
elif not all(isinstance(button, NavMenuButton) for button in buttons):
|
|
655
|
-
raise TypeError("All buttons defined in an item must be an instance or subclass of NavMenuButton")
|
|
656
|
-
self.buttons = buttons
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
class NavMenuButton(NavMenuBase, PermissionsMixin):
|
|
660
|
-
"""
|
|
661
|
-
This class represents a button within a NavMenuItem.
|
|
662
|
-
"""
|
|
663
|
-
|
|
664
|
-
@property
|
|
665
|
-
def initial_dict(self) -> dict:
|
|
666
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
667
|
-
return {
|
|
668
|
-
"link": self.link,
|
|
669
|
-
"icon_class": self.icon_class,
|
|
670
|
-
"button_class": self.button_class,
|
|
671
|
-
"weight": self.weight,
|
|
672
|
-
"buttons": {},
|
|
673
|
-
"permissions": self.permissions,
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
@property
|
|
677
|
-
def fixed_fields(self) -> tuple:
|
|
678
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
679
|
-
return (
|
|
680
|
-
("button_class", self.button_class),
|
|
681
|
-
("icon_class", self.icon_class),
|
|
682
|
-
("link", self.link),
|
|
683
|
-
("permissions", self.permissions),
|
|
684
|
-
)
|
|
685
|
-
|
|
686
|
-
def __init__(
|
|
687
|
-
self,
|
|
688
|
-
link,
|
|
689
|
-
title,
|
|
690
|
-
icon_class,
|
|
691
|
-
button_class=ButtonActionColorChoices.DEFAULT,
|
|
692
|
-
permissions=None,
|
|
693
|
-
weight=1000,
|
|
694
|
-
):
|
|
695
|
-
"""
|
|
696
|
-
Ensure button properties.
|
|
697
|
-
|
|
698
|
-
Args:
|
|
699
|
-
link (str): The link to be used for this button.
|
|
700
|
-
title (str): The title of the button.
|
|
701
|
-
icon_class (str): The icon class to be used as the icon for the start of the button.
|
|
702
|
-
button_class (str): The button class defines to be used to define the style of the button.
|
|
703
|
-
permissions (list): The permissions required to view this button.
|
|
704
|
-
weight (int): The weight of this button.
|
|
705
|
-
"""
|
|
706
|
-
super().__init__(permissions)
|
|
707
|
-
self.link = link
|
|
708
|
-
self.title = title
|
|
709
|
-
self.icon_class = icon_class
|
|
710
|
-
self.weight = weight
|
|
711
|
-
self.button_class = button_class
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
class NavMenuAddButton(NavMenuButton):
|
|
715
|
-
"""Add button subclass."""
|
|
716
|
-
|
|
717
|
-
def __init__(self, *args, **kwargs):
|
|
718
|
-
"""Ensure button properties."""
|
|
719
|
-
if "title" not in kwargs:
|
|
720
|
-
kwargs["title"] = "Add"
|
|
721
|
-
if "icon_class" not in kwargs:
|
|
722
|
-
kwargs["icon_class"] = ButtonActionIconChoices.ADD
|
|
723
|
-
if "button_class" not in kwargs:
|
|
724
|
-
kwargs["button_class"] = ButtonActionColorChoices.ADD
|
|
725
|
-
if "weight" not in kwargs:
|
|
726
|
-
kwargs["weight"] = 100
|
|
727
|
-
super().__init__(*args, **kwargs)
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
class NavMenuImportButton(NavMenuButton):
|
|
731
|
-
"""Import button subclass."""
|
|
732
|
-
|
|
733
|
-
def __init__(self, *args, **kwargs):
|
|
734
|
-
"""Ensure button properties."""
|
|
735
|
-
if "title" not in kwargs:
|
|
736
|
-
kwargs["title"] = "Import"
|
|
737
|
-
if "icon_class" not in kwargs:
|
|
738
|
-
kwargs["icon_class"] = ButtonActionIconChoices.IMPORT
|
|
739
|
-
if "button_class" not in kwargs:
|
|
740
|
-
kwargs["button_class"] = ButtonActionColorChoices.IMPORT
|
|
741
|
-
if "weight" not in kwargs:
|
|
742
|
-
kwargs["weight"] = 200
|
|
743
|
-
super().__init__(*args, **kwargs)
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
class NavContext(NavMenuBase):
|
|
747
|
-
"""Ths class represents a navigation menu tab for new ui.
|
|
748
|
-
|
|
749
|
-
Groups are each specified as a list of NavGrouping instances.
|
|
750
|
-
"""
|
|
751
|
-
|
|
752
|
-
def __init__(self, name, groups, weight=1000):
|
|
753
|
-
self.name = name
|
|
754
|
-
self.groups = groups
|
|
755
|
-
self.weight = weight
|
|
756
|
-
self.validate()
|
|
757
|
-
|
|
758
|
-
def validate(self):
|
|
759
|
-
# NavContext name must belong in this group ("Inventory", "Networks", "Security", "Automation", "Platform")
|
|
760
|
-
if self.name not in NAV_CONTEXT_NAMES:
|
|
761
|
-
raise TypeError(f"`{self.name}` is an invalid context name, valid choices are: {NAV_CONTEXT_NAMES}")
|
|
762
|
-
|
|
763
|
-
if self.groups:
|
|
764
|
-
groups = self.groups
|
|
765
|
-
if not isinstance(groups, (list, tuple)):
|
|
766
|
-
raise TypeError("Groups must be passed as a tuple or list.")
|
|
767
|
-
elif not all(isinstance(group, NavGrouping) for group in groups):
|
|
768
|
-
raise TypeError("All groups defined in a NavContext must be an instance of NavGrouping")
|
|
769
|
-
|
|
770
|
-
@property
|
|
771
|
-
def initial_dict(self) -> dict:
|
|
772
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
773
|
-
return {
|
|
774
|
-
"weight": self.weight,
|
|
775
|
-
"data": {},
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
@property
|
|
779
|
-
def fixed_fields(self) -> tuple:
|
|
780
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
781
|
-
return ()
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
class NavGrouping(NavMenuBase, PermissionsMixin):
|
|
785
|
-
"""
|
|
786
|
-
Ths class represents a navigation menu group for the new ui. This is built up from a name and a weight value. The name is
|
|
787
|
-
the display text and the weight defines its position in the navigation sidebar.
|
|
788
|
-
|
|
789
|
-
Items are each specified as a list of NavItem or NavGrouping instances.
|
|
790
|
-
"""
|
|
791
|
-
|
|
792
|
-
def __init__(self, name, items, weight=1000): # pylint:disable=super-init-not-called # this is dead code anyway
|
|
793
|
-
self.name = name
|
|
794
|
-
self.items = items
|
|
795
|
-
self.weight = weight
|
|
796
|
-
self.validate()
|
|
797
|
-
|
|
798
|
-
def validate(self):
|
|
799
|
-
if self.items:
|
|
800
|
-
items = self.items
|
|
801
|
-
if items is not None and not isinstance(items, (list, tuple)):
|
|
802
|
-
raise TypeError("Items must be passed as a tuple or list.")
|
|
803
|
-
|
|
804
|
-
if not all(isinstance(item, (NavItem, self.__class__)) for item in items):
|
|
805
|
-
raise TypeError("All items defined in a NavGrouping must be an instance of NavItem or NavGrouping")
|
|
806
|
-
|
|
807
|
-
@property
|
|
808
|
-
def initial_dict(self) -> dict:
|
|
809
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
810
|
-
return {
|
|
811
|
-
"weight": self.weight,
|
|
812
|
-
"data": {},
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
@property
|
|
816
|
-
def fixed_fields(self) -> tuple:
|
|
817
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
818
|
-
return ()
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
class NavItem(NavMenuBase, PermissionsMixin):
|
|
822
|
-
"""
|
|
823
|
-
This class represents a navigation menu item for the new ui. This constitutes link and its text.
|
|
824
|
-
|
|
825
|
-
Links are specified as Django reverse URL strings.
|
|
826
|
-
"""
|
|
827
|
-
|
|
828
|
-
def __init__( # pylint:disable=super-init-not-called # this is dead code anyway
|
|
829
|
-
self, name, link, *args, permissions=None, weight=1000, **kwargs
|
|
830
|
-
):
|
|
831
|
-
self.name = name
|
|
832
|
-
self.link = link
|
|
833
|
-
self.permissions = permissions or []
|
|
834
|
-
self.weight = weight
|
|
835
|
-
self.args = args
|
|
836
|
-
self.kwargs = kwargs
|
|
837
|
-
|
|
838
|
-
@property
|
|
839
|
-
def initial_dict(self) -> dict:
|
|
840
|
-
"""Attributes to be stored when adding this item to the nav menu data for the first time."""
|
|
841
|
-
return {
|
|
842
|
-
"name": self.name,
|
|
843
|
-
"weight": self.weight,
|
|
844
|
-
"permissions": self.permissions,
|
|
845
|
-
"data": self.url(),
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
@property
|
|
849
|
-
def fixed_fields(self):
|
|
850
|
-
"""Tuple of (name, attribute) entries describing fields that may not be altered after declaration."""
|
|
851
|
-
return (
|
|
852
|
-
("name", self.name),
|
|
853
|
-
("permissions", self.permissions),
|
|
854
|
-
)
|
|
855
|
-
|
|
856
|
-
def url(self):
|
|
857
|
-
try:
|
|
858
|
-
return reverse(self.link, args=self.args, kwargs=self.kwargs)
|
|
859
|
-
except NoReverseMatch as e:
|
|
860
|
-
logger.error("Error in link construction for %s: %s", self.name, e)
|
|
861
|
-
return ""
|
|
862
|
-
|
|
863
|
-
|
|
864
308
|
def post_migrate_send_nautobot_database_ready(sender, app_config, signal, **kwargs):
|
|
865
309
|
"""
|
|
866
310
|
Send the `nautobot_database_ready` signal to all installed core apps and Apps.
|
nautobot/core/celery/__init__.py
CHANGED
|
@@ -14,6 +14,7 @@ from django.utils.module_loading import import_string
|
|
|
14
14
|
from kombu.serialization import register
|
|
15
15
|
from prometheus_client import CollectorRegistry, multiprocess, start_http_server
|
|
16
16
|
|
|
17
|
+
from nautobot import add_success_logger
|
|
17
18
|
from nautobot.core.celery.control import discard_git_repository, refresh_git_repository # noqa: F401 # unused-import
|
|
18
19
|
from nautobot.core.celery.encoders import NautobotKombuJSONEncoder
|
|
19
20
|
from nautobot.core.celery.log import NautobotDatabaseHandler
|
|
@@ -135,6 +136,18 @@ def add_nautobot_log_handler(logger_instance, log_format=None):
|
|
|
135
136
|
logger_instance.addHandler(handler)
|
|
136
137
|
|
|
137
138
|
|
|
139
|
+
@signals.after_setup_logger.connect
|
|
140
|
+
def setup_nautobot_global_logging(logger, **kwargs): # pylint: disable=redefined-outer-name
|
|
141
|
+
"""Add SUCCESS log to celery global logger."""
|
|
142
|
+
logger.success = add_success_logger()
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@signals.after_setup_task_logger.connect
|
|
146
|
+
def setup_nautobot_task_logging(logger, **kwargs): # pylint: disable=redefined-outer-name
|
|
147
|
+
"""Add SUCCESS log to celery task logger."""
|
|
148
|
+
logger.success = add_success_logger()
|
|
149
|
+
|
|
150
|
+
|
|
138
151
|
@signals.celeryd_after_setup.connect
|
|
139
152
|
def setup_nautobot_job_logging(sender, instance, conf, **kwargs):
|
|
140
153
|
"""Add nautobot database logging handler to celery stdout/stderr redirect logger and celery task logger."""
|