nautobot 2.0.0a3__py3-none-any.whl → 2.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nautobot/apps/api.py +6 -8
- nautobot/apps/forms.py +0 -2
- nautobot/apps/ui.py +0 -8
- nautobot/circuits/api/serializers.py +9 -117
- nautobot/circuits/api/urls.py +1 -1
- nautobot/circuits/api/views.py +0 -1
- nautobot/circuits/forms.py +0 -65
- nautobot/circuits/migrations/0014_related_name_changes.py +1 -1
- nautobot/circuits/migrations/0016_tagsfield.py +34 -0
- nautobot/circuits/migrations/0017_fixup_null_statuses.py +22 -0
- nautobot/circuits/migrations/0018_status_nonnullable.py +22 -0
- nautobot/circuits/models.py +3 -87
- nautobot/circuits/navigation.py +14 -69
- nautobot/circuits/signals.py +0 -2
- nautobot/circuits/tables.py +39 -1
- nautobot/circuits/tests/integration/test_relationships.py +9 -9
- nautobot/circuits/tests/test_api.py +4 -8
- nautobot/circuits/tests/test_filters.py +10 -4
- nautobot/circuits/tests/test_models.py +5 -1
- nautobot/circuits/tests/test_views.py +27 -5
- nautobot/circuits/views.py +18 -10
- nautobot/core/api/__init__.py +8 -2
- nautobot/core/api/fields.py +15 -6
- nautobot/core/api/filter_backends.py +3 -2
- nautobot/core/api/metadata.py +237 -30
- nautobot/core/api/mixins.py +94 -0
- nautobot/core/api/pagination.py +4 -0
- nautobot/core/api/parsers.py +154 -0
- nautobot/core/api/renderers.py +153 -2
- nautobot/core/api/schema.py +46 -2
- nautobot/core/api/serializers.py +377 -35
- nautobot/core/api/urls.py +11 -3
- nautobot/core/api/utils.py +174 -2
- nautobot/core/api/versioning.py +32 -10
- nautobot/core/api/views.py +266 -72
- nautobot/core/apps/__init__.py +138 -220
- nautobot/core/celery/__init__.py +112 -41
- nautobot/core/celery/backends.py +19 -12
- nautobot/core/celery/control.py +46 -0
- nautobot/core/celery/encoders.py +53 -0
- nautobot/core/celery/log.py +38 -0
- nautobot/core/celery/schedulers.py +23 -4
- nautobot/core/celery/task.py +1 -16
- nautobot/core/checks.py +0 -27
- nautobot/core/choices.py +0 -113
- nautobot/core/{cli.py → cli/__init__.py} +1 -1
- nautobot/core/cli/__main__.py +3 -0
- nautobot/core/constants.py +0 -24
- nautobot/core/context_processors.py +12 -0
- nautobot/core/filters.py +2 -2
- nautobot/core/forms/__init__.py +0 -4
- nautobot/core/forms/fields.py +38 -65
- nautobot/core/forms/forms.py +4 -1
- nautobot/core/forms/utils.py +0 -52
- nautobot/core/graphql/schema.py +4 -27
- nautobot/core/jobs/__init__.py +75 -0
- nautobot/core/management/commands/build_ui.py +255 -0
- nautobot/core/management/commands/generate_test_data.py +3 -2
- nautobot/core/management/commands/post_upgrade.py +24 -24
- nautobot/core/models/__init__.py +26 -1
- nautobot/core/models/fields.py +24 -5
- nautobot/core/models/generics.py +2 -42
- nautobot/core/models/managers.py +5 -0
- nautobot/core/models/name_color_content_types.py +0 -14
- nautobot/core/models/tree_queries.py +14 -4
- nautobot/core/models/utils.py +5 -6
- nautobot/core/models/validators.py +17 -8
- nautobot/core/releases.py +8 -10
- nautobot/core/settings.py +80 -42
- nautobot/core/tables.py +5 -5
- nautobot/core/tasks.py +4 -7
- nautobot/core/templates/base.html +1 -49
- nautobot/core/templates/base_django.html +49 -0
- nautobot/core/templates/base_react.html +55 -0
- nautobot/core/templates/buttons/export.html +6 -4
- nautobot/core/templates/generic/object_bulk_create.html +10 -21
- nautobot/core/templates/generic/object_list.html +3 -1
- nautobot/core/templates/generic/object_retrieve_plugin_full_width.html +3 -0
- nautobot/core/templates/inc/footer.html +1 -0
- nautobot/core/templates/inc/javascript.html +0 -14
- nautobot/core/templates/inc/nav_menu.html +28 -33
- nautobot/core/templates/inc/object_details_advanced_panel.html +13 -0
- nautobot/core/templates/inc/relationships_table_rows.html +2 -2
- nautobot/core/templates/nautobot_config.py.j2 +8 -20
- nautobot/core/templates/plugin_template/__init__.py-tpl +1 -2
- nautobot/core/templates/rest_framework/api.html +8 -0
- nautobot/core/templatetags/buttons.py +32 -28
- nautobot/core/testing/__init__.py +47 -44
- nautobot/core/testing/api.py +362 -47
- nautobot/core/testing/filters.py +1 -1
- nautobot/core/testing/migrations.py +2 -0
- nautobot/core/testing/mixins.py +22 -9
- nautobot/core/testing/schema.py +2 -1
- nautobot/core/testing/views.py +21 -46
- nautobot/core/tests/integration/test_filters.py +17 -8
- nautobot/core/tests/integration/test_navbar.py +11 -34
- nautobot/core/tests/integration/test_plugin_navbar.py +9 -103
- nautobot/core/tests/nautobot_config.py +2 -3
- nautobot/core/tests/test_api.py +290 -21
- nautobot/core/tests/test_checks.py +0 -7
- nautobot/core/tests/test_filters.py +107 -59
- nautobot/core/tests/test_forms.py +26 -92
- nautobot/core/tests/test_graphql.py +110 -77
- nautobot/core/tests/test_logging.py +4 -0
- nautobot/core/tests/test_managers.py +3 -1
- nautobot/core/tests/test_models.py +2 -0
- nautobot/core/tests/test_paginator.py +3 -1
- nautobot/core/tests/test_releases.py +12 -12
- nautobot/core/tests/test_templatetags_helpers.py +4 -4
- nautobot/core/tests/test_utils.py +32 -68
- nautobot/core/tests/test_views.py +12 -15
- nautobot/core/utils/data.py +17 -0
- nautobot/core/utils/deprecation.py +9 -6
- nautobot/core/utils/filtering.py +8 -3
- nautobot/core/utils/git.py +12 -4
- nautobot/core/utils/lookup.py +3 -1
- nautobot/core/utils/requests.py +1 -104
- nautobot/core/views/__init__.py +1 -0
- nautobot/core/views/generic.py +75 -110
- nautobot/core/views/mixins.py +52 -61
- nautobot/core/views/renderers.py +6 -7
- nautobot/core/views/utils.py +80 -0
- nautobot/dcim/api/serializers.py +160 -667
- nautobot/dcim/api/urls.py +1 -1
- nautobot/dcim/api/views.py +7 -44
- nautobot/dcim/choices.py +2 -0
- nautobot/dcim/filters/__init__.py +21 -0
- nautobot/dcim/form_mixins.py +1 -27
- nautobot/dcim/forms.py +19 -765
- nautobot/dcim/migrations/0024_alter_device_and_rack_role_add_new_role.py +2 -1
- nautobot/dcim/migrations/0025_device_and_rack_roles_data_migrations.py +19 -13
- nautobot/dcim/migrations/0027_remove_device_role_and_rack_role.py +1 -1
- nautobot/dcim/migrations/0028_rename_foreignkey_fields.py +1 -1
- nautobot/dcim/migrations/0030_migrate_region_and_site_data_to_locations.py +2 -2
- nautobot/dcim/migrations/0035_related_name_changes.py +1 -1
- nautobot/dcim/migrations/0036_remove_region_and_site.py +1 -1
- nautobot/dcim/migrations/0040_tagsfield.py +109 -0
- nautobot/dcim/migrations/{0040_ipam__namespaces.py → 0041_ipam__namespaces.py} +1 -1
- nautobot/dcim/migrations/0042_fixup_null_statuses.py +51 -0
- nautobot/dcim/migrations/0043_status_nonnullable.py +72 -0
- nautobot/dcim/models/cables.py +3 -33
- nautobot/dcim/models/device_component_templates.py +6 -0
- nautobot/dcim/models/device_components.py +12 -198
- nautobot/dcim/models/devices.py +30 -143
- nautobot/dcim/models/locations.py +3 -64
- nautobot/dcim/models/power.py +3 -50
- nautobot/dcim/models/racks.py +7 -84
- nautobot/dcim/navigation.py +141 -467
- nautobot/dcim/signals.py +0 -2
- nautobot/dcim/tables/locations.py +2 -2
- nautobot/dcim/tables/power.py +1 -2
- nautobot/dcim/templates/dcim/console_port_connection_list.html +7 -0
- nautobot/dcim/templates/dcim/devicetype.html +2 -2
- nautobot/dcim/templates/dcim/interface_connection_list.html +7 -0
- nautobot/dcim/templates/dcim/location.html +16 -1
- nautobot/dcim/templates/dcim/locationtype.html +15 -0
- nautobot/dcim/templates/dcim/power_port_connection_list.html +7 -0
- nautobot/dcim/templates/dcim/rackgroup.html +0 -12
- nautobot/dcim/tests/test_api.py +166 -81
- nautobot/dcim/tests/test_cablepaths.py +41 -35
- nautobot/dcim/tests/test_filters.py +67 -23
- nautobot/dcim/tests/test_forms.py +5 -205
- nautobot/dcim/tests/test_graphql.py +7 -2
- nautobot/dcim/tests/test_migrations.py +6 -11
- nautobot/dcim/tests/test_models.py +182 -110
- nautobot/dcim/tests/test_natural_ordering.py +11 -8
- nautobot/dcim/tests/test_signals.py +6 -3
- nautobot/dcim/tests/test_views.py +197 -175
- nautobot/dcim/urls.py +11 -16
- nautobot/dcim/views.py +7 -134
- nautobot/docs/additional-features/caching.md +6 -87
- nautobot/docs/additional-features/job-scheduling-and-approvals.md +3 -0
- nautobot/docs/additional-features/jobs.md +177 -195
- nautobot/docs/administration/nautobot-server.md +6 -21
- nautobot/docs/administration/replicating-nautobot.md +0 -10
- nautobot/docs/configuration/optional-settings.md +32 -41
- nautobot/docs/configuration/required-settings.md +11 -52
- nautobot/docs/development/application-registry.md +2 -13
- nautobot/docs/development/extending-models.md +15 -17
- nautobot/docs/development/generic-views.md +0 -2
- nautobot/docs/development/getting-started.md +55 -5
- nautobot/docs/development/navigation-menu.md +22 -93
- nautobot/docs/development/react-ui.md +105 -0
- nautobot/docs/development/role-internals.md +1 -3
- nautobot/docs/development/style-guide.md +6 -4
- nautobot/docs/index.md +3 -2
- nautobot/docs/installation/migrating-from-netbox.md +11 -42
- nautobot/docs/installation/nautobot.md +1 -1
- nautobot/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
- nautobot/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
- nautobot/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
- nautobot/docs/installation/tables/v2-code-location-changes.yaml +241 -0
- nautobot/docs/installation/tables/v2-code-removals.yaml +67 -0
- nautobot/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
- nautobot/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
- nautobot/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
- nautobot/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
- nautobot/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
- nautobot/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
- nautobot/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
- nautobot/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
- nautobot/docs/installation/upgrading-from-nautobot-v1.md +170 -747
- nautobot/docs/models/dcim/device.md +3 -0
- nautobot/docs/models/dcim/deviceredundancygroup.md +3 -3
- nautobot/docs/models/extras/computedfield.md +4 -4
- nautobot/docs/models/extras/gitrepository.md +3 -0
- nautobot/docs/models/extras/job.md +1 -0
- nautobot/docs/models/extras/jobbutton.md +18 -13
- nautobot/docs/models/extras/jobhook.md +7 -4
- nautobot/docs/models/extras/jobresult.md +6 -2
- nautobot/docs/models/extras/relationship.md +2 -2
- nautobot/docs/models/extras/status.md +6 -19
- nautobot/docs/models/ipam/ipaddress.md +3 -0
- nautobot/docs/models/virtualization/virtualmachine.md +3 -0
- nautobot/docs/plugins/development.md +83 -21
- nautobot/docs/release-notes/version-1.5.md +53 -0
- nautobot/docs/release-notes/version-2.0.md +180 -0
- nautobot/docs/requirements.txt +1 -0
- nautobot/docs/rest-api/overview.md +384 -215
- nautobot/docs/rest-api/ui-related-endpoints.md +9 -0
- nautobot/extras/admin.py +3 -5
- nautobot/extras/api/customfields.py +15 -39
- nautobot/extras/api/fields.py +0 -11
- nautobot/extras/api/mixins.py +45 -0
- nautobot/extras/api/relationships.py +63 -158
- nautobot/extras/api/serializers.py +165 -700
- nautobot/extras/api/urls.py +1 -1
- nautobot/extras/api/views.py +294 -280
- nautobot/extras/apps.py +4 -7
- nautobot/extras/choices.py +11 -9
- nautobot/extras/constants.py +9 -3
- nautobot/extras/datasources/__init__.py +2 -0
- nautobot/extras/datasources/git.py +135 -186
- nautobot/extras/datasources/registry.py +25 -35
- nautobot/extras/filters/__init__.py +20 -19
- nautobot/extras/filters/mixins.py +4 -4
- nautobot/extras/forms/forms.py +63 -127
- nautobot/extras/forms/mixins.py +23 -51
- nautobot/extras/health_checks.py +0 -33
- nautobot/extras/jobs.py +387 -565
- nautobot/extras/management/commands/runjob.py +24 -62
- nautobot/extras/managers.py +30 -7
- nautobot/extras/migrations/0058_jobresult_add_time_status_idxs.py +38 -0
- nautobot/extras/migrations/{0058_joblogentry_scheduledjob_webhook_data_migration.py → 0059_joblogentry_scheduledjob_webhook_data_migration.py} +1 -1
- nautobot/extras/migrations/{0059_alter_joblogentry_scheduledjob_webhook_fields.py → 0060_alter_joblogentry_scheduledjob_webhook_fields.py} +1 -1
- nautobot/extras/migrations/{0060_role_and_alter_status.py → 0061_role_and_alter_status.py} +1 -7
- nautobot/extras/migrations/{0061_collect_roles_from_related_apps_roles.py → 0062_collect_roles_from_related_apps_roles.py} +33 -32
- nautobot/extras/migrations/{0062_alter_role_options.py → 0063_alter_role_options.py} +1 -1
- nautobot/extras/migrations/{0063_alter_configcontext_and_add_new_role.py → 0064_alter_configcontext_and_add_new_role.py} +1 -1
- nautobot/extras/migrations/0065_configcontext_data_migrations.py +44 -0
- nautobot/extras/migrations/{0065_rename_configcontext_role.py → 0066_rename_configcontext_role.py} +1 -1
- nautobot/extras/migrations/{0066_jobresult__add_celery_fields.py → 0067_jobresult__add_celery_fields.py} +36 -2
- nautobot/extras/migrations/{0067_created_datetime.py → 0068_created_datetime.py} +1 -1
- nautobot/extras/migrations/{0068_remove_site_and_region_attributes_from_config_context.py → 0069_remove_site_and_region_attributes_from_config_context.py} +1 -1
- nautobot/extras/migrations/{0069_replace_related_names.py → 0070_replace_related_names.py} +1 -1
- nautobot/extras/migrations/{0070_rename_model_fields.py → 0071_rename_model_fields.py} +1 -1
- nautobot/extras/migrations/0072_job__unique_name_data_migration.py +86 -0
- nautobot/extras/migrations/{0072_job__unique_name.py → 0073_job__unique_name.py} +13 -9
- nautobot/extras/migrations/{0073_remove_gitrepository_fields.py → 0074_remove_gitrepository_fields.py} +1 -1
- nautobot/extras/migrations/{0074_rename_slug_to_key_for_custom_field.py → 0075_rename_slug_to_key_for_custom_field.py} +1 -1
- nautobot/extras/migrations/{0075_migrate_custom_field_data.py → 0076_migrate_custom_field_data.py} +1 -1
- nautobot/extras/migrations/{0076_remove_name_field_and_make_label_field_non_nullable.py → 0077_remove_name_field_and_make_label_field_non_nullable.py} +1 -1
- nautobot/extras/migrations/{0077_remove_slug.py → 0078_remove_slug.py} +1 -5
- nautobot/extras/migrations/0079_tagsfield.py +28 -0
- nautobot/extras/migrations/0080_rename_relationship_slug_to_key.py +17 -0
- nautobot/extras/migrations/0081_rename_relationship_name_to_label.py +29 -0
- nautobot/extras/migrations/0082_ensure_relationship_keys_are_unique.py +43 -0
- nautobot/extras/migrations/0083_rename_computed_field_slug_to_key.py +21 -0
- nautobot/extras/migrations/0084_taggeditem_cleanup.py +43 -0
- nautobot/extras/migrations/0085_taggeditem_uniqueness.py +22 -0
- nautobot/extras/migrations/0086_job__celery_task_fields__dryrun_support.py +81 -0
- nautobot/extras/migrations/0087_job__commit_default_data_migration.py +26 -0
- nautobot/extras/migrations/0088_joblogentry__log_level_default.py +17 -0
- nautobot/extras/migrations/0089_joblogentry__log_level_data_migration.py +34 -0
- nautobot/extras/migrations/0090_scheduledjob__data_migration.py +57 -0
- nautobot/extras/models/__init__.py +2 -3
- nautobot/extras/models/change_logging.py +0 -36
- nautobot/extras/models/customfields.py +39 -33
- nautobot/extras/models/datasources.py +48 -50
- nautobot/extras/models/groups.py +5 -6
- nautobot/extras/models/jobs.py +189 -321
- nautobot/extras/models/mixins.py +0 -71
- nautobot/extras/models/models.py +0 -19
- nautobot/extras/models/relationships.py +19 -13
- nautobot/extras/models/roles.py +0 -34
- nautobot/extras/models/secrets.py +2 -26
- nautobot/extras/models/statuses.py +6 -5
- nautobot/extras/models/tags.py +2 -17
- nautobot/extras/navigation.py +89 -307
- nautobot/extras/plugins/__init__.py +3 -120
- nautobot/extras/plugins/utils.py +0 -3
- nautobot/extras/plugins/validators.py +5 -4
- nautobot/extras/plugins/views.py +16 -3
- nautobot/extras/querysets.py +1 -7
- nautobot/extras/registry.py +3 -0
- nautobot/extras/signals.py +26 -60
- nautobot/extras/tables.py +34 -40
- nautobot/extras/tasks.py +0 -12
- nautobot/extras/templates/extras/configcontext.html +1 -1
- nautobot/extras/templates/extras/configcontextschema.html +16 -1
- nautobot/extras/templates/extras/customfield.html +0 -13
- nautobot/extras/templates/extras/gitrepository.html +3 -3
- nautobot/extras/templates/extras/inc/jobresult.html +10 -0
- nautobot/extras/templates/extras/inc/panel_jobhistory.html +1 -1
- nautobot/extras/templates/extras/job.html +35 -25
- nautobot/extras/templates/extras/job_approval_request.html +15 -30
- nautobot/extras/templates/extras/job_detail.html +13 -31
- nautobot/extras/templates/extras/job_edit.html +15 -17
- nautobot/extras/templates/extras/jobresult.html +24 -6
- nautobot/extras/templates/extras/scheduledjob.html +2 -2
- nautobot/extras/templates/extras/secret.html +28 -0
- nautobot/extras/templatetags/job_buttons.py +1 -0
- nautobot/extras/{tests/example_jobs → test_jobs}/api_test_job.py +13 -6
- nautobot/extras/test_jobs/atomic_transaction.py +53 -0
- nautobot/extras/test_jobs/dry_run.py +29 -0
- nautobot/extras/{tests/example_jobs/test_duplicate_name.py → test_jobs/duplicate_name.py} +4 -0
- nautobot/extras/test_jobs/duplicate_name2.py +9 -0
- nautobot/extras/test_jobs/fail.py +23 -0
- nautobot/extras/{tests/example_jobs/test_field_default.py → test_jobs/field_default.py} +4 -0
- nautobot/extras/{tests/example_jobs/test_field_order.py → test_jobs/field_order.py} +4 -0
- nautobot/extras/{tests/example_jobs/test_file_upload_fail.py → test_jobs/file_upload_fail.py} +11 -6
- nautobot/extras/test_jobs/file_upload_pass.py +25 -0
- nautobot/extras/test_jobs/has_sensitive_variables.py +25 -0
- nautobot/extras/test_jobs/ipaddress_vars.py +66 -0
- nautobot/extras/test_jobs/job_button_receiver.py +28 -0
- nautobot/extras/test_jobs/job_hook_receiver.py +29 -0
- nautobot/extras/test_jobs/job_variables.py +88 -0
- nautobot/extras/test_jobs/location_with_custom_field.py +45 -0
- nautobot/extras/test_jobs/log_redaction.py +20 -0
- nautobot/extras/test_jobs/log_skip_db_logging.py +17 -0
- nautobot/extras/test_jobs/modify_db.py +25 -0
- nautobot/extras/{tests/example_jobs/test_no_field_order.py → test_jobs/no_field_order.py} +4 -0
- nautobot/extras/test_jobs/object_var_optional.py +21 -0
- nautobot/extras/test_jobs/object_var_required.py +21 -0
- nautobot/extras/test_jobs/object_vars.py +26 -0
- nautobot/extras/test_jobs/pass.py +25 -0
- nautobot/extras/test_jobs/profiling.py +32 -0
- nautobot/extras/test_jobs/read_only_job.py +15 -0
- nautobot/extras/{tests/example_jobs/test_required_args.py → test_jobs/required_args.py} +4 -0
- nautobot/extras/{tests/example_jobs/test_soft_time_limit_greater_than_time_limit.py → test_jobs/soft_time_limit_greater_than_time_limit.py} +5 -1
- nautobot/extras/{tests/example_jobs/test_task_queues.py → test_jobs/task_queues.py} +5 -1
- nautobot/extras/tests/integration/test_computedfields.py +1 -1
- nautobot/extras/tests/integration/test_configcontextschema.py +5 -3
- nautobot/extras/tests/integration/test_customfields.py +4 -2
- nautobot/extras/tests/integration/test_dynamicgroups.py +1 -1
- nautobot/extras/tests/integration/test_jobs.py +25 -27
- nautobot/extras/tests/integration/test_notes.py +8 -4
- nautobot/extras/tests/integration/test_relationships.py +2 -2
- nautobot/extras/tests/test_api.py +649 -642
- nautobot/extras/tests/test_changelog.py +3 -3
- nautobot/extras/tests/test_context_managers.py +5 -3
- nautobot/extras/tests/test_customfields.py +92 -50
- nautobot/extras/tests/test_datasources.py +189 -112
- nautobot/extras/tests/test_dynamicgroups.py +7 -8
- nautobot/extras/tests/test_filters.py +137 -89
- nautobot/extras/tests/test_forms.py +73 -75
- nautobot/extras/tests/{test_scripts.py → test_job_variables.py} +43 -49
- nautobot/extras/tests/test_jobs.py +262 -263
- nautobot/extras/tests/test_migrations.py +4 -3
- nautobot/extras/tests/test_models.py +116 -161
- nautobot/extras/tests/test_plugins.py +38 -60
- nautobot/extras/tests/test_relationships.py +167 -120
- nautobot/extras/tests/test_tags.py +6 -11
- nautobot/extras/tests/test_utils.py +31 -1
- nautobot/extras/tests/test_views.py +201 -145
- nautobot/extras/tests/test_webhooks.py +6 -2
- nautobot/extras/urls.py +42 -42
- nautobot/extras/utils.py +137 -163
- nautobot/extras/views.py +78 -152
- nautobot/ipam/api/fields.py +17 -0
- nautobot/ipam/api/serializers.py +58 -164
- nautobot/ipam/api/urls.py +1 -1
- nautobot/ipam/api/views.py +3 -2
- nautobot/ipam/apps.py +1 -2
- nautobot/ipam/filters.py +1 -10
- nautobot/ipam/forms.py +4 -177
- nautobot/ipam/lookups.py +1 -0
- nautobot/ipam/management/commands/__init__.py +0 -0
- nautobot/ipam/management/commands/fix_prefix_broadcast.py +17 -0
- nautobot/ipam/migrations/0010_alter_ipam_role_add_new_role.py +1 -1
- nautobot/ipam/migrations/0011_migrate_ipam_role_data.py +32 -38
- nautobot/ipam/migrations/0020_related_name_changes.py +1 -1
- nautobot/ipam/migrations/0022_aggregate_to_prefix_data_migration.py +2 -2
- nautobot/ipam/migrations/0028_tagsfield.py +44 -0
- nautobot/ipam/migrations/0029_ip_address_to_interface_uniqueness_constraints.py +18 -0
- nautobot/ipam/migrations/{0028_ipam__namespaces.py → 0030_ipam__namespaces.py} +77 -28
- nautobot/ipam/migrations/0031_ipam__prefix__add_parent.py +58 -0
- nautobot/ipam/migrations/0032_ipam__namespaces_finish.py +63 -0
- nautobot/ipam/migrations/0033_fixup_null_statuses.py +26 -0
- nautobot/ipam/migrations/0034_status_nonnullable.py +36 -0
- nautobot/ipam/models.py +100 -236
- nautobot/ipam/navigation.py +36 -181
- nautobot/ipam/querysets.py +20 -25
- nautobot/ipam/signals.py +49 -6
- nautobot/ipam/tables.py +10 -3
- nautobot/ipam/templates/ipam/namespace_ipaddresses.html +11 -0
- nautobot/ipam/templates/ipam/namespace_prefixes.html +11 -0
- nautobot/ipam/templates/ipam/namespace_retrieve.html +17 -4
- nautobot/ipam/templates/ipam/namespace_vrfs.html +11 -0
- nautobot/ipam/templates/ipam/prefix.html +1 -1
- nautobot/ipam/templates/ipam/vlangroup.html +0 -13
- nautobot/ipam/templates/ipam/vrf_edit.html +6 -0
- nautobot/ipam/tests/integration/test_prefixes.py +3 -26
- nautobot/ipam/tests/test_api.py +22 -19
- nautobot/ipam/tests/test_filters.py +59 -23
- nautobot/ipam/tests/test_migrations.py +6 -10
- nautobot/ipam/tests/test_models.py +323 -198
- nautobot/ipam/tests/test_ordering.py +2 -2
- nautobot/ipam/tests/test_querysets.py +44 -24
- nautobot/ipam/tests/test_views.py +73 -26
- nautobot/ipam/urls.py +16 -0
- nautobot/ipam/{utils.py → utils/__init__.py} +2 -2
- nautobot/ipam/utils/migrations.py +713 -0
- nautobot/ipam/views.py +137 -20
- nautobot/project-static/docs/404.html +1178 -10
- nautobot/project-static/docs/additional-features/caching.html +1224 -159
- nautobot/project-static/docs/additional-features/change-logging.html +1180 -12
- nautobot/project-static/docs/additional-features/config-contexts.html +1180 -12
- nautobot/project-static/docs/additional-features/graphql.html +1179 -11
- nautobot/project-static/docs/additional-features/healthcheck.html +1180 -12
- nautobot/project-static/docs/additional-features/job-scheduling-and-approvals.html +1184 -12
- nautobot/project-static/docs/additional-features/jobs.html +1514 -328
- nautobot/project-static/docs/additional-features/napalm.html +1180 -12
- nautobot/project-static/docs/additional-features/prometheus-metrics.html +1180 -12
- nautobot/project-static/docs/additional-features/template-filters.html +1180 -12
- nautobot/project-static/docs/administration/celery-queues.html +1178 -10
- nautobot/project-static/docs/administration/nautobot-server.html +1451 -304
- nautobot/project-static/docs/administration/nautobot-shell.html +1178 -10
- nautobot/project-static/docs/administration/permissions.html +1178 -10
- nautobot/project-static/docs/administration/replicating-nautobot.html +1262 -113
- nautobot/project-static/docs/apps/index.html +1178 -10
- nautobot/project-static/docs/apps/nautobot-apps.html +1178 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +1580 -426
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +1178 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +3481 -1838
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +1178 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +1178 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +1185 -11
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +1719 -551
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +2062 -930
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +1946 -659
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +1180 -12
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +1189 -21
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +9283 -6218
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +2734 -2122
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +1178 -10
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +2337 -1300
- nautobot/project-static/docs/configuration/authentication/ldap.html +1178 -10
- nautobot/project-static/docs/configuration/authentication/remote.html +1178 -10
- nautobot/project-static/docs/configuration/authentication/sso.html +1178 -10
- nautobot/project-static/docs/configuration/index.html +1178 -10
- nautobot/project-static/docs/configuration/optional-settings.html +1311 -160
- nautobot/project-static/docs/configuration/required-settings.html +1312 -211
- nautobot/project-static/docs/core-functionality/circuits.html +1178 -10
- nautobot/project-static/docs/core-functionality/device-types.html +1178 -10
- nautobot/project-static/docs/core-functionality/devices.html +1182 -10
- nautobot/project-static/docs/core-functionality/ipam.html +1182 -10
- nautobot/project-static/docs/core-functionality/power.html +1178 -10
- nautobot/project-static/docs/core-functionality/secrets.html +1178 -10
- nautobot/project-static/docs/core-functionality/services.html +1178 -10
- nautobot/project-static/docs/core-functionality/sites-and-racks.html +1178 -10
- nautobot/project-static/docs/core-functionality/tenancy.html +1178 -10
- nautobot/project-static/docs/core-functionality/virtualization.html +1182 -10
- nautobot/project-static/docs/core-functionality/vlans.html +1179 -11
- nautobot/project-static/docs/development/application-registry.html +1190 -42
- nautobot/project-static/docs/development/best-practices.html +1178 -10
- nautobot/project-static/docs/development/docker-compose-advanced-use-cases.html +1178 -10
- nautobot/project-static/docs/development/extending-models.html +1238 -83
- nautobot/project-static/docs/development/generic-views.html +1180 -14
- nautobot/project-static/docs/development/getting-started.html +1365 -90
- nautobot/project-static/docs/development/homepage.html +1178 -10
- nautobot/project-static/docs/development/index.html +1178 -10
- nautobot/project-static/docs/development/model-features.html +1178 -10
- nautobot/project-static/docs/development/natural-keys.html +1178 -10
- nautobot/project-static/docs/development/navigation-menu.html +1215 -125
- nautobot/project-static/docs/development/react-ui.html +4199 -0
- nautobot/project-static/docs/development/release-checklist.html +1178 -10
- nautobot/project-static/docs/development/role-internals.html +1179 -12
- nautobot/project-static/docs/development/style-guide.html +1188 -19
- nautobot/project-static/docs/development/templates.html +1178 -10
- nautobot/project-static/docs/development/testing.html +1178 -10
- nautobot/project-static/docs/development/user-preferences.html +1178 -10
- nautobot/project-static/docs/docker/index.html +1178 -10
- nautobot/project-static/docs/index.html +1183 -12
- nautobot/project-static/docs/installation/centos.html +1178 -10
- nautobot/project-static/docs/installation/external-authentication.html +1178 -10
- nautobot/project-static/docs/installation/http-server.html +1178 -10
- nautobot/project-static/docs/installation/index.html +1178 -10
- nautobot/project-static/docs/installation/migrating-from-netbox.html +1305 -189
- nautobot/project-static/docs/installation/migrating-from-postgresql.html +1178 -10
- nautobot/project-static/docs/installation/nautobot.html +1179 -11
- nautobot/project-static/docs/installation/region-and-site-data-migration-guide.html +1178 -10
- nautobot/project-static/docs/installation/selinux-troubleshooting.html +1178 -10
- nautobot/project-static/docs/installation/services.html +1178 -10
- nautobot/project-static/docs/installation/tables/v2-api-behavior-changes.yaml +70 -0
- nautobot/project-static/docs/installation/tables/v2-api-removed-fields.yaml +142 -0
- nautobot/project-static/docs/installation/tables/v2-api-renamed-fields.yaml +124 -0
- nautobot/project-static/docs/installation/tables/v2-code-location-changes.yaml +241 -0
- nautobot/project-static/docs/installation/tables/v2-code-removals.yaml +67 -0
- nautobot/project-static/docs/installation/tables/v2-database-behavior-changes.yaml +37 -0
- nautobot/project-static/docs/installation/tables/v2-database-removed-fields.yaml +166 -0
- nautobot/project-static/docs/installation/tables/v2-database-renamed-fields.yaml +340 -0
- nautobot/project-static/docs/installation/tables/v2-filters-corrected-fields.yaml +28 -0
- nautobot/project-static/docs/installation/tables/v2-filters-enhanced-fields.yaml +241 -0
- nautobot/project-static/docs/installation/tables/v2-filters-removed-fields.yaml +553 -0
- nautobot/project-static/docs/installation/tables/v2-filters-renamed-fields.yaml +223 -0
- nautobot/project-static/docs/installation/tables/v2-logging-renamed-loggers.yaml +23 -0
- nautobot/project-static/docs/installation/ubuntu.html +1178 -10
- nautobot/project-static/docs/installation/upgrading-from-nautobot-v1.html +3823 -2152
- nautobot/project-static/docs/installation/upgrading.html +1178 -10
- nautobot/project-static/docs/models/circuits/circuit.html +1293 -103
- nautobot/project-static/docs/models/circuits/circuittermination.html +1293 -103
- nautobot/project-static/docs/models/circuits/circuittype.html +1293 -103
- nautobot/project-static/docs/models/circuits/provider.html +1293 -103
- nautobot/project-static/docs/models/circuits/providernetwork.html +1293 -103
- nautobot/project-static/docs/models/dcim/cable.html +1324 -103
- nautobot/project-static/docs/models/dcim/consoleport.html +1293 -103
- nautobot/project-static/docs/models/dcim/consoleporttemplate.html +1293 -103
- nautobot/project-static/docs/models/dcim/consoleserverport.html +1293 -103
- nautobot/project-static/docs/models/dcim/consoleserverporttemplate.html +1293 -103
- nautobot/project-static/docs/models/dcim/device.html +1326 -132
- nautobot/project-static/docs/models/dcim/devicebay.html +1293 -103
- nautobot/project-static/docs/models/dcim/devicebaytemplate.html +1293 -103
- nautobot/project-static/docs/models/dcim/deviceredundancygroup.html +1379 -97
- nautobot/project-static/docs/models/dcim/devicetype.html +1293 -103
- nautobot/project-static/docs/models/dcim/frontport.html +1293 -103
- nautobot/project-static/docs/models/dcim/frontporttemplate.html +1293 -103
- nautobot/project-static/docs/models/dcim/interface.html +1293 -103
- nautobot/project-static/docs/models/dcim/interfacetemplate.html +1293 -103
- nautobot/project-static/docs/models/dcim/inventoryitem.html +1293 -103
- nautobot/project-static/docs/models/dcim/location.html +1293 -103
- nautobot/project-static/docs/models/dcim/locationtype.html +1293 -103
- nautobot/project-static/docs/models/dcim/manufacturer.html +1292 -102
- nautobot/project-static/docs/models/dcim/platform.html +1272 -82
- nautobot/project-static/docs/models/dcim/powerfeed.html +1270 -80
- nautobot/project-static/docs/models/dcim/poweroutlet.html +1272 -82
- nautobot/project-static/docs/models/dcim/poweroutlettemplate.html +1272 -82
- nautobot/project-static/docs/models/dcim/powerpanel.html +1270 -80
- nautobot/project-static/docs/models/dcim/powerport.html +1272 -82
- nautobot/project-static/docs/models/dcim/powerporttemplate.html +1272 -82
- nautobot/project-static/docs/models/dcim/rack.html +1272 -82
- nautobot/project-static/docs/models/dcim/rackgroup.html +1272 -82
- nautobot/project-static/docs/models/dcim/rackreservation.html +1272 -82
- nautobot/project-static/docs/models/dcim/rearport.html +1286 -96
- nautobot/project-static/docs/models/dcim/rearporttemplate.html +1286 -96
- nautobot/project-static/docs/models/dcim/region.html +1178 -10
- nautobot/project-static/docs/models/dcim/site.html +1178 -10
- nautobot/project-static/docs/models/dcim/virtualchassis.html +1284 -94
- nautobot/project-static/docs/models/extras/computedfield.html +1184 -16
- nautobot/project-static/docs/models/extras/configcontext.html +1314 -86
- nautobot/project-static/docs/models/extras/configcontextschema.html +1276 -86
- nautobot/project-static/docs/models/extras/customfield.html +1180 -12
- nautobot/project-static/docs/models/extras/customlink.html +1180 -12
- nautobot/project-static/docs/models/extras/dynamicgroup.html +1180 -12
- nautobot/project-static/docs/models/extras/exporttemplate.html +1180 -12
- nautobot/project-static/docs/models/extras/gitrepository.html +1184 -12
- nautobot/project-static/docs/models/extras/graphqlquery.html +1321 -86
- nautobot/project-static/docs/models/extras/imageattachment.html +1276 -86
- nautobot/project-static/docs/models/extras/job.html +1277 -86
- nautobot/project-static/docs/models/extras/jobbutton.html +1201 -29
- nautobot/project-static/docs/models/extras/jobhook.html +1188 -16
- nautobot/project-static/docs/models/extras/joblogentry.html +1274 -84
- nautobot/project-static/docs/models/extras/jobresult.html +1364 -169
- nautobot/project-static/docs/models/extras/note.html +1180 -12
- nautobot/project-static/docs/models/extras/relationship.html +1182 -14
- nautobot/project-static/docs/models/extras/role.html +1320 -86
- nautobot/project-static/docs/models/extras/secret.html +1314 -86
- nautobot/project-static/docs/models/extras/secretsgroup.html +1276 -86
- nautobot/project-static/docs/models/extras/status.html +1188 -59
- nautobot/project-static/docs/models/extras/tag.html +1180 -12
- nautobot/project-static/docs/models/extras/webhook.html +1180 -12
- nautobot/project-static/docs/models/ipam/ipaddress.html +1327 -102
- nautobot/project-static/docs/models/ipam/prefix.html +1276 -86
- nautobot/project-static/docs/models/ipam/rir.html +1276 -86
- nautobot/project-static/docs/models/ipam/routetarget.html +1276 -86
- nautobot/project-static/docs/models/ipam/service.html +1276 -86
- nautobot/project-static/docs/models/ipam/vlan.html +1276 -86
- nautobot/project-static/docs/models/ipam/vlangroup.html +1276 -86
- nautobot/project-static/docs/models/ipam/vrf.html +1276 -86
- nautobot/project-static/docs/models/tenancy/tenant.html +1276 -86
- nautobot/project-static/docs/models/tenancy/tenantgroup.html +1276 -86
- nautobot/project-static/docs/models/users/objectpermission.html +1314 -86
- nautobot/project-static/docs/models/users/token.html +1276 -86
- nautobot/project-static/docs/models/virtualization/cluster.html +1276 -86
- nautobot/project-static/docs/models/virtualization/clustergroup.html +1276 -86
- nautobot/project-static/docs/models/virtualization/clustertype.html +1276 -86
- nautobot/project-static/docs/models/virtualization/virtualmachine.html +1321 -127
- nautobot/project-static/docs/models/virtualization/vminterface.html +1276 -86
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/plugins/development.html +1726 -495
- nautobot/project-static/docs/plugins/index.html +1178 -10
- nautobot/project-static/docs/plugins/porting-from-netbox.html +1178 -10
- nautobot/project-static/docs/release-notes/index.html +1178 -10
- nautobot/project-static/docs/release-notes/version-1.0.html +1178 -10
- nautobot/project-static/docs/release-notes/version-1.1.html +1178 -10
- nautobot/project-static/docs/release-notes/version-1.2.html +1178 -10
- nautobot/project-static/docs/release-notes/version-1.3.html +1178 -10
- nautobot/project-static/docs/release-notes/version-1.4.html +1178 -10
- nautobot/project-static/docs/release-notes/version-1.5.html +1608 -225
- nautobot/project-static/docs/release-notes/version-2.0.html +1547 -47
- nautobot/project-static/docs/requirements.txt +1 -0
- nautobot/project-static/docs/rest-api/authentication.html +1179 -11
- nautobot/project-static/docs/rest-api/filtering.html +1178 -10
- nautobot/project-static/docs/rest-api/overview.html +1841 -446
- nautobot/project-static/docs/rest-api/ui-related-endpoints.html +4057 -0
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +197 -187
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guides/custom-fields.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/creating-devices.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/index.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/interfaces.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/ipam.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/platforms.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/regions.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/search-bar.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/tenants.html +1178 -10
- nautobot/project-static/docs/user-guides/getting-started/vlans-and-vlan-groups.html +1178 -10
- nautobot/project-static/docs/user-guides/git-data-source.html +1178 -10
- nautobot/project-static/docs/user-guides/graphql.html +1178 -10
- nautobot/project-static/docs/user-guides/relationships.html +1178 -10
- nautobot/project-static/docs/user-guides/s3-django-storage.html +1178 -10
- nautobot/project-static/js/forms.js +16 -9
- nautobot/project-static/js/theme.js +5 -0
- nautobot/tenancy/api/serializers.py +4 -32
- nautobot/tenancy/api/urls.py +1 -1
- nautobot/tenancy/forms.py +0 -28
- nautobot/tenancy/migrations/0008_tagsfield.py +19 -0
- nautobot/tenancy/models.py +0 -25
- nautobot/tenancy/navigation.py +6 -39
- nautobot/tenancy/templates/tenancy/tenant.html +12 -12
- nautobot/tenancy/templates/tenancy/tenantgroup.html +1 -1
- nautobot/tenancy/tests/test_api.py +1 -3
- nautobot/tenancy/tests/test_filters.py +10 -5
- nautobot/tenancy/views.py +0 -2
- nautobot/ui/.eslintignore +6 -0
- nautobot/ui/.gitignore +10 -0
- nautobot/ui/.prettierignore +9 -0
- nautobot/ui/.prettierrc +4 -0
- nautobot/ui/README.md +33 -0
- nautobot/ui/app_imports.js.j2 +7 -0
- nautobot/ui/craco.config.js +46 -0
- nautobot/ui/jsconfig-base.json +11 -0
- nautobot/ui/jsconfig.json +5 -0
- nautobot/ui/lib/nautobot-craco-alias-plugin.js +40 -0
- nautobot/ui/package-lock.json +21451 -0
- nautobot/ui/package.json +70 -0
- nautobot/ui/public/index.html +47 -0
- nautobot/ui/public/logo192.png +0 -0
- nautobot/ui/public/logo512.png +0 -0
- nautobot/ui/public/manifest.json +25 -0
- nautobot/ui/public/nautobot_logo.svg +131 -0
- nautobot/ui/public/robots.txt +3 -0
- nautobot/ui/src/App.js +71 -0
- nautobot/ui/src/components/AppFullWidthComponents.js +8 -0
- nautobot/ui/src/components/AppTab.js +40 -0
- nautobot/ui/src/components/Apps.js +60 -0
- nautobot/ui/src/components/HomeChangelogPanel.js +98 -0
- nautobot/ui/src/components/HomePanel.js +58 -0
- nautobot/ui/src/components/JobHistoryTable.js +78 -0
- nautobot/ui/src/components/Layout.js +53 -0
- nautobot/ui/src/components/LoadingWidget.js +25 -0
- nautobot/ui/src/components/Navbar.js +116 -0
- nautobot/ui/src/components/NotificationPopover.js +27 -0
- nautobot/ui/src/components/ObjectListTable.js +209 -0
- nautobot/ui/src/components/ReferenceDataTag.js +35 -0
- nautobot/ui/src/components/RouterButton.js +10 -0
- nautobot/ui/src/components/RouterLink.js +10 -0
- nautobot/ui/src/components/SidebarNav.js +147 -0
- nautobot/ui/src/components/Table.js +48 -0
- nautobot/ui/src/components/TableItem.js +71 -0
- nautobot/ui/src/components/__tests__/AppFullWidthComponents.test.js +16 -0
- nautobot/ui/src/components/__tests__/AppTab.test.js +21 -0
- nautobot/ui/src/components/__tests__/Apps.test.js +14 -0
- nautobot/ui/src/components/__tests__/Layout.test.js +33 -0
- nautobot/ui/src/components/__tests__/Table.test.js +36 -0
- nautobot/ui/src/components/__tests__/TableItem.test.js +37 -0
- nautobot/ui/src/components/__tests__/paginator.test.js +43 -0
- nautobot/ui/src/components/__tests__/paginator_form.test.js +13 -0
- nautobot/ui/src/components/pagination.js +93 -0
- nautobot/ui/src/components/paginator.js +79 -0
- nautobot/ui/src/components/paginator_form.js +43 -0
- nautobot/ui/src/components/usePagination.js +57 -0
- nautobot/ui/src/constants/apiPath.js +10 -0
- nautobot/ui/src/constants/icons.js +15 -0
- nautobot/ui/src/constants/size.js +15 -0
- nautobot/ui/src/index.js +65 -0
- nautobot/ui/src/reportWebVitals.js +15 -0
- nautobot/ui/src/router.js +77 -0
- nautobot/ui/src/utils/api.js +131 -0
- nautobot/ui/src/utils/app-import.js +15 -0
- nautobot/ui/src/utils/color.js +15 -0
- nautobot/ui/src/utils/date.js +14 -0
- nautobot/ui/src/utils/index.js +15 -0
- nautobot/ui/src/utils/navigation.js +32 -0
- nautobot/ui/src/utils/session.js +64 -0
- nautobot/ui/src/utils/store.js +242 -0
- nautobot/ui/src/utils/string.js +6 -0
- nautobot/ui/src/utils/url.js +4 -0
- nautobot/ui/src/views/Home.js +138 -0
- nautobot/ui/src/views/InstalledApps.js +80 -0
- nautobot/ui/src/views/Login.js +48 -0
- nautobot/ui/src/views/Logout.js +20 -0
- nautobot/ui/src/views/__tests__/BSCreateViewTemplate.test.js +11 -0
- nautobot/ui/src/views/__tests__/BSListViewTemplate.test.js +107 -0
- nautobot/ui/src/views/__tests__/Login.test.js +15 -0
- nautobot/ui/src/views/generic/GenericView.js +142 -0
- nautobot/ui/src/views/generic/ObjectCreate.js +96 -0
- nautobot/ui/src/views/generic/ObjectList.js +127 -0
- nautobot/ui/src/views/generic/ObjectRetrieve.js +551 -0
- nautobot/users/admin.py +1 -1
- nautobot/users/api/serializers.py +51 -61
- nautobot/users/api/urls.py +1 -1
- nautobot/users/api/views.py +53 -2
- nautobot/users/tests/test_api.py +110 -25
- nautobot/virtualization/api/serializers.py +18 -130
- nautobot/virtualization/api/urls.py +1 -1
- nautobot/virtualization/api/views.py +1 -22
- nautobot/virtualization/forms.py +13 -99
- nautobot/virtualization/migrations/0012_alter_virtualmachine_role_add_new_role.py +1 -1
- nautobot/virtualization/migrations/0013_migrate_virtualmachine_role_data.py +18 -11
- nautobot/virtualization/migrations/0015_rename_foreignkey_fields.py +1 -1
- nautobot/virtualization/migrations/0018_related_name_changes.py +1 -1
- nautobot/virtualization/migrations/0021_tagsfield_and_vminterface_to_primarymodel.py +39 -0
- nautobot/virtualization/migrations/0022_vminterface_timestamps_data_migration.py +17 -0
- nautobot/virtualization/migrations/{0021_ipam__namespaces.py → 0023_ipam__namespaces.py} +2 -2
- nautobot/virtualization/migrations/0024_fixup_null_statuses.py +25 -0
- nautobot/virtualization/migrations/0025_status_nonnullable.py +29 -0
- nautobot/virtualization/models.py +31 -123
- nautobot/virtualization/navigation.py +18 -99
- nautobot/virtualization/templates/virtualization/virtualmachine.html +2 -1
- nautobot/virtualization/templates/virtualization/virtualmachine_edit.html +6 -0
- nautobot/virtualization/tests/test_api.py +25 -26
- nautobot/virtualization/tests/test_filters.py +41 -15
- nautobot/virtualization/tests/test_models.py +31 -7
- nautobot/virtualization/tests/test_views.py +42 -25
- nautobot/virtualization/views.py +7 -6
- {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/METADATA +3 -7
- {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/RECORD +744 -602
- {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/WHEEL +1 -1
- nautobot/circuits/api/nested_serializers.py +0 -69
- nautobot/core/templates/plugin_template/navigation.py-tpl +0 -22
- nautobot/dcim/api/nested_serializers.py +0 -356
- nautobot/dcim/templates/dcim/device_import.html +0 -5
- nautobot/dcim/templates/dcim/device_import_child.html +0 -5
- nautobot/dcim/templates/dcim/inc/device_import_header.html +0 -4
- nautobot/extras/api/nested_serializers.py +0 -353
- nautobot/extras/migrations/0064_configcontext_data_migrations.py +0 -41
- nautobot/extras/migrations/0071_job__unique_name_data_migration.py +0 -46
- nautobot/extras/reports.py +0 -60
- nautobot/extras/scripts.py +0 -72
- nautobot/extras/tests/example_jobs/script_variables.py +0 -67
- nautobot/extras/tests/example_jobs/test_duplicate_name2.py +0 -5
- nautobot/extras/tests/example_jobs/test_fail.py +0 -16
- nautobot/extras/tests/example_jobs/test_file_upload_pass.py +0 -20
- nautobot/extras/tests/example_jobs/test_ipaddress_vars.py +0 -52
- nautobot/extras/tests/example_jobs/test_job_button_receiver.py +0 -21
- nautobot/extras/tests/example_jobs/test_job_hook_receiver.py +0 -20
- nautobot/extras/tests/example_jobs/test_location_with_custom_field.py +0 -35
- nautobot/extras/tests/example_jobs/test_log_redaction.py +0 -14
- nautobot/extras/tests/example_jobs/test_modify_db.py +0 -18
- nautobot/extras/tests/example_jobs/test_object_var_optional.py +0 -14
- nautobot/extras/tests/example_jobs/test_object_var_required.py +0 -14
- nautobot/extras/tests/example_jobs/test_object_vars.py +0 -29
- nautobot/extras/tests/example_jobs/test_pass.py +0 -19
- nautobot/extras/tests/example_jobs/test_read_only_fail.py +0 -24
- nautobot/extras/tests/example_jobs/test_read_only_no_commit_field.py +0 -10
- nautobot/extras/tests/example_jobs/test_read_only_pass.py +0 -22
- nautobot/ipam/api/nested_serializers.py +0 -159
- nautobot/ipam/migrations/0029_ipam__prefix__add_parent.py +0 -31
- nautobot/ipam/migrations/0030_ipam__prefix__data_migration.py +0 -13
- nautobot/ipam/migrations/0031_ipam__ipaddress__add_parent.py +0 -41
- nautobot/ipam/migrations/0032_ipam__ipaddress__data_migration.py +0 -11
- nautobot/tenancy/api/nested_serializers.py +0 -31
- nautobot/users/api/nested_serializers.py +0 -67
- nautobot/virtualization/api/nested_serializers.py +0 -65
- /nautobot/extras/{tests/example_jobs → test_jobs}/__init__.py +0 -0
- /nautobot/{dcim/models/sites.py → ipam/management/__init__.py} +0 -0
- {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.0.0a3.dist-info → nautobot-2.0.0b1.dist-info}/entry_points.txt +0 -0
nautobot/extras/models/mixins.py
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Class-modifying mixins that need to be standalone to avoid circular imports.
|
|
3
3
|
"""
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
from cacheops.utils import family_has_profile
|
|
7
|
-
from django.db.models import Q
|
|
8
4
|
from django.urls import NoReverseMatch, reverse
|
|
9
|
-
from funcy import once_per
|
|
10
5
|
|
|
11
|
-
from nautobot.core.forms.fields import DynamicModelMultipleChoiceField
|
|
12
6
|
from nautobot.core.utils.lookup import get_route_for_model
|
|
13
7
|
|
|
14
8
|
|
|
@@ -78,68 +72,3 @@ class NotesMixin:
|
|
|
78
72
|
continue
|
|
79
73
|
|
|
80
74
|
return None
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# 2.0 TODO: Remove after v2 since we will no longer care about backwards-incompatibility.
|
|
84
|
-
# - Remove the `monkey_mix` from `nautobot.core.apps.CoreConfig.ready()`
|
|
85
|
-
# - Convert this into a subclass instead of a mixin and move it to `nautobot.extras.models.managers.TaggableManager` (assuming this stays in `extras`)
|
|
86
|
-
# - Replace all `from taggit.managers import TaggableManager` references to `from nautobot.extras.models.managers import TaggableManager`
|
|
87
|
-
class TaggableManagerMonkeyMixin:
|
|
88
|
-
"""
|
|
89
|
-
Dynamically-applied monkey-patch mixin that is used to replace any defined
|
|
90
|
-
methods on eligible objects.
|
|
91
|
-
|
|
92
|
-
Intended to be used on the right-hand side of `monkey_mix()` to overload the
|
|
93
|
-
`formfield()` method.
|
|
94
|
-
|
|
95
|
-
Usage:
|
|
96
|
-
|
|
97
|
-
monkey_mix(TaggableManager, TaggableManagerMonkeyMixin)
|
|
98
|
-
|
|
99
|
-
See: `nautobot.core.apps.ready()`
|
|
100
|
-
"""
|
|
101
|
-
|
|
102
|
-
@once_per("cls")
|
|
103
|
-
def _install_hotfix(self, cls):
|
|
104
|
-
# Install auto-created models as their module attributes to make them picklable
|
|
105
|
-
module = sys.modules[cls.__module__]
|
|
106
|
-
if not hasattr(module, cls.__name__):
|
|
107
|
-
setattr(module, cls.__name__, cls)
|
|
108
|
-
|
|
109
|
-
# This is probably still needed if models are created dynamically.
|
|
110
|
-
def contribute_to_class(self, cls, name):
|
|
111
|
-
"""
|
|
112
|
-
Overload default so that we can assert that this is called when
|
|
113
|
-
attached to any model that is using a `TaggableManager`.
|
|
114
|
-
|
|
115
|
-
Using `.contribute_to_class()` is how field objects get added to the model
|
|
116
|
-
at during the instance preparation. This is also where any custom model
|
|
117
|
-
methods are hooked in. So in short this method asserts that any time a`
|
|
118
|
-
`TaggableManager` is added to a model, that model also gets its methods
|
|
119
|
-
monkey-mixed without having to define them on the model yourself.
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
self._no_monkey.contribute_to_class(self, cls, name)
|
|
123
|
-
# Django migrations create lots of fake models, just skip them
|
|
124
|
-
# NOTE: we make it here rather then inside _install_hotfix()
|
|
125
|
-
# because we don't want @once_per() to hold refs to all of them.
|
|
126
|
-
# family_has_profile is fork-lifted from cacheops which
|
|
127
|
-
# is used to identify "all proxy models, including subclasess, superclassses and siblings" for a model object.
|
|
128
|
-
# See: https://github.com/Suor/django-cacheops/blob/ad83e51b6d82ba2bf4820953925ff889e4c4b840/cacheops/utils.py#L16-L27
|
|
129
|
-
if cls.__module__ != "__fake__" and family_has_profile(cls):
|
|
130
|
-
self._install_hotfix(cls)
|
|
131
|
-
|
|
132
|
-
def formfield(self, form_class=DynamicModelMultipleChoiceField, **kwargs):
|
|
133
|
-
from nautobot.extras.models.tags import Tag
|
|
134
|
-
|
|
135
|
-
queryset = Tag.objects.filter(
|
|
136
|
-
Q(
|
|
137
|
-
content_types__model=self.model._meta.model_name,
|
|
138
|
-
content_types__app_label=self.model._meta.app_label,
|
|
139
|
-
)
|
|
140
|
-
| Q(content_types__isnull=True)
|
|
141
|
-
)
|
|
142
|
-
kwargs.setdefault("queryset", queryset)
|
|
143
|
-
kwargs.setdefault("required", False)
|
|
144
|
-
kwargs.setdefault("query_params", {"content_types": self.model._meta.label_lower})
|
|
145
|
-
return self._no_monkey.formfield(self, form_class=form_class, **kwargs)
|
nautobot/extras/models/models.py
CHANGED
|
@@ -12,7 +12,6 @@ from django.core.exceptions import ValidationError
|
|
|
12
12
|
from django.db import models
|
|
13
13
|
from django.http import HttpResponse
|
|
14
14
|
from django.utils.text import slugify
|
|
15
|
-
from django.urls import reverse
|
|
16
15
|
from graphene_django.settings import graphene_settings
|
|
17
16
|
from graphql import get_default_backend
|
|
18
17
|
from graphql.error import GraphQLSyntaxError
|
|
@@ -136,9 +135,6 @@ class ConfigContext(BaseModel, ChangeLoggedModel, ConfigContextSchemaValidationM
|
|
|
136
135
|
return f"[{self.owner}] {self.name}"
|
|
137
136
|
return self.name
|
|
138
137
|
|
|
139
|
-
def get_absolute_url(self):
|
|
140
|
-
return reverse("extras:configcontext", kwargs={"pk": self.pk})
|
|
141
|
-
|
|
142
138
|
def clean(self):
|
|
143
139
|
super().clean()
|
|
144
140
|
|
|
@@ -285,9 +281,6 @@ class ConfigContextSchema(OrganizationalModel):
|
|
|
285
281
|
return f"[{self.owner}] {self.name}"
|
|
286
282
|
return self.name
|
|
287
283
|
|
|
288
|
-
def get_absolute_url(self):
|
|
289
|
-
return reverse("extras:configcontextschema", args=[self.slug])
|
|
290
|
-
|
|
291
284
|
def clean(self):
|
|
292
285
|
"""
|
|
293
286
|
Validate the schema
|
|
@@ -360,9 +353,6 @@ class CustomLink(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
|
360
353
|
def __str__(self):
|
|
361
354
|
return self.name
|
|
362
355
|
|
|
363
|
-
def get_absolute_url(self):
|
|
364
|
-
return reverse("extras:customlink", kwargs={"pk": self.pk})
|
|
365
|
-
|
|
366
356
|
|
|
367
357
|
#
|
|
368
358
|
# Export templates
|
|
@@ -447,9 +437,6 @@ class ExportTemplate(BaseModel, ChangeLoggedModel, RelationshipModel, NotesMixin
|
|
|
447
437
|
|
|
448
438
|
return response
|
|
449
439
|
|
|
450
|
-
def get_absolute_url(self):
|
|
451
|
-
return reverse("extras:exporttemplate", kwargs={"pk": self.pk})
|
|
452
|
-
|
|
453
440
|
def clean(self):
|
|
454
441
|
super().clean()
|
|
455
442
|
if self.file_extension.startswith("."):
|
|
@@ -557,9 +544,6 @@ class GraphQLQuery(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
|
557
544
|
verbose_name = "GraphQL query"
|
|
558
545
|
verbose_name_plural = "GraphQL queries"
|
|
559
546
|
|
|
560
|
-
def get_absolute_url(self):
|
|
561
|
-
return reverse("extras:graphqlquery", kwargs={"pk": self.pk})
|
|
562
|
-
|
|
563
547
|
def save(self, *args, **kwargs):
|
|
564
548
|
variables = {}
|
|
565
549
|
schema = graphene_settings.SCHEMA
|
|
@@ -826,9 +810,6 @@ class Webhook(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
|
826
810
|
else:
|
|
827
811
|
return json.dumps(context, cls=JSONEncoder, ensure_ascii=False)
|
|
828
812
|
|
|
829
|
-
def get_absolute_url(self):
|
|
830
|
-
return reverse("extras:webhook", kwargs={"pk": self.pk})
|
|
831
|
-
|
|
832
813
|
@classmethod
|
|
833
814
|
def check_for_conflicts(
|
|
834
815
|
cls, instance=None, content_types=None, payload_url=None, type_create=None, type_update=None, type_delete=None
|
|
@@ -21,7 +21,7 @@ from nautobot.core.models.fields import AutoSlugField, slugify_dashes_to_undersc
|
|
|
21
21
|
from nautobot.core.models.querysets import RestrictedQuerySet
|
|
22
22
|
from nautobot.core.utils.lookup import get_filterset_for_model, get_route_for_model
|
|
23
23
|
from nautobot.extras.choices import RelationshipTypeChoices, RelationshipRequiredSideChoices, RelationshipSideChoices
|
|
24
|
-
from nautobot.extras.utils import FeatureQuery, extras_features
|
|
24
|
+
from nautobot.extras.utils import FeatureQuery, check_if_key_is_graphql_safe, extras_features
|
|
25
25
|
from nautobot.extras.models import ChangeLoggedModel
|
|
26
26
|
from nautobot.extras.models.mixins import NotesMixin
|
|
27
27
|
|
|
@@ -261,9 +261,9 @@ class RelationshipModel(models.Model):
|
|
|
261
261
|
|
|
262
262
|
required_model_class = getattr(relation, f"{opposite_side}_type").model_class()
|
|
263
263
|
required_model_meta = required_model_class._meta
|
|
264
|
-
cr_field_name = f"cr_{relation.
|
|
264
|
+
cr_field_name = f"cr_{relation.key}__{opposite_side}"
|
|
265
265
|
name_plural = cls._meta.verbose_name_plural
|
|
266
|
-
field_key = relation.
|
|
266
|
+
field_key = relation.key if output_for == "api" else cr_field_name
|
|
267
267
|
field_errors = {field_key: []}
|
|
268
268
|
|
|
269
269
|
if not required_model_class.objects.exists():
|
|
@@ -312,7 +312,7 @@ class RelationshipModel(models.Model):
|
|
|
312
312
|
)
|
|
313
313
|
elif output_for == "api":
|
|
314
314
|
field_errors[field_key].append(
|
|
315
|
-
f'You need to specify ["relationships"]["{relation.
|
|
315
|
+
f'You need to specify ["relationships"]["{relation.key}"]["{opposite_side}"]["objects"].'
|
|
316
316
|
)
|
|
317
317
|
|
|
318
318
|
if len(field_errors[field_key]) > 0:
|
|
@@ -346,11 +346,11 @@ class RelationshipManager(BaseManager.from_queryset(RestrictedQuerySet)):
|
|
|
346
346
|
|
|
347
347
|
|
|
348
348
|
class Relationship(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
populate_from="
|
|
349
|
+
label = models.CharField(max_length=100, unique=True, help_text="Label of the relationship as displayed to users")
|
|
350
|
+
key = AutoSlugField(
|
|
351
|
+
populate_from="label",
|
|
352
352
|
slugify_function=slugify_dashes_to_underscores,
|
|
353
|
-
help_text="Internal relationship
|
|
353
|
+
help_text="Internal relationship key. Please use underscores rather than dashes in this key.",
|
|
354
354
|
)
|
|
355
355
|
description = models.CharField(max_length=200, blank=True)
|
|
356
356
|
type = models.CharField(
|
|
@@ -435,10 +435,10 @@ class Relationship(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
|
435
435
|
objects = RelationshipManager()
|
|
436
436
|
|
|
437
437
|
class Meta:
|
|
438
|
-
ordering = ["
|
|
438
|
+
ordering = ["label"]
|
|
439
439
|
|
|
440
440
|
def __str__(self):
|
|
441
|
-
return self.
|
|
441
|
+
return self.label
|
|
442
442
|
|
|
443
443
|
@property
|
|
444
444
|
def symmetric(self):
|
|
@@ -454,9 +454,6 @@ class Relationship(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
|
454
454
|
return self.source_type
|
|
455
455
|
return None
|
|
456
456
|
|
|
457
|
-
def get_absolute_url(self):
|
|
458
|
-
return reverse("extras:relationship", args=[self.slug])
|
|
459
|
-
|
|
460
457
|
def get_label(self, side):
|
|
461
458
|
"""Return the label for a given side, source or destination.
|
|
462
459
|
|
|
@@ -562,6 +559,9 @@ class Relationship(BaseModel, ChangeLoggedModel, NotesMixin):
|
|
|
562
559
|
return field
|
|
563
560
|
|
|
564
561
|
def clean(self):
|
|
562
|
+
# Check if relationship.key is graphql safe.
|
|
563
|
+
if self.key != "":
|
|
564
|
+
check_if_key_is_graphql_safe(self.__class__.__name__, self.key)
|
|
565
565
|
# Check if source and destination filters are valid
|
|
566
566
|
for side in ["source", "destination"]:
|
|
567
567
|
if not getattr(self, f"{side}_filter"):
|
|
@@ -734,6 +734,12 @@ class RelationshipAssociation(BaseModel):
|
|
|
734
734
|
|
|
735
735
|
return None
|
|
736
736
|
|
|
737
|
+
def get_absolute_url(self, api=False):
|
|
738
|
+
# TODO: in the new UI we should be able to have an actual UI URL for this model
|
|
739
|
+
if not api:
|
|
740
|
+
return self.relationship.get_absolute_url(api=api)
|
|
741
|
+
return super().get_absolute_url(api=api)
|
|
742
|
+
|
|
737
743
|
def get_source(self):
|
|
738
744
|
"""Accessor for self.source - returns None if the object cannot be located."""
|
|
739
745
|
return self._get_genericforeignkey("source")
|
nautobot/extras/models/roles.py
CHANGED
|
@@ -23,20 +23,9 @@ class Role(NameColorContentTypesModel):
|
|
|
23
23
|
)
|
|
24
24
|
weight = models.PositiveSmallIntegerField(null=True, blank=True)
|
|
25
25
|
|
|
26
|
-
csv_headers = ["name", "weight", "color", "content_types", "description"]
|
|
27
|
-
|
|
28
26
|
class Meta:
|
|
29
27
|
ordering = ("weight", "name")
|
|
30
28
|
|
|
31
|
-
def to_csv(self):
|
|
32
|
-
return (
|
|
33
|
-
self.name,
|
|
34
|
-
self.weight,
|
|
35
|
-
self.color,
|
|
36
|
-
self.get_content_types(),
|
|
37
|
-
self.description,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
29
|
|
|
41
30
|
class RoleField(ForeignKeyLimitedByContentTypes):
|
|
42
31
|
"""Model database field that automatically limits role choices
|
|
@@ -46,27 +35,4 @@ class RoleField(ForeignKeyLimitedByContentTypes):
|
|
|
46
35
|
def __init__(self, *args, **kwargs):
|
|
47
36
|
kwargs.setdefault("to", Role)
|
|
48
37
|
kwargs.setdefault("on_delete", models.PROTECT)
|
|
49
|
-
kwargs.setdefault("blank", True)
|
|
50
38
|
super().__init__(*args, **kwargs)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class RoleModelMixin(models.Model):
|
|
54
|
-
"""
|
|
55
|
-
Abstract base class for any model which may have roles.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
role = RoleField(null=True, blank=True)
|
|
59
|
-
|
|
60
|
-
class Meta:
|
|
61
|
-
abstract = True
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
class RoleRequiredRoleModelMixin(models.Model):
|
|
65
|
-
"""
|
|
66
|
-
Abstract base class for any model which may have roles with role field required.
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
role = RoleField(null=False, blank=False)
|
|
70
|
-
|
|
71
|
-
class Meta:
|
|
72
|
-
abstract = True
|
|
@@ -3,7 +3,6 @@ import logging
|
|
|
3
3
|
from django.core.exceptions import ValidationError
|
|
4
4
|
from django.core.serializers.json import DjangoJSONEncoder
|
|
5
5
|
from django.db import models
|
|
6
|
-
from django.urls import reverse
|
|
7
6
|
|
|
8
7
|
from jinja2.exceptions import UndefinedError, TemplateSyntaxError
|
|
9
8
|
|
|
@@ -38,12 +37,6 @@ class Secret(PrimaryModel):
|
|
|
38
37
|
provider = models.CharField(max_length=100)
|
|
39
38
|
parameters = models.JSONField(encoder=DjangoJSONEncoder, default=dict)
|
|
40
39
|
|
|
41
|
-
csv_headers = [
|
|
42
|
-
"name",
|
|
43
|
-
"description",
|
|
44
|
-
"provider",
|
|
45
|
-
"parameters",
|
|
46
|
-
]
|
|
47
40
|
clone_fields = [
|
|
48
41
|
"provider",
|
|
49
42
|
]
|
|
@@ -54,17 +47,6 @@ class Secret(PrimaryModel):
|
|
|
54
47
|
def __str__(self):
|
|
55
48
|
return self.name
|
|
56
49
|
|
|
57
|
-
def get_absolute_url(self):
|
|
58
|
-
return reverse("extras:secret", args=[self.pk])
|
|
59
|
-
|
|
60
|
-
def to_csv(self):
|
|
61
|
-
return (
|
|
62
|
-
self.name,
|
|
63
|
-
self.description,
|
|
64
|
-
self.provider,
|
|
65
|
-
self.parameters,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
50
|
def rendered_parameters(self, obj=None):
|
|
69
51
|
"""Render self.parameters as a Jinja2 template with the given object as context."""
|
|
70
52
|
try:
|
|
@@ -117,17 +99,9 @@ class SecretsGroup(OrganizationalModel):
|
|
|
117
99
|
to=Secret, related_name="secrets_groups", through="extras.SecretsGroupAssociation", blank=True
|
|
118
100
|
)
|
|
119
101
|
|
|
120
|
-
csv_headers = ["name", "description"]
|
|
121
|
-
|
|
122
102
|
def __str__(self):
|
|
123
103
|
return self.name
|
|
124
104
|
|
|
125
|
-
def get_absolute_url(self):
|
|
126
|
-
return reverse("extras:secretsgroup", args=[self.pk])
|
|
127
|
-
|
|
128
|
-
def to_csv(self):
|
|
129
|
-
return (self.name, self.description)
|
|
130
|
-
|
|
131
105
|
def get_secret_value(self, access_type, secret_type, obj=None, **kwargs):
|
|
132
106
|
"""Helper method to retrieve a specific secret from this group.
|
|
133
107
|
|
|
@@ -151,6 +125,8 @@ class SecretsGroupAssociation(BaseModel):
|
|
|
151
125
|
access_type = models.CharField(max_length=32, choices=SecretsGroupAccessTypeChoices)
|
|
152
126
|
secret_type = models.CharField(max_length=32, choices=SecretsGroupSecretTypeChoices)
|
|
153
127
|
|
|
128
|
+
natural_key_field_names = ["secrets_group", "access_type", "secret_type", "secret"]
|
|
129
|
+
|
|
154
130
|
class Meta:
|
|
155
131
|
unique_together = (
|
|
156
132
|
# Don't allow the same access-type/secret-type combination to be used more than once in the same group
|
|
@@ -7,6 +7,7 @@ from django.utils.hashable import make_hashable
|
|
|
7
7
|
|
|
8
8
|
from nautobot.core.models.fields import ForeignKeyLimitedByContentTypes
|
|
9
9
|
from nautobot.core.models.name_color_content_types import NameColorContentTypesModel
|
|
10
|
+
from nautobot.core.utils.deprecation import class_deprecated
|
|
10
11
|
from nautobot.extras.utils import extras_features, FeatureQuery
|
|
11
12
|
|
|
12
13
|
|
|
@@ -47,9 +48,6 @@ class StatusField(ForeignKeyLimitedByContentTypes):
|
|
|
47
48
|
kwargs.setdefault("on_delete", models.PROTECT)
|
|
48
49
|
super().__init__(*args, **kwargs)
|
|
49
50
|
|
|
50
|
-
def get_limit_choices_to(self):
|
|
51
|
-
return {"content_types": ContentType.objects.get_for_model(self.model)}
|
|
52
|
-
|
|
53
51
|
def contribute_to_class(self, cls, *args, **kwargs):
|
|
54
52
|
"""
|
|
55
53
|
Overload default so that we can assert that `.get_FOO_display` is
|
|
@@ -102,12 +100,15 @@ class StatusField(ForeignKeyLimitedByContentTypes):
|
|
|
102
100
|
)
|
|
103
101
|
|
|
104
102
|
|
|
103
|
+
@class_deprecated(message="please directly declare `status = StatusField(...)` on your model instead")
|
|
105
104
|
class StatusModel(models.Model):
|
|
106
105
|
"""
|
|
107
|
-
|
|
106
|
+
Deprecated abstract base class for any model which may have statuses.
|
|
107
|
+
|
|
108
|
+
Just directly include a StatusField instead for any new models.
|
|
108
109
|
"""
|
|
109
110
|
|
|
110
|
-
status = StatusField()
|
|
111
|
+
status = StatusField(null=True) # for backward compatibility
|
|
111
112
|
|
|
112
113
|
class Meta:
|
|
113
114
|
abstract = True
|
nautobot/extras/models/tags.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from django.contrib.contenttypes.models import ContentType
|
|
2
2
|
from django.db import models
|
|
3
|
-
from django.urls import reverse
|
|
4
3
|
from taggit.models import TagBase, GenericUUIDTaggedItemBase
|
|
5
4
|
|
|
6
5
|
from nautobot.core.choices import ColorChoices
|
|
@@ -25,8 +24,7 @@ class TagQuerySet(RestrictedQuerySet):
|
|
|
25
24
|
"""
|
|
26
25
|
Return all `Tags` assigned to the given model.
|
|
27
26
|
"""
|
|
28
|
-
|
|
29
|
-
return self.filter(content_types=content_type)
|
|
27
|
+
return self.filter(content_types__model=model._meta.model_name, content_types__app_label=model._meta.app_label)
|
|
30
28
|
|
|
31
29
|
|
|
32
30
|
@extras_features(
|
|
@@ -44,19 +42,11 @@ class Tag(TagBase, BaseModel, ChangeLoggedModel, CustomFieldModel, RelationshipM
|
|
|
44
42
|
blank=True,
|
|
45
43
|
)
|
|
46
44
|
|
|
47
|
-
csv_headers = ["name", "slug", "color", "description"]
|
|
48
|
-
|
|
49
45
|
objects = BaseManager.from_queryset(TagQuerySet)()
|
|
50
46
|
|
|
51
47
|
class Meta:
|
|
52
48
|
ordering = ["name"]
|
|
53
49
|
|
|
54
|
-
def get_absolute_url(self):
|
|
55
|
-
return reverse("extras:tag", args=[self.slug])
|
|
56
|
-
|
|
57
|
-
def to_csv(self):
|
|
58
|
-
return (self.name, self.slug, self.color, self.description)
|
|
59
|
-
|
|
60
50
|
def validate_content_types_removal(self, content_types_id):
|
|
61
51
|
"""Validate content_types to be removed are not tagged to a model"""
|
|
62
52
|
errors = {}
|
|
@@ -76,12 +66,7 @@ class Tag(TagBase, BaseModel, ChangeLoggedModel, CustomFieldModel, RelationshipM
|
|
|
76
66
|
|
|
77
67
|
class TaggedItem(BaseModel, GenericUUIDTaggedItemBase):
|
|
78
68
|
tag = models.ForeignKey(to=Tag, related_name="%(app_label)s_%(class)s_items", on_delete=models.CASCADE)
|
|
79
|
-
object_id = models.UUIDField()
|
|
80
69
|
|
|
81
70
|
class Meta:
|
|
82
71
|
index_together = ("content_type", "object_id")
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# TODO: This isn't a guaranteed natural key for this model (see lack of a `unique_together` above), but in practice
|
|
86
|
-
# it is "nearly" unique. Once a proper unique_together is added and accounted for, this can be removed as redundant
|
|
87
|
-
natural_key_field_names = ["content_type", "object_id", "tag"]
|
|
72
|
+
unique_together = [["content_type", "object_id", "tag"]]
|