nautobot 3.0.0a3__py3-none-any.whl → 3.0.0rc1__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.
- nautobot/apps/choices.py +4 -0
- nautobot/apps/ui.py +4 -0
- nautobot/apps/utils.py +8 -0
- nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +0 -3
- nautobot/circuits/views.py +6 -2
- nautobot/core/api/serializers.py +1 -1
- nautobot/core/api/urls.py +1 -0
- nautobot/core/api/views.py +4 -0
- nautobot/core/choices.py +1 -1
- nautobot/core/cli/bootstrap_v3_to_v5.py +36 -13
- nautobot/core/cli/migrate_deprecated_templates.py +36 -9
- nautobot/core/filters.py +4 -0
- nautobot/core/forms/__init__.py +2 -0
- nautobot/core/forms/widgets.py +21 -2
- nautobot/core/jobs/__init__.py +56 -0
- nautobot/core/management/commands/generate_test_data.py +3 -3
- nautobot/core/models/__init__.py +11 -0
- nautobot/core/models/utils.py +1 -1
- nautobot/core/settings.py +17 -7
- nautobot/core/settings.yaml +4 -26
- nautobot/core/templates/admin/base.html +1 -2
- nautobot/core/templates/admin/change_list.html +9 -12
- nautobot/core/templates/base_django.html +1 -2
- nautobot/core/templates/components/panel/header_extra_content_table.html +1 -1
- nautobot/core/templates/components/tab/content_wrapper.html +4 -4
- nautobot/core/templates/echarts/echarts.html +21 -8
- nautobot/core/templates/generic/object_bulk_create.html +2 -2
- nautobot/core/templates/generic/object_bulk_delete.html +1 -1
- nautobot/core/templates/generic/object_bulk_edit.html +1 -1
- nautobot/core/templates/generic/object_bulk_import.html +1 -1
- nautobot/core/templates/generic/object_delete.html +1 -1
- nautobot/core/templates/generic/object_detail.html +1 -1
- nautobot/core/templates/generic/object_edit.html +1 -1
- nautobot/core/templates/generic/object_retrieve.html +2 -2
- nautobot/core/templates/graphene/graphiql.html +0 -1
- nautobot/core/templates/inc/footer.html +3 -1
- nautobot/core/templates/inc/header.html +10 -0
- nautobot/core/templates/inc/media.html +14 -0
- nautobot/core/templates/inc/nav_menu.html +1 -8
- nautobot/core/templates/inc/object_details_advanced_panel.html +2 -2
- nautobot/core/templates/nautobot_config.py.j2 +0 -6
- nautobot/core/templates/rest_framework/api.html +103 -2
- nautobot/core/templates/utilities/templatetags/filter_form_drawer.html +33 -0
- nautobot/core/templates/utilities/theme_preview.html +3 -0
- nautobot/core/templates/widgets/number_input_with_choices.html +44 -0
- nautobot/core/templatetags/helpers.py +24 -12
- nautobot/core/testing/integration.py +24 -13
- nautobot/core/testing/utils.py +18 -4
- nautobot/core/testing/views.py +104 -17
- nautobot/core/tests/integration/test_filters.py +48 -11
- nautobot/core/tests/integration/test_theme.py +22 -21
- nautobot/core/tests/nautobot_config.py +3 -0
- nautobot/core/tests/runner.py +1 -2
- nautobot/core/tests/test_breadcrumbs.py +21 -21
- nautobot/core/tests/test_jobs.py +73 -6
- nautobot/core/tests/test_renderers.py +59 -0
- nautobot/core/tests/test_settings_schema.py +1 -0
- nautobot/core/tests/test_templatetags_helpers.py +9 -0
- nautobot/core/tests/test_titles.py +0 -16
- nautobot/core/tests/test_ui.py +122 -3
- nautobot/core/tests/test_utils.py +41 -1
- nautobot/core/ui/breadcrumbs.py +68 -17
- nautobot/core/ui/bulk_buttons.py +1 -1
- nautobot/core/ui/choices.py +49 -65
- nautobot/core/ui/echarts.py +15 -20
- nautobot/core/ui/object_detail.py +54 -46
- nautobot/core/ui/titles.py +3 -6
- nautobot/core/urls.py +8 -8
- nautobot/core/utils/filtering.py +11 -1
- nautobot/core/utils/lookup.py +46 -0
- nautobot/core/views/mixins.py +31 -20
- nautobot/core/views/renderers.py +2 -3
- nautobot/data_validation/migrations/0002_data_migration_from_app.py +3 -2
- nautobot/dcim/api/serializers.py +3 -0
- nautobot/dcim/choices.py +49 -0
- nautobot/dcim/constants.py +7 -0
- nautobot/dcim/factory.py +1 -1
- nautobot/dcim/filters.py +13 -1
- nautobot/dcim/forms.py +89 -3
- nautobot/dcim/migrations/0075_interface_duplex_interface_speed_and_more.py +32 -0
- nautobot/dcim/migrations/{0075_add_deviceclusterassignment.py → 0076_add_deviceclusterassignment.py} +1 -1
- nautobot/dcim/migrations/{0076_device_cluster_to_clusters_data_migration.py → 0077_device_cluster_to_clusters_data_migration.py} +1 -1
- nautobot/dcim/migrations/{0077_remove_device_cluster.py → 0078_remove_device_cluster.py} +1 -1
- nautobot/dcim/migrations/{0078_remove_device_location_tenant_name_uniqueness.py → 0079_remove_device_location_tenant_name_uniqueness.py} +1 -1
- nautobot/dcim/migrations/{0079_device_name_data_migration.py → 0080_device_name_data_migration.py} +1 -1
- nautobot/dcim/migrations/0081_alter_device_device_redundancy_group_priority_and_more.py +25 -0
- nautobot/dcim/models/device_component_templates.py +33 -1
- nautobot/dcim/models/device_components.py +22 -1
- nautobot/dcim/models/devices.py +17 -4
- nautobot/dcim/tables/devices.py +15 -0
- nautobot/dcim/tables/devicetypes.py +8 -1
- nautobot/dcim/tables/racks.py +0 -2
- nautobot/dcim/tables/template_code.py +1 -1
- nautobot/dcim/templates/dcim/cable_trace.html +0 -2
- nautobot/dcim/templates/dcim/consoleport.html +1 -1
- nautobot/dcim/templates/dcim/consoleserverport.html +1 -1
- nautobot/dcim/templates/dcim/devicebay.html +1 -1
- nautobot/dcim/templates/dcim/frontport.html +1 -1
- nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
- nautobot/dcim/templates/dcim/inc/moduletype_component_table.html +1 -1
- nautobot/dcim/templates/dcim/inc/rack_elevation.html +1 -1
- nautobot/dcim/templates/dcim/interface.html +9 -1
- nautobot/dcim/templates/dcim/interface_edit.html +2 -0
- nautobot/dcim/templates/dcim/inventoryitem.html +1 -1
- nautobot/dcim/templates/dcim/module_consoleports.html +1 -1
- nautobot/dcim/templates/dcim/module_consoleserverports.html +1 -1
- nautobot/dcim/templates/dcim/module_frontports.html +1 -1
- nautobot/dcim/templates/dcim/module_interfaces.html +1 -1
- nautobot/dcim/templates/dcim/module_modulebays.html +1 -1
- nautobot/dcim/templates/dcim/module_poweroutlets.html +1 -1
- nautobot/dcim/templates/dcim/module_powerports.html +1 -1
- nautobot/dcim/templates/dcim/module_rearports.html +1 -1
- nautobot/dcim/templates/dcim/moduletype_list.html +2 -2
- nautobot/dcim/templates/dcim/poweroutlet.html +1 -1
- nautobot/dcim/templates/dcim/powerport.html +1 -1
- nautobot/dcim/templates/dcim/rack_elevation_list.html +1 -1
- nautobot/dcim/templates/dcim/rack_retrieve.html +0 -11
- nautobot/dcim/templates/dcim/rearport.html +1 -1
- nautobot/dcim/templates/dcim/trace/cable.html +1 -1
- nautobot/dcim/templates/dcim/virtualchassis_update.html +1 -1
- nautobot/dcim/tests/integration/test_controller.py +3 -6
- nautobot/dcim/tests/integration/test_controller_managed_device_group.py +1 -5
- nautobot/dcim/tests/integration/test_create_device.py +0 -2
- nautobot/dcim/tests/integration/test_device_bulk_operations.py +1 -3
- nautobot/dcim/tests/integration/test_fileinputpicker.py +6 -10
- nautobot/dcim/tests/integration/test_location_bulk_operations.py +0 -2
- nautobot/dcim/tests/integration/test_module_bay_position.py +3 -4
- nautobot/dcim/tests/test_api.py +186 -6
- nautobot/dcim/tests/test_filters.py +43 -1
- nautobot/dcim/tests/test_forms.py +110 -8
- nautobot/dcim/tests/test_graphql.py +44 -1
- nautobot/dcim/tests/test_models.py +265 -0
- nautobot/dcim/tests/test_tables.py +160 -0
- nautobot/dcim/tests/test_views.py +69 -7
- nautobot/dcim/views.py +232 -126
- nautobot/extras/api/views.py +51 -44
- nautobot/extras/datasources/git.py +3 -1
- nautobot/extras/filters.py +19 -2
- nautobot/extras/forms/forms.py +9 -2
- nautobot/extras/jobs.py +2 -0
- nautobot/extras/jobs_ui.py +4 -3
- nautobot/extras/management/__init__.py +2 -0
- nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +4 -1
- nautobot/extras/migrations/0131_configcontext_device_families.py +18 -0
- nautobot/extras/models/approvals.py +11 -1
- nautobot/extras/models/change_logging.py +4 -0
- nautobot/extras/models/jobs.py +1 -3
- nautobot/extras/models/models.py +10 -2
- nautobot/extras/plugins/marketplace_manifest.yml +49 -1
- nautobot/extras/plugins/views.py +0 -5
- nautobot/extras/querysets.py +8 -0
- nautobot/extras/tables.py +12 -0
- nautobot/extras/templates/django_ajax_tables/ajax_wrapper.html +2 -0
- nautobot/extras/templates/extras/configcontext_update.html +1 -0
- nautobot/extras/templates/extras/dynamicgroup_update.html +1 -1
- nautobot/extras/templates/extras/objectchange_retrieve.html +0 -2
- nautobot/extras/templates/extras/plugin_detail.html +3 -3
- nautobot/extras/templates/extras/secret_create.html +1 -1
- nautobot/extras/tests/integration/test_computedfields.py +8 -9
- nautobot/extras/tests/integration/test_customfields.py +1 -3
- nautobot/extras/tests/integration/test_dynamicgroups.py +7 -8
- nautobot/extras/tests/integration/test_relationships.py +0 -2
- nautobot/extras/tests/test_api.py +63 -0
- nautobot/extras/tests/test_changelog.py +24 -2
- nautobot/extras/tests/test_filters.py +36 -3
- nautobot/extras/tests/test_models.py +38 -2
- nautobot/extras/tests/test_utils.py +3 -4
- nautobot/extras/tests/test_views.py +22 -83
- nautobot/extras/urls.py +0 -14
- nautobot/extras/views.py +83 -52
- nautobot/ipam/filters.py +26 -0
- nautobot/ipam/tables.py +6 -0
- nautobot/ipam/templates/ipam/namespace_ip_addresses.html +1 -1
- nautobot/ipam/templates/ipam/namespace_prefixes.html +1 -1
- nautobot/ipam/templates/ipam/namespace_vrfs.html +1 -1
- nautobot/ipam/tests/test_filters.py +26 -1
- nautobot/ipam/tests/test_models.py +1 -1
- nautobot/ipam/views.py +9 -7
- nautobot/load_balancers/__init__.py +0 -0
- nautobot/load_balancers/api/__init__.py +1 -0
- nautobot/load_balancers/api/serializers.py +75 -0
- nautobot/load_balancers/api/urls.py +23 -0
- nautobot/load_balancers/api/views.py +61 -0
- nautobot/load_balancers/apps.py +17 -0
- nautobot/load_balancers/choices.py +167 -0
- nautobot/load_balancers/filters.py +225 -0
- nautobot/load_balancers/forms.py +532 -0
- nautobot/load_balancers/management/commands/__init__.py +0 -0
- nautobot/load_balancers/management/commands/generate_load_balancer_models_test_data.py +38 -0
- nautobot/load_balancers/migrations/0001_initial.py +465 -0
- nautobot/load_balancers/migrations/0002_create_default_statuses_pool_members.py +31 -0
- nautobot/load_balancers/migrations/__init__.py +0 -0
- nautobot/load_balancers/models.py +423 -0
- nautobot/load_balancers/navigation.py +80 -0
- nautobot/load_balancers/tables.py +255 -0
- nautobot/load_balancers/tests/__init__.py +474 -0
- nautobot/load_balancers/tests/test_api.py +353 -0
- nautobot/load_balancers/tests/test_filters.py +134 -0
- nautobot/load_balancers/tests/test_forms.py +266 -0
- nautobot/load_balancers/tests/test_models.py +195 -0
- nautobot/load_balancers/tests/test_views.py +229 -0
- nautobot/load_balancers/urls.py +17 -0
- nautobot/load_balancers/views.py +248 -0
- nautobot/project-static/dist/css/github-dark.min.css +10 -0
- nautobot/project-static/dist/css/github.min.css +10 -0
- nautobot/project-static/dist/css/nautobot.css +1 -11
- nautobot/project-static/dist/css/nautobot.css.map +1 -1
- nautobot/project-static/dist/js/libraries.js +1 -1
- nautobot/project-static/dist/js/libraries.js.map +1 -1
- nautobot/project-static/dist/js/nautobot.js +1 -1
- nautobot/project-static/dist/js/nautobot.js.map +1 -1
- nautobot/project-static/js/forms.js +13 -0
- nautobot/project-static/nautobot-icons/bus-globe.svg +3 -0
- nautobot/project-static/nautobot-icons/bus-shield-check.svg +3 -0
- nautobot/project-static/nautobot-icons/bus-shield.svg +3 -0
- nautobot/ui/package-lock.json +87 -4
- nautobot/ui/package.json +2 -1
- nautobot/ui/src/js/nautobot.js +0 -1
- nautobot/ui/src/js/select2.js +53 -2
- nautobot/ui/src/scss/nautobot.scss +51 -2
- nautobot/ui/webpack.config.js +13 -0
- nautobot/users/templates/users/preferences.html +11 -2
- nautobot/virtualization/filters.py +6 -1
- nautobot/virtualization/tests/test_filters.py +10 -1
- nautobot/virtualization/tests/test_models.py +1 -0
- nautobot/virtualization/views.py +4 -1
- nautobot/vpn/factory.py +25 -15
- nautobot/vpn/filters.py +1 -0
- nautobot/vpn/forms.py +1 -0
- nautobot/vpn/migrations/0001_initial.py +1 -1
- nautobot/vpn/models.py +16 -8
- nautobot/vpn/tables.py +5 -2
- nautobot/vpn/tests/test_api.py +0 -5
- nautobot/vpn/tests/test_forms.py +1 -2
- nautobot/vpn/tests/test_models.py +57 -7
- nautobot/vpn/tests/test_views.py +22 -3
- nautobot/vpn/views.py +78 -20
- {nautobot-3.0.0a3.dist-info → nautobot-3.0.0rc1.dist-info}/METADATA +4 -4
- {nautobot-3.0.0a3.dist-info → nautobot-3.0.0rc1.dist-info}/RECORD +243 -352
- nautobot/circuits/templates/circuits/circuit.html +0 -2
- nautobot/circuits/templates/circuits/circuit_edit.html +0 -2
- nautobot/circuits/templates/circuits/circuit_retrieve.html +0 -2
- nautobot/circuits/templates/circuits/circuit_update.html +0 -1
- nautobot/circuits/templates/circuits/circuittermination.html +0 -2
- nautobot/circuits/templates/circuits/circuittermination_edit.html +0 -2
- nautobot/circuits/templates/circuits/circuittermination_retrieve.html +0 -2
- nautobot/circuits/templates/circuits/circuittermination_update.html +0 -1
- nautobot/circuits/templates/circuits/circuittype.html +0 -2
- nautobot/circuits/templates/circuits/circuittype_retrieve.html +0 -2
- nautobot/circuits/templates/circuits/inc/circuit_termination.html +0 -85
- nautobot/circuits/templates/circuits/provider.html +0 -2
- nautobot/circuits/templates/circuits/provider_edit.html +0 -2
- nautobot/circuits/templates/circuits/provider_retrieve.html +0 -1
- nautobot/circuits/templates/circuits/provider_update.html +0 -1
- nautobot/circuits/templates/circuits/providernetwork.html +0 -2
- nautobot/circuits/templates/circuits/providernetwork_retrieve.html +0 -2
- nautobot/cloud/templates/cloud/cloudaccount_retrieve.html +0 -2
- nautobot/cloud/templates/cloud/cloudnetwork_retrieve.html +0 -2
- nautobot/cloud/templates/cloud/cloudresourcetype_retrieve.html +0 -2
- nautobot/cloud/templates/cloud/cloudservice_retrieve.html +0 -2
- nautobot/core/templates/buttons/import.html +0 -9
- nautobot/data_validation/templates/data_validation/datacompliance_retrieve.html +0 -1
- nautobot/dcim/templates/dcim/cable.html +0 -2
- nautobot/dcim/templates/dcim/cable_edit.html +0 -2
- nautobot/dcim/templates/dcim/controller/base.html +0 -2
- nautobot/dcim/templates/dcim/controller_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/controller_wirelessnetworks.html +0 -2
- nautobot/dcim/templates/dcim/controllermanageddevicegroup_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/device/base.html +0 -2
- nautobot/dcim/templates/dcim/device/consoleports.html +0 -2
- nautobot/dcim/templates/dcim/device/consoleserverports.html +0 -2
- nautobot/dcim/templates/dcim/device/devicebays.html +0 -2
- nautobot/dcim/templates/dcim/device/frontports.html +0 -2
- nautobot/dcim/templates/dcim/device/interfaces.html +0 -2
- nautobot/dcim/templates/dcim/device/inventory.html +0 -2
- nautobot/dcim/templates/dcim/device/modulebays.html +0 -2
- nautobot/dcim/templates/dcim/device/poweroutlets.html +0 -2
- nautobot/dcim/templates/dcim/device/powerports.html +0 -2
- nautobot/dcim/templates/dcim/device/rearports.html +0 -2
- nautobot/dcim/templates/dcim/device/wireless.html +0 -2
- nautobot/dcim/templates/dcim/device_component.html +0 -2
- nautobot/dcim/templates/dcim/device_edit.html +0 -2
- nautobot/dcim/templates/dcim/devicefamily_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/deviceredundancygroup_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/devicetype.html +0 -2
- nautobot/dcim/templates/dcim/devicetype_edit.html +0 -2
- nautobot/dcim/templates/dcim/devicetype_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/inc/device_napalm_tabs.html +0 -1
- nautobot/dcim/templates/dcim/interfaceredundancygroup_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/location.html +0 -2
- nautobot/dcim/templates/dcim/location_edit.html +0 -2
- nautobot/dcim/templates/dcim/location_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/locationtype.html +0 -2
- nautobot/dcim/templates/dcim/locationtype_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/manufacturer.html +0 -2
- nautobot/dcim/templates/dcim/modulebay_retrieve.html +0 -1
- nautobot/dcim/templates/dcim/platform.html +0 -2
- nautobot/dcim/templates/dcim/powerfeed.html +0 -2
- nautobot/dcim/templates/dcim/powerfeed_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/powerpanel.html +0 -2
- nautobot/dcim/templates/dcim/powerpanel_edit.html +0 -2
- nautobot/dcim/templates/dcim/powerpanel_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/rack.html +0 -2
- nautobot/dcim/templates/dcim/rack_edit.html +0 -2
- nautobot/dcim/templates/dcim/rackgroup.html +0 -2
- nautobot/dcim/templates/dcim/rackreservation.html +0 -2
- nautobot/dcim/templates/dcim/softwareimagefile_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/softwareversion_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/virtualchassis.html +0 -2
- nautobot/dcim/templates/dcim/virtualchassis_add.html +0 -2
- nautobot/dcim/templates/dcim/virtualchassis_edit.html +0 -2
- nautobot/dcim/templates/dcim/virtualchassis_retrieve.html +0 -2
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +0 -2
- nautobot/dcim/ui.py +0 -29
- nautobot/extras/templates/extras/computedfield.html +0 -2
- nautobot/extras/templates/extras/computedfield_retrieve.html +0 -2
- nautobot/extras/templates/extras/configcontext.html +0 -2
- nautobot/extras/templates/extras/configcontext_edit.html +0 -2
- nautobot/extras/templates/extras/configcontext_retrieve.html +0 -2
- nautobot/extras/templates/extras/configcontextschema.html +0 -2
- nautobot/extras/templates/extras/configcontextschema_edit.html +0 -2
- nautobot/extras/templates/extras/contact_retrieve.html +0 -2
- nautobot/extras/templates/extras/customfield.html +0 -2
- nautobot/extras/templates/extras/customfield_edit.html +0 -2
- nautobot/extras/templates/extras/customfield_retrieve.html +0 -2
- nautobot/extras/templates/extras/customlink.html +0 -2
- nautobot/extras/templates/extras/dynamicgroup.html +0 -2
- nautobot/extras/templates/extras/dynamicgroup_edit.html +0 -2
- nautobot/extras/templates/extras/exporttemplate.html +0 -2
- nautobot/extras/templates/extras/gitrepository.html +0 -2
- nautobot/extras/templates/extras/gitrepository_object_edit.html +0 -2
- nautobot/extras/templates/extras/graphqlquery.html +0 -2
- nautobot/extras/templates/extras/graphqlquery_list.html +0 -1
- nautobot/extras/templates/extras/graphqlquery_retrieve.html +0 -2
- nautobot/extras/templates/extras/job_detail.html +0 -2
- nautobot/extras/templates/extras/jobbutton_retrieve.html +0 -2
- nautobot/extras/templates/extras/jobhook.html +0 -2
- nautobot/extras/templates/extras/jobqueue_retrieve.html +0 -2
- nautobot/extras/templates/extras/jobresult.html +0 -2
- nautobot/extras/templates/extras/metadatatype_retrieve.html +0 -2
- nautobot/extras/templates/extras/note.html +0 -2
- nautobot/extras/templates/extras/note_retrieve.html +0 -1
- nautobot/extras/templates/extras/object_changelog.html +0 -2
- nautobot/extras/templates/extras/object_notes.html +0 -2
- nautobot/extras/templates/extras/objectchange.html +0 -2
- nautobot/extras/templates/extras/objectchange_list.html +0 -3
- nautobot/extras/templates/extras/relationship.html +0 -1
- nautobot/extras/templates/extras/secret.html +0 -1
- nautobot/extras/templates/extras/secret_edit.html +0 -1
- nautobot/extras/templates/extras/secretsgroup.html +0 -2
- nautobot/extras/templates/extras/secretsgroup_edit.html +0 -2
- nautobot/extras/templates/extras/secretsgroup_retrieve.html +0 -2
- nautobot/extras/templates/extras/status.html +0 -2
- nautobot/extras/templates/extras/tag.html +0 -2
- nautobot/extras/templates/extras/tag_edit.html +0 -2
- nautobot/extras/templates/extras/tag_retrieve.html +0 -2
- nautobot/extras/templates/extras/team_retrieve.html +0 -2
- nautobot/ipam/templates/ipam/namespace_retrieve.html +0 -1
- nautobot/ipam/templates/ipam/prefix.html +0 -2
- nautobot/ipam/templates/ipam/prefix_edit.html +0 -1
- nautobot/ipam/templates/ipam/prefix_retrieve.html +0 -2
- nautobot/ipam/templates/ipam/rir.html +0 -2
- nautobot/ipam/templates/ipam/routetarget.html +0 -1
- nautobot/ipam/templates/ipam/service.html +0 -2
- nautobot/ipam/templates/ipam/service_edit.html +0 -2
- nautobot/ipam/templates/ipam/service_retrieve.html +0 -2
- nautobot/ipam/templates/ipam/vlan.html +0 -2
- nautobot/ipam/templates/ipam/vlan_edit.html +0 -2
- nautobot/ipam/templates/ipam/vlan_retrieve.html +0 -2
- nautobot/ipam/templates/ipam/vlangroup.html +0 -2
- nautobot/ipam/templates/ipam/vrf.html +0 -1
- nautobot/tenancy/templates/tenancy/tenant.html +0 -2
- nautobot/tenancy/templates/tenancy/tenant_edit.html +0 -2
- nautobot/tenancy/templates/tenancy/tenantgroup.html +0 -2
- nautobot/tenancy/templates/tenancy/tenantgroup_retrieve.html +0 -1
- nautobot/virtualization/templates/virtualization/clustergroup.html +0 -2
- nautobot/virtualization/templates/virtualization/clustertype.html +0 -2
- nautobot/virtualization/templates/virtualization/virtualmachine.html +0 -2
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +0 -2
- nautobot/virtualization/templates/virtualization/virtualmachine_retrieve.html +0 -2
- nautobot/vpn/templates/vpn/vpnprofile.html +0 -2
- nautobot/wireless/templates/wireless/radioprofile_retrieve.html +0 -2
- nautobot/wireless/templates/wireless/supporteddatarate_retrieve.html +0 -2
- nautobot/wireless/templates/wireless/wirelessnetwork_retrieve.html +0 -2
- {nautobot-3.0.0a3.dist-info → nautobot-3.0.0rc1.dist-info}/LICENSE.txt +0 -0
- {nautobot-3.0.0a3.dist-info → nautobot-3.0.0rc1.dist-info}/NOTICE +0 -0
- {nautobot-3.0.0a3.dist-info → nautobot-3.0.0rc1.dist-info}/WHEEL +0 -0
- {nautobot-3.0.0a3.dist-info → nautobot-3.0.0rc1.dist-info}/entry_points.txt +0 -0
nautobot/dcim/views.py
CHANGED
|
@@ -36,10 +36,10 @@ from nautobot.core.exceptions import AbortTransaction
|
|
|
36
36
|
from nautobot.core.forms import BulkRenameForm, ConfirmationForm, ImportForm, restrict_form_fields
|
|
37
37
|
from nautobot.core.models.querysets import count_related
|
|
38
38
|
from nautobot.core.templatetags import helpers
|
|
39
|
-
from nautobot.core.templatetags.helpers import has_perms
|
|
39
|
+
from nautobot.core.templatetags.helpers import bettertitle, has_perms
|
|
40
40
|
from nautobot.core.ui import object_detail
|
|
41
41
|
from nautobot.core.ui.breadcrumbs import (
|
|
42
|
-
|
|
42
|
+
AncestorsInstanceBreadcrumbItem,
|
|
43
43
|
BaseBreadcrumbItem,
|
|
44
44
|
Breadcrumbs,
|
|
45
45
|
context_object_attr,
|
|
@@ -77,7 +77,6 @@ from nautobot.core.views.utils import common_detail_view_context, get_obj_from_c
|
|
|
77
77
|
from nautobot.core.views.viewsets import NautobotUIViewSet
|
|
78
78
|
from nautobot.dcim.choices import LocationDataToContactActionChoices
|
|
79
79
|
from nautobot.dcim.forms import LocationMigrateDataToContactForm
|
|
80
|
-
from nautobot.dcim.ui import RackBreadcrumbs
|
|
81
80
|
from nautobot.dcim.utils import get_all_network_driver_mappings, render_software_version_and_image_files
|
|
82
81
|
from nautobot.extras.models import ConfigContext, Contact, ContactAssociation, Role, Status, Team
|
|
83
82
|
from nautobot.extras.tables import DynamicGroupTable, ImageAttachmentTable
|
|
@@ -249,7 +248,14 @@ class LocationTypeUIViewSet(NautobotUIViewSet):
|
|
|
249
248
|
form_class = forms.LocationTypeForm
|
|
250
249
|
bulk_update_form_class = forms.LocationTypeBulkEditForm
|
|
251
250
|
serializer_class = serializers.LocationSerializer
|
|
252
|
-
breadcrumbs =
|
|
251
|
+
breadcrumbs = Breadcrumbs(
|
|
252
|
+
items={
|
|
253
|
+
"detail": [
|
|
254
|
+
ModelBreadcrumbItem(),
|
|
255
|
+
AncestorsInstanceBreadcrumbItem(),
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
)
|
|
253
259
|
|
|
254
260
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
255
261
|
panels=(
|
|
@@ -393,7 +399,14 @@ class LocationUIViewSet(NautobotUIViewSet):
|
|
|
393
399
|
form_class = forms.LocationForm
|
|
394
400
|
bulk_update_form_class = forms.LocationBulkEditForm
|
|
395
401
|
serializer_class = serializers.LocationSerializer
|
|
396
|
-
breadcrumbs =
|
|
402
|
+
breadcrumbs = Breadcrumbs(
|
|
403
|
+
items={
|
|
404
|
+
"detail": [
|
|
405
|
+
ModelBreadcrumbItem(),
|
|
406
|
+
AncestorsInstanceBreadcrumbItem(),
|
|
407
|
+
]
|
|
408
|
+
}
|
|
409
|
+
)
|
|
397
410
|
view_titles = Titles(titles={"detail": "{{ object.name }}"})
|
|
398
411
|
|
|
399
412
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
@@ -471,6 +484,7 @@ class LocationUIViewSet(NautobotUIViewSet):
|
|
|
471
484
|
table_attribute="images",
|
|
472
485
|
related_field_name="location",
|
|
473
486
|
show_table_config_button=False,
|
|
487
|
+
enable_related_link=False,
|
|
474
488
|
),
|
|
475
489
|
object_detail.ObjectsTablePanel(
|
|
476
490
|
section=SectionChoices.FULL_WIDTH,
|
|
@@ -486,25 +500,31 @@ class LocationUIViewSet(NautobotUIViewSet):
|
|
|
486
500
|
)
|
|
487
501
|
|
|
488
502
|
def get_extra_context(self, request, instance):
|
|
489
|
-
|
|
490
|
-
return super().get_extra_context(request, instance)
|
|
503
|
+
context = super().get_extra_context(request, instance)
|
|
491
504
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
505
|
+
if self.action == "retrieve":
|
|
506
|
+
# This query can get really expensive when there are big location trees in the DB. By casting it to a list we
|
|
507
|
+
# ensure it is only performed once rather than as a subquery for each of the different count stats.
|
|
508
|
+
related_locations = list(
|
|
509
|
+
instance.descendants(include_self=True).restrict(request.user, "view").values_list("pk", flat=True)
|
|
510
|
+
)
|
|
497
511
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
512
|
+
rack_groups = (
|
|
513
|
+
RackGroup.objects.annotate(rack_count=count_related(Rack, "rack_group"))
|
|
514
|
+
.restrict(request.user, "view")
|
|
515
|
+
.filter(location__in=related_locations)
|
|
516
|
+
)
|
|
503
517
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
518
|
+
context.update(
|
|
519
|
+
{
|
|
520
|
+
"rack_groups": rack_groups,
|
|
521
|
+
"rack_count": Rack.objects.restrict(request.user, "view")
|
|
522
|
+
.filter(location__in=related_locations)
|
|
523
|
+
.count(),
|
|
524
|
+
}
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
return context
|
|
508
528
|
|
|
509
529
|
|
|
510
530
|
class MigrateLocationDataToContactView(generic.ObjectEditView):
|
|
@@ -654,6 +674,14 @@ class RackGroupUIViewSet(NautobotUIViewSet):
|
|
|
654
674
|
serializer_class = serializers.RackGroupSerializer
|
|
655
675
|
table_class = tables.RackGroupTable
|
|
656
676
|
queryset = RackGroup.objects.all()
|
|
677
|
+
breadcrumbs = Breadcrumbs(
|
|
678
|
+
items={
|
|
679
|
+
"detail": [
|
|
680
|
+
ModelBreadcrumbItem(),
|
|
681
|
+
AncestorsInstanceBreadcrumbItem(),
|
|
682
|
+
]
|
|
683
|
+
}
|
|
684
|
+
)
|
|
657
685
|
|
|
658
686
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
659
687
|
panels=[
|
|
@@ -713,7 +741,26 @@ class RackUIViewSet(NautobotUIViewSet):
|
|
|
713
741
|
serializer_class = serializers.RackSerializer
|
|
714
742
|
table_class = tables.RackDetailTable
|
|
715
743
|
queryset = Rack.objects.select_related("location", "tenant__tenant_group", "rack_group", "role")
|
|
716
|
-
breadcrumbs =
|
|
744
|
+
breadcrumbs = Breadcrumbs(
|
|
745
|
+
items={
|
|
746
|
+
"detail": [
|
|
747
|
+
ModelBreadcrumbItem(),
|
|
748
|
+
AncestorsInstanceBreadcrumbItem(
|
|
749
|
+
instance=context_object_attr("location"),
|
|
750
|
+
ancestor_item=lambda ancestor: InstanceParentBreadcrumbItem(parent_key="location", parent=ancestor),
|
|
751
|
+
include_self=True,
|
|
752
|
+
),
|
|
753
|
+
AncestorsInstanceBreadcrumbItem(
|
|
754
|
+
instance=context_object_attr("rack_group"),
|
|
755
|
+
ancestor_item=lambda ancestor: InstanceParentBreadcrumbItem(
|
|
756
|
+
parent_key="rack_group", parent=ancestor
|
|
757
|
+
),
|
|
758
|
+
include_self=True,
|
|
759
|
+
should_render=context_object_attr("rack_group"),
|
|
760
|
+
),
|
|
761
|
+
]
|
|
762
|
+
}
|
|
763
|
+
)
|
|
717
764
|
|
|
718
765
|
def get_extra_context(self, request, instance):
|
|
719
766
|
context = super().get_extra_context(request, instance)
|
|
@@ -759,9 +806,6 @@ class RackElevationListView(generic.ObjectListView):
|
|
|
759
806
|
action_buttons = []
|
|
760
807
|
template_name = "dcim/rack_elevation_list.html"
|
|
761
808
|
view_titles = Titles(titles={"list": "Rack Elevation"})
|
|
762
|
-
breadcrumbs = Breadcrumbs(
|
|
763
|
-
items={"list": [ViewNameBreadcrumbItem(view_name="dcim:rack_elevation_list", label="Rack Elevation")]}
|
|
764
|
-
)
|
|
765
809
|
|
|
766
810
|
def extra_context(self):
|
|
767
811
|
racks = self.queryset
|
|
@@ -1018,6 +1062,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1018
1062
|
model=InterfaceTemplate,
|
|
1019
1063
|
),
|
|
1020
1064
|
include_paginator=True,
|
|
1065
|
+
enable_related_link=False,
|
|
1021
1066
|
),
|
|
1022
1067
|
),
|
|
1023
1068
|
),
|
|
@@ -1043,6 +1088,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1043
1088
|
model=FrontPortTemplate,
|
|
1044
1089
|
),
|
|
1045
1090
|
include_paginator=True,
|
|
1091
|
+
enable_related_link=False,
|
|
1046
1092
|
),
|
|
1047
1093
|
),
|
|
1048
1094
|
),
|
|
@@ -1068,6 +1114,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1068
1114
|
model=RearPortTemplate,
|
|
1069
1115
|
),
|
|
1070
1116
|
include_paginator=True,
|
|
1117
|
+
enable_related_link=False,
|
|
1071
1118
|
),
|
|
1072
1119
|
),
|
|
1073
1120
|
),
|
|
@@ -1093,6 +1140,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1093
1140
|
model=ConsolePortTemplate,
|
|
1094
1141
|
),
|
|
1095
1142
|
include_paginator=True,
|
|
1143
|
+
enable_related_link=False,
|
|
1096
1144
|
),
|
|
1097
1145
|
),
|
|
1098
1146
|
),
|
|
@@ -1118,6 +1166,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1118
1166
|
model=ConsoleServerPortTemplate,
|
|
1119
1167
|
),
|
|
1120
1168
|
include_paginator=True,
|
|
1169
|
+
enable_related_link=False,
|
|
1121
1170
|
),
|
|
1122
1171
|
),
|
|
1123
1172
|
),
|
|
@@ -1143,6 +1192,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1143
1192
|
model=PowerPortTemplate,
|
|
1144
1193
|
),
|
|
1145
1194
|
include_paginator=True,
|
|
1195
|
+
enable_related_link=False,
|
|
1146
1196
|
),
|
|
1147
1197
|
),
|
|
1148
1198
|
),
|
|
@@ -1168,6 +1218,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1168
1218
|
model=PowerOutletTemplate,
|
|
1169
1219
|
),
|
|
1170
1220
|
include_paginator=True,
|
|
1221
|
+
enable_related_link=False,
|
|
1171
1222
|
),
|
|
1172
1223
|
),
|
|
1173
1224
|
),
|
|
@@ -1193,6 +1244,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1193
1244
|
model=DeviceBayTemplate,
|
|
1194
1245
|
),
|
|
1195
1246
|
include_paginator=True,
|
|
1247
|
+
enable_related_link=False,
|
|
1196
1248
|
),
|
|
1197
1249
|
),
|
|
1198
1250
|
),
|
|
@@ -1218,6 +1270,7 @@ class DeviceTypeUIViewSet(NautobotUIViewSet):
|
|
|
1218
1270
|
model=ModuleBayTemplate,
|
|
1219
1271
|
),
|
|
1220
1272
|
include_paginator=True,
|
|
1273
|
+
enable_related_link=False,
|
|
1221
1274
|
),
|
|
1222
1275
|
),
|
|
1223
1276
|
),
|
|
@@ -1433,6 +1486,7 @@ class ModuleTypeUIViewSet(
|
|
|
1433
1486
|
ObjectDestroyViewMixin,
|
|
1434
1487
|
ObjectBulkDestroyViewMixin,
|
|
1435
1488
|
ObjectBulkUpdateViewMixin,
|
|
1489
|
+
# ObjectDataComplianceViewMixin, # TODO: enable once converted to UI framework
|
|
1436
1490
|
ObjectChangeLogViewMixin,
|
|
1437
1491
|
ObjectNotesViewMixin,
|
|
1438
1492
|
):
|
|
@@ -1481,65 +1535,68 @@ class ModuleTypeUIViewSet(
|
|
|
1481
1535
|
return super().get_required_permission()
|
|
1482
1536
|
|
|
1483
1537
|
def get_extra_context(self, request, instance):
|
|
1484
|
-
|
|
1485
|
-
|
|
1538
|
+
context = super().get_extra_context(request, instance)
|
|
1539
|
+
if self.action == "retrieve":
|
|
1540
|
+
instance_count = Module.objects.restrict(request.user).filter(module_type=instance).count()
|
|
1486
1541
|
|
|
1487
|
-
|
|
1542
|
+
# Component tables
|
|
1543
|
+
consoleport_table = tables.ConsolePortTemplateTable(
|
|
1544
|
+
ConsolePortTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1545
|
+
orderable=False,
|
|
1546
|
+
)
|
|
1547
|
+
consoleserverport_table = tables.ConsoleServerPortTemplateTable(
|
|
1548
|
+
ConsoleServerPortTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1549
|
+
orderable=False,
|
|
1550
|
+
)
|
|
1551
|
+
powerport_table = tables.PowerPortTemplateTable(
|
|
1552
|
+
PowerPortTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1553
|
+
orderable=False,
|
|
1554
|
+
)
|
|
1555
|
+
poweroutlet_table = tables.PowerOutletTemplateTable(
|
|
1556
|
+
PowerOutletTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1557
|
+
orderable=False,
|
|
1558
|
+
)
|
|
1559
|
+
interface_table = tables.InterfaceTemplateTable(
|
|
1560
|
+
list(InterfaceTemplate.objects.restrict(request.user, "view").filter(module_type=instance)),
|
|
1561
|
+
orderable=False,
|
|
1562
|
+
)
|
|
1563
|
+
front_port_table = tables.FrontPortTemplateTable(
|
|
1564
|
+
FrontPortTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1565
|
+
orderable=False,
|
|
1566
|
+
)
|
|
1567
|
+
rear_port_table = tables.RearPortTemplateTable(
|
|
1568
|
+
RearPortTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1569
|
+
orderable=False,
|
|
1570
|
+
)
|
|
1571
|
+
modulebay_table = tables.ModuleBayTemplateTable(
|
|
1572
|
+
ModuleBayTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1573
|
+
orderable=False,
|
|
1574
|
+
)
|
|
1575
|
+
if request.user.has_perm("dcim.change_moduletype"):
|
|
1576
|
+
consoleport_table.columns.show("pk")
|
|
1577
|
+
consoleserverport_table.columns.show("pk")
|
|
1578
|
+
powerport_table.columns.show("pk")
|
|
1579
|
+
poweroutlet_table.columns.show("pk")
|
|
1580
|
+
interface_table.columns.show("pk")
|
|
1581
|
+
front_port_table.columns.show("pk")
|
|
1582
|
+
rear_port_table.columns.show("pk")
|
|
1583
|
+
modulebay_table.columns.show("pk")
|
|
1488
1584
|
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
poweroutlet_table = tables.PowerOutletTemplateTable(
|
|
1503
|
-
PowerOutletTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1504
|
-
orderable=False,
|
|
1505
|
-
)
|
|
1506
|
-
interface_table = tables.InterfaceTemplateTable(
|
|
1507
|
-
list(InterfaceTemplate.objects.restrict(request.user, "view").filter(module_type=instance)),
|
|
1508
|
-
orderable=False,
|
|
1509
|
-
)
|
|
1510
|
-
front_port_table = tables.FrontPortTemplateTable(
|
|
1511
|
-
FrontPortTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1512
|
-
orderable=False,
|
|
1513
|
-
)
|
|
1514
|
-
rear_port_table = tables.RearPortTemplateTable(
|
|
1515
|
-
RearPortTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1516
|
-
orderable=False,
|
|
1517
|
-
)
|
|
1518
|
-
modulebay_table = tables.ModuleBayTemplateTable(
|
|
1519
|
-
ModuleBayTemplate.objects.restrict(request.user, "view").filter(module_type=instance),
|
|
1520
|
-
orderable=False,
|
|
1521
|
-
)
|
|
1522
|
-
if request.user.has_perm("dcim.change_moduletype"):
|
|
1523
|
-
consoleport_table.columns.show("pk")
|
|
1524
|
-
consoleserverport_table.columns.show("pk")
|
|
1525
|
-
powerport_table.columns.show("pk")
|
|
1526
|
-
poweroutlet_table.columns.show("pk")
|
|
1527
|
-
interface_table.columns.show("pk")
|
|
1528
|
-
front_port_table.columns.show("pk")
|
|
1529
|
-
rear_port_table.columns.show("pk")
|
|
1530
|
-
modulebay_table.columns.show("pk")
|
|
1585
|
+
context.update(
|
|
1586
|
+
{
|
|
1587
|
+
"instance_count": instance_count,
|
|
1588
|
+
"consoleport_table": consoleport_table,
|
|
1589
|
+
"consoleserverport_table": consoleserverport_table,
|
|
1590
|
+
"powerport_table": powerport_table,
|
|
1591
|
+
"poweroutlet_table": poweroutlet_table,
|
|
1592
|
+
"interface_table": interface_table,
|
|
1593
|
+
"front_port_table": front_port_table,
|
|
1594
|
+
"rear_port_table": rear_port_table,
|
|
1595
|
+
"modulebay_table": modulebay_table,
|
|
1596
|
+
}
|
|
1597
|
+
)
|
|
1531
1598
|
|
|
1532
|
-
return
|
|
1533
|
-
"instance_count": instance_count,
|
|
1534
|
-
"consoleport_table": consoleport_table,
|
|
1535
|
-
"consoleserverport_table": consoleserverport_table,
|
|
1536
|
-
"powerport_table": powerport_table,
|
|
1537
|
-
"poweroutlet_table": poweroutlet_table,
|
|
1538
|
-
"interface_table": interface_table,
|
|
1539
|
-
"front_port_table": front_port_table,
|
|
1540
|
-
"rear_port_table": rear_port_table,
|
|
1541
|
-
"modulebay_table": modulebay_table,
|
|
1542
|
-
}
|
|
1599
|
+
return context
|
|
1543
1600
|
|
|
1544
1601
|
@action(
|
|
1545
1602
|
detail=False,
|
|
@@ -2242,32 +2299,43 @@ class DeviceComponentPageMixin:
|
|
|
2242
2299
|
- Console Port assigned to the device: Devices / <Device name and link to details> / Console Ports (dcim/devices/<id>/console-ports/) / <Console Port name>
|
|
2243
2300
|
"""
|
|
2244
2301
|
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2302
|
+
def __init_subclass__(cls, **kwargs):
|
|
2303
|
+
super().__init_subclass__(**kwargs)
|
|
2304
|
+
|
|
2305
|
+
device_breadcrumbs = [
|
|
2306
|
+
ModelBreadcrumbItem(model=Device, should_render=lambda c: c["object"].device is not None),
|
|
2307
|
+
InstanceBreadcrumbItem(
|
|
2308
|
+
instance=lambda c: c["object"].device, should_render=lambda c: c["object"].device is not None
|
|
2309
|
+
),
|
|
2310
|
+
]
|
|
2311
|
+
module_breadcrumbs = [
|
|
2312
|
+
ModelBreadcrumbItem(model=Module, should_render=lambda c: c["object"].device is None),
|
|
2313
|
+
InstanceBreadcrumbItem(
|
|
2314
|
+
instance=lambda c: c["object"].module, should_render=lambda c: c["object"].device is None
|
|
2315
|
+
),
|
|
2316
|
+
]
|
|
2317
|
+
if device_breadcrumb_url := getattr(cls, "device_breadcrumb_url", None):
|
|
2318
|
+
device_breadcrumbs.append(
|
|
2252
2319
|
ViewNameBreadcrumbItem(
|
|
2253
|
-
|
|
2254
|
-
should_render=lambda c: c["object"].device is not None
|
|
2320
|
+
view_name=device_breadcrumb_url,
|
|
2321
|
+
should_render=lambda c: c["object"].device is not None,
|
|
2255
2322
|
reverse_kwargs=lambda c: {"pk": c["object"].device.pk},
|
|
2256
|
-
label=lambda c: c["object"]._meta.verbose_name_plural,
|
|
2257
|
-
),
|
|
2258
|
-
ModelBreadcrumbItem(model=Module, should_render=lambda c: c["object"].device is None),
|
|
2259
|
-
InstanceBreadcrumbItem(
|
|
2260
|
-
instance=lambda c: c["object"].module, should_render=lambda c: c["object"].device is None
|
|
2323
|
+
label=lambda c: bettertitle(c["object"]._meta.verbose_name_plural),
|
|
2261
2324
|
),
|
|
2325
|
+
)
|
|
2326
|
+
|
|
2327
|
+
if module_breadcrumb_url := getattr(cls, "module_breadcrumb_url", None):
|
|
2328
|
+
module_breadcrumbs.append(
|
|
2262
2329
|
ViewNameBreadcrumbItem(
|
|
2263
|
-
|
|
2264
|
-
should_render=lambda c: c["object"].device is None
|
|
2330
|
+
view_name=module_breadcrumb_url,
|
|
2331
|
+
should_render=lambda c: c["object"].device is None,
|
|
2265
2332
|
reverse_kwargs=lambda c: {"pk": c["object"].module.pk},
|
|
2266
|
-
label=lambda c: c["object"]._meta.verbose_name_plural,
|
|
2333
|
+
label=lambda c: bettertitle(c["object"]._meta.verbose_name_plural),
|
|
2267
2334
|
),
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2335
|
+
)
|
|
2336
|
+
|
|
2337
|
+
cls.breadcrumbs = Breadcrumbs(items={"detail": [*device_breadcrumbs, *module_breadcrumbs]})
|
|
2338
|
+
|
|
2271
2339
|
view_titles = Titles(
|
|
2272
2340
|
titles={
|
|
2273
2341
|
"detail": "{% if object.device %}{{ object.device }}{% else %}{{ object.module.display }}{% endif %} / {{ object }}"
|
|
@@ -2290,7 +2358,11 @@ class DeviceUIViewSet(NautobotUIViewSet):
|
|
|
2290
2358
|
items={
|
|
2291
2359
|
"detail": [
|
|
2292
2360
|
ModelBreadcrumbItem(model=Device),
|
|
2293
|
-
|
|
2361
|
+
AncestorsInstanceBreadcrumbItem(
|
|
2362
|
+
instance=context_object_attr("location"),
|
|
2363
|
+
include_self=True,
|
|
2364
|
+
ancestor_item=lambda ancestor: InstanceParentBreadcrumbItem(parent_key="location", parent=ancestor),
|
|
2365
|
+
),
|
|
2294
2366
|
InstanceBreadcrumbItem(
|
|
2295
2367
|
instance=lambda c: c["object"].parent_bay.device,
|
|
2296
2368
|
should_render=lambda c: hasattr(c["object"], "parent_bay"),
|
|
@@ -2304,7 +2376,7 @@ class DeviceUIViewSet(NautobotUIViewSet):
|
|
|
2304
2376
|
|
|
2305
2377
|
def get_queryset(self):
|
|
2306
2378
|
queryset = super().get_queryset()
|
|
2307
|
-
if self.
|
|
2379
|
+
if self.action == "retrieve":
|
|
2308
2380
|
queryset = queryset.select_related(
|
|
2309
2381
|
"controller_managed_device_group__controller",
|
|
2310
2382
|
"device_redundancy_group",
|
|
@@ -2698,6 +2770,7 @@ class DeviceUIViewSet(NautobotUIViewSet):
|
|
|
2698
2770
|
table_class=VRFDeviceAssignmentTable,
|
|
2699
2771
|
table_filter="device",
|
|
2700
2772
|
exclude_columns=["related_object_type", "related_object_name"],
|
|
2773
|
+
related_list_url_name="ipam:vrf_list",
|
|
2701
2774
|
show_table_config_button=False,
|
|
2702
2775
|
),
|
|
2703
2776
|
object_detail.ObjectsTablePanel(
|
|
@@ -2727,6 +2800,7 @@ class DeviceUIViewSet(NautobotUIViewSet):
|
|
|
2727
2800
|
table_attribute="images",
|
|
2728
2801
|
related_field_name="device",
|
|
2729
2802
|
show_table_config_button=False,
|
|
2803
|
+
enable_related_link=False,
|
|
2730
2804
|
),
|
|
2731
2805
|
object_detail.ObjectsTablePanel(
|
|
2732
2806
|
weight=100,
|
|
@@ -3094,7 +3168,7 @@ class DeviceUIViewSet(NautobotUIViewSet):
|
|
|
3094
3168
|
def get_extra_context(self, request, instance):
|
|
3095
3169
|
extra_context = super().get_extra_context(request, instance)
|
|
3096
3170
|
|
|
3097
|
-
if self.
|
|
3171
|
+
if self.action == "retrieve":
|
|
3098
3172
|
# VirtualChassis members
|
|
3099
3173
|
if instance.virtual_chassis is not None:
|
|
3100
3174
|
vc_members = (
|
|
@@ -3802,11 +3876,13 @@ class ConsolePortListView(generic.ObjectListView):
|
|
|
3802
3876
|
|
|
3803
3877
|
class ConsolePortView(DeviceComponentPageMixin, generic.ObjectView):
|
|
3804
3878
|
queryset = ConsolePort.objects.all()
|
|
3879
|
+
device_breadcrumb_url = "dcim:device_consoleports"
|
|
3880
|
+
module_breadcrumb_url = "dcim:module_consoleports"
|
|
3805
3881
|
|
|
3806
3882
|
def get_extra_context(self, request, instance):
|
|
3807
3883
|
return {
|
|
3808
|
-
"device_breadcrumb_url":
|
|
3809
|
-
"module_breadcrumb_url":
|
|
3884
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
3885
|
+
"module_breadcrumb_url": self.module_breadcrumb_url,
|
|
3810
3886
|
**super().get_extra_context(request, instance),
|
|
3811
3887
|
}
|
|
3812
3888
|
|
|
@@ -3868,11 +3944,13 @@ class ConsoleServerPortListView(generic.ObjectListView):
|
|
|
3868
3944
|
|
|
3869
3945
|
class ConsoleServerPortView(DeviceComponentPageMixin, generic.ObjectView):
|
|
3870
3946
|
queryset = ConsoleServerPort.objects.all()
|
|
3947
|
+
device_breadcrumb_url = "dcim:device_consoleserverports"
|
|
3948
|
+
module_breadcrumb_url = "dcim:module_consoleserverports"
|
|
3871
3949
|
|
|
3872
3950
|
def get_extra_context(self, request, instance):
|
|
3873
3951
|
return {
|
|
3874
|
-
"device_breadcrumb_url":
|
|
3875
|
-
"module_breadcrumb_url":
|
|
3952
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
3953
|
+
"module_breadcrumb_url": self.module_breadcrumb_url,
|
|
3876
3954
|
**super().get_extra_context(request, instance),
|
|
3877
3955
|
}
|
|
3878
3956
|
|
|
@@ -3934,11 +4012,13 @@ class PowerPortListView(generic.ObjectListView):
|
|
|
3934
4012
|
|
|
3935
4013
|
class PowerPortView(DeviceComponentPageMixin, generic.ObjectView):
|
|
3936
4014
|
queryset = PowerPort.objects.all()
|
|
4015
|
+
device_breadcrumb_url = "dcim:device_powerports"
|
|
4016
|
+
module_breadcrumb_url = "dcim:module_powerports"
|
|
3937
4017
|
|
|
3938
4018
|
def get_extra_context(self, request, instance):
|
|
3939
4019
|
return {
|
|
3940
|
-
"device_breadcrumb_url":
|
|
3941
|
-
"module_breadcrumb_url":
|
|
4020
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
4021
|
+
"module_breadcrumb_url": self.module_breadcrumb_url,
|
|
3942
4022
|
**super().get_extra_context(request, instance),
|
|
3943
4023
|
}
|
|
3944
4024
|
|
|
@@ -4000,11 +4080,13 @@ class PowerOutletListView(generic.ObjectListView):
|
|
|
4000
4080
|
|
|
4001
4081
|
class PowerOutletView(DeviceComponentPageMixin, generic.ObjectView):
|
|
4002
4082
|
queryset = PowerOutlet.objects.all()
|
|
4083
|
+
device_breadcrumb_url = "dcim:device_poweroutlets"
|
|
4084
|
+
module_breadcrumb_url = "dcim:module_poweroutlets"
|
|
4003
4085
|
|
|
4004
4086
|
def get_extra_context(self, request, instance):
|
|
4005
4087
|
return {
|
|
4006
|
-
"device_breadcrumb_url":
|
|
4007
|
-
"module_breadcrumb_url":
|
|
4088
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
4089
|
+
"module_breadcrumb_url": self.module_breadcrumb_url,
|
|
4008
4090
|
**super().get_extra_context(request, instance),
|
|
4009
4091
|
}
|
|
4010
4092
|
|
|
@@ -4069,6 +4151,8 @@ class InterfaceView(
|
|
|
4069
4151
|
generic.ObjectView,
|
|
4070
4152
|
):
|
|
4071
4153
|
queryset = Interface.objects.all()
|
|
4154
|
+
device_breadcrumb_url = "dcim:device_interfaces"
|
|
4155
|
+
module_breadcrumb_url = "dcim:module_interfaces"
|
|
4072
4156
|
|
|
4073
4157
|
def get_extra_context(self, request, instance):
|
|
4074
4158
|
# Get assigned IP addresses
|
|
@@ -4109,8 +4193,8 @@ class InterfaceView(
|
|
|
4109
4193
|
return {
|
|
4110
4194
|
"ipaddress_table": ipaddress_table,
|
|
4111
4195
|
"vlan_table": vlan_table,
|
|
4112
|
-
"device_breadcrumb_url":
|
|
4113
|
-
"module_breadcrumb_url":
|
|
4196
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
4197
|
+
"module_breadcrumb_url": self.module_breadcrumb_url,
|
|
4114
4198
|
"child_interfaces_table": child_interfaces_tables,
|
|
4115
4199
|
"redundancy_table": redundancy_table,
|
|
4116
4200
|
"virtual_device_contexts_table": virtual_device_contexts_table,
|
|
@@ -4199,11 +4283,13 @@ class FrontPortListView(generic.ObjectListView):
|
|
|
4199
4283
|
|
|
4200
4284
|
class FrontPortView(DeviceComponentPageMixin, generic.ObjectView):
|
|
4201
4285
|
queryset = FrontPort.objects.all()
|
|
4286
|
+
device_breadcrumb_url = "dcim:device_frontports"
|
|
4287
|
+
module_breadcrumb_url = "dcim:module_frontports"
|
|
4202
4288
|
|
|
4203
4289
|
def get_extra_context(self, request, instance):
|
|
4204
4290
|
return {
|
|
4205
|
-
"device_breadcrumb_url":
|
|
4206
|
-
"module_breadcrumb_url":
|
|
4291
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
4292
|
+
"module_breadcrumb_url": self.module_breadcrumb_url,
|
|
4207
4293
|
**super().get_extra_context(request, instance),
|
|
4208
4294
|
}
|
|
4209
4295
|
|
|
@@ -4265,11 +4351,13 @@ class RearPortListView(generic.ObjectListView):
|
|
|
4265
4351
|
|
|
4266
4352
|
class RearPortView(DeviceComponentPageMixin, generic.ObjectView):
|
|
4267
4353
|
queryset = RearPort.objects.all()
|
|
4354
|
+
device_breadcrumb_url = "dcim:device_rearports"
|
|
4355
|
+
module_breadcrumb_url = "dcim:module_rearports"
|
|
4268
4356
|
|
|
4269
4357
|
def get_extra_context(self, request, instance):
|
|
4270
4358
|
return {
|
|
4271
|
-
"device_breadcrumb_url":
|
|
4272
|
-
"module_breadcrumb_url":
|
|
4359
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
4360
|
+
"module_breadcrumb_url": self.module_breadcrumb_url,
|
|
4273
4361
|
**super().get_extra_context(request, instance),
|
|
4274
4362
|
}
|
|
4275
4363
|
|
|
@@ -4331,9 +4419,13 @@ class DeviceBayListView(generic.ObjectListView):
|
|
|
4331
4419
|
|
|
4332
4420
|
class DeviceBayView(DeviceComponentPageMixin, generic.ObjectView):
|
|
4333
4421
|
queryset = DeviceBay.objects.all()
|
|
4422
|
+
device_breadcrumb_url = "dcim:device_devicebays"
|
|
4334
4423
|
|
|
4335
4424
|
def get_extra_context(self, request, instance):
|
|
4336
|
-
return {
|
|
4425
|
+
return {
|
|
4426
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
4427
|
+
**super().get_extra_context(request, instance),
|
|
4428
|
+
}
|
|
4337
4429
|
|
|
4338
4430
|
|
|
4339
4431
|
class DeviceBayCreateView(generic.ComponentCreateView):
|
|
@@ -4568,6 +4660,7 @@ class InventoryItemListView(generic.ObjectListView):
|
|
|
4568
4660
|
|
|
4569
4661
|
class InventoryItemView(DeviceComponentPageMixin, generic.ObjectView):
|
|
4570
4662
|
queryset = InventoryItem.objects.all().select_related("device", "manufacturer", "software_version")
|
|
4663
|
+
device_breadcrumb_url = "dcim:device_inventory"
|
|
4571
4664
|
|
|
4572
4665
|
def get_extra_context(self, request, instance):
|
|
4573
4666
|
# Software images
|
|
@@ -4577,7 +4670,7 @@ class InventoryItemView(DeviceComponentPageMixin, generic.ObjectView):
|
|
|
4577
4670
|
software_version_images = []
|
|
4578
4671
|
|
|
4579
4672
|
return {
|
|
4580
|
-
"device_breadcrumb_url":
|
|
4673
|
+
"device_breadcrumb_url": self.device_breadcrumb_url,
|
|
4581
4674
|
"software_version_images": software_version_images,
|
|
4582
4675
|
**super().get_extra_context(request, instance),
|
|
4583
4676
|
}
|
|
@@ -4767,6 +4860,7 @@ class PathTraceView(generic.ObjectView):
|
|
|
4767
4860
|
|
|
4768
4861
|
additional_permissions = ["dcim.view_cable"]
|
|
4769
4862
|
template_name = "dcim/cable_trace.html"
|
|
4863
|
+
view_titles = Titles(titles={"detail": "Cable Trace for {{ object }}"})
|
|
4770
4864
|
|
|
4771
4865
|
def dispatch(self, request, *args, **kwargs):
|
|
4772
4866
|
model = kwargs.pop("model")
|
|
@@ -4803,6 +4897,7 @@ class PathTraceView(generic.ObjectView):
|
|
|
4803
4897
|
"path": path,
|
|
4804
4898
|
"related_paths": related_paths,
|
|
4805
4899
|
"total_length": path.get_total_length() if path else None,
|
|
4900
|
+
"view_titles": self.get_view_titles(),
|
|
4806
4901
|
**super().get_extra_context(request, instance),
|
|
4807
4902
|
}
|
|
4808
4903
|
|
|
@@ -5089,7 +5184,6 @@ class VirtualChassisUIViewSet(NautobotUIViewSet):
|
|
|
5089
5184
|
url_path="add-member",
|
|
5090
5185
|
url_name="add_member",
|
|
5091
5186
|
custom_view_base_action="change",
|
|
5092
|
-
custom_view_additional_permissions=["dcim.change_virtualchassis"],
|
|
5093
5187
|
)
|
|
5094
5188
|
def add_member(self, request, pk=None):
|
|
5095
5189
|
virtual_chassis = self.get_object()
|
|
@@ -5286,7 +5380,9 @@ class PowerFeedUIViewSet(NautobotUIViewSet):
|
|
|
5286
5380
|
items={
|
|
5287
5381
|
"detail": [
|
|
5288
5382
|
ModelBreadcrumbItem(),
|
|
5289
|
-
|
|
5383
|
+
AncestorsInstanceBreadcrumbItem(
|
|
5384
|
+
instance=context_object_attr("power_panel.location"), include_self=True
|
|
5385
|
+
),
|
|
5290
5386
|
InstanceBreadcrumbItem(instance=context_object_attr("power_panel")),
|
|
5291
5387
|
InstanceBreadcrumbItem(
|
|
5292
5388
|
instance=context_object_attr("rack"),
|
|
@@ -5522,7 +5618,8 @@ class InterfaceRedundancyGroupUIViewSet(NautobotUIViewSet):
|
|
|
5522
5618
|
prefetch_related_fields=["interface"],
|
|
5523
5619
|
order_by_fields=["priority"],
|
|
5524
5620
|
table_title="Interfaces",
|
|
5525
|
-
related_field_name="
|
|
5621
|
+
related_field_name="interface_redundancy_groups",
|
|
5622
|
+
related_list_url_name="dcim:interface_list",
|
|
5526
5623
|
include_columns=[
|
|
5527
5624
|
"interface__device",
|
|
5528
5625
|
"interface",
|
|
@@ -5775,6 +5872,14 @@ class SoftwareVersionUIViewSet(NautobotUIViewSet):
|
|
|
5775
5872
|
queryset = SoftwareVersion.objects.all()
|
|
5776
5873
|
serializer_class = serializers.SoftwareVersionSerializer
|
|
5777
5874
|
table_class = tables.SoftwareVersionTable
|
|
5875
|
+
breadcrumbs = Breadcrumbs(
|
|
5876
|
+
items={
|
|
5877
|
+
"detail": [
|
|
5878
|
+
ModelBreadcrumbItem(),
|
|
5879
|
+
InstanceBreadcrumbItem(instance=context_object_attr("platform")),
|
|
5880
|
+
]
|
|
5881
|
+
}
|
|
5882
|
+
)
|
|
5778
5883
|
object_detail_content = object_detail.ObjectDetailContent(
|
|
5779
5884
|
panels=(
|
|
5780
5885
|
object_detail.ObjectFieldsPanel(
|
|
@@ -5852,7 +5957,7 @@ class ControllerUIViewSet(NautobotUIViewSet):
|
|
|
5852
5957
|
object_detail.DistinctViewTab(
|
|
5853
5958
|
weight=700,
|
|
5854
5959
|
tab_id="wireless_networks",
|
|
5855
|
-
url_name="dcim:
|
|
5960
|
+
url_name="dcim:controller_wireless_networks",
|
|
5856
5961
|
label="Wireless Networks",
|
|
5857
5962
|
related_object_attribute="wireless_network_assignments",
|
|
5858
5963
|
panels=(
|
|
@@ -5867,6 +5972,7 @@ class ControllerUIViewSet(NautobotUIViewSet):
|
|
|
5867
5972
|
select_related_fields=["wireless_network"],
|
|
5868
5973
|
exclude_columns=["controller"],
|
|
5869
5974
|
include_paginator=True,
|
|
5975
|
+
enable_related_link=False,
|
|
5870
5976
|
),
|
|
5871
5977
|
),
|
|
5872
5978
|
),
|
|
@@ -5876,12 +5982,12 @@ class ControllerUIViewSet(NautobotUIViewSet):
|
|
|
5876
5982
|
@action(
|
|
5877
5983
|
detail=True,
|
|
5878
5984
|
url_path="wireless-networks",
|
|
5879
|
-
url_name="
|
|
5985
|
+
url_name="wireless_networks",
|
|
5880
5986
|
methods=["get"],
|
|
5881
5987
|
custom_view_base_action="view",
|
|
5882
5988
|
custom_view_additional_permissions=["wireless.view_controllermanageddevicegroupwirelessnetworkassignment"],
|
|
5883
5989
|
)
|
|
5884
|
-
def
|
|
5990
|
+
def wireless_networks(self, request, *args, **kwargs):
|
|
5885
5991
|
return Response({})
|
|
5886
5992
|
|
|
5887
5993
|
|