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
|
@@ -1,95 +1,35 @@
|
|
|
1
1
|
# Populating the Navigation Menu
|
|
2
2
|
|
|
3
|
-
Both core applications and plugins can contribute items to the navigation menu by defining `menu_items` inside of their app's `navigation.py`. Using the key and weight system, a developer can integrate amongst existing menu tabs, groups,
|
|
3
|
+
Both core applications and plugins can contribute items to the navigation menu by defining `menu_items` inside of their app's `navigation.py`. Using the key and weight system, a developer can integrate amongst existing menu contexts (a.k.a. tabs), groups, and items.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
--- 2.0.0
|
|
6
|
+
The updated UI does not permit including buttons into the navigation menu items. As such, `NavMenuButton` and its subclasses have been removed, and the `buttons` parameter to `NavMenuItem` is no longer supported.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## Defining and Modifying Menus
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
Nautobot will intelligently merge the contents of all apps' `menu_items` defined in their `navigation.py` to create the final navigation menu structure. This is done by matching on objects' `name` fields to identify items that need to be consolidated.
|
|
11
|
+
|
|
12
|
+
The example below shows adding a new group containing a new item under the base `Inventory` menu context. The group is being defined with a weight of `150`, which means it will appear between the already defined `Devices` (weight `100`) and `Organization` (weight `200`) groups in this context.
|
|
10
13
|
|
|
11
14
|
!!! tip
|
|
12
|
-
Weights for already existing items can be found in the nautobot source code (in `navigation.py`)
|
|
15
|
+
Weights for already existing items can be found in the nautobot source code (in `navigation.py`).
|
|
13
16
|
|
|
14
|
-
This pattern works for modifying all objects in the tree. New
|
|
17
|
+
This pattern works for modifying all objects in the tree. New groups can be added to existing tabs and new items can be added to existing groups. The set of tabs is defined by the Nautobot `nautobot.core.apps.MENU_TABS` constant and cannot generally be changed.
|
|
15
18
|
|
|
16
19
|
``` python
|
|
17
|
-
|
|
20
|
+
menu_items = (
|
|
18
21
|
NavMenuTab(
|
|
19
|
-
name="
|
|
22
|
+
name="Inventory",
|
|
20
23
|
groups=(
|
|
21
24
|
NavMenuGroup(
|
|
22
|
-
name="Example
|
|
25
|
+
name="Example App",
|
|
23
26
|
weight=150,
|
|
24
27
|
items=(
|
|
25
28
|
NavMenuItem(
|
|
26
|
-
link="plugins:example_plugin:examplemodel_list",
|
|
27
29
|
name="Example Model",
|
|
28
|
-
|
|
29
|
-
"example_plugin.view_examplemodel"
|
|
30
|
-
],
|
|
31
|
-
buttons=(
|
|
32
|
-
NavMenuAddButton(
|
|
33
|
-
link="plugins:example_plugin:examplemodel_add",
|
|
34
|
-
permissions=[
|
|
35
|
-
"example_plugin.add_examplemodel",
|
|
36
|
-
],
|
|
37
|
-
),
|
|
38
|
-
NavMenuImportButton(
|
|
39
|
-
link="plugins:example_plugin:examplemodel_import",
|
|
40
|
-
permissions=[
|
|
41
|
-
"example_plugin.add_examplemodel"
|
|
42
|
-
],
|
|
43
|
-
),
|
|
44
|
-
),
|
|
45
|
-
),
|
|
46
|
-
),
|
|
47
|
-
),
|
|
48
|
-
),
|
|
49
|
-
),
|
|
50
|
-
)
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Adding a New Menu
|
|
54
|
-
|
|
55
|
-
The code below shows how to add a new tab to the navbar. A tab is defined by a `NavMenuTab` object. Similarly a group is defined using `NavMenuGroup`. Both of these objects are used as containers for actual items.
|
|
56
|
-
|
|
57
|
-
The position in the navigation menu is defined by the weight. The lower the weight the closer to the start of the menus the object will be. All core objects have weights in multiples of 100, meaning there is plenty of space around the objects for plugins to customize.
|
|
58
|
-
|
|
59
|
-
Below you can see `Example Tab` has a weight value of `150`. This means the tab will appear between `Organization` and `Devices`.
|
|
60
|
-
|
|
61
|
-
``` python
|
|
62
|
-
from nautobot.core.apps import NavMenuAddButton, NavMenuGroup, NavMenuItem, NavMenuImportButton, NavMenuTab
|
|
63
|
-
|
|
64
|
-
menu_items = (
|
|
65
|
-
NavMenuTab(
|
|
66
|
-
name="Example Tab",
|
|
67
|
-
weight=150,
|
|
68
|
-
groups=(
|
|
69
|
-
NavMenuGroup(
|
|
70
|
-
name="Example Group 1",
|
|
71
|
-
weight=100,
|
|
72
|
-
items=(
|
|
73
|
-
NavMenuItem(
|
|
30
|
+
weight=100,
|
|
74
31
|
link="plugins:example_plugin:examplemodel_list",
|
|
75
|
-
|
|
76
|
-
permissions=[
|
|
77
|
-
"example_plugin.view_examplemodel"
|
|
78
|
-
],
|
|
79
|
-
buttons=(
|
|
80
|
-
NavMenuAddButton(
|
|
81
|
-
link="plugins:example_plugin:examplemodel_add",
|
|
82
|
-
permissions=[
|
|
83
|
-
"example_plugin.add_examplemodel",
|
|
84
|
-
],
|
|
85
|
-
),
|
|
86
|
-
NavMenuImportButton(
|
|
87
|
-
link="plugins:example_plugin:examplemodel_import",
|
|
88
|
-
permissions=[
|
|
89
|
-
"example_plugin.add_examplemodel"
|
|
90
|
-
],
|
|
91
|
-
),
|
|
92
|
-
),
|
|
32
|
+
permissions=["example_plugin.view_examplemodel"],
|
|
93
33
|
),
|
|
94
34
|
),
|
|
95
35
|
),
|
|
@@ -107,16 +47,18 @@ menu_items = (
|
|
|
107
47
|
A `NavMenuTab` has the following attributes:
|
|
108
48
|
|
|
109
49
|
* `name` - Display name to be shown in navigation menu
|
|
110
|
-
* `
|
|
111
|
-
* `permissions` - A list of permissions required to display this link (optional)
|
|
50
|
+
* `permissions` - A list of permissions required to display this object (optional)
|
|
112
51
|
* `groups` - List or tuple of `NavMenuGroup`
|
|
113
52
|
|
|
53
|
+
--- 2.0.0
|
|
54
|
+
As the sequence of menu "tabs"/"contexts" in Nautobot is now constant, the `weight` property has been removed from `NavMenuTab`.
|
|
55
|
+
|
|
114
56
|
A `NavMenuGroup` has the following attributes:
|
|
115
57
|
|
|
116
58
|
* `name` - Display name to be shown in navigation menu
|
|
117
59
|
* `weight` - Defines the position the object should be displayed at (optional)
|
|
118
|
-
* `permissions` - A list of permissions required to display this
|
|
119
|
-
* `items` - List or tuple of `NavMenuItem`
|
|
60
|
+
* `permissions` - A list of permissions required to display this object (optional)
|
|
61
|
+
* `items` - List or tuple of `NavMenuGroup` and/or `NavMenuItem`
|
|
120
62
|
|
|
121
63
|
A `NavMenuItem` has the following attributes:
|
|
122
64
|
|
|
@@ -124,19 +66,6 @@ A `NavMenuItem` has the following attributes:
|
|
|
124
66
|
* `name` - The text presented to the user
|
|
125
67
|
* `weight` - Defines the position the object should be displayed at (optional)
|
|
126
68
|
* `permissions` - A list of permissions required to display this link (optional)
|
|
127
|
-
* `buttons` - An iterable of NavMenuButton (or subclasses of NavMenuButton) instances to display (optional)
|
|
128
|
-
|
|
129
|
-
!!! note
|
|
130
|
-
Any buttons associated within a menu item will be hidden if the user does not have permission to access the menu item, regardless of what permissions are set on the buttons.
|
|
131
69
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
* `title` - The tooltip text (displayed when the mouse hovers over the button)
|
|
135
|
-
* `link` - The name of the URL path to which this button links
|
|
136
|
-
* `weight` - Defines the position the object should be displayed at (optional)
|
|
137
|
-
* `icon_class` - Button icon CSS classes (Nautobot currently supports [Material Design Icons](https://materialdesignicons.com) or one of the choices provided by `ButtonActionIconChoices`)
|
|
138
|
-
* `button_class` - One of the choices provided by `ButtonActionColorChoices` (optional)
|
|
139
|
-
* `permissions` - A list of permissions required to display this button (optional)
|
|
140
|
-
|
|
141
|
-
!!! note
|
|
142
|
-
`NavMenuAddButton` and `NavMenuImportButton` are subclasses of `NavMenuButton` that can be used to provide the commonly used "Add" and "Import" buttons.
|
|
70
|
+
--- 2.0.0
|
|
71
|
+
The `buttons` attribute was removed from `NavMenuItem`.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Building the React UI
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
Nautobot 2.0 introduces a new user interface built on React. This new UI will eventually be a complete replacement for the previous Django-based UI. It currently prioritizes read-only operations for core views. In subsequent releases, more operations and features will become available in this new UI.
|
|
6
|
+
|
|
7
|
+
## Design Patterns
|
|
8
|
+
|
|
9
|
+
A key change with moving to a client-side application for the user interface is that the application is now stateful. This means that the application is aware of the current state of the user interface, and can update the UI without requiring a page refresh. This is a significant change from the previous Django-based UI, which was stateless. In order to achieve this, a perspective on how the UI is rendered is required. Since much of the data is retrieved from the API, the UI is rendered in two phases:
|
|
10
|
+
|
|
11
|
+
- **Phase 1**: The UI is rendered with placeholder data, and the API is queried for the actual data
|
|
12
|
+
- **Phase 2**: The UI is re-rendered with the actual data
|
|
13
|
+
|
|
14
|
+
This encourages the UI to be built in a way that is resilient to changes in the data, and allows the UI to be updated without requiring a page refresh. Placeholder data can either be empty, for example on a list view this is easy: an empty list `[]`. But in more complex cases, a view may choose to show a loading indicator until the data is available.
|
|
15
|
+
|
|
16
|
+
In most cases, we build the UI with the preference we only display the final component once the data is available and display a loading indicator until then.
|
|
17
|
+
|
|
18
|
+
### State Management
|
|
19
|
+
|
|
20
|
+
The React UI is built with a concept of state management, which is handled by Redux. There is a single state store that is used to manage the state of the entire application, split into two core sections:
|
|
21
|
+
|
|
22
|
+
- **Application State**: Managed by Redux
|
|
23
|
+
- Is the user logged in?
|
|
24
|
+
- What is the current user?
|
|
25
|
+
- What is the current page?
|
|
26
|
+
- What are the models and navigation menu the user can access?
|
|
27
|
+
- **API State**: Managed by RTK Query (a subset library provided by Redux)
|
|
28
|
+
- Previous responses to detail and list requests
|
|
29
|
+
|
|
30
|
+
These sections are known as "slices" of state, and have their own methods for updating and retrieving state. For more information on Redux, see the [Redux documentation](https://redux.js.org/).
|
|
31
|
+
|
|
32
|
+
### Hooks
|
|
33
|
+
|
|
34
|
+
The React UI uses hooks to manage state and side effects. Hooks are functions that let you "hook into" React state and lifecycle features. To learn more about hooks, see the [React Hooks documentation](https://react.dev/reference/react).
|
|
35
|
+
|
|
36
|
+
## Getting Started With Development
|
|
37
|
+
|
|
38
|
+
The libraries and tools used to build the React UI are:
|
|
39
|
+
|
|
40
|
+
- [React](https://reactjs.org/)
|
|
41
|
+
- [React Router](https://reactrouter.com/)
|
|
42
|
+
- [Chakra UI](https://chakra-ui.com/)
|
|
43
|
+
- [Redux](https://redux.js.org/)
|
|
44
|
+
- [React Redux](https://react-redux.js.org/)
|
|
45
|
+
- [RTK Query](https://redux-toolkit.js.org/rtk-query/overview)
|
|
46
|
+
|
|
47
|
+
### Documenting Your Code
|
|
48
|
+
|
|
49
|
+
The UI uses JS Doc to document the code. For more information on JS Doc, see the [JS Doc website](https://jsdoc.app/).
|
|
50
|
+
|
|
51
|
+
We prefer to use the `@param` and `@returns` tags to document the parameters and return values of functions. For example:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
/**
|
|
55
|
+
* Given an API payload with session information, updates the state with the session information
|
|
56
|
+
* @param {Object} state - The current state
|
|
57
|
+
* @param {Object} action - The called-with payload and action type
|
|
58
|
+
* @returns The updated state
|
|
59
|
+
*/
|
|
60
|
+
updateAuthStateWithSession(state, action) {
|
|
61
|
+
//...
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Linting & Formatting
|
|
66
|
+
|
|
67
|
+
#### Linting
|
|
68
|
+
|
|
69
|
+
The UI uses ESLint to lint the code. For more information on ESLint, see the [ESLint website](https://eslint.org/).
|
|
70
|
+
|
|
71
|
+
To check for linting errors, run the following command:
|
|
72
|
+
|
|
73
|
+
```shell
|
|
74
|
+
invoke eslint
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
To automatically fix some linting errors, run the following command:
|
|
78
|
+
|
|
79
|
+
```shell
|
|
80
|
+
invoke eslint -a
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Formatting
|
|
84
|
+
|
|
85
|
+
The UI uses Prettier to format the code. For more information on Prettier, see the [Prettier website](https://prettier.io/).
|
|
86
|
+
|
|
87
|
+
To check for linting errors, run the following command:
|
|
88
|
+
|
|
89
|
+
```shell
|
|
90
|
+
invoke prettier
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
To automatically format the code, run the following command:
|
|
94
|
+
|
|
95
|
+
```shell
|
|
96
|
+
invoke prettier -a
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Additional Links
|
|
100
|
+
|
|
101
|
+
Here are some links to resources that may be helpful when working with the React UI:
|
|
102
|
+
|
|
103
|
+
- [React and Effects](https://react.dev/learn/synchronizing-with-effects)
|
|
104
|
+
- [RTK Query and Asynchronous Hooks](https://redux-toolkit.js.org/rtk-query/usage/queries#query-hook-options)
|
|
105
|
+
- [Using useDispatch](https://react-redux.js.org/api/hooks#usedispatch)
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
data models of their own that implement a `role` field. Proceed at your
|
|
6
6
|
own risk!
|
|
7
7
|
|
|
8
|
-
Any model that is intended to have a `role` field must
|
|
8
|
+
Any model that is intended to have a `role` field must use a `nautobot.extras.models.roles.RoleField` field for its foreign-key to the Role model. This field type will automatically assign a `related_name` for the reverse relationship back to the inheriting model's verbose plural name (e.g. `devices`).
|
|
9
9
|
|
|
10
10
|
## `RoleField` model field
|
|
11
11
|
|
|
@@ -23,8 +23,6 @@ Any filter form that is intended to have a `role` field must inherit from `nauto
|
|
|
23
23
|
|
|
24
24
|
Any bulk edit form that is intended to have a `role` field must inherit from `nautobot.extras.forms.RoleModelBulkEditFormMixin`. This mixin adds a non-required `role` field to the form, and constrains the eligible role choices to the object type being edited.
|
|
25
25
|
|
|
26
|
-
Any CSV import form that is intended to have a required or non-required `role` field must inherit from either `nautobot.extras.forms.RoleRequiredRoleModelCSVFormMixin` or `nautobot.extras.forms.RoleModelCSVFormMixin`, respectively, which adds the specified role field to the form and constrains the eligible role choices to the object type being imported.
|
|
27
|
-
|
|
28
26
|
## `RoleSerializerField` serializer field
|
|
29
27
|
|
|
30
28
|
Any serializer that is intended to have a `role` field must either inherit from one of these:
|
|
@@ -4,11 +4,13 @@ Nautobot generally follows the [Django style guide](https://docs.djangoproject.c
|
|
|
4
4
|
|
|
5
5
|
* [Flake8](https://flake8.pycqa.org/) is used to validate code style.
|
|
6
6
|
* [Black](https://black.readthedocs.io/) is used to enforce code formatting conventions.
|
|
7
|
+
* [ESLint](https://eslint.org) is used to validate code style for the UI.
|
|
8
|
+
* [Prettier](https://prettier.io) is used to enforce code formatting conventions for the UI.
|
|
7
9
|
* [Pylint](https://pylint.pycqa.org/en/latest/) is used for Python static code analysis.
|
|
8
10
|
* [Hadolint](https://github.com/hadolint/hadolint) is used to lint and validate Docker best practices in the Dockerfile.
|
|
9
11
|
* [MarkdownLint-cli](https://github.com/igorshubovych/markdownlint-cli) is used to lint and validate Markdown (documentation) files.
|
|
10
12
|
|
|
11
|
-
Nautobot-specific configuration of these tools is maintained in the files `.flake8`, `.markdownlint.yml`, or `pyproject.toml` as appropriate to the individual tool.
|
|
13
|
+
Nautobot-specific configuration of these tools is maintained in the files `.flake8`, `.markdownlint.yml`, `.prettierrc`, `package.json`, or `pyproject.toml` as appropriate to the individual tool.
|
|
12
14
|
|
|
13
15
|
It is strongly recommended to include all of the above tools as part of your commit process before opening any pull request. A Git commit hook is provided in the source at `scripts/git-hooks/pre-commit`. Linking to this script from `.git/hooks/` will invoke these tools prior to every commit attempt and abort if the validation fails.
|
|
14
16
|
|
|
@@ -22,6 +24,8 @@ You can also invoke these utilities manually against the development Docker cont
|
|
|
22
24
|
```no-highlight
|
|
23
25
|
invoke flake8
|
|
24
26
|
invoke black
|
|
27
|
+
invoke eslint
|
|
28
|
+
invoke prettier
|
|
25
29
|
invoke check-migrations
|
|
26
30
|
invoke hadolint
|
|
27
31
|
invoke markdownlint
|
|
@@ -53,8 +57,6 @@ New dependencies can be added to the project via the `poetry add` command. This
|
|
|
53
57
|
|
|
54
58
|
* Every model should have a docstring. Every custom method should include an explanation of its function.
|
|
55
59
|
|
|
56
|
-
* Nested API serializers generate minimal representations of an object. These are stored separately from the primary serializers to avoid circular dependencies. Always import nested serializers from other apps directly. For example, from within the DCIM app you would write `from nautobot.ipam.api.nested_serializers import NestedIPAddressSerializer`.
|
|
57
|
-
|
|
58
60
|
* The combination of `nautobot.core.filters.BaseFilterSet`, `nautobot.extras.filters.CreatedUpdatedModelFilterSetMixin`, `nautobot.extras.filters.CustomFieldModelFilterSetMixin`, and `nautobot.extras.filters.RelationshipModelFilterSetMixin` is such a common use case throughout the code base that they have a helper class which combines all of these at `nautobot.extras.NautobotFilterSet`. Use this helper class if you need the functionality from these classes.
|
|
59
61
|
|
|
60
62
|
* The combination of `nautobot.core.forms.BootstrapMixin`, `nautobot.extras.forms.CustomFieldModelFormMixin`, `nautobot.extras.forms.RelationshipModelFormMixin` and `nautobot.extras.forms.NoteModelFormMixin` is such a common use case throughout the code base that they have a helper class which combines all of these at `nautobot.extras.forms.NautobotModelForm`. Use this helper class if you need the functionality from these classes.
|
|
@@ -67,7 +69,7 @@ New dependencies can be added to the project via the `poetry add` command. This
|
|
|
67
69
|
|
|
68
70
|
* API serializers for most models should inherit from `nautobot.extras.api.serializers.NautobotModelSerializer` and any appropriate mixins. Only use more abstract base classes such as ValidatedModelSerializer where absolutely required.
|
|
69
71
|
|
|
70
|
-
* `NautobotModelSerializer` will automatically add serializer fields for `id`, `created`/`last_updated` (if applicable), `custom_fields`, `computed_fields`, and `relationships`, so there's generally no need to explicitly declare these fields in `.Meta.fields` of each serializer class. Similarly, `TaggedModelSerializerMixin` and
|
|
72
|
+
* `NautobotModelSerializer` will automatically add serializer fields for `id`, `created`/`last_updated` (if applicable), `custom_fields`, `computed_fields`, and `relationships`, so there's generally no need to explicitly declare these fields in `.Meta.fields` of each serializer class. Similarly, `TaggedModelSerializerMixin` and `` will automatically add the `tags` and `status` fields when included in a serializer class.
|
|
71
73
|
|
|
72
74
|
* API Views for most models should inherit from `nautobot.extras.api.views.NautobotModelViewSet`. Only use more abstract base classes such as `ModelViewSet` where absolutely required.
|
|
73
75
|
|
nautobot/docs/index.md
CHANGED
|
@@ -72,7 +72,7 @@ Nautobot is built on the [Django](https://djangoproject.com/) Python Web framewo
|
|
|
72
72
|
| WSGI service | uWSGI or Gunicorn |
|
|
73
73
|
| Application | Django/Python |
|
|
74
74
|
| Database | PostgreSQL 9.6+ or MySQL 8.0+ |
|
|
75
|
-
| Cache | Redis
|
|
75
|
+
| Cache | Django/Redis |
|
|
76
76
|
| Task queuing | Redis/Celery |
|
|
77
77
|
| Live device access | NAPALM |
|
|
78
78
|
|
|
@@ -80,7 +80,8 @@ Nautobot is built on the [Django](https://djangoproject.com/) Python Web framewo
|
|
|
80
80
|
MySQL support was added.
|
|
81
81
|
|
|
82
82
|
--- 2.0.0
|
|
83
|
-
django-rq support was removed.
|
|
83
|
+
- `django-rq` support was removed.
|
|
84
|
+
- `django-cacheops` usage was removed and replaced with Django's native caching features.
|
|
84
85
|
|
|
85
86
|
The following diagram displays how data travels through Nautobot's application stack.
|
|
86
87
|
|
|
@@ -69,28 +69,16 @@ The following backwards-incompatible changes have been made to the data model in
|
|
|
69
69
|
|
|
70
70
|
### Status Fields
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
Status names are now lower-cased when setting the `status` field on CSV imports. The `slug` value is used for create/update of objects and for filtering in the API.
|
|
74
|
-
|
|
75
|
-
A new [`Status`](../models/extras/status.md) model has been added to represent the `status` field for many models. Each status has a human-readable `name` field (e.g. `Active`), and a `slug` field (e.g. `active`).
|
|
72
|
+
A new [`Status`](../models/extras/status.md) model has been added to represent the `status` field for many models. Each status has a human-readable `name` field (e.g. `Active`), a `color`, a `description`, and a set of `content_types` that it can be applied to (for example, `Device` and `Location`).
|
|
76
73
|
|
|
77
74
|
### Display name
|
|
78
75
|
|
|
79
76
|
Several models such as device type and VLAN exposed a `display_name` property, which has now been renamed to `display`. In fact, there are several other instances, especially in the REST API, where the `display_name` field was used and as such, all instances have been renamed to `display`.
|
|
80
77
|
|
|
81
|
-
#### CSV Imports
|
|
82
|
-
|
|
83
|
-
When using CSV import to define a `status` field on imported objects, such as when importing Devices or Prefixes, the `Status.slug` field is used.
|
|
84
|
-
|
|
85
|
-
For example, the built-in **Active** status has a slug of `active`, so the `active` value would be used for import.
|
|
86
|
-
|
|
87
78
|
#### Default Choices
|
|
88
79
|
|
|
89
80
|
Because `status` fields are now stored in the database, they cannot have a default value, just like other similar objects like Device Roles or Device Types. In cases where `status` was not required to be set because it would use the default value, you must now provide a `status` yourself.
|
|
90
81
|
|
|
91
|
-
!!! note
|
|
92
|
-
For consistency in the API, the `slug` value of a `status` is used when creating or updating an object.
|
|
93
|
-
|
|
94
82
|
#### Choices in Code
|
|
95
83
|
|
|
96
84
|
All `*StatusChoices` enums used for populated `status` field choices (such as `nautobot.dcim.choices.DeviceStatusChoices`) are deprecated. Any code you have that is leveraging these will now result in an error when performing lookups on objects with `status` fields.
|
|
@@ -145,10 +133,10 @@ All IPAM objects with network field types (`ipam.IPAddress`, and `ipam.Prefix`)
|
|
|
145
133
|
|
|
146
134
|
Below is a summary of the underlying technical changes to network fields. These will be explained in more detail in the following sections.
|
|
147
135
|
|
|
148
|
-
- For `IPAddress`, the `address` field was exploded out to `host
|
|
136
|
+
- For `IPAddress`, the `address` field was exploded out to `host` and `mask_length` fields; `address` was converted into a computed field.
|
|
149
137
|
- For `Prefix` objects, the `prefix` field was exploded out to `network`, `broadcast`, and `prefix_length` fields; `prefix` was converted into a computed field.
|
|
150
138
|
- The `host`, `network`, and `broadcast` fields are now of a `varbinary` database type, which is represented as a packed binary integer (for example, the host `1.1.1.1` is packed as `b"\x01\x01\x01\x01"`)
|
|
151
|
-
- Network membership queries are accomplished by triangulating the "position" of an address using the
|
|
139
|
+
- Network membership queries are accomplished by triangulating the "position" of an address using the `host` of the `IPAddress` and the `network` and `broadcast` of the `Prefix`.
|
|
152
140
|
|
|
153
141
|
!!! note
|
|
154
142
|
You should never have to worry about the binary nature of how the network fields are stored in the database! The Django database ORM takes care of it all!
|
|
@@ -159,7 +147,7 @@ The following fields have changed when working with `ipam.IPAddress` objects:
|
|
|
159
147
|
|
|
160
148
|
##### `address` is now a computed field
|
|
161
149
|
|
|
162
|
-
This field is computed from `{host}/{
|
|
150
|
+
This field is computed from `{host}/{mask_length}` and is represented as a `netaddr.IPNetwork` object.
|
|
163
151
|
|
|
164
152
|
```python
|
|
165
153
|
>>> ip = IPAddress(address="1.1.1.1/30")
|
|
@@ -185,7 +173,7 @@ IPNetwork('1.1.1.1/30')
|
|
|
185
173
|
```
|
|
186
174
|
|
|
187
175
|
!!! note
|
|
188
|
-
If you use a `
|
|
176
|
+
If you use a `mask_length` other than `/32` (IPv4) or `/128` (IPv6) it **must** be included in your lookups
|
|
189
177
|
|
|
190
178
|
This field *cannot be used in **nested** filter expressions*:
|
|
191
179
|
|
|
@@ -209,47 +197,28 @@ This field *can* be used in nested filter expressions, for example:
|
|
|
209
197
|
>>> Device.objects.filter(primary_ip4__host="1.1.1.1")
|
|
210
198
|
```
|
|
211
199
|
|
|
212
|
-
##### IPAddress `
|
|
200
|
+
##### IPAddress `mask_length` contains the prefix length
|
|
213
201
|
|
|
214
202
|
This is an integer, such as `30` for `/30`.
|
|
215
203
|
|
|
216
204
|
```python
|
|
217
|
-
>>> ip.
|
|
205
|
+
>>> ip.mask_length
|
|
218
206
|
30
|
|
219
207
|
```
|
|
220
208
|
|
|
221
|
-
For IP addresses with a
|
|
209
|
+
For IP addresses with a mask length other than a host prefix, you will need to filter using `host` and `mask_length` fields for greater accuracy.
|
|
222
210
|
|
|
223
|
-
For example, if you have multiple `IPAddress` objects with the same `host` value but different `
|
|
211
|
+
For example, if you have multiple `IPAddress` objects with the same `host` value but different `mask_length`:
|
|
224
212
|
|
|
225
213
|
```python
|
|
226
214
|
>>> IPAddress.objects.create(address="1.1.1.1/32")
|
|
227
215
|
<IPAddress: 1.1.1.1/32>
|
|
228
216
|
>>> IPAddress.objects.filter(host="1.1.1.1")
|
|
229
217
|
<IPAddressQuerySet [<IPAddress: 1.1.1.1/30>, <IPAddress: 1.1.1.1/32>]>
|
|
230
|
-
>>> IPAddress.objects.filter(host="1.1.1.1",
|
|
218
|
+
>>> IPAddress.objects.filter(host="1.1.1.1", mask_length=30)
|
|
231
219
|
<IPAddressQuerySet [<IPAddress: 1.1.1.1/30>]>
|
|
232
220
|
```
|
|
233
221
|
|
|
234
|
-
##### IPAddress `broadcast` contains the broadcast address
|
|
235
|
-
|
|
236
|
-
If the prefix length is that of a host prefix (e.g. `/32`), `broadcast` will be the same as the `host` :
|
|
237
|
-
|
|
238
|
-
```python
|
|
239
|
-
>>> IPAddress.objects.get(address="1.1.1.1/32").broadcast
|
|
240
|
-
'1.1.1.1'
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
If the prefix length is any larger (e.g. `/24`), `broadcast` will be that of the containing network for that prefix length (e.g. `1.1.1.255`):
|
|
244
|
-
|
|
245
|
-
```python
|
|
246
|
-
>>> IPAddress.objects.create(address="1.1.1.1/24").broadcast
|
|
247
|
-
'1.1.1.255'
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
!!! note
|
|
251
|
-
This field is largely for internal use only for facilitating network membership queries and it is not recommend that you use it for filtering.
|
|
252
|
-
|
|
253
222
|
#### Changes to `Aggregate` and `Prefix`
|
|
254
223
|
|
|
255
224
|
The following fields have changed when working with `ipam.Aggregate` and `ipam.Prefix` objects.
|
|
@@ -349,7 +318,7 @@ Prefix.objects.filter(prefix__net_mask_length=value)
|
|
|
349
318
|
Nautobot:
|
|
350
319
|
|
|
351
320
|
```python
|
|
352
|
-
IPAddress.objects.filter(
|
|
321
|
+
IPAddress.objects.filter(mask_length=value)
|
|
353
322
|
# or
|
|
354
323
|
Prefix.objects.filter(prefix_length=value)
|
|
355
324
|
```
|
|
@@ -204,7 +204,7 @@ Edit `$NAUTOBOT_ROOT/nautobot_config.py`, and head over to the documentation on
|
|
|
204
204
|
|
|
205
205
|
* [`ALLOWED_HOSTS`](../configuration/required-settings.md#allowed_hosts): You must set this value. This can be set to `["*"]` for a quick start, but this value is not suitable for production deployment.
|
|
206
206
|
* [`DATABASES`](../configuration/required-settings.md#databases): Database connection parameters. If you installed your database server on the same system as Nautobot, you'll need to update the `USER` and `PASSWORD` fields here. If you are using MySQL, you'll also need to update the `ENGINE` field, changing the default database driver suffix from `django.db.backends.postgresql` to `django.db.backends.mysql`.
|
|
207
|
-
* **Redis settings**: Redis configuration requires multiple settings
|
|
207
|
+
* **Redis settings**: Redis configuration requires multiple settings, if different from the defaults. If you installed Redis on the same system as Nautobot, you do not need to change these settings.
|
|
208
208
|
|
|
209
209
|
!!! important
|
|
210
210
|
You absolutely must update your required settings in your `nautobot_config.py` or Nautobot will not work.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
- Model: "(all)"
|
|
3
|
+
Field: "created"
|
|
4
|
+
Changes: "Now is a date/time rather than only a date"
|
|
5
|
+
- Model: "Cable"
|
|
6
|
+
Field: "status"
|
|
7
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
8
|
+
- Model: "Circuit"
|
|
9
|
+
Field: "status"
|
|
10
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
11
|
+
- Model: "Device"
|
|
12
|
+
Field: "config_context"
|
|
13
|
+
Changes: "Now is only included when specifically requested with `?include=config_context` query parameter"
|
|
14
|
+
- Model: "Device"
|
|
15
|
+
Field: "location"
|
|
16
|
+
Changes: "Now required, no longer optional"
|
|
17
|
+
- Model: "Device"
|
|
18
|
+
Field: "status"
|
|
19
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
20
|
+
- Model: "DeviceRedundancyGroup"
|
|
21
|
+
Field: "status"
|
|
22
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
23
|
+
- Model: "Interface"
|
|
24
|
+
Field: "status"
|
|
25
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
26
|
+
- Model: "IPAddress"
|
|
27
|
+
Field: "role"
|
|
28
|
+
Changes: "Now is a foreign-key to `Role` rather than a string"
|
|
29
|
+
- Model: "IPAddress"
|
|
30
|
+
Field: "status"
|
|
31
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
32
|
+
- Model: "JobLogEntry"
|
|
33
|
+
Field: "display"
|
|
34
|
+
Changes: "Now contains the message text rather than the message timestamp"
|
|
35
|
+
- Model: "Location"
|
|
36
|
+
Field: "status"
|
|
37
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
38
|
+
- Model: "PowerFeed"
|
|
39
|
+
Field: "status"
|
|
40
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
41
|
+
- Model: "PowerPanel"
|
|
42
|
+
Field: "location"
|
|
43
|
+
Changes: "Now required, no longer optional"
|
|
44
|
+
- Model: "Prefix"
|
|
45
|
+
Field: "status"
|
|
46
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
47
|
+
- Model: "Rack"
|
|
48
|
+
Field: "location"
|
|
49
|
+
Changes: "Now required, no longer optional"
|
|
50
|
+
- Model: "Rack"
|
|
51
|
+
Field: "status"
|
|
52
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
53
|
+
- Model: "RackGroup"
|
|
54
|
+
Field: "location"
|
|
55
|
+
Changes: "Now required, no longer optional"
|
|
56
|
+
- Model: "RackGroup"
|
|
57
|
+
Field: "rack_count"
|
|
58
|
+
Changes: "Now only counts Racks directly belonging to this RackGroup, not those belonging to its descendants"
|
|
59
|
+
- Model: "TenantGroup"
|
|
60
|
+
Field: "tenant_count"
|
|
61
|
+
Changes: "Now only counts Tenants directly belonging to this TenantGroup, not those belonging to its descendants"
|
|
62
|
+
- Model: "VirtualMachine"
|
|
63
|
+
Field: "status"
|
|
64
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
65
|
+
- Model: "VLAN"
|
|
66
|
+
Field: "status"
|
|
67
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|
|
68
|
+
- Model: "VMInterface"
|
|
69
|
+
Field: "status"
|
|
70
|
+
Changes: "Now is a foreign-key rather than a pseudo-enum"
|