nautobot 2.2.2__py3-none-any.whl → 2.2.4__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.
Potentially problematic release.
This version of nautobot might be problematic. Click here for more details.
- nautobot/apps/jobs.py +2 -0
- nautobot/core/api/utils.py +12 -9
- nautobot/core/apps/__init__.py +2 -2
- nautobot/core/celery/__init__.py +79 -68
- nautobot/core/celery/backends.py +9 -1
- nautobot/core/celery/control.py +4 -7
- nautobot/core/celery/schedulers.py +4 -2
- nautobot/core/celery/task.py +78 -5
- nautobot/core/graphql/schema.py +2 -1
- nautobot/core/jobs/__init__.py +2 -1
- nautobot/core/settings.py +6 -4
- nautobot/core/settings.yaml +51 -16
- nautobot/core/templates/admin/base.html +2 -2
- nautobot/core/templates/base_django.html +2 -2
- nautobot/core/templates/buttons/export.html +47 -47
- nautobot/core/templates/generic/object_list.html +3 -3
- nautobot/core/templates/inc/javascript.html +3 -0
- nautobot/core/templates/inc/media.html +3 -0
- nautobot/core/templates/login.html +2 -2
- nautobot/core/templates/nautobot_config.py.j2 +2 -0
- nautobot/core/templatetags/helpers.py +66 -9
- nautobot/core/testing/__init__.py +6 -1
- nautobot/core/testing/api.py +12 -13
- nautobot/core/testing/mixins.py +2 -2
- nautobot/core/testing/views.py +50 -51
- nautobot/core/tests/test_api.py +23 -2
- nautobot/core/tests/test_jobs.py +79 -2
- nautobot/core/tests/test_templatetags_helpers.py +32 -0
- nautobot/core/tests/test_views.py +52 -0
- nautobot/core/tests/test_views_utils.py +22 -1
- nautobot/core/utils/module_loading.py +89 -0
- nautobot/core/views/mixins.py +4 -0
- nautobot/core/views/utils.py +3 -2
- nautobot/dcim/choices.py +14 -0
- nautobot/dcim/forms.py +51 -1
- nautobot/dcim/models/device_components.py +9 -5
- nautobot/dcim/templates/dcim/location.html +32 -13
- nautobot/dcim/templates/dcim/location_migrate_data_to_contact.html +102 -0
- nautobot/dcim/tests/test_views.py +376 -55
- nautobot/dcim/urls.py +5 -0
- nautobot/dcim/views.py +172 -21
- nautobot/extras/api/serializers.py +17 -6
- nautobot/extras/api/views.py +21 -10
- nautobot/extras/constants.py +3 -3
- nautobot/extras/datasources/git.py +47 -58
- nautobot/extras/forms/forms.py +3 -1
- nautobot/extras/jobs.py +79 -146
- nautobot/extras/models/datasources.py +0 -2
- nautobot/extras/models/jobs.py +36 -18
- nautobot/extras/plugins/__init__.py +1 -20
- nautobot/extras/signals.py +6 -9
- nautobot/extras/test_jobs/__init__.py +8 -0
- nautobot/extras/test_jobs/dry_run.py +3 -2
- nautobot/extras/test_jobs/fail.py +43 -0
- nautobot/extras/test_jobs/ipaddress_vars.py +40 -1
- nautobot/extras/test_jobs/jobs_module/__init__.py +5 -0
- nautobot/extras/test_jobs/jobs_module/jobs_submodule/__init__.py +1 -0
- nautobot/extras/test_jobs/jobs_module/jobs_submodule/jobs.py +6 -0
- nautobot/extras/test_jobs/pass.py +40 -0
- nautobot/extras/test_jobs/relative_import.py +11 -0
- nautobot/extras/tests/test_api.py +3 -0
- nautobot/extras/tests/test_context_managers.py +18 -0
- nautobot/extras/tests/test_datasources.py +125 -118
- nautobot/extras/tests/test_job_variables.py +57 -15
- nautobot/extras/tests/test_jobs.py +135 -1
- nautobot/extras/tests/test_models.py +26 -19
- nautobot/extras/tests/test_plugins.py +1 -3
- nautobot/extras/tests/test_views.py +2 -4
- nautobot/extras/utils.py +2 -1
- nautobot/extras/views.py +82 -116
- nautobot/ipam/api/views.py +8 -1
- nautobot/ipam/graphql/types.py +11 -0
- nautobot/ipam/mixins.py +32 -0
- nautobot/ipam/models.py +2 -1
- nautobot/ipam/querysets.py +6 -1
- nautobot/ipam/tests/test_models.py +82 -0
- nautobot/ipam/views.py +6 -6
- nautobot/project-static/docs/404.html +107 -51
- nautobot/project-static/docs/apps/index.html +107 -51
- nautobot/project-static/docs/apps/nautobot-apps.html +107 -51
- nautobot/project-static/docs/assets/_mkdocstrings.css +6 -1
- nautobot/project-static/docs/assets/extra.css +11 -0
- nautobot/project-static/docs/assets/javascripts/bundle.3220b9d7.min.js +29 -0
- nautobot/project-static/docs/assets/javascripts/bundle.3220b9d7.min.js.map +7 -0
- nautobot/project-static/docs/assets/stylesheets/main.66ac8b77.min.css +1 -0
- nautobot/project-static/docs/assets/stylesheets/main.66ac8b77.min.css.map +1 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/__init__.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/admin.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +108 -52
- nautobot/project-static/docs/code-reference/nautobot/apps/change_logging.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/choices.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/config.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/constants.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/datasources.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/exceptions.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/factory.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/forms.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/graphql.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +287 -262
- nautobot/project-static/docs/code-reference/nautobot/apps/models.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/querysets.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/secrets.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/tables.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/ui.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/urls.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/utils.html +107 -51
- nautobot/project-static/docs/code-reference/nautobot/apps/views.html +107 -51
- nautobot/project-static/docs/development/apps/api/configuration-view.html +110 -54
- nautobot/project-static/docs/development/apps/api/database-backend-config.html +110 -54
- nautobot/project-static/docs/development/apps/api/models/django-admin.html +107 -51
- nautobot/project-static/docs/development/apps/api/models/global-search.html +110 -54
- nautobot/project-static/docs/development/apps/api/models/graphql.html +113 -57
- nautobot/project-static/docs/development/apps/api/models/index.html +107 -51
- nautobot/project-static/docs/development/apps/api/nautobot-app-config.html +113 -57
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +107 -51
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +110 -54
- nautobot/project-static/docs/development/apps/api/platform-features/git-repository-content.html +107 -51
- nautobot/project-static/docs/development/apps/api/platform-features/index.html +107 -51
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +110 -54
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +111 -55
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +110 -54
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +110 -54
- nautobot/project-static/docs/development/apps/api/platform-features/uniquely-identify-objects.html +107 -51
- nautobot/project-static/docs/development/apps/api/prometheus.html +110 -54
- nautobot/project-static/docs/development/apps/api/setup.html +107 -51
- nautobot/project-static/docs/development/apps/api/testing.html +113 -57
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +110 -54
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +110 -54
- nautobot/project-static/docs/development/apps/api/ui-extensions/index.html +107 -51
- nautobot/project-static/docs/development/apps/api/ui-extensions/navigation.html +107 -51
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +113 -57
- nautobot/project-static/docs/development/apps/api/views/base-template.html +107 -51
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +110 -54
- nautobot/project-static/docs/development/apps/api/views/django-generic-views.html +107 -51
- nautobot/project-static/docs/development/apps/api/views/help-documentation.html +110 -54
- nautobot/project-static/docs/development/apps/api/views/index.html +107 -51
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +113 -57
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +122 -66
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +110 -54
- nautobot/project-static/docs/development/apps/api/views/notes.html +110 -54
- nautobot/project-static/docs/development/apps/api/views/rest-api.html +107 -51
- nautobot/project-static/docs/development/apps/api/views/urls.html +107 -51
- nautobot/project-static/docs/development/apps/index.html +128 -72
- nautobot/project-static/docs/development/apps/migration/code-updates.html +107 -51
- nautobot/project-static/docs/development/apps/migration/dependency-updates.html +107 -51
- nautobot/project-static/docs/development/apps/migration/from-v1.html +107 -51
- nautobot/project-static/docs/development/apps/migration/model-updates/dcim.html +107 -51
- nautobot/project-static/docs/development/apps/migration/model-updates/extras.html +107 -51
- nautobot/project-static/docs/development/apps/migration/model-updates/global.html +107 -51
- nautobot/project-static/docs/development/apps/migration/model-updates/ipam.html +107 -51
- nautobot/project-static/docs/development/apps/porting-from-netbox.html +110 -54
- nautobot/project-static/docs/development/core/application-registry.html +242 -144
- nautobot/project-static/docs/development/core/best-practices.html +122 -66
- nautobot/project-static/docs/development/core/bootstrap-ui.html +107 -51
- nautobot/project-static/docs/development/core/caching.html +107 -51
- nautobot/project-static/docs/development/core/controllers.html +107 -51
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +113 -57
- nautobot/project-static/docs/development/core/generic-views.html +110 -54
- nautobot/project-static/docs/development/core/getting-started.html +135 -79
- nautobot/project-static/docs/development/core/homepage.html +110 -54
- nautobot/project-static/docs/development/core/index.html +107 -51
- nautobot/project-static/docs/development/core/model-checklist.html +156 -52
- nautobot/project-static/docs/development/core/model-features.html +108 -52
- nautobot/project-static/docs/development/core/natural-keys.html +110 -54
- nautobot/project-static/docs/development/core/navigation-menu.html +107 -51
- nautobot/project-static/docs/development/core/release-checklist.html +107 -51
- nautobot/project-static/docs/development/core/role-internals.html +107 -51
- nautobot/project-static/docs/development/core/settings.html +107 -51
- nautobot/project-static/docs/development/core/style-guide.html +110 -54
- nautobot/project-static/docs/development/core/templates.html +113 -57
- nautobot/project-static/docs/development/core/testing.html +125 -69
- nautobot/project-static/docs/development/core/user-preferences.html +107 -51
- nautobot/project-static/docs/development/index.html +107 -51
- nautobot/project-static/docs/development/jobs/index.html +504 -172
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +111 -55
- nautobot/project-static/docs/docker/index.html +3 -3
- nautobot/project-static/docs/index.html +125 -69
- nautobot/project-static/docs/installation/selinux-troubleshooting.html +3 -3
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/index.html +107 -51
- nautobot/project-static/docs/release-notes/version-1.0.html +107 -51
- nautobot/project-static/docs/release-notes/version-1.1.html +107 -51
- nautobot/project-static/docs/release-notes/version-1.2.html +107 -51
- nautobot/project-static/docs/release-notes/version-1.3.html +107 -51
- nautobot/project-static/docs/release-notes/version-1.4.html +107 -51
- nautobot/project-static/docs/release-notes/version-1.5.html +116 -60
- nautobot/project-static/docs/release-notes/version-1.6.html +107 -51
- nautobot/project-static/docs/release-notes/version-2.0.html +110 -54
- nautobot/project-static/docs/release-notes/version-2.1.html +107 -51
- nautobot/project-static/docs/release-notes/version-2.2.html +500 -114
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +262 -262
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/ldap.html +107 -51
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/remote.html +107 -51
- nautobot/project-static/docs/user-guide/administration/configuration/authentication/sso.html +107 -51
- nautobot/project-static/docs/user-guide/administration/configuration/index.html +107 -51
- nautobot/project-static/docs/user-guide/administration/configuration/optional-settings.html +251 -164
- nautobot/project-static/docs/user-guide/administration/configuration/required-settings.html +113 -57
- nautobot/project-static/docs/user-guide/administration/configuration/time-zones.html +107 -51
- nautobot/project-static/docs/user-guide/administration/guides/caching.html +113 -57
- nautobot/project-static/docs/user-guide/administration/guides/celery-queues.html +107 -51
- nautobot/project-static/docs/user-guide/administration/guides/healthcheck.html +107 -51
- nautobot/project-static/docs/user-guide/administration/guides/permissions.html +107 -51
- nautobot/project-static/docs/user-guide/administration/guides/prometheus-metrics.html +113 -57
- nautobot/project-static/docs/user-guide/administration/guides/replicating-nautobot.html +107 -51
- nautobot/project-static/docs/user-guide/administration/guides/request-profiling.html +107 -51
- nautobot/project-static/docs/user-guide/administration/guides/s3-django-storage.html +107 -51
- nautobot/project-static/docs/user-guide/administration/installation/app-install.html +171 -112
- nautobot/project-static/docs/user-guide/administration/installation/docker.html +13 -8626
- nautobot/project-static/docs/user-guide/administration/installation/external-authentication.html +117 -61
- nautobot/project-static/docs/user-guide/administration/installation/health-checks.html +13 -8614
- nautobot/project-static/docs/user-guide/administration/installation/http-server.html +252 -165
- nautobot/project-static/docs/user-guide/administration/installation/index.html +165 -192
- nautobot/project-static/docs/user-guide/administration/installation/install_system.html +411 -691
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +248 -229
- nautobot/project-static/docs/user-guide/administration/installation/selinux-troubleshooting.html +13 -8118
- nautobot/project-static/docs/user-guide/administration/installation/services.html +350 -240
- nautobot/project-static/docs/user-guide/administration/installation-extras/docker.html +8684 -0
- nautobot/project-static/docs/user-guide/administration/installation-extras/health-checks.html +8672 -0
- nautobot/project-static/docs/user-guide/administration/installation-extras/selinux-troubleshooting.html +8176 -0
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-netbox.html +110 -54
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +110 -54
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +155 -99
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-shell.html +107 -51
- nautobot/project-static/docs/user-guide/administration/upgrading/database-backup.html +109 -53
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/after-you-upgrade.html +107 -51
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/before-you-upgrade.html +107 -51
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/for-developers.html +107 -51
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/index.html +107 -51
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/ipam/whats-changed.html +107 -51
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/region-and-site-data-migration-guide.html +107 -51
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +117 -58
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuit.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittermination.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/circuits/circuittype.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/circuits/provider.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/cable.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controller.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/controllermanageddevicegroup.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/device.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicefamily.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +116 -60
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +119 -63
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/dcim/manufacturer.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerfeed.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerpanel.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rack.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackgroup.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rackreservation.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareimagefile.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/softwareversion.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/dcim/virtualchassis.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/extras/contact.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/extras/team.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +125 -69
- nautobot/project-static/docs/user-guide/core-data-model/ipam/namespace.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/ipam/prefix.html +128 -72
- nautobot/project-static/docs/user-guide/core-data-model/ipam/rir.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/ipam/routetarget.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/ipam/service.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +227 -60
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlangroup.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vrf.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/overview/introduction.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenant.html +110 -54
- nautobot/project-static/docs/user-guide/core-data-model/tenancy/tenantgroup.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/cluster.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustergroup.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/clustertype.html +107 -51
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/virtualmachine.html +113 -57
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +113 -57
- nautobot/project-static/docs/user-guide/feature-guides/contacts-and-teams.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +113 -57
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-devices.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/creating-location-types-and-locations.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/index.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/interfaces.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/ipam.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/platforms.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/search-bar.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/tenants.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/getting-started/vlans-and-vlan-groups.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/git-data-source.html +110 -54
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +113 -57
- nautobot/project-static/docs/user-guide/feature-guides/ip-address-merge-tool.html +107 -51
- nautobot/project-static/docs/user-guide/feature-guides/relationships.html +110 -54
- nautobot/project-static/docs/user-guide/feature-guides/software-image-files-and-versions.html +107 -51
- nautobot/project-static/docs/user-guide/index.html +109 -53
- nautobot/project-static/docs/user-guide/platform-functionality/change-logging.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +113 -57
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +128 -72
- nautobot/project-static/docs/user-guide/platform-functionality/customlink.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +125 -69
- nautobot/project-static/docs/user-guide/platform-functionality/exporttemplate.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/externalintegration.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +125 -69
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/graphqlquery.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/imageattachment.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +143 -100
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +113 -57
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +113 -57
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +123 -67
- nautobot/project-static/docs/user-guide/platform-functionality/napalm.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +116 -60
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +131 -75
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +149 -93
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/ui-related-endpoints.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/role.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +116 -60
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +119 -63
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +137 -81
- nautobot/project-static/docs/user-guide/platform-functionality/users/objectpermission.html +110 -54
- nautobot/project-static/docs/user-guide/platform-functionality/users/token.html +107 -51
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +110 -54
- nautobot/project-static/js/forms.js +18 -11
- nautobot/tenancy/views.py +2 -6
- nautobot/virtualization/views.py +5 -9
- {nautobot-2.2.2.dist-info → nautobot-2.2.4.dist-info}/METADATA +4 -4
- {nautobot-2.2.2.dist-info → nautobot-2.2.4.dist-info}/RECORD +357 -348
- nautobot/extras/test_jobs/job_variables.py +0 -93
- nautobot/project-static/docs/assets/javascripts/bundle.bd41221c.min.js +0 -29
- nautobot/project-static/docs/assets/javascripts/bundle.bd41221c.min.js.map +0 -7
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css +0 -1
- nautobot/project-static/docs/assets/stylesheets/main.bcfcd587.min.css.map +0 -1
- {nautobot-2.2.2.dist-info → nautobot-2.2.4.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.2.2.dist-info → nautobot-2.2.4.dist-info}/NOTICE +0 -0
- {nautobot-2.2.2.dist-info → nautobot-2.2.4.dist-info}/WHEEL +0 -0
- {nautobot-2.2.2.dist-info → nautobot-2.2.4.dist-info}/entry_points.txt +0 -0
nautobot/apps/jobs.py
CHANGED
|
@@ -12,6 +12,7 @@ from nautobot.extras.jobs import (
|
|
|
12
12
|
enqueue_job_hooks,
|
|
13
13
|
FileVar,
|
|
14
14
|
get_job,
|
|
15
|
+
get_jobs,
|
|
15
16
|
IntegerVar,
|
|
16
17
|
IPAddressVar,
|
|
17
18
|
IPAddressWithMaskVar,
|
|
@@ -40,6 +41,7 @@ __all__ = (
|
|
|
40
41
|
"enqueue_job_hooks",
|
|
41
42
|
"FileVar",
|
|
42
43
|
"get_job",
|
|
44
|
+
"get_jobs",
|
|
43
45
|
"GitRepositoryDryRun",
|
|
44
46
|
"GitRepositorySync",
|
|
45
47
|
"IntegerVar",
|
nautobot/core/api/utils.py
CHANGED
|
@@ -167,28 +167,31 @@ def is_api_request(request):
|
|
|
167
167
|
return request.path_info.startswith(api_path)
|
|
168
168
|
|
|
169
169
|
|
|
170
|
-
def get_view_name(view
|
|
170
|
+
def get_view_name(view):
|
|
171
171
|
"""
|
|
172
172
|
Derive the view name from its associated model, if it has one. Fall back to DRF's built-in `get_view_name`.
|
|
173
173
|
"""
|
|
174
|
-
if hasattr(view, "
|
|
174
|
+
if hasattr(view, "name") and view.name:
|
|
175
|
+
return view.name
|
|
176
|
+
elif hasattr(view, "queryset"):
|
|
175
177
|
# Determine the model name from the queryset.
|
|
176
|
-
|
|
178
|
+
if hasattr(view, "detail") and view.detail:
|
|
179
|
+
name = view.queryset.model._meta.verbose_name
|
|
180
|
+
else:
|
|
181
|
+
name = view.queryset.model._meta.verbose_name_plural
|
|
177
182
|
name = " ".join([w[0].upper() + w[1:] for w in name.split()]) # Capitalize each word
|
|
178
183
|
|
|
179
184
|
else:
|
|
180
185
|
# Replicate DRF's built-in behavior.
|
|
181
|
-
name = getattr(view, "name", None)
|
|
182
|
-
if name is not None:
|
|
183
|
-
return view.name
|
|
184
|
-
|
|
185
186
|
name = view.__class__.__name__
|
|
186
187
|
name = formatting.remove_trailing_string(name, "View")
|
|
187
188
|
name = formatting.remove_trailing_string(name, "ViewSet")
|
|
188
189
|
name = formatting.camelcase_to_spaces(name)
|
|
189
190
|
|
|
190
|
-
|
|
191
|
-
|
|
191
|
+
# Suffix may be set by some Views, such as a ViewSet.
|
|
192
|
+
suffix = getattr(view, "suffix", None)
|
|
193
|
+
if suffix:
|
|
194
|
+
name += " " + suffix
|
|
192
195
|
|
|
193
196
|
return name
|
|
194
197
|
|
nautobot/core/apps/__init__.py
CHANGED
|
@@ -918,9 +918,9 @@ class CoreConfig(NautobotConfig):
|
|
|
918
918
|
super().ready()
|
|
919
919
|
|
|
920
920
|
# Register jobs last after everything else has been done.
|
|
921
|
-
from nautobot.core.celery import
|
|
921
|
+
from nautobot.core.celery import import_jobs
|
|
922
922
|
|
|
923
|
-
|
|
923
|
+
import_jobs()
|
|
924
924
|
|
|
925
925
|
|
|
926
926
|
class NautobotConstanceConfig(ConstanceConfig):
|
nautobot/core/celery/__init__.py
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
from importlib.util import find_spec
|
|
2
1
|
import json
|
|
3
2
|
import logging
|
|
4
3
|
import os
|
|
5
4
|
from pathlib import Path
|
|
6
|
-
import pkgutil
|
|
7
5
|
import shutil
|
|
8
|
-
import sys
|
|
9
6
|
|
|
10
7
|
from celery import Celery, shared_task, signals
|
|
11
8
|
from celery.app.log import TaskFormatter
|
|
12
9
|
from celery.utils.log import get_logger
|
|
13
10
|
from django.conf import settings
|
|
11
|
+
from django.db.utils import ProgrammingError
|
|
14
12
|
from django.utils.functional import SimpleLazyObject
|
|
15
13
|
from django.utils.module_loading import import_string
|
|
16
14
|
from kombu.serialization import register
|
|
@@ -19,6 +17,8 @@ from prometheus_client import CollectorRegistry, multiprocess, start_http_server
|
|
|
19
17
|
from nautobot.core.celery.control import discard_git_repository, refresh_git_repository # noqa: F401 # unused-import
|
|
20
18
|
from nautobot.core.celery.encoders import NautobotKombuJSONEncoder
|
|
21
19
|
from nautobot.core.celery.log import NautobotDatabaseHandler
|
|
20
|
+
from nautobot.core.utils.module_loading import import_modules_privately
|
|
21
|
+
from nautobot.extras.registry import registry
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
24
24
|
|
|
@@ -29,16 +29,6 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "nautobot_config")
|
|
|
29
29
|
class NautobotCelery(Celery):
|
|
30
30
|
task_cls = "nautobot.core.celery.task:NautobotTask"
|
|
31
31
|
|
|
32
|
-
def register_task(self, task, **options):
|
|
33
|
-
"""Override the default task name for job classes to allow app provided jobs to use the full module path."""
|
|
34
|
-
from nautobot.extras.jobs import Job
|
|
35
|
-
|
|
36
|
-
if issubclass(task, Job):
|
|
37
|
-
task = task()
|
|
38
|
-
task.name = task.registered_name
|
|
39
|
-
|
|
40
|
-
return super().register_task(task, **options)
|
|
41
|
-
|
|
42
32
|
|
|
43
33
|
app = NautobotCelery("nautobot")
|
|
44
34
|
|
|
@@ -53,60 +43,77 @@ app.autodiscover_tasks()
|
|
|
53
43
|
|
|
54
44
|
|
|
55
45
|
@signals.import_modules.connect
|
|
56
|
-
def
|
|
46
|
+
def import_jobs(sender=None, **kwargs):
|
|
57
47
|
"""
|
|
58
|
-
Import system Jobs into
|
|
48
|
+
Import system Jobs into Nautobot as well as Jobs from JOBS_ROOT and GIT_ROOT.
|
|
49
|
+
|
|
50
|
+
Note that app-provided jobs are automatically imported at startup time via NautobotAppConfig.ready()
|
|
51
|
+
"""
|
|
52
|
+
import nautobot.core.jobs # noqa: F401
|
|
53
|
+
|
|
54
|
+
_import_jobs_from_jobs_root()
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
try:
|
|
57
|
+
_import_jobs_from_git_repositories()
|
|
58
|
+
except ProgrammingError: # Database not ready yet, as may be the case on initial startup and migration
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _import_jobs_from_jobs_root():
|
|
63
|
+
"""
|
|
64
|
+
(Re)import all modules in settings.JOBS_ROOT.
|
|
61
65
|
"""
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
existing_module_path = os.path.realpath(existing_module.origin)
|
|
75
|
-
jobs_root_path = os.path.realpath(jobs_root)
|
|
76
|
-
if not existing_module_path.startswith(jobs_root_path):
|
|
77
|
-
raise ImportError(
|
|
78
|
-
f"JOBS_ROOT Jobs module {module_name} conflicts with existing module {existing_module_path}"
|
|
79
|
-
)
|
|
80
|
-
sender.loader.import_task_module(module_name)
|
|
81
|
-
except Exception as exc:
|
|
82
|
-
logger.exception(exc)
|
|
83
|
-
|
|
84
|
-
git_root = settings.GIT_ROOT
|
|
85
|
-
if git_root and os.path.exists(git_root):
|
|
86
|
-
if git_root not in sys.path:
|
|
87
|
-
sys.path.append(git_root)
|
|
88
|
-
|
|
89
|
-
# We can't detect which Git directories we're *supposed* to auto-load Jobs from if we can't read GitRepository
|
|
90
|
-
# records from the DB, unfortunately.
|
|
91
|
-
# We work around this in JobModel.job_task to try later loading Git jobs on-the-fly if needed.
|
|
92
|
-
if database_ready:
|
|
66
|
+
if not (settings.JOBS_ROOT and os.path.isdir(settings.JOBS_ROOT)):
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
# Flush any previously loaded non-system, non-App Jobs
|
|
70
|
+
for job_class_path in list(registry["jobs"]):
|
|
71
|
+
if job_class_path.startswith("nautobot."):
|
|
72
|
+
# System job
|
|
73
|
+
continue
|
|
74
|
+
if any(job_class_path.startswith(f"{app_name}.") for app_name in settings.PLUGINS):
|
|
75
|
+
# App provided job
|
|
76
|
+
continue
|
|
77
|
+
try:
|
|
93
78
|
from nautobot.extras.models import GitRepository
|
|
94
79
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
80
|
+
if any(
|
|
81
|
+
job_class_path.startswith(f"{repo.slug}.")
|
|
82
|
+
for repo in GitRepository.objects.filter(provided_contents__contains="extras.job")
|
|
83
|
+
):
|
|
84
|
+
# Git provided job
|
|
85
|
+
continue
|
|
86
|
+
except ProgrammingError: # Database not ready yet, as may be the case on initial startup and migration
|
|
87
|
+
pass
|
|
88
|
+
# Else, it's presumably a JOBS_ROOT job
|
|
89
|
+
del registry["jobs"][job_class_path]
|
|
90
|
+
|
|
91
|
+
# Load all modules in JOBS_ROOT
|
|
92
|
+
import_modules_privately(path=os.path.realpath(settings.JOBS_ROOT))
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _import_jobs_from_git_repositories():
|
|
96
|
+
git_root = os.path.realpath(settings.GIT_ROOT)
|
|
97
|
+
if not (git_root and os.path.exists(git_root)):
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
from nautobot.extras.models import GitRepository
|
|
101
|
+
|
|
102
|
+
# Make sure there are no git clones in GIT_ROOT that *aren't* tracked by a GitRepository;
|
|
103
|
+
# for example, maybe a GitRepository was deleted while this worker process wasn't running?
|
|
104
|
+
for filename in os.listdir(git_root):
|
|
105
|
+
filepath = os.path.join(git_root, filename)
|
|
106
|
+
if (
|
|
107
|
+
os.path.isdir(filepath)
|
|
108
|
+
and os.path.isdir(os.path.join(filepath, ".git"))
|
|
109
|
+
and not GitRepository.objects.filter(slug=filename).exists()
|
|
110
|
+
):
|
|
111
|
+
logger.warning("Deleting unmanaged (leftover?) Git repository clone at %s", filepath)
|
|
112
|
+
shutil.rmtree(filepath)
|
|
106
113
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
114
|
+
# Make sure all GitRepository records that include Jobs have up-to-date git clones, and load their jobs
|
|
115
|
+
for repo in GitRepository.objects.filter(provided_contents__contains="extras.job"):
|
|
116
|
+
refresh_git_repository(state=None, repository_pk=repo.pk, head=repo.current_head)
|
|
110
117
|
|
|
111
118
|
|
|
112
119
|
def add_nautobot_log_handler(logger_instance, log_format=None):
|
|
@@ -151,11 +158,11 @@ def setup_prometheus(**kwargs):
|
|
|
151
158
|
multiprocess_coordination_directory.mkdir(parents=True, exist_ok=True)
|
|
152
159
|
|
|
153
160
|
# Set up the collector registry
|
|
154
|
-
|
|
155
|
-
multiprocess.MultiProcessCollector(
|
|
161
|
+
collector_registry = CollectorRegistry()
|
|
162
|
+
multiprocess.MultiProcessCollector(collector_registry, path=multiprocess_coordination_directory)
|
|
156
163
|
for port in settings.CELERY_WORKER_PROMETHEUS_PORTS:
|
|
157
164
|
try:
|
|
158
|
-
start_http_server(port, registry=
|
|
165
|
+
start_http_server(port, registry=collector_registry)
|
|
159
166
|
break
|
|
160
167
|
except OSError:
|
|
161
168
|
continue
|
|
@@ -206,9 +213,13 @@ register("nautobot_json", _dumps, _loads, content_type="application/x-nautobot-j
|
|
|
206
213
|
nautobot_task = shared_task
|
|
207
214
|
|
|
208
215
|
|
|
216
|
+
registry["jobs"] = {}
|
|
217
|
+
|
|
218
|
+
|
|
209
219
|
def register_jobs(*jobs):
|
|
210
|
-
"""
|
|
220
|
+
"""
|
|
221
|
+
Method to register jobs - with Celery in Nautobot 2.0 through 2.2.2, with Nautobot itself in 2.2.3 and later.
|
|
222
|
+
"""
|
|
211
223
|
for job in jobs:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
app.register_task(job)
|
|
224
|
+
if job.class_path not in registry["jobs"]:
|
|
225
|
+
registry["jobs"][job.class_path] = job
|
nautobot/core/celery/backends.py
CHANGED
|
@@ -37,6 +37,7 @@ class NautobotDatabaseBackend(DatabaseBackend):
|
|
|
37
37
|
"worker": None,
|
|
38
38
|
}
|
|
39
39
|
if request and self.app.conf.find_value_for_key("extended", "result"):
|
|
40
|
+
task_name = getattr(request, "task", None)
|
|
40
41
|
# do not encode args/kwargs as we store these in a JSONField instead of TextField
|
|
41
42
|
task_args = getattr(request, "args", None)
|
|
42
43
|
task_kwargs = getattr(request, "kwargs", None)
|
|
@@ -54,6 +55,13 @@ class NautobotDatabaseBackend(DatabaseBackend):
|
|
|
54
55
|
if traceback is not None:
|
|
55
56
|
traceback = sanitize(traceback)
|
|
56
57
|
|
|
58
|
+
# Preserve the JobResult data behavior from Nautobot 2.0 through 2.2 (wherein the Job itself was the task)
|
|
59
|
+
# by manipulating `task_name` and `task_args` to hide the fact that we are now calling
|
|
60
|
+
# `run_job.apply(args=[JobClass.class_path, ...])` instead of `JobClass.apply(args=[...])`.
|
|
61
|
+
if task_name == "nautobot.extras.jobs.run_job" and task_args:
|
|
62
|
+
task_name = task_args[0]
|
|
63
|
+
task_args = task_args[1:]
|
|
64
|
+
|
|
57
65
|
extended_props.update(
|
|
58
66
|
{
|
|
59
67
|
"task_args": task_args,
|
|
@@ -61,7 +69,7 @@ class NautobotDatabaseBackend(DatabaseBackend):
|
|
|
61
69
|
"celery_kwargs": celery_kwargs,
|
|
62
70
|
"job_model_id": properties.get("nautobot_job_job_model_id", None),
|
|
63
71
|
"scheduled_job_id": properties.get("nautobot_job_scheduled_job_id", None),
|
|
64
|
-
"task_name":
|
|
72
|
+
"task_name": task_name,
|
|
65
73
|
"traceback": traceback,
|
|
66
74
|
"user_id": properties.get("nautobot_job_user_id", None),
|
|
67
75
|
"worker": getattr(request, "hostname", None),
|
nautobot/core/celery/control.py
CHANGED
|
@@ -13,14 +13,14 @@ def refresh_git_repository(state, repository_pk, head):
|
|
|
13
13
|
"""
|
|
14
14
|
Celery worker control event to ensure that all active workers have the correct head for a given Git repository.
|
|
15
15
|
"""
|
|
16
|
-
from nautobot.extras.datasources.git import ensure_git_repository,
|
|
16
|
+
from nautobot.extras.datasources.git import ensure_git_repository, refresh_job_code_from_repository
|
|
17
17
|
from nautobot.extras.models import GitRepository
|
|
18
18
|
|
|
19
19
|
try:
|
|
20
20
|
repository = GitRepository.objects.get(pk=repository_pk)
|
|
21
21
|
# Refresh the repository on disk
|
|
22
22
|
ensure_git_repository(repository, head=head, logger=logger)
|
|
23
|
-
|
|
23
|
+
refresh_job_code_from_repository(repository.slug, ignore_import_errors=False)
|
|
24
24
|
|
|
25
25
|
return {"ok": {"head": repository.current_head}}
|
|
26
26
|
except Exception as exc:
|
|
@@ -33,12 +33,9 @@ def discard_git_repository(state, repository_slug):
|
|
|
33
33
|
"""
|
|
34
34
|
Celery worker control even to ensure that all active workers unload a given Git repository and delete it from disk.
|
|
35
35
|
"""
|
|
36
|
-
from nautobot.extras.datasources.git import
|
|
36
|
+
from nautobot.extras.datasources.git import refresh_job_code_from_repository
|
|
37
37
|
|
|
38
38
|
filesystem_path = os.path.join(settings.GIT_ROOT, repository_slug)
|
|
39
39
|
if os.path.isdir(filesystem_path):
|
|
40
40
|
shutil.rmtree(filesystem_path)
|
|
41
|
-
|
|
42
|
-
refresh_code_from_repository(
|
|
43
|
-
repository_slug, consumer=state.consumer if state is not None else None, skip_reimport=True
|
|
44
|
-
)
|
|
41
|
+
refresh_job_code_from_repository(repository_slug, skip_reimport=True)
|
|
@@ -22,11 +22,13 @@ class NautobotScheduleEntry(ModelEntry):
|
|
|
22
22
|
"""Initialize the model entry."""
|
|
23
23
|
self.app = app or current_app._get_current_object()
|
|
24
24
|
self.name = f"{model.name}_{model.pk}"
|
|
25
|
-
self.task =
|
|
25
|
+
self.task = "nautobot.extras.jobs.run_job"
|
|
26
26
|
try:
|
|
27
27
|
# Nautobot scheduled jobs pass args/kwargs as constructed objects,
|
|
28
28
|
# but Celery built-in jobs such as celery.backend_cleanup pass them as JSON to be parsed
|
|
29
|
-
self.args = model.
|
|
29
|
+
self.args = [model.task] + (
|
|
30
|
+
model.args if isinstance(model.args, (tuple, list)) else loads(model.args or "[]")
|
|
31
|
+
)
|
|
30
32
|
self.kwargs = model.kwargs if isinstance(model.kwargs, dict) else loads(model.kwargs or "{}")
|
|
31
33
|
except (TypeError, ValueError) as exc:
|
|
32
34
|
logger.exception("Removing schedule %s for argument deserialization error: %s", self.name, exc)
|
nautobot/core/celery/task.py
CHANGED
|
@@ -1,12 +1,85 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
from billiard.einfo import ExceptionInfo, ExceptionWithTraceback
|
|
2
|
+
from celery import states, Task
|
|
3
|
+
from celery.exceptions import Retry
|
|
4
|
+
from celery.result import EagerResult
|
|
5
|
+
from celery.utils.functional import maybe_list
|
|
6
|
+
from celery.utils.nodenames import gethostname
|
|
7
|
+
from kombu.utils.uuid import uuid
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class NautobotTask(Task):
|
|
9
11
|
"""Nautobot extensions to tasks for integrating with Job machinery."""
|
|
10
12
|
|
|
13
|
+
def apply(
|
|
14
|
+
self,
|
|
15
|
+
args=None,
|
|
16
|
+
kwargs=None,
|
|
17
|
+
link=None,
|
|
18
|
+
link_error=None,
|
|
19
|
+
task_id=None,
|
|
20
|
+
retries=None,
|
|
21
|
+
throw=None,
|
|
22
|
+
logfile=None,
|
|
23
|
+
loglevel=None,
|
|
24
|
+
headers=None,
|
|
25
|
+
**options,
|
|
26
|
+
):
|
|
27
|
+
"""Fix celery's Task.apply() method to propagate options to the task result just like apply_async does."""
|
|
28
|
+
# trace imports Task, so need to import inline.
|
|
29
|
+
from celery.app.trace import build_tracer
|
|
30
|
+
|
|
31
|
+
app = self._get_app()
|
|
32
|
+
args = args or ()
|
|
33
|
+
kwargs = kwargs or {}
|
|
34
|
+
task_id = task_id or uuid()
|
|
35
|
+
retries = retries or 0
|
|
36
|
+
if throw is None:
|
|
37
|
+
throw = app.conf.task_eager_propagates
|
|
38
|
+
|
|
39
|
+
# Make sure we get the task instance, not class.
|
|
40
|
+
task = app._tasks[self.name]
|
|
41
|
+
|
|
42
|
+
request = {
|
|
43
|
+
"id": task_id,
|
|
44
|
+
"retries": retries,
|
|
45
|
+
"is_eager": True,
|
|
46
|
+
"logfile": logfile,
|
|
47
|
+
"loglevel": loglevel or 0,
|
|
48
|
+
"hostname": gethostname(),
|
|
49
|
+
"callbacks": maybe_list(link),
|
|
50
|
+
"errbacks": maybe_list(link_error),
|
|
51
|
+
"headers": headers,
|
|
52
|
+
"ignore_result": options.get("ignore_result", False),
|
|
53
|
+
"delivery_info": {
|
|
54
|
+
"is_eager": True,
|
|
55
|
+
"exchange": options.get("exchange"),
|
|
56
|
+
"routing_key": options.get("routing_key"),
|
|
57
|
+
"priority": options.get("priority"),
|
|
58
|
+
},
|
|
59
|
+
"properties": options, # <------- this is the one line fix to the overloaded method
|
|
60
|
+
}
|
|
61
|
+
if "stamped_headers" in options:
|
|
62
|
+
request["stamped_headers"] = maybe_list(options["stamped_headers"])
|
|
63
|
+
request["stamps"] = {header: maybe_list(options.get(header, [])) for header in request["stamped_headers"]}
|
|
64
|
+
|
|
65
|
+
tb = None
|
|
66
|
+
tracer = build_tracer(
|
|
67
|
+
task.name,
|
|
68
|
+
task,
|
|
69
|
+
eager=True,
|
|
70
|
+
propagate=throw,
|
|
71
|
+
app=self._get_app(),
|
|
72
|
+
)
|
|
73
|
+
ret = tracer(task_id, args, kwargs, request)
|
|
74
|
+
retval = ret.retval
|
|
75
|
+
if isinstance(retval, ExceptionInfo):
|
|
76
|
+
retval, tb = retval.exception, retval.traceback
|
|
77
|
+
if isinstance(retval, ExceptionWithTraceback):
|
|
78
|
+
retval = retval.exc
|
|
79
|
+
if isinstance(retval, Retry) and retval.sig is not None:
|
|
80
|
+
return retval.sig.apply(retries=retries + 1)
|
|
81
|
+
state = states.SUCCESS if ret.info is None else ret.info.state
|
|
82
|
+
return EagerResult(task_id, retval, state, traceback=tb)
|
|
83
|
+
|
|
11
84
|
|
|
12
85
|
Task = NautobotTask # So that the class path resolves.
|
nautobot/core/graphql/schema.py
CHANGED
|
@@ -45,7 +45,7 @@ from nautobot.extras.graphql.types import DynamicGroupType, TagType
|
|
|
45
45
|
from nautobot.extras.models import ComputedField, CustomField, Relationship
|
|
46
46
|
from nautobot.extras.registry import registry
|
|
47
47
|
from nautobot.extras.utils import check_if_key_is_graphql_safe
|
|
48
|
-
from nautobot.ipam.graphql.types import IPAddressType, PrefixType
|
|
48
|
+
from nautobot.ipam.graphql.types import IPAddressType, PrefixType, VLANType
|
|
49
49
|
from nautobot.virtualization.graphql.types import VirtualMachineType, VMInterfaceType
|
|
50
50
|
|
|
51
51
|
logger = logging.getLogger(__name__)
|
|
@@ -71,6 +71,7 @@ registry["graphql_types"]["extras.tag"] = TagType
|
|
|
71
71
|
registry["graphql_types"]["extras.dynamicgroup"] = DynamicGroupType
|
|
72
72
|
registry["graphql_types"]["ipam.ipaddress"] = IPAddressType
|
|
73
73
|
registry["graphql_types"]["ipam.prefix"] = PrefixType
|
|
74
|
+
registry["graphql_types"]["ipam.vlan"] = VLANType
|
|
74
75
|
registry["graphql_types"]["virtualization.virtualmachine"] = VirtualMachineType
|
|
75
76
|
registry["graphql_types"]["virtualization.vminterface"] = VMInterfaceType
|
|
76
77
|
|
nautobot/core/jobs/__init__.py
CHANGED
|
@@ -50,7 +50,8 @@ class GitRepositorySync(Job):
|
|
|
50
50
|
# Given that the above succeeded, tell all workers (including ourself) to call ensure_git_repository()
|
|
51
51
|
app.control.broadcast("refresh_git_repository", repository_pk=repository.pk, head=repository.current_head)
|
|
52
52
|
finally:
|
|
53
|
-
|
|
53
|
+
if job_result.duration:
|
|
54
|
+
self.logger.info("Repository synchronization completed in %s", job_result.duration)
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
class GitRepositoryDryRun(Job):
|
nautobot/core/settings.py
CHANGED
|
@@ -69,7 +69,7 @@ ALLOWED_URL_SCHEMES = [
|
|
|
69
69
|
"xmpp",
|
|
70
70
|
]
|
|
71
71
|
|
|
72
|
-
# Banners to display to users. HTML
|
|
72
|
+
# Banners to display to users. Markdown and limited HTML are allowed.
|
|
73
73
|
if "NAUTOBOT_BANNER_BOTTOM" in os.environ and os.environ["NAUTOBOT_BANNER_BOTTOM"] != "":
|
|
74
74
|
BANNER_BOTTOM = os.environ["NAUTOBOT_BANNER_BOTTOM"]
|
|
75
75
|
if "NAUTOBOT_BANNER_LOGIN" in os.environ and os.environ["NAUTOBOT_BANNER_LOGIN"] != "":
|
|
@@ -686,15 +686,15 @@ CONSTANCE_CONFIG = {
|
|
|
686
686
|
),
|
|
687
687
|
"BANNER_BOTTOM": ConstanceConfigItem(
|
|
688
688
|
default="",
|
|
689
|
-
help_text="Custom HTML to display in a banner at the bottom of all pages.",
|
|
689
|
+
help_text="Custom Markdown or limited HTML to display in a banner at the bottom of all pages.",
|
|
690
690
|
),
|
|
691
691
|
"BANNER_LOGIN": ConstanceConfigItem(
|
|
692
692
|
default="",
|
|
693
|
-
help_text="Custom HTML to display in a banner at the top of the login page.",
|
|
693
|
+
help_text="Custom Markdown or limited HTML to display in a banner at the top of the login page.",
|
|
694
694
|
),
|
|
695
695
|
"BANNER_TOP": ConstanceConfigItem(
|
|
696
696
|
default="",
|
|
697
|
-
help_text="Custom HTML to display in a banner at the top of all pages.",
|
|
697
|
+
help_text="Custom Markdown or limited HTML to display in a banner at the top of all pages.",
|
|
698
698
|
),
|
|
699
699
|
"CHANGELOG_RETENTION": ConstanceConfigItem(
|
|
700
700
|
default=90,
|
|
@@ -972,6 +972,8 @@ BRANDING_FILEPATHS = {
|
|
|
972
972
|
"NAUTOBOT_BRANDING_FILEPATHS_HEADER_BULLET", None
|
|
973
973
|
), # bullet image used for various view headers
|
|
974
974
|
"nav_bullet": os.getenv("NAUTOBOT_BRANDING_FILEPATHS_NAV_BULLET", None), # bullet image used for nav menu headers
|
|
975
|
+
"css": os.getenv("NAUTOBOT_BRANDING_FILEPATHS_CSS", None), # Custom global CSS
|
|
976
|
+
"javascript": os.getenv("NAUTOBOT_BRANDING_FILEPATHS_JAVASCRIPT", None), # Custom global JavaScript
|
|
975
977
|
}
|
|
976
978
|
|
|
977
979
|
# Title to use in place of "Nautobot"
|
nautobot/core/settings.yaml
CHANGED
|
@@ -128,24 +128,40 @@ properties:
|
|
|
128
128
|
type: "array"
|
|
129
129
|
BANNER_BOTTOM:
|
|
130
130
|
default: ""
|
|
131
|
-
description:
|
|
131
|
+
description: >-
|
|
132
|
+
Custom content to be displayed in a banner at the bottom of all Nautobot pages.
|
|
133
|
+
details: |-
|
|
134
|
+
+/- 2.2.4
|
|
135
|
+
Markdown formatting is supported within this message, as well as
|
|
136
|
+
[a limited subset of HTML](../../platform-functionality/template-filters.md#render_markdown).
|
|
132
137
|
environment_variable: "NAUTOBOT_BANNER_BOTTOM"
|
|
133
138
|
is_constance_config: true
|
|
134
139
|
type: "string"
|
|
135
140
|
BANNER_LOGIN:
|
|
136
141
|
default: ""
|
|
137
|
-
description:
|
|
142
|
+
description: >-
|
|
143
|
+
Custom content to be displayed in a banner on the login page above the login form.
|
|
144
|
+
details: |-
|
|
145
|
+
+/- 2.2.4
|
|
146
|
+
Markdown formatting is supported within this message, as well as
|
|
147
|
+
[a limited subset of HTML](../../platform-functionality/template-filters.md#render_markdown).
|
|
138
148
|
environment_variable: "NAUTOBOT_BANNER_LOGIN"
|
|
139
149
|
is_constance_config: true
|
|
140
150
|
type: "string"
|
|
141
151
|
BANNER_TOP:
|
|
142
152
|
default: ""
|
|
143
|
-
description:
|
|
153
|
+
description: >-
|
|
154
|
+
Custom content to be displayed in a banner at the top of all Nautobot pages.
|
|
155
|
+
details: |-
|
|
156
|
+
+/- 2.2.4
|
|
157
|
+
Markdown formatting is supported within this message, as well as
|
|
158
|
+
[a limited subset of HTML](../../platform-functionality/template-filters.md#render_markdown).
|
|
144
159
|
environment_variable: "NAUTOBOT_BANNER_TOP"
|
|
145
160
|
is_constance_config: true
|
|
146
161
|
type: "string"
|
|
147
162
|
BRANDING_FILEPATHS:
|
|
148
163
|
default:
|
|
164
|
+
css: null
|
|
149
165
|
favicon: null
|
|
150
166
|
header_bullet: null
|
|
151
167
|
icon_16: null
|
|
@@ -153,57 +169,76 @@ properties:
|
|
|
153
169
|
icon_180: null
|
|
154
170
|
icon_192: null
|
|
155
171
|
icon_mask: null
|
|
172
|
+
javascript: null
|
|
156
173
|
logo: null
|
|
157
174
|
nav_bullet: null
|
|
158
175
|
description: >-
|
|
159
|
-
A set of filepaths relative to the [`MEDIA_ROOT`](#media_root) which locate
|
|
160
|
-
custom branding
|
|
176
|
+
A set of filepaths relative to the [`MEDIA_ROOT`](#media_root) which locate assets used for
|
|
177
|
+
custom branding of your Nautobot instance.
|
|
178
|
+
With the exception of `css` and `javascript`, which provide the option to add an _additional_ file to Nautobot
|
|
179
|
+
page content, each of the other assets takes the place of the corresponding stock Nautobot asset.
|
|
161
180
|
This allows for, for instance, providing your own navbar logo and favicon.
|
|
162
|
-
If a custom
|
|
181
|
+
If a custom asset is not provided for any of the above options, the stock Nautobot asset is used.
|
|
182
|
+
details: |-
|
|
183
|
+
+++ 2.1.0
|
|
184
|
+
The `header_bullet` and `nav_bullet` assets were added as options.
|
|
185
|
+
|
|
186
|
+
+++ 2.2.4
|
|
187
|
+
The `css` and `javascript` assets were added as options.
|
|
163
188
|
properties:
|
|
189
|
+
css:
|
|
190
|
+
"$ref": "#/definitions/relative_path"
|
|
191
|
+
default: null
|
|
192
|
+
description: "Custom global CSS file"
|
|
193
|
+
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_CSS"
|
|
164
194
|
favicon:
|
|
165
195
|
"$ref": "#/definitions/relative_path"
|
|
166
|
-
default:
|
|
196
|
+
default: null
|
|
167
197
|
description: "Browser favicon"
|
|
168
198
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_FAVICON"
|
|
169
199
|
header_bullet:
|
|
170
200
|
"$ref": "#/definitions/relative_path"
|
|
171
|
-
default:
|
|
201
|
+
default: null
|
|
172
202
|
description: "Bullet image used for various view headers"
|
|
173
203
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_HEADER_BULLET"
|
|
174
204
|
icon_16:
|
|
175
205
|
"$ref": "#/definitions/relative_path"
|
|
176
|
-
default:
|
|
206
|
+
default: null
|
|
177
207
|
description: "16x16px icon"
|
|
178
208
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_ICON_16"
|
|
179
209
|
icon_180:
|
|
180
210
|
"$ref": "#/definitions/relative_path"
|
|
181
|
-
default:
|
|
211
|
+
default: null
|
|
182
212
|
description: "180x180px icon - used for the apple-touch-icon header"
|
|
183
213
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_ICON_180"
|
|
184
214
|
icon_192:
|
|
185
215
|
"$ref": "#/definitions/relative_path"
|
|
186
|
-
default:
|
|
216
|
+
default: null
|
|
187
217
|
description: "192x192px icon"
|
|
188
218
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_ICON_192"
|
|
189
219
|
icon_32:
|
|
190
220
|
"$ref": "#/definitions/relative_path"
|
|
191
|
-
default:
|
|
221
|
+
default: null
|
|
192
222
|
description: "32x32px icon"
|
|
193
223
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_ICON_32"
|
|
194
224
|
icon_mask:
|
|
195
225
|
"$ref": "#/definitions/relative_path"
|
|
196
|
-
default:
|
|
226
|
+
default: null
|
|
197
227
|
description: "Mono-chrome icon used for the mask-icon header"
|
|
198
228
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_ICON_MASK"
|
|
229
|
+
javascript:
|
|
230
|
+
"$ref": "#/definitions/relative_path"
|
|
231
|
+
default: null
|
|
232
|
+
description: "Custom global JavaScript file"
|
|
233
|
+
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_JAVASCRIPT"
|
|
199
234
|
logo:
|
|
200
235
|
"$ref": "#/definitions/relative_path"
|
|
201
|
-
default:
|
|
236
|
+
default: null
|
|
202
237
|
description: "Navbar logo"
|
|
203
238
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_LOGO"
|
|
204
239
|
nav_bullet:
|
|
205
240
|
"$ref": "#/definitions/relative_path"
|
|
206
|
-
default:
|
|
241
|
+
default: null
|
|
207
242
|
description: "Bullet image used for nav menu headers"
|
|
208
243
|
environment_variable: "NAUTOBOT_BRANDING_FILEPATHS_NAV_BULLET"
|
|
209
244
|
type: "object"
|
|
@@ -1135,7 +1170,7 @@ properties:
|
|
|
1135
1170
|
!!! note
|
|
1136
1171
|
The Docker container normally attempts to run migrations on startup; however, if the database is
|
|
1137
1172
|
in a read-only state the Docker container will fail to start. Setting the environment variable
|
|
1138
|
-
[`NAUTOBOT_DOCKER_SKIP_INIT`](../installation/docker.md#nautobot_docker_skip_init) to `true`
|
|
1173
|
+
[`NAUTOBOT_DOCKER_SKIP_INIT`](../installation-extras/docker.md#nautobot_docker_skip_init) to `true`
|
|
1139
1174
|
will prevent the migrations from occurring.
|
|
1140
1175
|
|
|
1141
1176
|
!!! note
|