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
|
@@ -29,6 +29,7 @@ from nautobot.core.utils.permissions import get_permission_for_model
|
|
|
29
29
|
from nautobot.dcim.models import (
|
|
30
30
|
ConsolePort,
|
|
31
31
|
Device,
|
|
32
|
+
DeviceFamily,
|
|
32
33
|
DeviceType,
|
|
33
34
|
Interface,
|
|
34
35
|
Location,
|
|
@@ -96,7 +97,6 @@ from nautobot.extras.models import (
|
|
|
96
97
|
from nautobot.extras.templatetags.job_buttons import NO_CONFIRM_BUTTON
|
|
97
98
|
from nautobot.extras.tests.constants import BIG_GRAPHQL_DEVICE_QUERY
|
|
98
99
|
from nautobot.extras.tests.test_jobs import get_job_class_and_model
|
|
99
|
-
from nautobot.extras.tests.test_relationships import RequiredRelationshipTestMixin
|
|
100
100
|
from nautobot.extras.utils import get_pending_approval_workflow_stages, RoleModelsQuery, TaggableClassesQuery
|
|
101
101
|
from nautobot.ipam.models import IPAddress, Prefix, VLAN, VLANGroup, VRF
|
|
102
102
|
from nautobot.tenancy.models import Tenant
|
|
@@ -132,14 +132,14 @@ class ApprovalWorkflowDefinitionViewTestCase(
|
|
|
132
132
|
ApprovalWorkflowDefinition.objects.create(
|
|
133
133
|
name=f"Test Approval Workflow {i}",
|
|
134
134
|
model_content_type=cls.scheduledjob_ct,
|
|
135
|
-
|
|
135
|
+
weight=i,
|
|
136
136
|
)
|
|
137
137
|
|
|
138
138
|
cls.form_data = {
|
|
139
139
|
"name": "Test Approval Workflow Definition 5",
|
|
140
140
|
"model_content_type": cls.scheduledjob_ct.pk,
|
|
141
141
|
"model_constraints": '{"name": "Bulk Delete Objects"}',
|
|
142
|
-
"
|
|
142
|
+
"weight": 5,
|
|
143
143
|
# These are the "management_form" fields required by the dynamic CustomFieldChoice formsets.
|
|
144
144
|
"approval_workflow_stage_definitions-TOTAL_FORMS": "0", # Set to 0 so validation succeeds until we need it
|
|
145
145
|
"approval_workflow_stage_definitions-INITIAL_FORMS": "1",
|
|
@@ -161,14 +161,14 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
161
161
|
cls.approval_workflow_definition = ApprovalWorkflowDefinition.objects.create(
|
|
162
162
|
name="Test Approval Workflow Definition 1",
|
|
163
163
|
model_content_type=cls.scheduledjob_ct,
|
|
164
|
-
|
|
164
|
+
weight=10,
|
|
165
165
|
)
|
|
166
166
|
cls.approver_group = Group.objects.create(name="Test Group 1")
|
|
167
167
|
cls.updated_approver_group = Group.objects.create(name="Test Group 2")
|
|
168
168
|
# Deletable objects
|
|
169
169
|
ApprovalWorkflowStageDefinition.objects.create(
|
|
170
170
|
approval_workflow_definition=cls.approval_workflow_definition,
|
|
171
|
-
|
|
171
|
+
sequence=100,
|
|
172
172
|
name="Test Approval Workflow 1 Stage 1 Definition",
|
|
173
173
|
min_approvers=2,
|
|
174
174
|
denial_message="Stage 1 Denial Message",
|
|
@@ -176,7 +176,7 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
176
176
|
)
|
|
177
177
|
ApprovalWorkflowStageDefinition.objects.create(
|
|
178
178
|
approval_workflow_definition=cls.approval_workflow_definition,
|
|
179
|
-
|
|
179
|
+
sequence=200,
|
|
180
180
|
name="Test Approval Workflow 1 Stage 2 Definition",
|
|
181
181
|
min_approvers=3,
|
|
182
182
|
denial_message="Stage 2 Denial Message",
|
|
@@ -184,7 +184,7 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
184
184
|
)
|
|
185
185
|
ApprovalWorkflowStageDefinition.objects.create(
|
|
186
186
|
approval_workflow_definition=cls.approval_workflow_definition,
|
|
187
|
-
|
|
187
|
+
sequence=300,
|
|
188
188
|
name="Test Approval Workflow 1 Stage 3 Definition",
|
|
189
189
|
min_approvers=4,
|
|
190
190
|
denial_message="Stage 3 Denial Message",
|
|
@@ -192,7 +192,7 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
192
192
|
)
|
|
193
193
|
ApprovalWorkflowStageDefinition.objects.create(
|
|
194
194
|
approval_workflow_definition=cls.approval_workflow_definition,
|
|
195
|
-
|
|
195
|
+
sequence=400,
|
|
196
196
|
name="Test Approval Workflow 1 Stage 4 Definition",
|
|
197
197
|
min_approvers=4,
|
|
198
198
|
denial_message="Stage 4 Denial Message",
|
|
@@ -200,7 +200,7 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
200
200
|
)
|
|
201
201
|
ApprovalWorkflowStageDefinition.objects.create(
|
|
202
202
|
approval_workflow_definition=cls.approval_workflow_definition,
|
|
203
|
-
|
|
203
|
+
sequence=500,
|
|
204
204
|
name="Test Approval Workflow 1 Stage 5 Definition",
|
|
205
205
|
min_approvers=4,
|
|
206
206
|
denial_message="Stage 5 Denial Message",
|
|
@@ -209,7 +209,7 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
209
209
|
|
|
210
210
|
cls.form_data = {
|
|
211
211
|
"approval_workflow_definition": cls.approval_workflow_definition.pk,
|
|
212
|
-
"
|
|
212
|
+
"sequence": 600,
|
|
213
213
|
"name": "Approval Workflow Stage 1 Definition",
|
|
214
214
|
"min_approvers": 2,
|
|
215
215
|
"denial_message": "Stage 1 is denied",
|
|
@@ -218,7 +218,7 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
218
218
|
|
|
219
219
|
cls.update_data = {
|
|
220
220
|
"approval_workflow_definition": cls.approval_workflow_definition.pk,
|
|
221
|
-
"
|
|
221
|
+
"sequence": 700,
|
|
222
222
|
"name": "Updated approval workflow stage 1",
|
|
223
223
|
"min_approvers": 3,
|
|
224
224
|
"denial_message": "updated message",
|
|
@@ -226,7 +226,7 @@ class ApprovalWorkflowStageDefinitionViewTestCase(ViewTestCases.PrimaryObjectVie
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
cls.bulk_edit_data = {
|
|
229
|
-
"
|
|
229
|
+
"sequence": 800,
|
|
230
230
|
"min_approvers": 5,
|
|
231
231
|
"denial_message": "updated denial message",
|
|
232
232
|
}
|
|
@@ -264,7 +264,7 @@ class ApprovalWorkflowViewTestCase(
|
|
|
264
264
|
]
|
|
265
265
|
approval_workflow_definitions = [
|
|
266
266
|
ApprovalWorkflowDefinition.objects.create(
|
|
267
|
-
name=f"Test Approval Workflow {i}", model_content_type=cls.scheduledjob_ct,
|
|
267
|
+
name=f"Test Approval Workflow {i}", model_content_type=cls.scheduledjob_ct, weight=i
|
|
268
268
|
)
|
|
269
269
|
for i in range(5)
|
|
270
270
|
]
|
|
@@ -332,7 +332,7 @@ class ApprovalWorkflowStageViewTestCase(
|
|
|
332
332
|
ApprovalWorkflowDefinition.objects.create(
|
|
333
333
|
name=f"Test Approval Workflow {i}",
|
|
334
334
|
model_content_type=cls.scheduledjob_ct,
|
|
335
|
-
|
|
335
|
+
weight=i,
|
|
336
336
|
)
|
|
337
337
|
for i in range(5)
|
|
338
338
|
]
|
|
@@ -342,7 +342,7 @@ class ApprovalWorkflowStageViewTestCase(
|
|
|
342
342
|
cls.approval_workflow_stage_definitions.append(
|
|
343
343
|
ApprovalWorkflowStageDefinition.objects.create(
|
|
344
344
|
approval_workflow_definition=approval_workflow_definition,
|
|
345
|
-
|
|
345
|
+
sequence=i * 100,
|
|
346
346
|
name=f"Test Approval Workflow Stage {i} Definition",
|
|
347
347
|
min_approvers=i + 1,
|
|
348
348
|
denial_message=f"Stage {i} Denial Message",
|
|
@@ -516,7 +516,7 @@ class ApprovalWorkflowStageResponseViewTestCase(
|
|
|
516
516
|
ApprovalWorkflowDefinition.objects.create(
|
|
517
517
|
name=f"Test Approval Workflow {i} Definition",
|
|
518
518
|
model_content_type=cls.scheduledjob_ct,
|
|
519
|
-
|
|
519
|
+
weight=i,
|
|
520
520
|
)
|
|
521
521
|
for i in range(5)
|
|
522
522
|
]
|
|
@@ -526,7 +526,7 @@ class ApprovalWorkflowStageResponseViewTestCase(
|
|
|
526
526
|
cls.approval_workflow_stage_definitions.append(
|
|
527
527
|
ApprovalWorkflowStageDefinition.objects.create(
|
|
528
528
|
approval_workflow_definition=approval_workflow_definition,
|
|
529
|
-
|
|
529
|
+
sequence=i * 100,
|
|
530
530
|
name=f"Test Approval Workflow Stage {i} Definition",
|
|
531
531
|
min_approvers=i + 1,
|
|
532
532
|
denial_message=f"Stage {i} Denial Message",
|
|
@@ -730,6 +730,7 @@ class ConfigContextTestCase(
|
|
|
730
730
|
"regions": [],
|
|
731
731
|
"locations": [location.pk],
|
|
732
732
|
"roles": [],
|
|
733
|
+
"device_families": [DeviceFamily.objects.first().pk],
|
|
733
734
|
"device_types": [],
|
|
734
735
|
"platforms": [],
|
|
735
736
|
"tenant_groups": [],
|
|
@@ -764,6 +765,7 @@ class ConfigContextTestCase(
|
|
|
764
765
|
"regions": [],
|
|
765
766
|
"locations": [],
|
|
766
767
|
"roles": [],
|
|
768
|
+
"device_families": [],
|
|
767
769
|
"device_types": [],
|
|
768
770
|
"platforms": [],
|
|
769
771
|
"tenant_groups": [],
|
|
@@ -803,6 +805,7 @@ class ConfigContextTestCase(
|
|
|
803
805
|
"regions": [],
|
|
804
806
|
"locations": [],
|
|
805
807
|
"roles": [],
|
|
808
|
+
"device_families": [],
|
|
806
809
|
"device_types": [],
|
|
807
810
|
"platforms": [],
|
|
808
811
|
"tenant_groups": [],
|
|
@@ -2346,6 +2349,7 @@ class SavedViewTest(ModelViewTestCase):
|
|
|
2346
2349
|
self.assertIn(str(sv_shared.pk), response_body, msg=response_body)
|
|
2347
2350
|
self.assertNotIn(str(sv_not_shared.pk), response_body, msg=response_body)
|
|
2348
2351
|
|
|
2352
|
+
@tag("example_app")
|
|
2349
2353
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
2350
2354
|
def test_create_saved_views_contain_boolean_filter_params(self):
|
|
2351
2355
|
"""
|
|
@@ -2754,59 +2758,6 @@ class ScheduledJobTestCase(
|
|
|
2754
2758
|
crontab="15 10 * * *",
|
|
2755
2759
|
)
|
|
2756
2760
|
|
|
2757
|
-
def test_only_enabled_is_listed(self):
|
|
2758
|
-
self.add_permissions("extras.view_scheduledjob")
|
|
2759
|
-
|
|
2760
|
-
# this should not appear, since it's not enabled
|
|
2761
|
-
ScheduledJob.objects.create(
|
|
2762
|
-
enabled=False,
|
|
2763
|
-
name="test4",
|
|
2764
|
-
task="pass_job.TestPassJob",
|
|
2765
|
-
interval=JobExecutionType.TYPE_IMMEDIATELY,
|
|
2766
|
-
user=self.user,
|
|
2767
|
-
start_time=timezone.now(),
|
|
2768
|
-
)
|
|
2769
|
-
|
|
2770
|
-
response = self.client.get(self._get_url("list"))
|
|
2771
|
-
self.assertHttpStatus(response, 200)
|
|
2772
|
-
self.assertNotIn("test4", extract_page_body(response.content.decode(response.charset)))
|
|
2773
|
-
|
|
2774
|
-
def test_approved_required_jobs_are_listed_only_when_approved(self):
|
|
2775
|
-
self.add_permissions("extras.view_scheduledjob")
|
|
2776
|
-
|
|
2777
|
-
# this should not appear, since it's not approved
|
|
2778
|
-
ScheduledJob.objects.create(
|
|
2779
|
-
enabled=True,
|
|
2780
|
-
approval_required=True,
|
|
2781
|
-
decision_date=None,
|
|
2782
|
-
name="test4",
|
|
2783
|
-
task="pass_job.TestPassJob",
|
|
2784
|
-
interval=JobExecutionType.TYPE_IMMEDIATELY,
|
|
2785
|
-
user=self.user,
|
|
2786
|
-
start_time=timezone.now(),
|
|
2787
|
-
)
|
|
2788
|
-
ScheduledJob.objects.create(
|
|
2789
|
-
enabled=True,
|
|
2790
|
-
approval_required=False,
|
|
2791
|
-
name="test5",
|
|
2792
|
-
task="pass_job.TestPassJob",
|
|
2793
|
-
interval=JobExecutionType.TYPE_IMMEDIATELY,
|
|
2794
|
-
user=self.user,
|
|
2795
|
-
start_time=timezone.now(),
|
|
2796
|
-
)
|
|
2797
|
-
response = self.client.get(self._get_url("list"))
|
|
2798
|
-
self.assertHttpStatus(response, 200)
|
|
2799
|
-
self.assertNotIn("test4", extract_page_body(response.content.decode(response.charset)))
|
|
2800
|
-
self.assertIn("test5", extract_page_body(response.content.decode(response.charset)))
|
|
2801
|
-
|
|
2802
|
-
scheduled_job = ScheduledJob.objects.get(name="test4")
|
|
2803
|
-
scheduled_job.decision_date = timezone.now()
|
|
2804
|
-
scheduled_job.save()
|
|
2805
|
-
|
|
2806
|
-
response = self.client.get(self._get_url("list"))
|
|
2807
|
-
self.assertHttpStatus(response, 200)
|
|
2808
|
-
self.assertIn("test4", extract_page_body(response.content.decode(response.charset)))
|
|
2809
|
-
|
|
2810
2761
|
def test_non_valid_crontab_syntax(self):
|
|
2811
2762
|
self.add_permissions("extras.view_scheduledjob")
|
|
2812
2763
|
|
|
@@ -3290,7 +3241,6 @@ class JobTestCase(
|
|
|
3290
3241
|
|
|
3291
3242
|
result = JobResult.objects.latest()
|
|
3292
3243
|
self.assertRedirects(response, reverse("extras:jobresult", kwargs={"pk": result.pk}))
|
|
3293
|
-
mock_begin_approval_workflow.assert_not_called()
|
|
3294
3244
|
|
|
3295
3245
|
def test_rerun_job(self):
|
|
3296
3246
|
self.add_permissions("extras.run_job")
|
|
@@ -3327,7 +3277,8 @@ class JobTestCase(
|
|
|
3327
3277
|
)
|
|
3328
3278
|
self.assertInHTML('<input type="hidden" name="_profile" value="True" id="id__profile">', content)
|
|
3329
3279
|
self.assertInHTML(
|
|
3330
|
-
'<input type="checkbox" name="_ignore_singleton_lock" id="id__ignore_singleton_lock" checked>',
|
|
3280
|
+
'<input type="checkbox" name="_ignore_singleton_lock" id="id__ignore_singleton_lock" class="form-check-input" checked>',
|
|
3281
|
+
content,
|
|
3331
3282
|
)
|
|
3332
3283
|
|
|
3333
3284
|
@mock.patch("nautobot.extras.views.get_worker_count", return_value=1)
|
|
@@ -3461,7 +3412,7 @@ class JobTestCase(
|
|
|
3461
3412
|
ApprovalWorkflowDefinition.objects.create(
|
|
3462
3413
|
name="Test Approval Workflow Definition 1",
|
|
3463
3414
|
model_content_type=ContentType.objects.get_for_model(ScheduledJob),
|
|
3464
|
-
|
|
3415
|
+
weight=0,
|
|
3465
3416
|
)
|
|
3466
3417
|
|
|
3467
3418
|
self.add_permissions("extras.run_job")
|
|
@@ -3491,7 +3442,7 @@ class JobTestCase(
|
|
|
3491
3442
|
ApprovalWorkflowDefinition.objects.create(
|
|
3492
3443
|
name="Approval Definition",
|
|
3493
3444
|
model_content_type=ContentType.objects.get_for_model(ScheduledJob),
|
|
3494
|
-
|
|
3445
|
+
weight=0,
|
|
3495
3446
|
)
|
|
3496
3447
|
data = {
|
|
3497
3448
|
"_schedule_type": "immediately",
|
|
@@ -3510,11 +3461,13 @@ class JobTestCase(
|
|
|
3510
3461
|
self.add_permissions("extras.run_job")
|
|
3511
3462
|
self.add_permissions("extras.view_scheduledjob")
|
|
3512
3463
|
|
|
3513
|
-
ApprovalWorkflowDefinition
|
|
3464
|
+
workflow = ApprovalWorkflowDefinition(
|
|
3514
3465
|
name="Approval Definition",
|
|
3515
3466
|
model_content_type=ContentType.objects.get_for_model(ScheduledJob),
|
|
3516
|
-
|
|
3467
|
+
weight=0,
|
|
3468
|
+
model_constraints={"job_model__name": self.test_pass.name},
|
|
3517
3469
|
)
|
|
3470
|
+
workflow.validated_save()
|
|
3518
3471
|
data = {
|
|
3519
3472
|
"_schedule_type": "future",
|
|
3520
3473
|
"_schedule_name": "test",
|
|
@@ -3522,14 +3475,15 @@ class JobTestCase(
|
|
|
3522
3475
|
}
|
|
3523
3476
|
|
|
3524
3477
|
for i, run_url in enumerate(self.run_urls):
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3478
|
+
with self.subTest(run_url=run_url):
|
|
3479
|
+
if "_schedule_name" in data:
|
|
3480
|
+
data["_schedule_name"] = f"test {i}"
|
|
3481
|
+
response = self.client.post(run_url, data)
|
|
3482
|
+
scheduled_job = ScheduledJob.objects.last()
|
|
3483
|
+
self.assertRedirects(
|
|
3484
|
+
response,
|
|
3485
|
+
reverse("extras:scheduledjob_approvalworkflow", args=[scheduled_job.pk]),
|
|
3486
|
+
)
|
|
3533
3487
|
|
|
3534
3488
|
@mock.patch("nautobot.extras.views.get_worker_count", return_value=1)
|
|
3535
3489
|
def test_run_scheduled_job_with_no_approval_workflow_defined(self, _):
|
|
@@ -3574,7 +3528,7 @@ class JobTestCase(
|
|
|
3574
3528
|
ApprovalWorkflowDefinition.objects.create(
|
|
3575
3529
|
name="Approval Definition",
|
|
3576
3530
|
model_content_type=ContentType.objects.get_for_model(ScheduledJob),
|
|
3577
|
-
|
|
3531
|
+
weight=0,
|
|
3578
3532
|
)
|
|
3579
3533
|
|
|
3580
3534
|
data = {
|
|
@@ -3599,7 +3553,7 @@ class JobTestCase(
|
|
|
3599
3553
|
ApprovalWorkflowDefinition.objects.create(
|
|
3600
3554
|
name="Approval Definition",
|
|
3601
3555
|
model_content_type=ContentType.objects.get_for_model(ScheduledJob),
|
|
3602
|
-
|
|
3556
|
+
weight=0,
|
|
3603
3557
|
)
|
|
3604
3558
|
|
|
3605
3559
|
data = {
|
|
@@ -3625,7 +3579,7 @@ class JobTestCase(
|
|
|
3625
3579
|
ApprovalWorkflowDefinition.objects.create(
|
|
3626
3580
|
name="Approval Definition",
|
|
3627
3581
|
model_content_type=ContentType.objects.get_for_model(ScheduledJob),
|
|
3628
|
-
|
|
3582
|
+
weight=0,
|
|
3629
3583
|
)
|
|
3630
3584
|
data = {
|
|
3631
3585
|
"_schedule_type": "future",
|
|
@@ -3765,14 +3719,12 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3765
3719
|
|
|
3766
3720
|
self.location_type = LocationType.objects.get(name="Campus")
|
|
3767
3721
|
|
|
3768
|
-
@tag("fix_in_v3")
|
|
3769
3722
|
def test_view_object_with_job_button(self):
|
|
3770
3723
|
"""Ensure that the job button is rendered."""
|
|
3771
3724
|
response = self.client.get(self.location_type.get_absolute_url(), follow=True)
|
|
3772
3725
|
self.assertBodyContains(response, f"JobButton {self.location_type.name}")
|
|
3773
3726
|
self.assertBodyContains(response, "Click me!")
|
|
3774
3727
|
|
|
3775
|
-
@tag("fix_in_v3")
|
|
3776
3728
|
def test_task_queue_hidden_input_is_present(self):
|
|
3777
3729
|
"""
|
|
3778
3730
|
Ensure that the job button respects the job class' task_queues and the job class default job queue is passed as a hidden form input.
|
|
@@ -3800,7 +3752,6 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3800
3752
|
f'<input type="hidden" name="_job_queue" value="{self.job.default_job_queue.pk}">', content, content
|
|
3801
3753
|
)
|
|
3802
3754
|
|
|
3803
|
-
@tag("fix_in_v3")
|
|
3804
3755
|
def test_view_object_with_unsafe_text(self):
|
|
3805
3756
|
"""Ensure that JobButton text can't be used as a vector for XSS."""
|
|
3806
3757
|
self.job_button_1.text = '<script>alert("Hello world!")</script>'
|
|
@@ -3820,7 +3771,6 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3820
3771
|
self.assertNotIn("<script>alert", content, content)
|
|
3821
3772
|
self.assertIn("<script>alert", content, content)
|
|
3822
3773
|
|
|
3823
|
-
@tag("fix_in_v3")
|
|
3824
3774
|
def test_view_object_with_unsafe_name(self):
|
|
3825
3775
|
"""Ensure that JobButton names can't be used as a vector for XSS."""
|
|
3826
3776
|
self.job_button_1.text = "JobButton {{ obj"
|
|
@@ -3832,7 +3782,6 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3832
3782
|
self.assertNotIn("<script>alert", content, content)
|
|
3833
3783
|
self.assertIn("<script>alert", content, content)
|
|
3834
3784
|
|
|
3835
|
-
@tag("fix_in_v3")
|
|
3836
3785
|
def test_render_constrained_run_permissions(self):
|
|
3837
3786
|
obj_perm = ObjectPermission(
|
|
3838
3787
|
name="Test permission",
|
|
@@ -3851,8 +3800,9 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3851
3800
|
NO_CONFIRM_BUTTON.format(
|
|
3852
3801
|
button_id=self.job_button_1.pk,
|
|
3853
3802
|
button_text=f"JobButton {self.location_type.name}",
|
|
3854
|
-
button_class=self.job_button_1.
|
|
3803
|
+
button_class=self.job_button_1.button_class_css_class,
|
|
3855
3804
|
disabled="",
|
|
3805
|
+
menu_item="",
|
|
3856
3806
|
),
|
|
3857
3807
|
content,
|
|
3858
3808
|
)
|
|
@@ -3860,8 +3810,9 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3860
3810
|
NO_CONFIRM_BUTTON.format(
|
|
3861
3811
|
button_id=self.job_button_2.pk,
|
|
3862
3812
|
button_text="Click me!",
|
|
3863
|
-
button_class=self.job_button_2.
|
|
3813
|
+
button_class=self.job_button_2.button_class_css_class,
|
|
3864
3814
|
disabled="disabled",
|
|
3815
|
+
menu_item="",
|
|
3865
3816
|
),
|
|
3866
3817
|
content,
|
|
3867
3818
|
)
|
|
@@ -3882,6 +3833,7 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3882
3833
|
button_text=f"JobButton {self.location_type.name}",
|
|
3883
3834
|
button_class="link",
|
|
3884
3835
|
disabled="",
|
|
3836
|
+
menu_item="dropdown-item",
|
|
3885
3837
|
)
|
|
3886
3838
|
+ "</li>",
|
|
3887
3839
|
content,
|
|
@@ -3893,12 +3845,14 @@ class JobButtonRenderingTestCase(TestCase):
|
|
|
3893
3845
|
button_text="Click me!",
|
|
3894
3846
|
button_class="link",
|
|
3895
3847
|
disabled="disabled",
|
|
3848
|
+
menu_item="dropdown-item",
|
|
3896
3849
|
)
|
|
3897
3850
|
+ "</li>",
|
|
3898
3851
|
content,
|
|
3899
3852
|
)
|
|
3900
3853
|
|
|
3901
3854
|
|
|
3855
|
+
@tag("example_app")
|
|
3902
3856
|
class JobCustomTemplateTestCase(TestCase):
|
|
3903
3857
|
@classmethod
|
|
3904
3858
|
def setUpTestData(cls):
|
|
@@ -4067,17 +4021,7 @@ class ObjectMetadataTestCase(
|
|
|
4067
4021
|
self.assertNotIn(instance2.assigned_object.get_absolute_url(), content, msg=content)
|
|
4068
4022
|
|
|
4069
4023
|
|
|
4070
|
-
class RelationshipTestCase(
|
|
4071
|
-
ViewTestCases.CreateObjectViewTestCase,
|
|
4072
|
-
ViewTestCases.DeleteObjectViewTestCase,
|
|
4073
|
-
ViewTestCases.EditObjectViewTestCase,
|
|
4074
|
-
ViewTestCases.BulkDeleteObjectsViewTestCase,
|
|
4075
|
-
ViewTestCases.GetObjectViewTestCase,
|
|
4076
|
-
ViewTestCases.GetObjectChangelogViewTestCase,
|
|
4077
|
-
ViewTestCases.ListObjectsViewTestCase,
|
|
4078
|
-
RequiredRelationshipTestMixin,
|
|
4079
|
-
ViewTestCases.BulkEditObjectsViewTestCase,
|
|
4080
|
-
):
|
|
4024
|
+
class RelationshipTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|
4081
4025
|
model = Relationship
|
|
4082
4026
|
slug_source = "label"
|
|
4083
4027
|
slugify_function = staticmethod(slugify_dashes_to_underscores)
|
|
@@ -4591,7 +4535,6 @@ class RoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTestCases
|
|
|
4591
4535
|
"remove_content_types": [device_ct.pk],
|
|
4592
4536
|
}
|
|
4593
4537
|
|
|
4594
|
-
@tag("fix_in_v3")
|
|
4595
4538
|
@override_settings(EXEMPT_VIEW_PERMISSIONS=["*"])
|
|
4596
4539
|
def test_view_with_content_types(self):
|
|
4597
4540
|
"""
|
|
@@ -4610,13 +4553,10 @@ class RoleTestCase(ViewTestCases.OrganizationalObjectViewTestCase, ViewTestCases
|
|
|
4610
4553
|
if content_type not in role_content_types:
|
|
4611
4554
|
if result == "Contact Associations":
|
|
4612
4555
|
# AssociationContact Table in the contact tab should be there.
|
|
4613
|
-
self.assertInHTML(
|
|
4614
|
-
|
|
4615
|
-
response_body,
|
|
4616
|
-
)
|
|
4617
|
-
# ContactAssociationTable related to this role instances should not be there.
|
|
4556
|
+
self.assertInHTML(f"<strong>{result}</strong>", response_body)
|
|
4557
|
+
# ContactAssociationTable related to this role instances in the main tab should not be there.
|
|
4618
4558
|
self.assertNotIn(
|
|
4619
|
-
f'<strong>{result}</strong>\n </div>\n \n\n<table class="table table-hover nb-table-headings"
|
|
4559
|
+
f'<strong>{result}</strong>\n </div>\n \n\n\n\n <table class="table table-hover nb-table-headings">',
|
|
4620
4560
|
response_body,
|
|
4621
4561
|
)
|
|
4622
4562
|
else:
|
nautobot/extras/urls.py
CHANGED
|
@@ -5,7 +5,6 @@ from nautobot.core.views.routers import NautobotUIViewSetRouter
|
|
|
5
5
|
from nautobot.extras import views
|
|
6
6
|
from nautobot.extras.models import (
|
|
7
7
|
Job,
|
|
8
|
-
Relationship,
|
|
9
8
|
ScheduledJob,
|
|
10
9
|
)
|
|
11
10
|
|
|
@@ -135,19 +134,6 @@ urlpatterns = [
|
|
|
135
134
|
name="scheduledjob_approvalworkflow",
|
|
136
135
|
kwargs={"model": ScheduledJob},
|
|
137
136
|
),
|
|
138
|
-
# Custom relationships
|
|
139
|
-
path(
|
|
140
|
-
"relationships/<uuid:pk>/changelog/",
|
|
141
|
-
views.ObjectChangeLogView.as_view(),
|
|
142
|
-
name="relationship_changelog",
|
|
143
|
-
kwargs={"model": Relationship},
|
|
144
|
-
),
|
|
145
|
-
path(
|
|
146
|
-
"relationships/<uuid:pk>/notes/",
|
|
147
|
-
views.ObjectNotesView.as_view(),
|
|
148
|
-
name="relationship_notes",
|
|
149
|
-
kwargs={"model": Relationship},
|
|
150
|
-
),
|
|
151
137
|
# Secrets
|
|
152
138
|
path(
|
|
153
139
|
"secrets/provider/<str:provider_slug>/form/",
|