nautobot 2.4.3__py3-none-any.whl → 2.4.5__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/__init__.py +19 -3
- nautobot/apps/filters.py +2 -0
- nautobot/circuits/filters.py +1 -1
- nautobot/circuits/tests/test_models.py +5 -3
- nautobot/cloud/filters.py +3 -6
- nautobot/cloud/tests/test_filters.py +21 -0
- nautobot/core/admin.py +2 -0
- nautobot/core/celery/__init__.py +5 -3
- nautobot/core/jobs/__init__.py +5 -3
- nautobot/core/management/commands/generate_performance_test_endpoints.py +9 -6
- nautobot/core/models/utils.py +6 -1
- nautobot/core/templates/inc/javascript.html +1 -0
- nautobot/core/templatetags/ui_framework.py +20 -4
- nautobot/core/testing/__init__.py +2 -0
- nautobot/core/testing/forms.py +1 -1
- nautobot/core/testing/mixins.py +9 -0
- nautobot/core/tests/test_api.py +1 -1
- nautobot/core/tests/test_graphql.py +3 -3
- nautobot/core/tests/test_jobs.py +30 -28
- nautobot/core/ui/object_detail.py +1 -1
- nautobot/dcim/api/serializers.py +36 -0
- nautobot/dcim/api/views.py +1 -1
- nautobot/dcim/elevations.py +17 -4
- nautobot/dcim/factory.py +9 -1
- nautobot/dcim/filters/__init__.py +27 -1
- nautobot/dcim/forms.py +13 -1
- nautobot/dcim/models/devices.py +11 -5
- nautobot/dcim/signals.py +26 -0
- nautobot/dcim/templates/dcim/virtualdevicecontext_retrieve.html +0 -62
- nautobot/dcim/templates/dcim/virtualdevicecontext_update.html +6 -0
- nautobot/dcim/tests/test_api.py +176 -0
- nautobot/dcim/tests/test_filters.py +56 -3
- nautobot/dcim/tests/test_jobs.py +4 -6
- nautobot/dcim/tests/test_models.py +40 -0
- nautobot/dcim/views.py +24 -14
- nautobot/extras/api/mixins.py +1 -1
- nautobot/extras/api/views.py +2 -2
- nautobot/extras/choices.py +8 -3
- nautobot/extras/filters/__init__.py +4 -0
- nautobot/extras/jobs.py +181 -103
- nautobot/extras/management/utils.py +13 -2
- nautobot/extras/models/datasources.py +11 -4
- nautobot/extras/models/jobs.py +20 -17
- nautobot/extras/plugins/__init__.py +26 -1
- nautobot/extras/tables.py +25 -29
- nautobot/extras/templates/extras/inc/jobresult.html +12 -13
- nautobot/extras/templates/extras/objectchange.html +28 -12
- nautobot/extras/test_jobs/atomic_transaction.py +6 -6
- nautobot/extras/test_jobs/fail.py +75 -1
- nautobot/extras/tests/test_api.py +17 -16
- nautobot/extras/tests/test_datasources.py +64 -54
- nautobot/extras/tests/test_filters.py +2 -0
- nautobot/extras/tests/test_jobs.py +69 -62
- nautobot/extras/tests/test_models.py +1 -1
- nautobot/extras/tests/test_plugins.py +32 -1
- nautobot/extras/tests/test_relationships.py +5 -5
- nautobot/extras/tests/test_views.py +12 -2
- nautobot/extras/views.py +10 -1
- nautobot/ipam/api/serializers.py +7 -8
- nautobot/ipam/api/views.py +2 -2
- nautobot/ipam/factory.py +27 -8
- nautobot/ipam/filters.py +67 -29
- nautobot/ipam/formfields.py +51 -0
- nautobot/ipam/forms.py +28 -1
- nautobot/ipam/migrations/0051_added_optional_vrf_relationship_to_vdc.py +41 -0
- nautobot/ipam/models.py +63 -5
- nautobot/ipam/querysets.py +6 -0
- nautobot/ipam/tables.py +21 -7
- nautobot/ipam/templates/ipam/rir.html +1 -43
- nautobot/ipam/tests/test_api.py +107 -66
- nautobot/ipam/tests/test_filters.py +145 -5
- nautobot/ipam/tests/test_models.py +16 -0
- nautobot/ipam/tests/test_views.py +15 -2
- nautobot/ipam/urls.py +1 -21
- nautobot/ipam/views.py +24 -41
- nautobot/project-static/css/base.css +11 -0
- nautobot/project-static/css/dark.css +2 -1
- nautobot/project-static/docs/code-reference/nautobot/apps/filters.html +62 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +43 -5
- nautobot/project-static/docs/code-reference/nautobot/apps/testing.html +35 -0
- nautobot/project-static/docs/development/apps/api/configuration-view.html +0 -3
- nautobot/project-static/docs/development/apps/api/models/graphql.html +0 -4
- nautobot/project-static/docs/development/apps/api/platform-features/custom-validators.html +94 -1
- nautobot/project-static/docs/development/apps/api/platform-features/filter-extensions.html +0 -3
- nautobot/project-static/docs/development/apps/api/platform-features/jinja2-filters.html +0 -3
- nautobot/project-static/docs/development/apps/api/platform-features/populating-extensibility-features.html +0 -3
- nautobot/project-static/docs/development/apps/api/platform-features/secrets-providers.html +0 -3
- nautobot/project-static/docs/development/apps/api/prometheus.html +0 -3
- nautobot/project-static/docs/development/apps/api/testing.html +0 -6
- nautobot/project-static/docs/development/apps/api/ui-extensions/banners.html +0 -3
- nautobot/project-static/docs/development/apps/api/ui-extensions/home-page.html +0 -3
- nautobot/project-static/docs/development/apps/api/ui-extensions/object-views.html +0 -3
- nautobot/project-static/docs/development/apps/api/views/core-view-overrides.html +0 -3
- nautobot/project-static/docs/development/apps/api/views/nautobot-generic-views.html +1 -7
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewset.html +0 -7
- nautobot/project-static/docs/development/apps/api/views/nautobotuiviewsetrouter.html +0 -4
- nautobot/project-static/docs/development/apps/api/views/notes.html +0 -3
- nautobot/project-static/docs/development/apps/index.html +2 -35
- nautobot/project-static/docs/development/apps/migration/code-updates.html +1 -1
- nautobot/project-static/docs/development/core/application-registry.html +0 -6
- nautobot/project-static/docs/development/core/best-practices.html +0 -27
- nautobot/project-static/docs/development/core/docker-compose-advanced-use-cases.html +58 -4
- nautobot/project-static/docs/development/core/getting-started.html +12 -16
- nautobot/project-static/docs/development/core/homepage.html +0 -3
- nautobot/project-static/docs/development/core/style-guide.html +0 -5
- nautobot/project-static/docs/development/core/templates.html +0 -3
- nautobot/project-static/docs/development/core/testing.html +0 -9
- nautobot/project-static/docs/development/jobs/index.html +30 -43
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/overview/application_stack.html +0 -18
- nautobot/project-static/docs/release-notes/version-2.4.html +374 -0
- nautobot/project-static/docs/requirements.txt +2 -2
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +290 -290
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/configuration/settings.html +0 -10
- nautobot/project-static/docs/user-guide/administration/guides/docker.html +0 -15
- nautobot/project-static/docs/user-guide/administration/installation/index.html +0 -16
- nautobot/project-static/docs/user-guide/administration/installation/nautobot.html +1 -4
- nautobot/project-static/docs/user-guide/administration/installation/services.html +0 -11
- nautobot/project-static/docs/user-guide/administration/migration/migrating-from-postgresql.html +3 -3
- nautobot/project-static/docs/user-guide/administration/tools/nautobot-server.html +5 -35
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/tables/v2-code-location-changes.yaml +1 -1
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +1 -1
- nautobot/project-static/docs/user-guide/administration/upgrading/upgrading.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/circuits/providernetwork.html +0 -3
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleport.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleporttemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverport.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/consoleserverporttemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebay.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicebaytemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/deviceredundancygroup.html +0 -3
- nautobot/project-static/docs/user-guide/core-data-model/dcim/devicetype.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontport.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/frontporttemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interface.html +1 -17
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfaceredundancygroup.html +0 -3
- nautobot/project-static/docs/user-guide/core-data-model/dcim/interfacetemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/inventoryitem.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/location.html +0 -3
- nautobot/project-static/docs/user-guide/core-data-model/dcim/locationtype.html +1 -7
- nautobot/project-static/docs/user-guide/core-data-model/dcim/platform.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlet.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/poweroutlettemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerport.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/powerporttemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearport.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/dcim/rearporttemplate.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontext.html +0 -6
- nautobot/project-static/docs/user-guide/core-data-model/extras/configcontextschema.html +0 -3
- nautobot/project-static/docs/user-guide/core-data-model/ipam/ipaddress.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +0 -4
- nautobot/project-static/docs/user-guide/core-data-model/virtualization/vminterface.html +0 -8
- nautobot/project-static/docs/user-guide/feature-guides/custom-fields.html +3 -3
- nautobot/project-static/docs/user-guide/feature-guides/graphql.html +0 -6
- nautobot/project-static/docs/user-guide/platform-functionality/computedfield.html +0 -3
- nautobot/project-static/docs/user-guide/platform-functionality/customfield.html +3 -15
- nautobot/project-static/docs/user-guide/platform-functionality/dynamicgroup.html +0 -26
- nautobot/project-static/docs/user-guide/platform-functionality/gitrepository.html +0 -8
- nautobot/project-static/docs/user-guide/platform-functionality/graphql.html +0 -3
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +0 -8
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/job-scheduling-and-approvals.html +0 -7
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobbutton.html +0 -3
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/jobhook.html +0 -3
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +0 -14
- nautobot/project-static/docs/user-guide/platform-functionality/note.html +0 -3
- nautobot/project-static/docs/user-guide/platform-functionality/relationship.html +1 -10
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/authentication.html +0 -3
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/filtering.html +0 -14
- nautobot/project-static/docs/user-guide/platform-functionality/rest-api/overview.html +0 -19
- nautobot/project-static/docs/user-guide/platform-functionality/secret.html +3 -9
- nautobot/project-static/docs/user-guide/platform-functionality/status.html +0 -8
- nautobot/project-static/docs/user-guide/platform-functionality/tag.html +0 -4
- nautobot/project-static/docs/user-guide/platform-functionality/template-filters.html +1 -13
- nautobot/project-static/docs/user-guide/platform-functionality/webhook.html +0 -5
- nautobot/project-static/js/editor.js +292 -0
- nautobot/project-static/monaco-editor-0.52.2/README.md +81 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/base/worker/workerMain.js +31 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/basic-languages/xml/xml.js +10 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/basic-languages/yaml/yaml.js +10 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/editor/editor.main.css +8 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/editor/editor.main.js +798 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/language/json/jsonMode.js +19 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/language/json/jsonWorker.js +42 -0
- nautobot/project-static/monaco-editor-0.52.2/vs/loader.js +11 -0
- nautobot/tenancy/filters/__init__.py +3 -5
- nautobot/tenancy/tests/test_filters.py +10 -0
- nautobot/virtualization/views.py +0 -1
- nautobot/wireless/tables.py +9 -4
- nautobot/wireless/tests/test_api.py +0 -9
- {nautobot-2.4.3.dist-info → nautobot-2.4.5.dist-info}/METADATA +4 -4
- {nautobot-2.4.3.dist-info → nautobot-2.4.5.dist-info}/RECORD +198 -186
- {nautobot-2.4.3.dist-info → nautobot-2.4.5.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.4.3.dist-info → nautobot-2.4.5.dist-info}/NOTICE +0 -0
- {nautobot-2.4.3.dist-info → nautobot-2.4.5.dist-info}/WHEEL +0 -0
- {nautobot-2.4.3.dist-info → nautobot-2.4.5.dist-info}/entry_points.txt +0 -0
|
@@ -7487,6 +7487,15 @@
|
|
|
7487
7487
|
</span>
|
|
7488
7488
|
</a>
|
|
7489
7489
|
|
|
7490
|
+
</li>
|
|
7491
|
+
|
|
7492
|
+
<li class="md-nav__item">
|
|
7493
|
+
<a href="#nautobot.apps.filters.PrefixFilter" class="md-nav__link">
|
|
7494
|
+
<span class="md-ellipsis">
|
|
7495
|
+
PrefixFilter
|
|
7496
|
+
</span>
|
|
7497
|
+
</a>
|
|
7498
|
+
|
|
7490
7499
|
</li>
|
|
7491
7500
|
|
|
7492
7501
|
<li class="md-nav__item">
|
|
@@ -9724,6 +9733,15 @@
|
|
|
9724
9733
|
</span>
|
|
9725
9734
|
</a>
|
|
9726
9735
|
|
|
9736
|
+
</li>
|
|
9737
|
+
|
|
9738
|
+
<li class="md-nav__item">
|
|
9739
|
+
<a href="#nautobot.apps.filters.PrefixFilter" class="md-nav__link">
|
|
9740
|
+
<span class="md-ellipsis">
|
|
9741
|
+
PrefixFilter
|
|
9742
|
+
</span>
|
|
9743
|
+
</a>
|
|
9744
|
+
|
|
9727
9745
|
</li>
|
|
9728
9746
|
|
|
9729
9747
|
<li class="md-nav__item">
|
|
@@ -10755,6 +10773,50 @@ are needed.</p>
|
|
|
10755
10773
|
|
|
10756
10774
|
|
|
10757
10775
|
|
|
10776
|
+
</div>
|
|
10777
|
+
|
|
10778
|
+
</div>
|
|
10779
|
+
|
|
10780
|
+
</div>
|
|
10781
|
+
|
|
10782
|
+
<div class="doc doc-object doc-class">
|
|
10783
|
+
|
|
10784
|
+
|
|
10785
|
+
|
|
10786
|
+
<h2 id="nautobot.apps.filters.PrefixFilter" class="doc doc-heading">
|
|
10787
|
+
<code>nautobot.apps.filters.PrefixFilter</code>
|
|
10788
|
+
|
|
10789
|
+
|
|
10790
|
+
<a href="#nautobot.apps.filters.PrefixFilter" class="headerlink" title="Permanent link">¶</a></h2>
|
|
10791
|
+
|
|
10792
|
+
|
|
10793
|
+
<div class="doc doc-contents ">
|
|
10794
|
+
<p class="doc doc-class-bases">
|
|
10795
|
+
Bases: <code><a class="autorefs autorefs-internal" title="nautobot.core.filters.NaturalKeyOrPKMultipleChoiceFilter" href="#nautobot.apps.filters.NaturalKeyOrPKMultipleChoiceFilter">NaturalKeyOrPKMultipleChoiceFilter</a></code></p>
|
|
10796
|
+
|
|
10797
|
+
|
|
10798
|
+
<p>Filter that supports filtering a foreign key to Prefix by either its PK or by a literal <code>prefix</code> string.</p>
|
|
10799
|
+
|
|
10800
|
+
|
|
10801
|
+
|
|
10802
|
+
|
|
10803
|
+
|
|
10804
|
+
|
|
10805
|
+
|
|
10806
|
+
|
|
10807
|
+
|
|
10808
|
+
<div class="doc doc-children">
|
|
10809
|
+
|
|
10810
|
+
|
|
10811
|
+
|
|
10812
|
+
|
|
10813
|
+
|
|
10814
|
+
|
|
10815
|
+
|
|
10816
|
+
|
|
10817
|
+
|
|
10818
|
+
|
|
10819
|
+
|
|
10758
10820
|
</div>
|
|
10759
10821
|
|
|
10760
10822
|
</div>
|
|
@@ -7419,6 +7419,15 @@
|
|
|
7419
7419
|
</span>
|
|
7420
7420
|
</a>
|
|
7421
7421
|
|
|
7422
|
+
</li>
|
|
7423
|
+
|
|
7424
|
+
<li class="md-nav__item">
|
|
7425
|
+
<a href="#nautobot.apps.jobs.BaseJob.fail" class="md-nav__link">
|
|
7426
|
+
<span class="md-ellipsis">
|
|
7427
|
+
fail
|
|
7428
|
+
</span>
|
|
7429
|
+
</a>
|
|
7430
|
+
|
|
7422
7431
|
</li>
|
|
7423
7432
|
|
|
7424
7433
|
<li class="md-nav__item">
|
|
@@ -9776,6 +9785,15 @@
|
|
|
9776
9785
|
</span>
|
|
9777
9786
|
</a>
|
|
9778
9787
|
|
|
9788
|
+
</li>
|
|
9789
|
+
|
|
9790
|
+
<li class="md-nav__item">
|
|
9791
|
+
<a href="#nautobot.apps.jobs.BaseJob.fail" class="md-nav__link">
|
|
9792
|
+
<span class="md-ellipsis">
|
|
9793
|
+
fail
|
|
9794
|
+
</span>
|
|
9795
|
+
</a>
|
|
9796
|
+
|
|
9779
9797
|
</li>
|
|
9780
9798
|
|
|
9781
9799
|
<li class="md-nav__item">
|
|
@@ -10624,11 +10642,13 @@ during a approval review workflow.</p>
|
|
|
10624
10642
|
<tbody>
|
|
10625
10643
|
<tr class="doc-section-item">
|
|
10626
10644
|
<td>
|
|
10627
|
-
<code>
|
|
10645
|
+
<code>Any</code>
|
|
10628
10646
|
</td>
|
|
10629
10647
|
<td>
|
|
10630
10648
|
<div class="doc-md-description">
|
|
10631
|
-
<p>The return value of this handler is ignored
|
|
10649
|
+
<p>The return value of this handler is ignored normally, <strong>except</strong> if <code>self.fail()</code> is called herein,
|
|
10650
|
+
in which case the return value will be used as the overall JobResult return value
|
|
10651
|
+
since <code>self.run()</code> will <strong>not</strong> be called in such a case.</p>
|
|
10632
10652
|
</div>
|
|
10633
10653
|
</td>
|
|
10634
10654
|
</tr>
|
|
@@ -10835,6 +10855,23 @@ path would consider this a failure of the job execution, as described in <code>n
|
|
|
10835
10855
|
<div class="doc doc-object doc-function">
|
|
10836
10856
|
|
|
10837
10857
|
|
|
10858
|
+
<h3 id="nautobot.apps.jobs.BaseJob.fail" class="doc doc-heading">
|
|
10859
|
+
<code class="highlight language-python"><span class="n">fail</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></code>
|
|
10860
|
+
|
|
10861
|
+
<a href="#nautobot.apps.jobs.BaseJob.fail" class="headerlink" title="Permanent link">¶</a></h3>
|
|
10862
|
+
|
|
10863
|
+
|
|
10864
|
+
<div class="doc doc-contents ">
|
|
10865
|
+
|
|
10866
|
+
<p>Mark this job as failed without immediately raising an exception and aborting.</p>
|
|
10867
|
+
|
|
10868
|
+
</div>
|
|
10869
|
+
|
|
10870
|
+
</div>
|
|
10871
|
+
|
|
10872
|
+
<div class="doc doc-object doc-function">
|
|
10873
|
+
|
|
10874
|
+
|
|
10838
10875
|
<h3 id="nautobot.apps.jobs.BaseJob.file_path" class="doc doc-heading">
|
|
10839
10876
|
<code class="highlight language-python"><span class="n">file_path</span><span class="p">()</span></code>
|
|
10840
10877
|
|
|
@@ -10914,11 +10951,12 @@ path would consider this a failure of the job execution, as described in <code>n
|
|
|
10914
10951
|
<code>exc</code>
|
|
10915
10952
|
</td>
|
|
10916
10953
|
<td>
|
|
10917
|
-
<code>
|
|
10954
|
+
<code>Any</code>
|
|
10918
10955
|
</td>
|
|
10919
10956
|
<td>
|
|
10920
10957
|
<div class="doc-md-description">
|
|
10921
|
-
<p>
|
|
10958
|
+
<p>Exception raised by the task (if any) <strong>or</strong> return value from the task, if it failed cleanly,
|
|
10959
|
+
such as if the Job called <code>self.fail()</code> rather than raising an exception.</p>
|
|
10922
10960
|
</div>
|
|
10923
10961
|
</td>
|
|
10924
10962
|
<td>
|
|
@@ -10982,7 +11020,7 @@ path would consider this a failure of the job execution, as described in <code>n
|
|
|
10982
11020
|
</td>
|
|
10983
11021
|
<td>
|
|
10984
11022
|
<div class="doc-md-description">
|
|
10985
|
-
<p>Exception information.</p>
|
|
11023
|
+
<p>Exception information, or None.</p>
|
|
10986
11024
|
</div>
|
|
10987
11025
|
</td>
|
|
10988
11026
|
<td>
|
|
@@ -8238,6 +8238,15 @@
|
|
|
8238
8238
|
</span>
|
|
8239
8239
|
</a>
|
|
8240
8240
|
|
|
8241
|
+
</li>
|
|
8242
|
+
|
|
8243
|
+
<li class="md-nav__item">
|
|
8244
|
+
<a href="#nautobot.apps.testing.NautobotTestCaseMixin.assertJobResultStatus" class="md-nav__link">
|
|
8245
|
+
<span class="md-ellipsis">
|
|
8246
|
+
assertJobResultStatus
|
|
8247
|
+
</span>
|
|
8248
|
+
</a>
|
|
8249
|
+
|
|
8241
8250
|
</li>
|
|
8242
8251
|
|
|
8243
8252
|
<li class="md-nav__item">
|
|
@@ -11423,6 +11432,15 @@
|
|
|
11423
11432
|
</span>
|
|
11424
11433
|
</a>
|
|
11425
11434
|
|
|
11435
|
+
</li>
|
|
11436
|
+
|
|
11437
|
+
<li class="md-nav__item">
|
|
11438
|
+
<a href="#nautobot.apps.testing.NautobotTestCaseMixin.assertJobResultStatus" class="md-nav__link">
|
|
11439
|
+
<span class="md-ellipsis">
|
|
11440
|
+
assertJobResultStatus
|
|
11441
|
+
</span>
|
|
11442
|
+
</a>
|
|
11443
|
+
|
|
11426
11444
|
</li>
|
|
11427
11445
|
|
|
11428
11446
|
<li class="md-nav__item">
|
|
@@ -14322,6 +14340,23 @@ in the dictionary.</p>
|
|
|
14322
14340
|
<div class="doc doc-object doc-function">
|
|
14323
14341
|
|
|
14324
14342
|
|
|
14343
|
+
<h3 id="nautobot.apps.testing.NautobotTestCaseMixin.assertJobResultStatus" class="doc doc-heading">
|
|
14344
|
+
<code class="highlight language-python"><span class="n">assertJobResultStatus</span><span class="p">(</span><span class="n">job_result</span><span class="p">,</span> <span class="n">expected_status</span><span class="o">=</span><span class="n">JobResultStatusChoices</span><span class="o">.</span><span class="n">STATUS_SUCCESS</span><span class="p">)</span></code>
|
|
14345
|
+
|
|
14346
|
+
<a href="#nautobot.apps.testing.NautobotTestCaseMixin.assertJobResultStatus" class="headerlink" title="Permanent link">¶</a></h3>
|
|
14347
|
+
|
|
14348
|
+
|
|
14349
|
+
<div class="doc doc-contents ">
|
|
14350
|
+
|
|
14351
|
+
<p>Assert that the given job_result has the expected_status, or print the job logs to aid in debugging.</p>
|
|
14352
|
+
|
|
14353
|
+
</div>
|
|
14354
|
+
|
|
14355
|
+
</div>
|
|
14356
|
+
|
|
14357
|
+
<div class="doc doc-object doc-function">
|
|
14358
|
+
|
|
14359
|
+
|
|
14325
14360
|
<h3 id="nautobot.apps.testing.NautobotTestCaseMixin.assertQuerysetEqualAndNotEmpty" class="doc doc-heading">
|
|
14326
14361
|
<code class="highlight language-python"><span class="n">assertQuerysetEqualAndNotEmpty</span><span class="p">(</span><span class="n">qs</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></code>
|
|
14327
14362
|
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="adding-links-to-the-installed-apps-view">Adding Links to the Installed Apps View<a class="headerlink" href="#adding-links-to-the-installed-apps-view" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.2.0</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>It's common for many apps to provide an "app configuration" <a href="views/index.html">view</a> used for interactive configuration of aspects of the app that don't necessarily need to be managed by a system administrator via <code>PLUGINS_CONFIG</code>. The <code>NautobotAppConfig</code> setting of <code>config_view_name</code> lets you provide the URL pattern name defined for this view, which will then be accessible via a button on the <strong>Apps -> Installed Apps</strong> UI view.</p>
|
|
9129
9126
|
<p>For example, if the <code>animal_sounds</code> app provides a configuration view, which is set up in <code>urls.py</code> as follows:</p>
|
|
9130
9127
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># urls.py</span>
|
|
@@ -9245,10 +9245,6 @@
|
|
|
9245
9245
|
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
|
|
9246
9246
|
</code></pre></div>
|
|
9247
9247
|
<h2 id="creating-your-own-graphql-type-object">Creating Your Own GraphQL Type Object<a class="headerlink" href="#creating-your-own-graphql-type-object" title="Permanent link">¶</a></h2>
|
|
9248
|
-
<details class="version-changed">
|
|
9249
|
-
<summary>Changed in version 1.6.2</summary>
|
|
9250
|
-
<p>A new base class was introduced for Nautobot GraphQL object types: <code>nautobot.core.graphql.types.OptimizedNautobotObjectType</code>. This class inherits from <code>graphene_django_optimizer.OptimizedDjangoObjectType</code> and adds generic Nautobot specific functionality.</p>
|
|
9251
|
-
</details>
|
|
9252
9248
|
<p>In some cases, such as when a model is using Generic Foreign Keys, or when a model has constructed fields that should also be reflected in GraphQL, the default GraphQL type definition generated by the <code>@extras_features</code> decorator may not work as the developer intends, and it will be preferable to provide custom GraphQL types.</p>
|
|
9253
9249
|
<p>By default, Nautobot looks for custom GraphQL types in an iterable named <code>graphql_types</code> within a <code>graphql/types.py</code> file. (This can be overridden by setting <code>graphql_types</code> to a custom value on the app's <code>NautobotAppConfig</code>.) Each type defined in this way must be a class inheriting from <code>graphene_django.DjangoObjectType</code>, <code>graphene_django_optimizer.OptimizedDjangoObjectType</code>, or <code>nautobot.core.graphql.types.OptimizedNautobotObjectType</code> and must follow the <a href="https://docs.graphene-python.org/projects/django/en/latest/queries/">standards defined by <code>graphene-django</code></a>.</p>
|
|
9254
9250
|
<p>Nautobot uses a library called <a href="https://github.com/tfoxy/graphene-django-optimizer"><code>graphene-django-optimizer</code></a> to decrease the time queries take to process. By inheriting from <code>graphene_django_optimizer</code> type classes are automatically optimized.</p>
|
|
@@ -6534,6 +6534,17 @@
|
|
|
6534
6534
|
|
|
6535
6535
|
|
|
6536
6536
|
|
|
6537
|
+
<label class="md-nav__link md-nav__link--active" for="__toc">
|
|
6538
|
+
|
|
6539
|
+
|
|
6540
|
+
<span class="md-ellipsis">
|
|
6541
|
+
Custom Validators
|
|
6542
|
+
</span>
|
|
6543
|
+
|
|
6544
|
+
|
|
6545
|
+
<span class="md-nav__icon md-icon"></span>
|
|
6546
|
+
</label>
|
|
6547
|
+
|
|
6537
6548
|
<a href="custom-validators.html" class="md-nav__link md-nav__link--active">
|
|
6538
6549
|
|
|
6539
6550
|
|
|
@@ -6544,6 +6555,34 @@
|
|
|
6544
6555
|
|
|
6545
6556
|
</a>
|
|
6546
6557
|
|
|
6558
|
+
|
|
6559
|
+
|
|
6560
|
+
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
|
6561
|
+
|
|
6562
|
+
|
|
6563
|
+
|
|
6564
|
+
|
|
6565
|
+
|
|
6566
|
+
|
|
6567
|
+
<label class="md-nav__title" for="__toc">
|
|
6568
|
+
<span class="md-nav__icon md-icon"></span>
|
|
6569
|
+
Table of contents
|
|
6570
|
+
</label>
|
|
6571
|
+
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
6572
|
+
|
|
6573
|
+
<li class="md-nav__item">
|
|
6574
|
+
<a href="#user-context" class="md-nav__link">
|
|
6575
|
+
<span class="md-ellipsis">
|
|
6576
|
+
User Context
|
|
6577
|
+
</span>
|
|
6578
|
+
</a>
|
|
6579
|
+
|
|
6580
|
+
</li>
|
|
6581
|
+
|
|
6582
|
+
</ul>
|
|
6583
|
+
|
|
6584
|
+
</nav>
|
|
6585
|
+
|
|
6547
6586
|
</li>
|
|
6548
6587
|
|
|
6549
6588
|
|
|
@@ -9105,6 +9144,23 @@
|
|
|
9105
9144
|
|
|
9106
9145
|
|
|
9107
9146
|
|
|
9147
|
+
<label class="md-nav__title" for="__toc">
|
|
9148
|
+
<span class="md-nav__icon md-icon"></span>
|
|
9149
|
+
Table of contents
|
|
9150
|
+
</label>
|
|
9151
|
+
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
|
9152
|
+
|
|
9153
|
+
<li class="md-nav__item">
|
|
9154
|
+
<a href="#user-context" class="md-nav__link">
|
|
9155
|
+
<span class="md-ellipsis">
|
|
9156
|
+
User Context
|
|
9157
|
+
</span>
|
|
9158
|
+
</a>
|
|
9159
|
+
|
|
9160
|
+
</li>
|
|
9161
|
+
|
|
9162
|
+
</ul>
|
|
9163
|
+
|
|
9108
9164
|
</nav>
|
|
9109
9165
|
</div>
|
|
9110
9166
|
</div>
|
|
@@ -9124,7 +9180,7 @@
|
|
|
9124
9180
|
<h1 id="implementing-custom-validators">Implementing Custom Validators<a class="headerlink" href="#implementing-custom-validators" title="Permanent link">¶</a></h1>
|
|
9125
9181
|
<p>Apps can register custom validator classes which implement model validation logic to be executed during a model's <code>clean()</code> method. Like template extensions, custom validators are registered to a single model and offer a method which app authors override to implement their validation logic. This is accomplished by subclassing <code>CustomValidator</code> and implementing the <code>clean()</code> method.</p>
|
|
9126
9182
|
<p>App authors must raise <code>django.core.exceptions.ValidationError</code> within the <code>clean()</code> method to trigger validation error messages which are propagated to the user and prevent saving of the model instance. A convenience method <code>validation_error()</code> may be used to simplify this process. Raising a <code>ValidationError</code> is no different than vanilla Django, and the convenience method will simply pass the provided message through to the exception.</p>
|
|
9127
|
-
<p>When a CustomValidator is instantiated, the model instance is assigned to context dictionary using the <code>object</code> key, much like TemplateExtension. E.g. <code>self.context['object']</code>.</p>
|
|
9183
|
+
<p>When a CustomValidator is instantiated, the model instance is assigned to context dictionary using the <code>object</code> key, much like TemplateExtension. E.g. <code>self.context['object']</code>. The context is also populated with the current request user object. E.g. <code>self.context['user']</code>.</p>
|
|
9128
9184
|
<p>Declared subclasses should be gathered into a list or tuple for integration with Nautobot. By default, Nautobot looks for an iterable named <code>custom_validators</code> within a <code>custom_validators.py</code> file. (This can be overridden by setting <code>custom_validators</code> to a custom value on the app's <code>NautobotAppConfig</code>.) An example is below.</p>
|
|
9129
9185
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># custom_validators.py</span>
|
|
9130
9186
|
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="kn">from</span> <span class="nn">nautobot.apps.models</span> <span class="kn">import</span> <span class="n">CustomValidator</span>
|
|
@@ -9145,6 +9201,43 @@
|
|
|
9145
9201
|
<a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a>
|
|
9146
9202
|
<a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a><span class="n">custom_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">LocationValidator</span><span class="p">]</span>
|
|
9147
9203
|
</code></pre></div>
|
|
9204
|
+
<h2 id="user-context">User Context<a class="headerlink" href="#user-context" title="Permanent link">¶</a></h2>
|
|
9205
|
+
<details class="version-added">
|
|
9206
|
+
<summary>Added in version 2.4.4</summary>
|
|
9207
|
+
</details>
|
|
9208
|
+
<p>Custom validators have access to the current user via <code>self.context['user']</code> whenever the custom validator is invoked within a web request context. This is true for any Web UI, REST API request, Job execution, and anytime the <code>web_request_context</code> context manager is used in <code>nbshell</code> or a out of band script. In the event a custom validator is run outside of a web request context, <code>self.context['user']</code> will be populated with an instance of <code>AnonymousUser</code> from <code>django.contrib.auth</code>. This allows a custom validator author to write code that is durable to cases where a real user is not available.</p>
|
|
9209
|
+
<p>With the user object, you can inspect the groups and permissions that the user has, allowing more granular access related validation.</p>
|
|
9210
|
+
<p>This example shows a custom validator that only allows users in the group "Tenant Managers" to change the tenant of a location:</p>
|
|
9211
|
+
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="c1"># custom_validators.py</span>
|
|
9212
|
+
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="kn">from</span> <span class="nn">nautobot.apps.models</span> <span class="kn">import</span> <span class="n">CustomValidator</span>
|
|
9213
|
+
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a>
|
|
9214
|
+
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a>
|
|
9215
|
+
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="k">class</span> <span class="nc">LocationTenantValidator</span><span class="p">(</span><span class="n">CustomValidator</span><span class="p">):</span>
|
|
9216
|
+
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="w"> </span><span class="sd">"""Custom validator for Locations to enforce that only some users can update the Tenant."""</span>
|
|
9217
|
+
<a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a>
|
|
9218
|
+
<a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a> <span class="n">model</span> <span class="o">=</span> <span class="s1">'dcim.location'</span>
|
|
9219
|
+
<a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a>
|
|
9220
|
+
<a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a> <span class="k">def</span> <span class="nf">clean</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
9221
|
+
<a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a> <span class="n">new_object_state</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="s2">"object"</span><span class="p">]</span>
|
|
9222
|
+
<a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">new_object_state</span><span class="o">.</span><span class="n">present_in_database</span><span class="p">:</span>
|
|
9223
|
+
<a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a> <span class="c1"># This is a brand new Location, so skip the rest of the checks here</span>
|
|
9224
|
+
<a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a> <span class="k">return</span>
|
|
9225
|
+
<a id="__codelineno-1-15" name="__codelineno-1-15" href="#__codelineno-1-15"></a>
|
|
9226
|
+
<a id="__codelineno-1-16" name="__codelineno-1-16" href="#__codelineno-1-16"></a> <span class="c1"># Get a copy of the object as it currently exists in the database</span>
|
|
9227
|
+
<a id="__codelineno-1-17" name="__codelineno-1-17" href="#__codelineno-1-17"></a> <span class="n">current_object_state</span> <span class="o">=</span> <span class="n">new_object_state</span><span class="o">.</span><span class="n">_meta</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">new_object_state</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
|
|
9228
|
+
<a id="__codelineno-1-18" name="__codelineno-1-18" href="#__codelineno-1-18"></a>
|
|
9229
|
+
<a id="__codelineno-1-19" name="__codelineno-1-19" href="#__codelineno-1-19"></a> <span class="c1"># Compare the tenant values between the two states</span>
|
|
9230
|
+
<a id="__codelineno-1-20" name="__codelineno-1-20" href="#__codelineno-1-20"></a> <span class="k">if</span> <span class="n">new_object_state</span><span class="o">.</span><span class="n">tenant</span> <span class="o">!=</span> <span class="n">current_object_state</span><span class="o">.</span><span class="n">tenant</span><span class="p">:</span>
|
|
9231
|
+
<a id="__codelineno-1-21" name="__codelineno-1-21" href="#__codelineno-1-21"></a>
|
|
9232
|
+
<a id="__codelineno-1-22" name="__codelineno-1-22" href="#__codelineno-1-22"></a> <span class="c1"># Check if the user has permission to change the tenant, via being a member of "Tenant Managers"</span>
|
|
9233
|
+
<a id="__codelineno-1-23" name="__codelineno-1-23" href="#__codelineno-1-23"></a> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">context</span><span class="p">[</span><span class="s2">"user"</span><span class="p">]</span><span class="o">.</span><span class="n">groups</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">"Tenant Managers"</span><span class="p">)</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
|
|
9234
|
+
<a id="__codelineno-1-24" name="__codelineno-1-24" href="#__codelineno-1-24"></a> <span class="bp">self</span><span class="o">.</span><span class="n">validation_error</span><span class="p">({</span>
|
|
9235
|
+
<a id="__codelineno-1-25" name="__codelineno-1-25" href="#__codelineno-1-25"></a> <span class="s2">"tenant"</span><span class="p">:</span> <span class="s2">"You do not have permission to change the tenant"</span>
|
|
9236
|
+
<a id="__codelineno-1-26" name="__codelineno-1-26" href="#__codelineno-1-26"></a> <span class="p">})</span>
|
|
9237
|
+
<a id="__codelineno-1-27" name="__codelineno-1-27" href="#__codelineno-1-27"></a>
|
|
9238
|
+
<a id="__codelineno-1-28" name="__codelineno-1-28" href="#__codelineno-1-28"></a>
|
|
9239
|
+
<a id="__codelineno-1-29" name="__codelineno-1-29" href="#__codelineno-1-29"></a><span class="n">custom_validators</span> <span class="o">=</span> <span class="p">[</span><span class="n">LocationTenantValidator</span><span class="p">]</span>
|
|
9240
|
+
</code></pre></div>
|
|
9148
9241
|
|
|
9149
9242
|
|
|
9150
9243
|
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="extending-filters">Extending Filters<a class="headerlink" href="#extending-filters" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.3.0</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>Apps can extend any model-based <code>FilterSet</code> and <code>FilterForm</code> classes that are provided by the Nautobot core.</p>
|
|
9129
9126
|
<p>The requirements to extend a filter set or a filter form (or both) are:</p>
|
|
9130
9127
|
<ul>
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="adding-jinja2-filters">Adding Jinja2 Filters<a class="headerlink" href="#adding-jinja2-filters" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.1.0</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>Apps can define custom Jinja2 filters to be used when rendering templates defined in computed fields. Check out the <a href="https://jinja.palletsprojects.com/en/3.0.x/api/#custom-filters">official Jinja2 documentation</a> on how to create filter functions.</p>
|
|
9129
9126
|
<p>In the file that defines your filters (by default <code>jinja_filters.py</code>, but configurable in the <code>NautobotAppConfig</code> if desired), you must import the <code>library</code> module from the <code>django_jinja</code> library. Filters must then be decorated with <code>@library.filter</code>. See an example below that defines a filter called <code>leet_speak</code>.</p>
|
|
9130
9127
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="kn">from</span> <span class="nn">django_jinja</span> <span class="kn">import</span> <span class="n">library</span>
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="populating-extensibility-features">Populating Extensibility Features<a class="headerlink" href="#populating-extensibility-features" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.2.0</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>In many cases, an app may wish to make use of Nautobot's various extensibility features, such as <a href="../../../../user-guide/platform-functionality/customfield.html">custom fields</a> or <a href="../../../../user-guide/platform-functionality/relationship.html">relationships</a>. It can be useful for an app to automatically create a custom field definition or relationship definition as a consequence of being installed and activated, so that everyday usage of the app can rely upon these definitions to be present.</p>
|
|
9129
9126
|
<p>To make this possible, Nautobot provides a custom <a href="https://docs.djangoproject.com/en/stable/topics/signals/">signal</a>, <code>nautobot_database_ready</code>, that apps can register to listen for. This signal is triggered when <code>nautobot-server migrate</code> or <code>nautobot-server post_upgrade</code> is run after installing an app, and provides an opportunity for the app to make any desired additions to the database at this time.</p>
|
|
9130
9127
|
<p>For example, maybe we want our app to make use of a Relationship allowing each Location to be linked to our Animal model. We would define our callback function that makes sure this Relationship exists, by convention in a <code>signals.py</code> file:</p>
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="implementing-secrets-providers">Implementing Secrets Providers<a class="headerlink" href="#implementing-secrets-providers" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.2.0</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>An app can define and register additional providers (sources) for <a href="../../../../user-guide/platform-functionality/secret.html">Secrets</a>, allowing Nautobot to retrieve secret values from additional systems or data sources. By default, Nautobot looks for an iterable named <code>secrets_providers</code> within a <code>secrets.py</code> file. (This can be overridden by setting <code>secrets_providers</code> to a custom value on the app's <code>NautobotAppConfig</code>.)</p>
|
|
9129
9126
|
<p>To define a new <code>SecretsProvider</code> subclass, we must specify the following:</p>
|
|
9130
9127
|
<ul>
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="prometheus-metrics">Prometheus Metrics<a class="headerlink" href="#prometheus-metrics" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.5.13</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>It is possible for Nautobot apps to provide their own <a href="../../../user-guide/administration/guides/prometheus-metrics.html">Prometheus metrics</a>. There are two general ways to achieve this:</p>
|
|
9129
9126
|
<ol>
|
|
9130
9127
|
<li>Use the <code>prometheus_client</code> library directly in your app code. Depending on whether that code runs in the web server or the worker context, the metric will show up in the respective <code>/metrics</code> endpoint(s) (i.e. metrics generated in the worker context show up in the worker's endpoint and those generated in the web application's context show up in the web application's endpoint).</li>
|
|
@@ -9232,14 +9232,8 @@
|
|
|
9232
9232
|
<h1 id="testing-apps">Testing Apps<a class="headerlink" href="#testing-apps" title="Permanent link">¶</a></h1>
|
|
9233
9233
|
<p>In general apps can be tested like other Django apps. In most cases you'll want to run your automated tests via the <code>nautobot-server test <app_module></code> command or, if using the <code>coverage</code> Python library, <code>coverage run --module nautobot.core.cli test <app_module></code>.</p>
|
|
9234
9234
|
<h2 id="factories">Factories<a class="headerlink" href="#factories" title="Permanent link">¶</a></h2>
|
|
9235
|
-
<details class="version-added">
|
|
9236
|
-
<summary>Added in version 1.5.0</summary>
|
|
9237
|
-
</details>
|
|
9238
9235
|
<p>The <a href="../../../user-guide/administration/configuration/settings.html#test_use_factories"><code>TEST_USE_FACTORIES</code></a> setting defaults to <code>False</code> when testing apps, primarily for backwards-compatibility reasons. It can prove a useful way of populating a baseline of Nautobot database data for your tests and save you the trouble of creating a large amount of baseline data yourself. We recommend adding <a href="https://pypi.org/project/factory-boy/"><code>factory-boy</code></a> to your app's development dependencies and settings <code>TEST_USE_FACTORIES = True</code> in your app's development/test <code>nautobot_config.py</code> to take advantage of this.</p>
|
|
9239
9236
|
<h2 id="performance-tests">Performance Tests<a class="headerlink" href="#performance-tests" title="Permanent link">¶</a></h2>
|
|
9240
|
-
<details class="version-added">
|
|
9241
|
-
<summary>Added in version 1.5.0</summary>
|
|
9242
|
-
</details>
|
|
9243
9237
|
<h2 id="running-performance-tests">Running Performance Tests<a class="headerlink" href="#running-performance-tests" title="Permanent link">¶</a></h2>
|
|
9244
9238
|
<p>You need to install <code>django-slowtests</code> as a part of your app dev dependency to run performance tests. It has a very intuitive way to measure the performance of your own tests for your app (all you have to do is tag your tests with <code>performance</code>) and do <code>invoke performance-test</code> to get the time to run your tests with <code>NautobotPerformanceTestRunner</code>.</p>
|
|
9245
9239
|
<p><code>NautobotPerformanceTestRunner</code> is used by adding the flag <code>--testrunner nautobot.core.tests.runner.NautobotPerformanceTestRunner</code> to the <code>coverage run</code> command used for unit tests. This flag will replace the default <code>NautobotTestRunner</code> while retaining all its functionalities with the addition of performance evaluation after test
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="adding-a-banner">Adding a Banner<a class="headerlink" href="#adding-a-banner" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.2.0</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>An app can provide a function that renders a custom banner on any number of Nautobot views. By default Nautobot looks for a function <code>banner()</code> inside of <code>banner.py</code>. (This can be overridden by setting <code>banner_function</code> to a custom value on the app's <code>NautobotAppConfig</code>.)</p>
|
|
9129
9126
|
<p>This function currently receives a single argument, <code>context</code>, which is the <a href="https://docs.djangoproject.com/en/stable/ref/templates/api/#using-requestcontext">Django request context</a> in which the current page is being rendered. The function can return <code>None</code> if no banner is needed for a given page view, or can return a <code>Banner</code> object describing the banner contents. Here's a simple example <code>banner.py</code>:</p>
|
|
9130
9127
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># banner.py</span>
|
|
@@ -9122,9 +9122,6 @@
|
|
|
9122
9122
|
|
|
9123
9123
|
|
|
9124
9124
|
<h1 id="adding-home-page-content">Adding Home Page Content<a class="headerlink" href="#adding-home-page-content" title="Permanent link">¶</a></h1>
|
|
9125
|
-
<details class="version-added">
|
|
9126
|
-
<summary>Added in version 1.2.0</summary>
|
|
9127
|
-
</details>
|
|
9128
9125
|
<p>Apps can add content to the Nautobot home page. By default, Nautobot looks for a <code>layout</code> list inside of <code>homepage.py</code>. (This can be overridden by setting <code>homepage_layout</code> to a custom value on the app's <code>NautobotAppConfig</code>.)</p>
|
|
9129
9126
|
<p>Using a key and weight system, a developer can integrate the app content amongst existing panels, groups, and items and/or create entirely new panels as desired.</p>
|
|
9130
9127
|
<p>More documentation and examples can be found in the guide on <a href="../../../core/homepage.html">Home Page Panels</a>.</p>
|
|
@@ -9457,9 +9457,6 @@
|
|
|
9457
9457
|
</code></pre></div>
|
|
9458
9458
|
<p>Note that a <code>Tab</code> defines its contents directly (as <code>panels</code>) while the <code>DistinctViewTab</code> instead provides a <code>url_name</code> to the related URL that it should link against.</p>
|
|
9459
9459
|
<h3 id="via-detail_tabs-deprecated">Via <code>detail_tabs()</code> (Deprecated)<a class="headerlink" href="#via-detail_tabs-deprecated" title="Permanent link">¶</a></h3>
|
|
9460
|
-
<details class="version-added">
|
|
9461
|
-
<summary>Added in version 1.4.0</summary>
|
|
9462
|
-
</details>
|
|
9463
9460
|
<p>The <code>TemplateExtension.detail_tabs()</code> method should return a list of dicts, each of which has the keys <code>"title"</code> and <code>"url"</code>. In addition, in order for tabs to work properly:</p>
|
|
9464
9461
|
<ul>
|
|
9465
9462
|
<li>The <code>"url"</code> key should typically be a URL that includes <code>self.context["object"].pk</code> in some form (so that the URL may know which object is being referenced)</li>
|
|
@@ -9124,9 +9124,6 @@
|
|
|
9124
9124
|
|
|
9125
9125
|
|
|
9126
9126
|
<h1 id="replacing-views">Replacing Views<a class="headerlink" href="#replacing-views" title="Permanent link">¶</a></h1>
|
|
9127
|
-
<details class="version-added">
|
|
9128
|
-
<summary>Added in version 1.4.0</summary>
|
|
9129
|
-
</details>
|
|
9130
9127
|
<p>You may override any of the core or app views by providing an <code>override_views</code> <code>dict</code> in an app's <code>views.py</code> file.</p>
|
|
9131
9128
|
<p>To override a view, you must specify the view's fully qualified name as the <code>dict</code> key which consists of the app name followed by the view's name separated by a colon, for instance <code>dcim:device</code>. The <code>dict</code> value should be the overriding view function.</p>
|
|
9132
9129
|
<p>A simple example to override the device detail view:</p>
|
|
@@ -9182,15 +9182,9 @@
|
|
|
9182
9182
|
<p class="admonition-title">Warning</p>
|
|
9183
9183
|
<p>Currently preferred way of implementing views is to use <a href="nautobotuiviewset.html"><code>NautobotUIViewSet</code></a></p>
|
|
9184
9184
|
</div>
|
|
9185
|
-
<
|
|
9186
|
-
<summary>Added in version 1.1.0</summary>
|
|
9187
|
-
<p>Via <a href="https://github.com/nautobot/nautobot/issues/14">PR #14</a>, some <code>generic</code> views have been exposed to help aid in App development. These views have some requirements that must be in place in order to work. These can be used by importing them from <code>from nautobot.core.views import generic</code>.</p>
|
|
9188
|
-
</details>
|
|
9185
|
+
<p>Some <code>generic</code> views have been exposed to help aid in App development. These views have some requirements that must be in place in order to work. These can be used by importing them from <code>from nautobot.core.views import generic</code>.</p>
|
|
9189
9186
|
<p>More documentation and examples can be found in <a href="../../../core/generic-views.html">Generic Views</a> guide.</p>
|
|
9190
9187
|
<h2 id="note-url-endpoint">Note URL Endpoint<a class="headerlink" href="#note-url-endpoint" title="Permanent link">¶</a></h2>
|
|
9191
|
-
<details class="version-added">
|
|
9192
|
-
<summary>Added in version 1.4.0</summary>
|
|
9193
|
-
</details>
|
|
9194
9188
|
<p>Models that inherit from <code>PrimaryModel</code> and <code>OrganizationalModel</code> can have notes associated. In order to utilize this new feature you will need to add the endpoint to <code>urls.py</code>. Here is an option to be able to support both 1.4+ and older versions of Nautobot:</p>
|
|
9195
9189
|
<div class="admonition tip">
|
|
9196
9190
|
<p class="admonition-title">Tip</p>
|
|
@@ -9280,9 +9280,6 @@
|
|
|
9280
9280
|
|
|
9281
9281
|
|
|
9282
9282
|
<h1 id="nautobotuiviewset">NautobotUIViewSet<a class="headerlink" href="#nautobotuiviewset" title="Permanent link">¶</a></h1>
|
|
9283
|
-
<details class="version-added">
|
|
9284
|
-
<summary>Added in version 1.4.0</summary>
|
|
9285
|
-
</details>
|
|
9286
9283
|
<p>New in Nautobot 1.4 is the debut of <code>NautobotUIViewSet</code>: A powerful app development tool that can save app developer hundreds of lines of code compared to using legacy <code>generic.views</code>. Using it to gain access to default functionalities previous provided by <code>generic.views</code> such as <code>create()</code>, <code>update()</code>, <code>partial_update()</code>, <code>bulk_update()</code>, <code>destroy()</code>, <code>bulk_destroy()</code>, <code>retrieve()</code> and <code>list()</code> actions.</p>
|
|
9287
9284
|
<p>Note that this ViewSet is catered specifically to the UI, not the API.</p>
|
|
9288
9285
|
<p>Concrete examples on how to use <code>NautobotUIViewSet</code> resides in <code>nautobot.circuits.views</code>.</p>
|
|
@@ -9443,10 +9440,6 @@ The framework provides many pre-built panel types.</p>
|
|
|
9443
9440
|
<p>If you do not provide your own templates in the <code>yourapp/templates/yourapp</code> folder, <code>NautobotUIViewSet</code> will fall back to <code>generic/object_{self.action}.html</code>.</p>
|
|
9444
9441
|
<p>Since in many cases the <code>create</code> and <code>update</code> templates for a model will be identical, you are not required to create both. If you provide a <code>{app_label}/{model_opts.model_name}_create.html</code> file but not a <code>{app_label}/{model_opts.model_name}_update.html</code> file, then when you update an object, it will fall back to <code>{app_label}/{model_opts.model_name}_create.html</code> and vice versa.</p>
|
|
9445
9442
|
<h3 id="adding-custom-views-to-nautobotuiviewset-nautobotuiviewsetrouter">Adding Custom Views To NautobotUIViewSet & NautobotUIViewSetRouter<a class="headerlink" href="#adding-custom-views-to-nautobotuiviewset-nautobotuiviewsetrouter" title="Permanent link">¶</a></h3>
|
|
9446
|
-
<details class="version-changed">
|
|
9447
|
-
<summary>Changed in version 1.6.0</summary>
|
|
9448
|
-
<p>Via <a href="https://github.com/nautobot/nautobot/pull/4045">PR #4045</a>, notes and changelog views provided by mixins have now been moved to this pattern.</p>
|
|
9449
|
-
</details>
|
|
9450
9443
|
<p>Django REST Framework provides the ability to decorate a method on a ViewSet with <code>@action(detail=True)</code> to add the method as a view to the ViewSetRouter. This method must return a fully rendered HTML view.</p>
|
|
9451
9444
|
<p>Below is an example of adding a custom action view to an App's ViewSet. A few considerations to keep in mind:</p>
|
|
9452
9445
|
<ul>
|
|
@@ -9154,10 +9154,6 @@
|
|
|
9154
9154
|
<a id="__codelineno-0-27" name="__codelineno-0-27" href="#__codelineno-0-27"></a><span class="p">]</span>
|
|
9155
9155
|
<a id="__codelineno-0-28" name="__codelineno-0-28" href="#__codelineno-0-28"></a><span class="n">urlpatterns</span> <span class="o">+=</span> <span class="n">router</span><span class="o">.</span><span class="n">urls</span>
|
|
9156
9156
|
</code></pre></div>
|
|
9157
|
-
<details class="version-added">
|
|
9158
|
-
<summary>Added in version 1.5.1</summary>
|
|
9159
|
-
<p>Changelog and Notes views and URLs are now provided in the NautobotUIViewSet and NautobotUIViewSetRouter.</p>
|
|
9160
|
-
</details>
|
|
9161
9157
|
|
|
9162
9158
|
|
|
9163
9159
|
|
|
@@ -9124,9 +9124,6 @@
|
|
|
9124
9124
|
|
|
9125
9125
|
|
|
9126
9126
|
<h1 id="note-url-endpoint">Note URL Endpoint<a class="headerlink" href="#note-url-endpoint" title="Permanent link">¶</a></h1>
|
|
9127
|
-
<details class="version-added">
|
|
9128
|
-
<summary>Added in version 1.4.0</summary>
|
|
9129
|
-
</details>
|
|
9130
9127
|
<p>Models that inherit from <code>PrimaryModel</code> and <code>OrganizationalModel</code> can have notes associated. In order to utilize this new feature you will need to add the endpoint to <code>urls.py</code>. Here is an option to be able to support both 1.4+ and older versions of Nautobot:</p>
|
|
9131
9128
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="n">urlpatterns</span> <span class="o">=</span> <span class="p">[</span>
|
|
9132
9129
|
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> <span class="n">path</span><span class="p">(</span><span class="s1">'random/'</span><span class="p">,</span> <span class="n">views</span><span class="o">.</span><span class="n">RandomAnimalView</span><span class="o">.</span><span class="n">as_view</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="s1">'random_animal'</span><span class="p">),</span>
|