nautobot 3.0.0a2__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 -2
- nautobot/apps/filters.py +7 -9
- nautobot/apps/models.py +2 -2
- nautobot/apps/ui.py +13 -1
- nautobot/apps/utils.py +8 -0
- nautobot/circuits/filters.py +3 -2
- nautobot/circuits/navigation.py +3 -2
- nautobot/circuits/templates/circuits/circuit_create.html +3 -3
- nautobot/circuits/templates/circuits/circuittermination_create.html +9 -24
- nautobot/circuits/templates/circuits/inc/circuit_termination_cable_fragment.html +6 -6
- nautobot/circuits/templates/circuits/inc/speed_widget.html +12 -12
- nautobot/circuits/tests/integration/test_circuit.py +10 -13
- nautobot/circuits/tests/integration/test_circuits_bulk_operations.py +0 -3
- nautobot/circuits/views.py +6 -2
- nautobot/cloud/filters.py +1 -1
- nautobot/cloud/navigation.py +3 -2
- nautobot/core/api/schema.py +1 -1
- nautobot/core/api/serializers.py +6 -1
- nautobot/core/api/urls.py +2 -0
- nautobot/core/api/views.py +12 -0
- nautobot/core/apps/__init__.py +11 -10
- nautobot/core/celery/__init__.py +3 -5
- nautobot/core/checks.py +46 -0
- nautobot/core/choices.py +1 -1
- nautobot/core/cli/bootstrap_v3_to_v5.py +105 -13
- nautobot/core/cli/migrate_deprecated_templates.py +227 -0
- nautobot/core/constants.py +3 -0
- nautobot/core/context_processors.py +9 -1
- nautobot/core/filters.py +4 -0
- nautobot/core/forms/__init__.py +2 -0
- nautobot/core/forms/forms.py +1 -1
- nautobot/core/forms/widgets.py +21 -2
- nautobot/core/jobs/__init__.py +62 -3
- nautobot/core/jobs/groups.py +31 -1
- nautobot/core/management/commands/generate_test_data.py +28 -9
- nautobot/core/models/__init__.py +11 -0
- nautobot/core/models/generics.py +9 -1
- nautobot/core/models/tree_queries.py +10 -5
- nautobot/core/models/utils.py +1 -1
- nautobot/core/settings.py +35 -19
- nautobot/core/settings.yaml +17 -33
- nautobot/core/signals.py +12 -1
- nautobot/core/tables.py +13 -6
- nautobot/core/templates/40x.html +1 -1
- nautobot/core/templates/500.html +2 -2
- nautobot/core/templates/admin/base.html +1 -2
- nautobot/core/templates/admin/change_list.html +9 -12
- nautobot/core/templates/admin/config/config.html +12 -12
- nautobot/core/templates/admin/index.html +3 -3
- nautobot/core/templates/base_django.html +1 -2
- nautobot/core/templates/buttons/export.html +1 -1
- nautobot/core/templates/components/button/dropdown.html +5 -3
- nautobot/core/templates/components/panel/body_wrapper_generic_table.html +1 -1
- nautobot/core/templates/components/panel/header_extra_content_table.html +1 -1
- nautobot/core/templates/components/panel/panel.html +3 -3
- nautobot/core/templates/components/tab/content_wrapper.html +6 -7
- nautobot/core/templates/components/tab/label_wrapper_distinct_view.html +1 -1
- nautobot/core/templates/echarts/echarts.html +22 -9
- nautobot/core/templates/generic/object_bulk_add_component.html +2 -1
- nautobot/core/templates/generic/object_bulk_create.html +6 -5
- nautobot/core/templates/generic/object_bulk_delete.html +1 -1
- nautobot/core/templates/generic/object_bulk_destroy.html +3 -3
- 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_bulk_remove.html +2 -2
- nautobot/core/templates/generic/object_bulk_update.html +5 -4
- nautobot/core/templates/generic/object_create.html +5 -4
- 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_import.html +2 -1
- nautobot/core/templates/generic/object_list.html +12 -4
- nautobot/core/templates/generic/object_notes.html +5 -3
- nautobot/core/templates/generic/object_retrieve.html +4 -5
- nautobot/core/templates/graphene/graphiql.html +7 -8
- nautobot/core/templates/home.html +1 -1
- nautobot/core/templates/import_success.html +2 -1
- nautobot/core/templates/inc/computed_fields/panel_data.html +1 -1
- nautobot/core/templates/inc/created_updated.html +7 -3
- nautobot/core/templates/inc/custom_fields/panel_data.html +1 -1
- nautobot/core/templates/inc/footer.html +3 -1
- nautobot/core/templates/inc/form_static_field.html +6 -0
- nautobot/core/templates/inc/header.html +11 -1
- nautobot/core/templates/inc/image_attachments.html +2 -1
- nautobot/core/templates/inc/media.html +14 -0
- nautobot/core/templates/inc/nav_menu.html +3 -9
- nautobot/core/templates/inc/object_details_advanced_panel.html +2 -2
- nautobot/core/templates/inc/search_panel.html +4 -4
- nautobot/core/templates/login.html +4 -2
- nautobot/core/templates/nautobot_config.py.j2 +6 -11
- nautobot/core/templates/redoc_ui.html +7 -0
- nautobot/core/templates/rest_framework/api.html +103 -2
- nautobot/core/templates/search.html +1 -1
- nautobot/core/templates/swagger_ui.html +17 -3
- nautobot/core/templates/system_jobs/import_objects.html +1 -2
- nautobot/core/templates/utilities/confirmation_form.html +2 -2
- nautobot/core/templates/utilities/obj_table.html +10 -2
- nautobot/core/templates/utilities/render_field.html +7 -7
- nautobot/core/templates/utilities/render_jinja2.html +2 -2
- nautobot/core/templates/utilities/templatetags/filter_form_drawer.html +37 -4
- nautobot/core/templates/utilities/theme_preview.html +19 -3
- nautobot/core/templates/widgets/number_input_with_choices.html +44 -0
- nautobot/core/templates/widgets/selectwithdisabled_option.html +3 -1
- nautobot/core/templatetags/helpers.py +76 -18
- nautobot/core/testing/api.py +68 -9
- nautobot/core/testing/filters.py +0 -23
- nautobot/core/testing/integration.py +41 -17
- nautobot/core/testing/mixins.py +2 -0
- nautobot/core/testing/utils.py +18 -4
- nautobot/core/testing/views.py +104 -13
- nautobot/core/tests/integration/test_app_home.py +34 -30
- nautobot/core/tests/integration/test_app_navbar.py +3 -0
- 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/nautobot_config_without_example_apps.py +4 -0
- nautobot/core/tests/runner.py +8 -1
- nautobot/core/tests/test_api.py +5 -3
- nautobot/core/tests/test_breadcrumbs.py +27 -28
- nautobot/core/tests/test_checks.py +28 -0
- nautobot/core/tests/test_cli.py +40 -0
- nautobot/core/tests/test_config.py +2 -1
- nautobot/core/tests/test_forms.py +55 -13
- nautobot/core/tests/test_jobs.py +144 -3
- nautobot/core/tests/test_nautobot_server.py +2 -0
- nautobot/core/tests/test_navigations.py +76 -1
- nautobot/core/tests/test_patch_social_django.py +42 -0
- nautobot/core/tests/test_renderers.py +59 -0
- nautobot/core/tests/test_settings_schema.py +1 -0
- nautobot/core/tests/test_tables.py +3 -1
- nautobot/core/tests/test_templatetags_helpers.py +62 -13
- nautobot/core/tests/test_templatetags_ui_framework.py +4 -4
- nautobot/core/tests/test_titles.py +0 -16
- nautobot/core/tests/test_tree_queries.py +14 -1
- nautobot/core/tests/test_ui.py +123 -4
- nautobot/core/tests/test_utils.py +72 -5
- nautobot/core/tests/test_views.py +159 -31
- nautobot/core/ui/breadcrumbs.py +70 -29
- nautobot/core/ui/bulk_buttons.py +1 -1
- nautobot/core/ui/choices.py +143 -27
- nautobot/core/ui/constants.py +76 -12
- nautobot/core/ui/echarts.py +15 -20
- nautobot/core/ui/object_detail.py +143 -55
- nautobot/core/ui/titles.py +3 -6
- nautobot/core/urls.py +20 -9
- nautobot/core/utils/cache.py +2 -1
- nautobot/core/utils/filtering.py +28 -18
- nautobot/core/utils/lookup.py +49 -8
- nautobot/core/utils/module_loading.py +21 -0
- nautobot/core/utils/patch_social_django.py +128 -0
- nautobot/core/views/__init__.py +38 -1
- nautobot/core/views/generic.py +3 -3
- nautobot/core/views/mixins.py +45 -22
- nautobot/core/views/renderers.py +4 -3
- nautobot/core/views/viewsets.py +2 -1
- nautobot/data_validation/apps.py +1 -5
- nautobot/data_validation/custom_validators.py +4 -4
- nautobot/data_validation/filters.py +1 -1
- nautobot/data_validation/forms.py +40 -0
- nautobot/data_validation/migrations/0001_initial.py +0 -7
- nautobot/data_validation/migrations/0002_data_migration_from_app.py +3 -14
- nautobot/data_validation/models.py +16 -7
- nautobot/data_validation/navigation.py +8 -1
- nautobot/data_validation/tables.py +12 -5
- nautobot/data_validation/templates/data_validation/datacompliance_tab.html +1 -0
- nautobot/data_validation/templates/data_validation/device_constraints.html +61 -0
- nautobot/data_validation/tests/__init__.py +2 -2
- nautobot/data_validation/tests/migrations/test_migrations.py +83 -3
- nautobot/data_validation/tests/test_data_compliance_rules.py +12 -7
- nautobot/data_validation/tests/test_filters.py +8 -6
- nautobot/data_validation/tests/test_models.py +15 -0
- nautobot/data_validation/tests/test_views.py +190 -32
- nautobot/data_validation/urls.py +2 -5
- nautobot/data_validation/views.py +73 -40
- nautobot/dcim/api/serializers.py +3 -13
- nautobot/dcim/apps.py +4 -0
- nautobot/dcim/choices.py +65 -0
- nautobot/dcim/constants.py +7 -0
- nautobot/dcim/custom_validators.py +84 -0
- nautobot/dcim/factory.py +1 -1
- nautobot/dcim/filter_mixins.py +353 -4
- nautobot/dcim/{filters/__init__.py → filters.py} +15 -36
- nautobot/dcim/forms.py +90 -4
- 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/0079_remove_device_location_tenant_name_uniqueness.py +16 -0
- nautobot/dcim/migrations/0080_device_name_data_migration.py +59 -0
- 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 +98 -64
- nautobot/dcim/models/devices.py +30 -20
- nautobot/dcim/navigation.py +7 -6
- nautobot/dcim/tables/devices.py +18 -0
- nautobot/dcim/tables/devicetypes.py +8 -1
- nautobot/dcim/tables/racks.py +0 -2
- nautobot/dcim/tables/template_code.py +15 -15
- nautobot/dcim/templates/dcim/cable_connect.html +28 -112
- nautobot/dcim/templates/dcim/cable_trace.html +0 -4
- nautobot/dcim/templates/dcim/{cable_edit.html → cable_update.html} +1 -1
- nautobot/dcim/templates/dcim/consoleport.html +7 -6
- nautobot/dcim/templates/dcim/consoleserverport.html +7 -6
- nautobot/dcim/templates/dcim/device/config.html +2 -2
- nautobot/dcim/templates/dcim/device/lldp_neighbors.html +1 -1
- nautobot/dcim/templates/dcim/device/status.html +8 -8
- nautobot/dcim/templates/dcim/device.html +1 -1
- nautobot/dcim/templates/dcim/device_component_add.html +2 -2
- nautobot/dcim/templates/dcim/device_create.html +5 -3
- nautobot/dcim/templates/dcim/device_interface_delete.html +1 -1
- nautobot/dcim/templates/dcim/device_list.html +73 -10
- nautobot/dcim/templates/dcim/devicebay.html +1 -1
- nautobot/dcim/templates/dcim/devicebay_populate.html +2 -2
- nautobot/dcim/templates/dcim/devicetype_component_add.html +2 -2
- nautobot/dcim/templates/dcim/footer_convert_to_contact_or_team_record.html +14 -0
- nautobot/dcim/templates/dcim/frontport.html +10 -9
- nautobot/dcim/templates/dcim/inc/devicetype_component_table.html +1 -1
- nautobot/dcim/templates/dcim/inc/edit_form_softwareversion_js.html +2 -2
- 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 +35 -7
- nautobot/dcim/templates/dcim/interface_bulk_delete.html +1 -1
- nautobot/dcim/templates/dcim/interface_edit.html +2 -0
- nautobot/dcim/templates/dcim/inventoryitem.html +1 -1
- nautobot/dcim/templates/dcim/inventoryitem_add.html +3 -1
- nautobot/dcim/templates/dcim/inventoryitem_bulk_delete.html +1 -1
- nautobot/dcim/templates/dcim/inventoryitem_edit.html +3 -1
- nautobot/dcim/templates/dcim/module/base.html +49 -9
- 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_list.html +57 -8
- 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/modulefamily_retrieve.html +1 -1
- nautobot/dcim/templates/dcim/moduletype_list.html +2 -2
- nautobot/dcim/templates/dcim/moduletype_retrieve.html +49 -9
- nautobot/dcim/templates/dcim/platform_create.html +1 -1
- nautobot/dcim/templates/dcim/poweroutlet.html +1 -1
- nautobot/dcim/templates/dcim/powerport.html +6 -5
- nautobot/dcim/templates/dcim/rack_elevation_list.html +17 -5
- nautobot/dcim/templates/dcim/rack_retrieve.html +22 -15
- nautobot/dcim/templates/dcim/rearport.html +8 -7
- nautobot/dcim/templates/dcim/trace/cable.html +1 -1
- nautobot/dcim/templates/dcim/virtualchassis_add_member.html +16 -14
- nautobot/dcim/templates/dcim/virtualchassis_update.html +15 -7
- nautobot/dcim/tests/integration/test_controller.py +4 -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 +194 -6
- nautobot/dcim/tests/test_custom_validators.py +229 -0
- nautobot/dcim/tests/test_filters.py +55 -7
- nautobot/dcim/tests/test_forms.py +110 -8
- nautobot/dcim/tests/test_graphql.py +44 -1
- nautobot/dcim/tests/test_models.py +328 -4
- nautobot/dcim/tests/test_tables.py +160 -0
- nautobot/dcim/tests/test_views.py +132 -29
- nautobot/dcim/urls.py +64 -21
- nautobot/dcim/utils.py +3 -3
- nautobot/dcim/views.py +777 -397
- nautobot/extras/api/views.py +60 -45
- nautobot/extras/choices.py +2 -13
- nautobot/extras/datasources/git.py +3 -1
- nautobot/extras/{filters/mixins.py → filter_mixins.py} +1 -1
- nautobot/extras/{filters/customfields.py → filter_mixins_customfields.py} +42 -6
- nautobot/extras/{filters/__init__.py → filters.py} +33 -48
- nautobot/extras/forms/forms.py +14 -15
- nautobot/extras/forms/mixins.py +0 -41
- nautobot/extras/jobs.py +2 -0
- nautobot/extras/jobs_ui.py +4 -3
- nautobot/extras/management/__init__.py +11 -0
- nautobot/extras/management/commands/refresh_dynamic_group_member_caches.py +4 -1
- nautobot/extras/migrations/0127_approval_workflow_models.py +6 -6
- nautobot/extras/migrations/0129_jobresult_debug_log_count_jobresult_error_log_count_and_more.py +37 -0
- nautobot/extras/migrations/0130_jobresult_generate_log_entry_counts.py +42 -0
- nautobot/extras/migrations/0131_configcontext_device_families.py +18 -0
- nautobot/extras/models/__init__.py +1 -2
- nautobot/extras/models/approvals.py +33 -14
- nautobot/extras/models/change_logging.py +4 -0
- nautobot/extras/models/contacts.py +2 -0
- nautobot/extras/models/groups.py +44 -5
- nautobot/extras/models/jobs.py +60 -4
- nautobot/extras/models/mixins.py +28 -0
- nautobot/extras/models/models.py +23 -2
- nautobot/extras/models/secrets.py +1 -0
- nautobot/extras/models/statuses.py +0 -15
- nautobot/extras/navigation.py +13 -9
- nautobot/extras/plugins/__init__.py +33 -55
- nautobot/extras/plugins/marketplace_manifest.yml +49 -1
- nautobot/extras/plugins/tables.py +3 -3
- nautobot/extras/plugins/urls.py +2 -21
- nautobot/extras/plugins/utils.py +1 -33
- nautobot/extras/plugins/views.py +0 -9
- nautobot/extras/querysets.py +8 -0
- nautobot/extras/signals.py +20 -19
- nautobot/extras/tables.py +64 -68
- nautobot/extras/templates/django_ajax_tables/ajax_wrapper.html +2 -0
- nautobot/extras/templates/extras/approval_dashboard.html +7 -5
- nautobot/extras/templates/extras/approvalworkflowdefinition_update.html +4 -2
- nautobot/extras/templates/extras/approvalworkflowstage_retrieve.html +20 -12
- nautobot/extras/templates/extras/configcontext_update.html +1 -0
- nautobot/extras/templates/extras/configcontextschema_validation.html +2 -2
- nautobot/extras/templates/extras/dynamicgroup_retrieve.html +11 -5
- nautobot/extras/templates/extras/dynamicgroup_update.html +1 -1
- nautobot/extras/templates/extras/gitrepository_result.html +0 -2
- nautobot/extras/templates/extras/inc/approval_buttons_column.html +20 -6
- nautobot/extras/templates/extras/inc/bulk_edit_overridable_field.html +8 -7
- nautobot/extras/templates/extras/inc/configcontext_format.html +10 -3
- nautobot/extras/templates/extras/inc/graphqlquery_execute.html +71 -0
- nautobot/extras/templates/extras/inc/job_tiles.html +15 -3
- nautobot/extras/templates/extras/inc/json_format.html +10 -3
- nautobot/extras/templates/extras/inc/overridable_field.html +13 -12
- nautobot/extras/templates/extras/job.html +29 -12
- nautobot/extras/templates/extras/job_bulk_edit.html +18 -0
- nautobot/extras/templates/extras/job_edit.html +52 -46
- nautobot/extras/templates/extras/job_list.html +29 -25
- nautobot/extras/templates/extras/marketplace.html +5 -9
- nautobot/extras/templates/extras/object_configcontext.html +1 -1
- nautobot/extras/templates/extras/object_dynamicgroups.html +2 -2
- nautobot/extras/templates/extras/objectchange_retrieve.html +19 -39
- nautobot/extras/templates/extras/plugin_detail.html +29 -24
- nautobot/extras/templates/extras/plugins_list.html +16 -26
- nautobot/extras/templates/extras/role_retrieve.html +64 -0
- nautobot/extras/templates/extras/scheduledjob.html +4 -2
- nautobot/extras/templates/extras/secret_create.html +1 -1
- nautobot/extras/templatetags/custom_links.py +12 -12
- nautobot/extras/templatetags/job_buttons.py +14 -12
- nautobot/extras/test_jobs/invalid_import.py +9 -0
- nautobot/extras/test_jobs/log_counts_by_level.py +23 -0
- nautobot/extras/test_jobs/missing_import.py +11 -0
- nautobot/extras/tests/integration/test_computedfields.py +8 -9
- nautobot/extras/tests/integration/test_configcontextschema.py +27 -26
- nautobot/extras/tests/integration/test_customfields.py +9 -10
- nautobot/extras/tests/integration/test_dynamicgroups.py +12 -9
- nautobot/extras/tests/integration/test_plugin_banner.py +3 -0
- nautobot/extras/tests/integration/test_plugins.py +18 -6
- nautobot/extras/tests/integration/test_relationships.py +0 -2
- nautobot/extras/tests/test_api.py +90 -18
- nautobot/extras/tests/test_approvals.py +38 -38
- nautobot/extras/tests/test_changelog.py +59 -5
- nautobot/extras/tests/test_customfields.py +22 -13
- nautobot/extras/tests/test_customfields_filters.py +479 -0
- nautobot/extras/tests/test_dynamicgroups.py +39 -1
- nautobot/extras/tests/test_filters.py +57 -22
- nautobot/extras/tests/test_forms.py +18 -21
- nautobot/extras/tests/test_jobs.py +25 -4
- nautobot/extras/tests/test_migrations.py +1 -0
- nautobot/extras/tests/test_models.py +51 -33
- nautobot/extras/tests/test_plugins.py +36 -10
- nautobot/extras/tests/test_utils.py +3 -4
- nautobot/extras/tests/test_views.py +52 -112
- nautobot/extras/urls.py +0 -14
- nautobot/extras/views.py +164 -71
- nautobot/ipam/factory.py +7 -0
- nautobot/ipam/filter_mixins.py +38 -0
- nautobot/ipam/filters.py +53 -38
- nautobot/ipam/formfields.py +1 -1
- nautobot/ipam/forms.py +6 -3
- nautobot/ipam/migrations/0030_ipam__namespaces.py +13 -0
- nautobot/ipam/migrations/0031_ipam___data_migrations.py +4 -1
- nautobot/ipam/migrations/0054_namespace_tenant.py +25 -0
- nautobot/ipam/models.py +29 -2
- nautobot/ipam/navigation.py +3 -2
- nautobot/ipam/signals.py +71 -0
- nautobot/ipam/tables.py +19 -6
- nautobot/ipam/templates/ipam/inc/toggle_available.html +10 -10
- nautobot/ipam/templates/ipam/inc/vlangroup_header.html +1 -0
- nautobot/ipam/templates/ipam/ipaddress.html +14 -0
- nautobot/ipam/templates/ipam/ipaddress_merge.html +3 -3
- nautobot/ipam/templates/ipam/ipaddresstointerface_retrieve.html +1 -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_update.html +15 -0
- nautobot/ipam/templates/ipam/namespace_vrfs.html +1 -1
- nautobot/ipam/templates/ipam/prefix_delete.html +1 -1
- nautobot/ipam/templates/ipam/prefix_list.html +14 -13
- nautobot/ipam/templates/ipam/vlan_interfaces.html +1 -1
- nautobot/ipam/templates/ipam/vlan_vminterfaces.html +1 -1
- nautobot/ipam/tests/migration/test_migrations.py +89 -0
- nautobot/ipam/tests/test_api.py +13 -6
- nautobot/ipam/tests/test_filters.py +36 -1
- nautobot/ipam/tests/test_forms.py +1 -1
- nautobot/ipam/tests/test_models.py +44 -2
- nautobot/ipam/tests/test_tables.py +1 -2
- nautobot/ipam/tests/test_utils.py +1 -1
- nautobot/ipam/tests/test_views.py +13 -14
- nautobot/ipam/ui.py +0 -17
- nautobot/ipam/utils/migrations.py +16 -2
- nautobot/ipam/utils/testing.py +9 -3
- nautobot/ipam/views.py +53 -11
- 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/cabletrace.js +1 -1
- nautobot/project-static/js/forms.js +13 -0
- nautobot/project-static/js/interface_filtering.js +20 -16
- nautobot/project-static/nautobot-icons/battery-3.svg +3 -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/project-static/nautobot-icons/cloud.svg +1 -1
- nautobot/project-static/nautobot-icons/control-panel.svg +1 -1
- nautobot/project-static/nautobot-icons/device-lifecycle.svg +1 -1
- nautobot/project-static/nautobot-icons/elements.svg +1 -1
- nautobot/project-static/nautobot-icons/extensibility.svg +3 -0
- nautobot/project-static/nautobot-icons/hammer.svg +1 -1
- nautobot/project-static/nautobot-icons/organization.svg +3 -0
- nautobot/project-static/nautobot-icons/secrets.svg +1 -1
- nautobot/project-static/nautobot-icons/security.svg +3 -0
- nautobot/project-static/nautobot-icons/server.svg +1 -1
- nautobot/project-static/nautobot-icons/star-filled.svg +1 -1
- nautobot/project-static/nautobot-icons/star.svg +1 -1
- nautobot/tenancy/api/serializers.py +1 -0
- nautobot/tenancy/api/views.py +2 -1
- nautobot/tenancy/{filters/__init__.py → filters.py} +2 -10
- nautobot/tenancy/navigation.py +3 -1
- nautobot/tenancy/tests/test_filters.py +0 -2
- nautobot/tenancy/views.py +2 -1
- nautobot/ui/package-lock.json +87 -4
- nautobot/ui/package.json +2 -1
- nautobot/ui/src/js/collapse.js +3 -3
- nautobot/ui/src/js/nautobot.js +16 -1
- nautobot/ui/src/js/select2.js +53 -2
- nautobot/ui/src/scss/colors.scss +1 -1
- nautobot/ui/src/scss/nautobot.scss +112 -30
- nautobot/ui/webpack.config.js +13 -0
- nautobot/users/templates/users/preferences.html +11 -2
- nautobot/users/templates/users/profile.html +45 -12
- nautobot/users/templates/users/sessionkey_delete.html +1 -1
- nautobot/users/tests/test_api.py +4 -0
- nautobot/users/views.py +4 -2
- nautobot/virtualization/filters.py +6 -1
- nautobot/virtualization/models.py +1 -68
- nautobot/virtualization/navigation.py +3 -2
- nautobot/virtualization/templates/virtualization/virtual_machine_vminterface_delete.html +1 -1
- nautobot/virtualization/templates/virtualization/virtualmachine_list.html +2 -2
- nautobot/virtualization/templates/virtualization/virtualmachine_update.html +3 -1
- nautobot/virtualization/tests/test_api.py +3 -0
- nautobot/virtualization/tests/test_filters.py +10 -1
- nautobot/virtualization/tests/test_models.py +45 -4
- nautobot/virtualization/views.py +4 -1
- nautobot/vpn/__init__.py +0 -0
- nautobot/vpn/api/serializers.py +113 -0
- nautobot/vpn/api/urls.py +19 -0
- nautobot/vpn/api/views.py +70 -0
- nautobot/vpn/apps.py +8 -0
- nautobot/vpn/choices.py +171 -0
- nautobot/vpn/factory.py +219 -0
- nautobot/vpn/filters.py +234 -0
- nautobot/vpn/forms.py +487 -0
- nautobot/vpn/homepage.py +19 -0
- nautobot/vpn/migrations/0001_initial.py +541 -0
- nautobot/vpn/migrations/0002_populate_defaults.py +199 -0
- nautobot/vpn/migrations/__init__.py +0 -0
- nautobot/vpn/models.py +535 -0
- nautobot/vpn/navigation.py +98 -0
- nautobot/vpn/tables.py +383 -0
- nautobot/vpn/templates/vpn/vpnprofile_create.html +150 -0
- nautobot/vpn/tests/__init__.py +0 -0
- nautobot/vpn/tests/test_api.py +336 -0
- nautobot/vpn/tests/test_filters.py +139 -0
- nautobot/vpn/tests/test_forms.py +293 -0
- nautobot/vpn/tests/test_models.py +147 -0
- nautobot/vpn/tests/test_views.py +300 -0
- nautobot/vpn/urls.py +16 -0
- nautobot/vpn/views.py +495 -0
- nautobot/wireless/navigation.py +3 -2
- nautobot/wireless/tests/integration/test_radio_profile.py +1 -5
- nautobot/wireless/tests/test_api.py +1 -1
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/METADATA +15 -15
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/RECORD +514 -572
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/entry_points.txt +1 -0
- 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/template_content.py +0 -42
- nautobot/data_validation/templates/data_validation/datacompliance_retrieve.html +0 -1
- nautobot/dcim/filters/mixins.py +0 -354
- 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 -243
- 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 -97
- 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/inc/prefix_header_extra_content_table.html +0 -4
- 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/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/dcim/templates/dcim/{cable.html → cable_retrieve.html} +0 -0
- /nautobot/tenancy/{filters/mixins.py → filter_mixins.py} +0 -0
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/LICENSE.txt +0 -0
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/NOTICE +0 -0
- {nautobot-3.0.0a2.dist-info → nautobot-3.0.0rc1.dist-info}/WHEEL +0 -0
nautobot/apps/choices.py
CHANGED
|
@@ -14,8 +14,10 @@ from nautobot.dcim.choices import (
|
|
|
14
14
|
ConsolePortTypeChoices,
|
|
15
15
|
DeviceFaceChoices,
|
|
16
16
|
DeviceRedundancyGroupFailoverStrategyChoices,
|
|
17
|
+
InterfaceDuplexChoices,
|
|
17
18
|
InterfaceModeChoices,
|
|
18
19
|
InterfaceRedundancyGroupProtocolChoices,
|
|
20
|
+
InterfaceSpeedChoices,
|
|
19
21
|
InterfaceTypeChoices,
|
|
20
22
|
PortTypeChoices,
|
|
21
23
|
PowerFeedBreakerPoleChoices,
|
|
@@ -43,7 +45,6 @@ from nautobot.extras.choices import (
|
|
|
43
45
|
ButtonClassChoices,
|
|
44
46
|
CustomFieldFilterLogicChoices,
|
|
45
47
|
CustomFieldTypeChoices,
|
|
46
|
-
CustomLinkButtonClassChoices,
|
|
47
48
|
DynamicGroupOperatorChoices,
|
|
48
49
|
JobExecutionType,
|
|
49
50
|
JobResultStatusChoices,
|
|
@@ -79,15 +80,16 @@ __all__ = (
|
|
|
79
80
|
"ConsolePortTypeChoices",
|
|
80
81
|
"CustomFieldFilterLogicChoices",
|
|
81
82
|
"CustomFieldTypeChoices",
|
|
82
|
-
"CustomLinkButtonClassChoices",
|
|
83
83
|
"DeviceFaceChoices",
|
|
84
84
|
"DeviceRedundancyGroupFailoverStrategyChoices",
|
|
85
85
|
"DynamicGroupOperatorChoices",
|
|
86
86
|
"IPAddressRoleChoices",
|
|
87
87
|
"IPAddressTypeChoices",
|
|
88
88
|
"IPAddressVersionChoices",
|
|
89
|
+
"InterfaceDuplexChoices",
|
|
89
90
|
"InterfaceModeChoices",
|
|
90
91
|
"InterfaceRedundancyGroupProtocolChoices",
|
|
92
|
+
"InterfaceSpeedChoices",
|
|
91
93
|
"InterfaceTypeChoices",
|
|
92
94
|
"JobExecutionType",
|
|
93
95
|
"JobResultStatusChoices",
|
nautobot/apps/filters.py
CHANGED
|
@@ -28,24 +28,22 @@ from nautobot.core.filters import (
|
|
|
28
28
|
TagFilter,
|
|
29
29
|
TreeNodeMultipleChoiceFilter,
|
|
30
30
|
)
|
|
31
|
-
from nautobot.extras.
|
|
31
|
+
from nautobot.extras.filter_mixins import (
|
|
32
|
+
ConfigContextRoleFilter,
|
|
32
33
|
CreatedUpdatedModelFilterSetMixin,
|
|
33
34
|
CustomFieldModelFilterSetMixin,
|
|
34
|
-
NautobotFilterSet,
|
|
35
|
-
RelationshipModelFilterSetMixin,
|
|
36
|
-
StatusModelFilterSetMixin,
|
|
37
|
-
)
|
|
38
|
-
from nautobot.extras.filters.mixins import (
|
|
39
|
-
ConfigContextRoleFilter,
|
|
40
35
|
LocalContextModelFilterSetMixin,
|
|
41
36
|
RelationshipFilter,
|
|
37
|
+
RelationshipModelFilterSetMixin,
|
|
42
38
|
RoleFilter,
|
|
43
39
|
RoleModelFilterSetMixin,
|
|
44
40
|
StatusFilter,
|
|
41
|
+
StatusModelFilterSetMixin,
|
|
45
42
|
)
|
|
43
|
+
from nautobot.extras.filters import NautobotFilterSet
|
|
46
44
|
from nautobot.extras.plugins import FilterExtension
|
|
47
|
-
from nautobot.ipam.
|
|
48
|
-
from nautobot.tenancy.
|
|
45
|
+
from nautobot.ipam.filter_mixins import PrefixFilter
|
|
46
|
+
from nautobot.tenancy.filter_mixins import TenancyModelFilterSetMixin
|
|
49
47
|
|
|
50
48
|
__all__ = (
|
|
51
49
|
"BaseFilterSet",
|
nautobot/apps/models.py
CHANGED
|
@@ -43,11 +43,11 @@ from nautobot.extras.models import (
|
|
|
43
43
|
CustomFieldModel,
|
|
44
44
|
RelationshipModel,
|
|
45
45
|
StatusField,
|
|
46
|
-
StatusModel,
|
|
47
46
|
)
|
|
48
47
|
from nautobot.extras.models.mixins import (
|
|
49
48
|
ApprovableModelMixin,
|
|
50
49
|
ContactMixin,
|
|
50
|
+
DataComplianceModelMixin,
|
|
51
51
|
DynamicGroupMixin,
|
|
52
52
|
DynamicGroupsModelMixin,
|
|
53
53
|
NotesMixin,
|
|
@@ -76,6 +76,7 @@ __all__ = (
|
|
|
76
76
|
"ContentTypeRelatedQuerySet",
|
|
77
77
|
"CustomFieldModel",
|
|
78
78
|
"CustomValidator",
|
|
79
|
+
"DataComplianceModelMixin",
|
|
79
80
|
"DataComplianceRule",
|
|
80
81
|
"DynamicGroupMixin",
|
|
81
82
|
"DynamicGroupsModelMixin",
|
|
@@ -97,7 +98,6 @@ __all__ = (
|
|
|
97
98
|
"RestrictedQuerySet",
|
|
98
99
|
"SavedViewMixin",
|
|
99
100
|
"StatusField",
|
|
100
|
-
"StatusModel",
|
|
101
101
|
"TagsField",
|
|
102
102
|
"TagsManager",
|
|
103
103
|
"TreeManager",
|
nautobot/apps/ui.py
CHANGED
|
@@ -4,6 +4,7 @@ from nautobot.core.choices import ButtonColorChoices
|
|
|
4
4
|
from nautobot.core.ui.base import PermissionsMixin
|
|
5
5
|
from nautobot.core.ui.breadcrumbs import (
|
|
6
6
|
AncestorsBreadcrumbs,
|
|
7
|
+
AncestorsInstanceBreadcrumbItem,
|
|
7
8
|
BaseBreadcrumbItem,
|
|
8
9
|
Breadcrumbs,
|
|
9
10
|
context_object_attr,
|
|
@@ -12,7 +13,14 @@ from nautobot.core.ui.breadcrumbs import (
|
|
|
12
13
|
ModelBreadcrumbItem,
|
|
13
14
|
ViewNameBreadcrumbItem,
|
|
14
15
|
)
|
|
15
|
-
from nautobot.core.ui.choices import
|
|
16
|
+
from nautobot.core.ui.choices import (
|
|
17
|
+
EChartsThemeColors,
|
|
18
|
+
EChartsTypeChoices,
|
|
19
|
+
LayoutChoices,
|
|
20
|
+
NavigationIconChoices,
|
|
21
|
+
NavigationWeightChoices,
|
|
22
|
+
SectionChoices,
|
|
23
|
+
)
|
|
16
24
|
from nautobot.core.ui.echarts import (
|
|
17
25
|
EChartsBase,
|
|
18
26
|
queryset_to_nested_dict_keys_as_series,
|
|
@@ -59,6 +67,7 @@ from nautobot.extras.plugins import Banner, TemplateExtension
|
|
|
59
67
|
|
|
60
68
|
__all__ = (
|
|
61
69
|
"AncestorsBreadcrumbs",
|
|
70
|
+
"AncestorsInstanceBreadcrumbItem",
|
|
62
71
|
"Banner",
|
|
63
72
|
"BannerClassChoices",
|
|
64
73
|
"BaseBreadcrumbItem",
|
|
@@ -72,6 +81,7 @@ __all__ = (
|
|
|
72
81
|
"DropdownButton",
|
|
73
82
|
"EChartsBase",
|
|
74
83
|
"EChartsPanel",
|
|
84
|
+
"EChartsThemeColors",
|
|
75
85
|
"EChartsTypeChoices",
|
|
76
86
|
"GroupedKeyValueTablePanel",
|
|
77
87
|
"HomePageBase",
|
|
@@ -90,6 +100,8 @@ __all__ = (
|
|
|
90
100
|
"NavMenuImportButton",
|
|
91
101
|
"NavMenuItem",
|
|
92
102
|
"NavMenuTab",
|
|
103
|
+
"NavigationIconChoices",
|
|
104
|
+
"NavigationWeightChoices",
|
|
93
105
|
"ObjectDetailContent",
|
|
94
106
|
"ObjectFieldsPanel",
|
|
95
107
|
"ObjectTextPanel",
|
nautobot/apps/utils.py
CHANGED
|
@@ -27,10 +27,13 @@ from nautobot.core.utils.filtering import (
|
|
|
27
27
|
from nautobot.core.utils.git import BranchDoesNotExist, convert_git_diff_log_to_list, GitRepo, swap_status_initials
|
|
28
28
|
from nautobot.core.utils.logging import sanitize
|
|
29
29
|
from nautobot.core.utils.lookup import (
|
|
30
|
+
get_breadcrumbs_for_model,
|
|
30
31
|
get_changes_for_model,
|
|
32
|
+
get_detail_view_components_context_for_model,
|
|
31
33
|
get_filterset_for_model,
|
|
32
34
|
get_form_for_model,
|
|
33
35
|
get_model_from_name,
|
|
36
|
+
get_object_detail_content_for_model,
|
|
34
37
|
get_related_class_for_model,
|
|
35
38
|
get_related_field_for_models,
|
|
36
39
|
get_route_for_model,
|
|
@@ -38,6 +41,7 @@ from nautobot.core.utils.lookup import (
|
|
|
38
41
|
get_url_for_url_pattern,
|
|
39
42
|
get_url_patterns,
|
|
40
43
|
get_view_for_model,
|
|
44
|
+
get_view_titles_for_model,
|
|
41
45
|
)
|
|
42
46
|
from nautobot.core.utils.migrations import migrate_content_type_references_to_new_model
|
|
43
47
|
from nautobot.core.utils.permissions import (
|
|
@@ -97,8 +101,10 @@ __all__ = (
|
|
|
97
101
|
"generate_signature",
|
|
98
102
|
"get_all_lookup_expr_for_field",
|
|
99
103
|
"get_base_template",
|
|
104
|
+
"get_breadcrumbs_for_model",
|
|
100
105
|
"get_celery_queues",
|
|
101
106
|
"get_changes_for_model",
|
|
107
|
+
"get_detail_view_components_context_for_model",
|
|
102
108
|
"get_filter_field_label",
|
|
103
109
|
"get_filterable_params_from_filter_params",
|
|
104
110
|
"get_filterset_field",
|
|
@@ -107,6 +113,7 @@ __all__ = (
|
|
|
107
113
|
"get_form_for_model",
|
|
108
114
|
"get_latest_release",
|
|
109
115
|
"get_model_from_name",
|
|
116
|
+
"get_object_detail_content_for_model",
|
|
110
117
|
"get_permission_for_model",
|
|
111
118
|
"get_related_class_for_model",
|
|
112
119
|
"get_related_field_for_models",
|
|
@@ -116,6 +123,7 @@ __all__ = (
|
|
|
116
123
|
"get_url_for_url_pattern",
|
|
117
124
|
"get_url_patterns",
|
|
118
125
|
"get_view_for_model",
|
|
126
|
+
"get_view_titles_for_model",
|
|
119
127
|
"get_worker_count",
|
|
120
128
|
"hex_to_rgb",
|
|
121
129
|
"image_upload",
|
nautobot/circuits/filters.py
CHANGED
|
@@ -13,8 +13,9 @@ from nautobot.dcim.filters import (
|
|
|
13
13
|
PathEndpointModelFilterSetMixin,
|
|
14
14
|
)
|
|
15
15
|
from nautobot.dcim.models import Location
|
|
16
|
-
from nautobot.extras.
|
|
17
|
-
from nautobot.
|
|
16
|
+
from nautobot.extras.filter_mixins import StatusModelFilterSetMixin
|
|
17
|
+
from nautobot.extras.filters import NautobotFilterSet
|
|
18
|
+
from nautobot.tenancy.filter_mixins import TenancyModelFilterSetMixin
|
|
18
19
|
|
|
19
20
|
from .models import Circuit, CircuitTermination, CircuitType, Provider, ProviderNetwork
|
|
20
21
|
|
nautobot/circuits/navigation.py
CHANGED
|
@@ -4,12 +4,13 @@ from nautobot.core.apps import (
|
|
|
4
4
|
NavMenuItem,
|
|
5
5
|
NavMenuTab,
|
|
6
6
|
)
|
|
7
|
+
from nautobot.core.ui.choices import NavigationIconChoices, NavigationWeightChoices
|
|
7
8
|
|
|
8
9
|
menu_items = (
|
|
9
10
|
NavMenuTab(
|
|
10
11
|
name="Circuits",
|
|
11
|
-
icon=
|
|
12
|
-
weight=
|
|
12
|
+
icon=NavigationIconChoices.CIRCUITS,
|
|
13
|
+
weight=NavigationWeightChoices.CIRCUITS,
|
|
13
14
|
groups=(
|
|
14
15
|
NavMenuGroup(
|
|
15
16
|
name="Circuits",
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
{% render_field form.circuit_type %}
|
|
11
11
|
{% render_field form.status %}
|
|
12
12
|
{% render_field form.install_date %}
|
|
13
|
-
<div class="mb-10 d-flex justify-content-center">
|
|
14
|
-
<label class="col-
|
|
15
|
-
<div class="col-
|
|
13
|
+
<div class="mb-10 d-md-flex justify-content-center">
|
|
14
|
+
<label class="col-md-3 col-form-label" for="id_commit_rate">{{ form.commit_rate.label }}</label>
|
|
15
|
+
<div class="col-md-9">
|
|
16
16
|
<div class="input-group">
|
|
17
17
|
{{ form.commit_rate }}
|
|
18
18
|
{% include 'circuits/inc/speed_widget.html' with target_field='commit_rate' %}
|
|
@@ -7,24 +7,9 @@
|
|
|
7
7
|
<div class="card">
|
|
8
8
|
<div class="card-header"><strong>Termination</strong></div>
|
|
9
9
|
<div class="card-body">
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<p class="form-control-plaintext">{{ obj.circuit.provider }}</p>
|
|
14
|
-
</div>
|
|
15
|
-
</div>
|
|
16
|
-
<div class="mb-10 d-flex justify-content-center">
|
|
17
|
-
<label class="col-lg-3 col-form-label">Circuit</label>
|
|
18
|
-
<div class="col-lg-9">
|
|
19
|
-
<p class="form-control-plaintext">{{ obj.circuit.cid }}</p>
|
|
20
|
-
</div>
|
|
21
|
-
</div>
|
|
22
|
-
<div class="mb-10 d-flex justify-content-center">
|
|
23
|
-
<label class="col-lg-3 col-form-label">Termination</label>
|
|
24
|
-
<div class="col-lg-9">
|
|
25
|
-
<p class="form-control-plaintext">{{ form.term_side.value }}</p>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
10
|
+
{% include "inc/form_static_field.html" with label="Provider" value=obj.circuit.provider %}
|
|
11
|
+
{% include "inc/form_static_field.html" with label="Circuit" value=obj.circuit.cid %}
|
|
12
|
+
{% include "inc/form_static_field.html" with label="Termination" value=form.term_side.value %}
|
|
28
13
|
{% with location_tab_active=form.initial.location %}
|
|
29
14
|
{% with providernetwork_tab_active=form.initial.provider_network %}
|
|
30
15
|
{% with cloudnetwork_tab_active=form.initial.cloud_network %}
|
|
@@ -58,9 +43,9 @@
|
|
|
58
43
|
<div class="card">
|
|
59
44
|
<div class="card-header"><strong>Termination Details</strong></div>
|
|
60
45
|
<div class="card-body">
|
|
61
|
-
<div class="mb-10 d-flex justify-content-center">
|
|
62
|
-
<label class="col-
|
|
63
|
-
<div class="col-
|
|
46
|
+
<div class="mb-10 d-md-flex justify-content-center">
|
|
47
|
+
<label class="col-md-3 col-form-label" for="id_port_speed">{{ form.port_speed.label }}</label>
|
|
48
|
+
<div class="col-md-9">
|
|
64
49
|
<div class="input-group">
|
|
65
50
|
{{ form.port_speed }}
|
|
66
51
|
{% include 'circuits/inc/speed_widget.html' with target_field='port_speed' %}
|
|
@@ -68,9 +53,9 @@
|
|
|
68
53
|
<span class="form-text">{{ form.port_speed.help_text }}</span>
|
|
69
54
|
</div>
|
|
70
55
|
</div>
|
|
71
|
-
<div class="mb-10 d-flex justify-content-center">
|
|
72
|
-
<label class="col-
|
|
73
|
-
<div class="col-
|
|
56
|
+
<div class="mb-10 d-md-flex justify-content-center">
|
|
57
|
+
<label class="col-md-3 col-form-label" for="id_upstream_speed">{{ form.upstream_speed.label }}</label>
|
|
58
|
+
<div class="col-md-9">
|
|
74
59
|
<div class="input-group">
|
|
75
60
|
{{ form.upstream_speed }}
|
|
76
61
|
{% include 'circuits/inc/speed_widget.html' with target_field='upstream_speed' %}
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
{% if perms.dcim.add_cable %}
|
|
25
25
|
<div class="float-end">
|
|
26
26
|
<span class="dropdown">
|
|
27
|
-
<button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
27
|
+
<button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" data-bs-popper-config='{"strategy": "fixed"}' aria-haspopup="true" aria-expanded="false">
|
|
28
28
|
<span class="mdi mdi-ethernet-cable" aria-hidden="true"></span> Connect
|
|
29
29
|
</button>
|
|
30
|
-
<ul class="dropdown-menu dropdown-menu-
|
|
31
|
-
<li><a href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='interface' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Interface</a></li>
|
|
32
|
-
<li><a href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='front-port' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Front Port</a></li>
|
|
33
|
-
<li><a href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='rear-port' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Rear Port</a></li>
|
|
34
|
-
<li><a href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='circuit-termination' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Circuit Termination</a></li>
|
|
30
|
+
<ul class="dropdown-menu dropdown-menu-end">
|
|
31
|
+
<li><a class="dropdown-item" href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='interface' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Interface</a></li>
|
|
32
|
+
<li><a class="dropdown-item" href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='front-port' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Front Port</a></li>
|
|
33
|
+
<li><a class="dropdown-item" href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='rear-port' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Rear Port</a></li>
|
|
34
|
+
<li><a class="dropdown-item" href="{% url 'circuits:circuittermination_connect' termination_a_id=termination.pk termination_b_type='circuit-termination' %}?termination_b_location={{ termination.location.pk }}&return_url={{ object.get_absolute_url }}">Circuit Termination</a></li>
|
|
35
35
|
</ul>
|
|
36
36
|
</span>
|
|
37
37
|
</div>
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
<span class="input-group-btn">
|
|
2
|
-
<button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown">
|
|
2
|
+
<button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" data-bs-popper-config='{"strategy": "fixed"}'>
|
|
3
3
|
<span class="mdi mdi-chevron-down"></span>
|
|
4
4
|
</button>
|
|
5
|
-
<ul class="dropdown-menu dropdown-menu-
|
|
6
|
-
<li><a href="#" target="{{ target_field }}" data="10000" class="set_speed">10 Mbps</a></li>
|
|
7
|
-
<li><a href="#" target="{{ target_field }}" data="100000" class="set_speed">100 Mbps</a></li>
|
|
8
|
-
<li><a href="#" target="{{ target_field }}" data="1000000" class="set_speed">1 Gbps</a></li>
|
|
9
|
-
<li><a href="#" target="{{ target_field }}" data="10000000" class="set_speed">10 Gbps</a></li>
|
|
10
|
-
<li><a href="#" target="{{ target_field }}" data="25000000" class="set_speed">25 Gbps</a></li>
|
|
11
|
-
<li><a href="#" target="{{ target_field }}" data="40000000" class="set_speed">40 Gbps</a></li>
|
|
12
|
-
<li><a href="#" target="{{ target_field }}" data="100000000" class="set_speed">100 Gbps</a></li>
|
|
13
|
-
<li class="divider"></li>
|
|
14
|
-
<li><a href="#" target="{{ target_field }}" data="1544" class="set_speed">T1 (1.544 Mbps)</a></li>
|
|
15
|
-
<li><a href="#" target="{{ target_field }}" data="2048" class="set_speed">E1 (2.048 Mbps)</a></li>
|
|
5
|
+
<ul class="dropdown-menu dropdown-menu-end">
|
|
6
|
+
<li><a href="#" target="{{ target_field }}" data="10000" class="set_speed dropdown-item">10 Mbps</a></li>
|
|
7
|
+
<li><a href="#" target="{{ target_field }}" data="100000" class="set_speed dropdown-item">100 Mbps</a></li>
|
|
8
|
+
<li><a href="#" target="{{ target_field }}" data="1000000" class="set_speed dropdown-item">1 Gbps</a></li>
|
|
9
|
+
<li><a href="#" target="{{ target_field }}" data="10000000" class="set_speed dropdown-item">10 Gbps</a></li>
|
|
10
|
+
<li><a href="#" target="{{ target_field }}" data="25000000" class="set_speed dropdown-item">25 Gbps</a></li>
|
|
11
|
+
<li><a href="#" target="{{ target_field }}" data="40000000" class="set_speed dropdown-item">40 Gbps</a></li>
|
|
12
|
+
<li><a href="#" target="{{ target_field }}" data="100000000" class="set_speed dropdown-item">100 Gbps</a></li>
|
|
13
|
+
<li><hr class="dropdown-divider"></li>
|
|
14
|
+
<li><a href="#" target="{{ target_field }}" data="1544" class="set_speed dropdown-item">T1 (1.544 Mbps)</a></li>
|
|
15
|
+
<li><a href="#" target="{{ target_field }}" data="2048" class="set_speed dropdown-item">E1 (2.048 Mbps)</a></li>
|
|
16
16
|
</ul>
|
|
17
17
|
</span>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from django.contrib.contenttypes.models import ContentType
|
|
2
|
-
from django.test import tag
|
|
3
2
|
from django.urls import reverse
|
|
4
3
|
|
|
5
4
|
from nautobot.circuits.models import Circuit, CircuitTermination, CircuitType, Provider
|
|
@@ -48,7 +47,6 @@ class CircuitTestCase(SeleniumTestCase, ObjectsListMixin, ObjectDetailsMixin):
|
|
|
48
47
|
)
|
|
49
48
|
return circuit
|
|
50
49
|
|
|
51
|
-
@tag("fix_in_v3")
|
|
52
50
|
def test_circuit_create(self):
|
|
53
51
|
cid = "Circuit-test-abc123"
|
|
54
52
|
description = "My Precious Circuit"
|
|
@@ -87,16 +85,15 @@ class CircuitTestCase(SeleniumTestCase, ObjectsListMixin, ObjectDetailsMixin):
|
|
|
87
85
|
circuit = Circuit.objects.get(cid=cid)
|
|
88
86
|
self.assertIn(self.live_server_url + reverse("circuits:circuit", kwargs={"pk": circuit.pk}), self.browser.url)
|
|
89
87
|
|
|
90
|
-
self.assertPanelValue("
|
|
91
|
-
self.assertPanelValue("
|
|
92
|
-
self.assertPanelValue("
|
|
93
|
-
self.assertPanelValue("
|
|
94
|
-
self.assertPanelValue("
|
|
95
|
-
self.assertPanelValue("
|
|
96
|
-
self.assertPanelValue("
|
|
97
|
-
self.assertPanelValue("
|
|
88
|
+
self.assertPanelValue("CIRCUIT", "Circuit ID", cid)
|
|
89
|
+
self.assertPanelValue("CIRCUIT", "Status", "Active")
|
|
90
|
+
self.assertPanelValue("CIRCUIT", "Provider", self.provider.name)
|
|
91
|
+
self.assertPanelValue("CIRCUIT", "Circuit Type", self.circuit_type.name)
|
|
92
|
+
self.assertPanelValue("CIRCUIT", "Tenant", self.tenant.name)
|
|
93
|
+
self.assertPanelValue("CIRCUIT", "Date Installed", "Jan. 1, 2025")
|
|
94
|
+
self.assertPanelValue("CIRCUIT", "Commit Rate (Kbps)", "192")
|
|
95
|
+
self.assertPanelValue("CIRCUIT", "Description", description)
|
|
98
96
|
|
|
99
|
-
@tag("fix_in_v3")
|
|
100
97
|
def test_circuit_create_termination(self):
|
|
101
98
|
circuit = self.create_circuit("Circuit-test-termination")
|
|
102
99
|
sides = ["A", "Z"]
|
|
@@ -108,7 +105,7 @@ class CircuitTestCase(SeleniumTestCase, ObjectsListMixin, ObjectDetailsMixin):
|
|
|
108
105
|
self.assertIn(details_url, self.browser.url)
|
|
109
106
|
|
|
110
107
|
# Find and click add termination button
|
|
111
|
-
termination_panel_xpath = f'//*[@id="main"]//div[@class
|
|
108
|
+
termination_panel_xpath = f'//*[@id="main"]//div[contains(@class, "card-header") and contains(normalize-space(), "TERMINATION - {side} SIDE")]'
|
|
112
109
|
self.browser.find_by_xpath(f'{termination_panel_xpath}//a[normalize-space()="Add"]').click()
|
|
113
110
|
|
|
114
111
|
port_speed = ord(side)
|
|
@@ -129,7 +126,7 @@ class CircuitTestCase(SeleniumTestCase, ObjectsListMixin, ObjectDetailsMixin):
|
|
|
129
126
|
self.assertTrue(self.browser.is_text_present(f"Created circuit termination Termination {side}"))
|
|
130
127
|
|
|
131
128
|
# Assert that value are properly set
|
|
132
|
-
panel_label = f"
|
|
129
|
+
panel_label = f"TERMINATION - {side} SIDE"
|
|
133
130
|
self.assertPanelValue(panel_label, "Location", self.location.name)
|
|
134
131
|
self.assertPanelValue(panel_label, "Speed", port_speed)
|
|
135
132
|
self.assertPanelValue(panel_label, "Speed", upstream_speed)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import uuid
|
|
2
2
|
|
|
3
|
-
from django.test import tag
|
|
4
|
-
|
|
5
3
|
from nautobot.circuits.models import Circuit, CircuitType, Provider
|
|
6
4
|
from nautobot.core.testing.integration import (
|
|
7
5
|
BulkOperationsTestCases,
|
|
@@ -9,7 +7,6 @@ from nautobot.core.testing.integration import (
|
|
|
9
7
|
from nautobot.extras.models import Status
|
|
10
8
|
|
|
11
9
|
|
|
12
|
-
@tag("fix_in_v3")
|
|
13
10
|
class CircuitBulkOperationsTestCase(BulkOperationsTestCases.BulkOperationsTestCase):
|
|
14
11
|
"""
|
|
15
12
|
Test circuits bulk edit / delete operations.
|
nautobot/circuits/views.py
CHANGED
|
@@ -60,7 +60,7 @@ class CircuitTypeUIViewSet(NautobotUIViewSet):
|
|
|
60
60
|
|
|
61
61
|
class CircuitTerminationObjectFieldsPanel(ObjectFieldsPanel):
|
|
62
62
|
def get_extra_context(self, context):
|
|
63
|
-
return {"termination": context["object"]}
|
|
63
|
+
return {"termination": context["object"], **super().get_extra_context(context)}
|
|
64
64
|
|
|
65
65
|
def render_key(self, key, value, context):
|
|
66
66
|
if key == "connected_endpoint":
|
|
@@ -226,7 +226,11 @@ class CircuitUIViewSet(NautobotUIViewSet):
|
|
|
226
226
|
return True
|
|
227
227
|
|
|
228
228
|
def get_extra_context(self, context):
|
|
229
|
-
return {
|
|
229
|
+
return {
|
|
230
|
+
"termination": context[self.context_object_key],
|
|
231
|
+
"side": self.side,
|
|
232
|
+
**super().get_extra_context(context),
|
|
233
|
+
}
|
|
230
234
|
|
|
231
235
|
def get_data(self, context):
|
|
232
236
|
"""
|
nautobot/cloud/filters.py
CHANGED
|
@@ -9,7 +9,7 @@ from nautobot.dcim.models import Manufacturer
|
|
|
9
9
|
from nautobot.extras.filters import NautobotFilterSet
|
|
10
10
|
from nautobot.extras.models import SecretsGroup
|
|
11
11
|
from nautobot.extras.utils import FeatureQuery
|
|
12
|
-
from nautobot.ipam.
|
|
12
|
+
from nautobot.ipam.filter_mixins import PrefixFilter
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class CloudAccountFilterSet(NautobotFilterSet):
|
nautobot/cloud/navigation.py
CHANGED
|
@@ -4,12 +4,13 @@ from nautobot.core.apps import (
|
|
|
4
4
|
NavMenuItem,
|
|
5
5
|
NavMenuTab,
|
|
6
6
|
)
|
|
7
|
+
from nautobot.core.ui.choices import NavigationIconChoices, NavigationWeightChoices
|
|
7
8
|
|
|
8
9
|
menu_items = (
|
|
9
10
|
NavMenuTab(
|
|
10
11
|
name="Cloud",
|
|
11
|
-
icon=
|
|
12
|
-
weight=
|
|
12
|
+
icon=NavigationIconChoices.CLOUD,
|
|
13
|
+
weight=NavigationWeightChoices.CLOUD,
|
|
13
14
|
groups=(
|
|
14
15
|
NavMenuGroup(
|
|
15
16
|
name="Cloud",
|
nautobot/core/api/schema.py
CHANGED
|
@@ -143,7 +143,7 @@ class NautobotAutoSchema(AutoSchema):
|
|
|
143
143
|
"name": "exclude_m2m",
|
|
144
144
|
"required": False,
|
|
145
145
|
"description": "Exclude many-to-many fields from the response",
|
|
146
|
-
"schema": {"type": "boolean"
|
|
146
|
+
"schema": {"type": "boolean"},
|
|
147
147
|
}
|
|
148
148
|
)
|
|
149
149
|
# TODO: add "include" parameter to the schema where relevant - nautobot/nautobot#685
|
nautobot/core/api/serializers.py
CHANGED
|
@@ -64,6 +64,7 @@ class OptInFieldsMixin:
|
|
|
64
64
|
- Removes all serializer fields specified in `Meta.opt_in_fields` list that aren't specified in the
|
|
65
65
|
`include` query parameter. (applies to GET requests only)
|
|
66
66
|
- If the `exclude_m2m` query parameter is truthy, remove all many-to-many serializer fields for performance.
|
|
67
|
+
If `exclude_m2m` is not provided, only `tags`, `content_types`, and `object_types` are included by default.
|
|
67
68
|
|
|
68
69
|
As an example, if the serializer specifies that `opt_in_fields = ["computed_fields"]`
|
|
69
70
|
but `computed_fields` is not specified in the `?include` query parameter, `computed_fields` will be popped
|
|
@@ -102,9 +103,13 @@ class OptInFieldsMixin:
|
|
|
102
103
|
|
|
103
104
|
# If exclude_m2m is present and truthy, mark any many-to-many fields as write-only so they
|
|
104
105
|
# don't get included in the response.
|
|
105
|
-
|
|
106
|
+
# If exclude_m2m is not present, we include a subset of many-to-many fields by default.
|
|
107
|
+
exclude_m2m = params.get("exclude_m2m", self.context.get("exclude_m2m", None))
|
|
108
|
+
if exclude_m2m is None or is_truthy(exclude_m2m):
|
|
106
109
|
for field_instance in fields.values():
|
|
107
110
|
if isinstance(field_instance, (serializers.ManyRelatedField, serializers.ListSerializer)):
|
|
111
|
+
if exclude_m2m is None and field_instance.source in constants.DEFAULT_M2M_FIELDS:
|
|
112
|
+
continue
|
|
108
113
|
field_instance.write_only = True
|
|
109
114
|
|
|
110
115
|
self.__pruned_fields = fields
|
nautobot/core/api/urls.py
CHANGED
|
@@ -48,9 +48,11 @@ urlpatterns = [
|
|
|
48
48
|
path("dcim/", include("nautobot.dcim.api.urls")),
|
|
49
49
|
path("extras/", include("nautobot.extras.api.urls")),
|
|
50
50
|
path("ipam/", include("nautobot.ipam.api.urls")),
|
|
51
|
+
path("load-balancers/", include("nautobot.load_balancers.api.urls")),
|
|
51
52
|
path("tenancy/", include("nautobot.tenancy.api.urls")),
|
|
52
53
|
path("users/", include("nautobot.users.api.urls")),
|
|
53
54
|
path("virtualization/", include("nautobot.virtualization.api.urls")),
|
|
55
|
+
path("vpn/", include("nautobot.vpn.api.urls")),
|
|
54
56
|
path("wireless/", include("nautobot.wireless.api.urls")),
|
|
55
57
|
path("status/", StatusView.as_view(), name="api-status"),
|
|
56
58
|
path("docs/", NautobotSpectacularSwaggerView.as_view(url_name="schema"), name="api_docs"),
|
nautobot/core/api/views.py
CHANGED
|
@@ -458,6 +458,10 @@ class APIRootView(AuthenticatedAPIRootView):
|
|
|
458
458
|
"ipam",
|
|
459
459
|
reverse("ipam-api:api-root", request=request, format=format),
|
|
460
460
|
),
|
|
461
|
+
(
|
|
462
|
+
"load-balancers",
|
|
463
|
+
reverse("load_balancers-api:api-root", request=request, format=format),
|
|
464
|
+
),
|
|
461
465
|
(
|
|
462
466
|
"plugins",
|
|
463
467
|
reverse("plugins-api:api-root", request=request, format=format),
|
|
@@ -479,6 +483,14 @@ class APIRootView(AuthenticatedAPIRootView):
|
|
|
479
483
|
format=format,
|
|
480
484
|
),
|
|
481
485
|
),
|
|
486
|
+
(
|
|
487
|
+
"vpn",
|
|
488
|
+
reverse(
|
|
489
|
+
"vpn-api:api-root",
|
|
490
|
+
request=request,
|
|
491
|
+
format=format,
|
|
492
|
+
),
|
|
493
|
+
),
|
|
482
494
|
(
|
|
483
495
|
"wireless",
|
|
484
496
|
reverse(
|
nautobot/core/apps/__init__.py
CHANGED
|
@@ -9,7 +9,6 @@ from django.db.models.signals import post_migrate
|
|
|
9
9
|
from django.urls import reverse
|
|
10
10
|
from django.urls.exceptions import NoReverseMatch
|
|
11
11
|
from django.utils.http import urlencode
|
|
12
|
-
from django.utils.module_loading import import_string
|
|
13
12
|
from graphene.types import generic, String
|
|
14
13
|
|
|
15
14
|
from nautobot.core.signals import nautobot_database_ready
|
|
@@ -31,7 +30,8 @@ from nautobot.core.ui.nav import ( # isort: skip # noqa: F401
|
|
|
31
30
|
NavMenuTab,
|
|
32
31
|
NAV_CONTEXT_NAMES,
|
|
33
32
|
)
|
|
34
|
-
|
|
33
|
+
from nautobot.core.utils.module_loading import import_string_optional
|
|
34
|
+
from nautobot.core.utils.patch_social_django import patch_django_storage
|
|
35
35
|
from nautobot.extras.registry import registry
|
|
36
36
|
|
|
37
37
|
logger = logging.getLogger(__name__)
|
|
@@ -60,17 +60,11 @@ class NautobotConfig(AppConfig):
|
|
|
60
60
|
"""
|
|
61
61
|
Ready function initiates the import application.
|
|
62
62
|
"""
|
|
63
|
-
|
|
64
|
-
homepage_layout = import_string(f"{self.name}.{self.homepage_layout}")
|
|
63
|
+
if homepage_layout := import_string_optional(f"{self.name}.{self.homepage_layout}"):
|
|
65
64
|
register_homepage_panels(self.path, self.label, homepage_layout)
|
|
66
|
-
except ImportError:
|
|
67
|
-
pass
|
|
68
65
|
|
|
69
|
-
|
|
70
|
-
menu_items = import_string(f"{self.name}.{self.menu_tabs}")
|
|
66
|
+
if menu_items := import_string_optional(f"{self.name}.{self.menu_tabs}"):
|
|
71
67
|
register_menu_items(menu_items)
|
|
72
|
-
except ImportError:
|
|
73
|
-
pass
|
|
74
68
|
|
|
75
69
|
|
|
76
70
|
def create_or_check_entry(grouping, record, key, path):
|
|
@@ -364,6 +358,13 @@ class CoreConfig(NautobotConfig):
|
|
|
364
358
|
logger.warning("Maintenance mode enabled: disabling update of most recent login time")
|
|
365
359
|
user_logged_in.disconnect(update_last_login, dispatch_uid="update_last_login")
|
|
366
360
|
|
|
361
|
+
# SECURITY
|
|
362
|
+
# Patch social_django to prevent account takeover vulnerability
|
|
363
|
+
from social_django.models import DjangoStorage
|
|
364
|
+
|
|
365
|
+
# TODO: When upgrading to 5.6.0 or later, remove the patch
|
|
366
|
+
patch_django_storage(DjangoStorage)
|
|
367
|
+
|
|
367
368
|
post_migrate.connect(post_migrate_send_nautobot_database_ready, sender=self)
|
|
368
369
|
|
|
369
370
|
super().ready()
|
nautobot/core/celery/__init__.py
CHANGED
|
@@ -12,7 +12,6 @@ from django.apps import apps
|
|
|
12
12
|
from django.conf import settings
|
|
13
13
|
from django.db.utils import OperationalError, ProgrammingError
|
|
14
14
|
from django.utils.functional import SimpleLazyObject
|
|
15
|
-
from django.utils.module_loading import import_string
|
|
16
15
|
from kombu.serialization import register
|
|
17
16
|
from prometheus_client import CollectorRegistry, multiprocess, start_http_server
|
|
18
17
|
|
|
@@ -21,8 +20,7 @@ from nautobot.core.branching import BranchContext
|
|
|
21
20
|
from nautobot.core.celery.control import discard_git_repository, refresh_git_repository # noqa: F401 # unused-import
|
|
22
21
|
from nautobot.core.celery.encoders import NautobotKombuJSONEncoder
|
|
23
22
|
from nautobot.core.celery.log import NautobotDatabaseHandler
|
|
24
|
-
from nautobot.core.utils.module_loading import import_modules_privately
|
|
25
|
-
from nautobot.extras.plugins.utils import import_object
|
|
23
|
+
from nautobot.core.utils.module_loading import import_modules_privately, import_string_optional
|
|
26
24
|
from nautobot.extras.registry import registry
|
|
27
25
|
|
|
28
26
|
logger = logging.getLogger(__name__)
|
|
@@ -140,7 +138,7 @@ def _import_dynamic_jobs_from_apps():
|
|
|
140
138
|
del sys.modules[job.__module__]
|
|
141
139
|
|
|
142
140
|
# Load app jobs
|
|
143
|
-
app_config.features["jobs"] =
|
|
141
|
+
app_config.features["jobs"] = import_string_optional(f"{app_config.__module__}.{app_config.jobs}")
|
|
144
142
|
|
|
145
143
|
|
|
146
144
|
def add_nautobot_log_handler(logger_instance, log_format=None):
|
|
@@ -220,7 +218,7 @@ def nautobot_kombu_json_loads_hook(data):
|
|
|
220
218
|
qual_name = data.pop("__nautobot_type__")
|
|
221
219
|
branch_name = data.pop("__nautobot_branch__", None)
|
|
222
220
|
logger.debug("Performing nautobot deserialization for type %s", qual_name)
|
|
223
|
-
cls =
|
|
221
|
+
cls = import_string_optional(qual_name) # fully qualified dotted import path
|
|
224
222
|
if cls:
|
|
225
223
|
|
|
226
224
|
def get_object():
|