nautobot 2.2.2__py3-none-any.whl → 2.2.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nautobot/apps/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/templates/generic/object_list.html +3 -3
- 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_templatetags_helpers.py +32 -0
- nautobot/core/tests/test_views.py +19 -0
- nautobot/core/tests/test_views_utils.py +22 -1
- nautobot/core/utils/module_loading.py +89 -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 +137 -0
- nautobot/dcim/urls.py +5 -0
- nautobot/dcim/views.py +149 -1
- 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_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/views.py +47 -95
- 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/project-static/docs/assets/extra.css +4 -0
- nautobot/project-static/docs/code-reference/nautobot/apps/api.html +1 -1
- nautobot/project-static/docs/code-reference/nautobot/apps/jobs.html +180 -211
- nautobot/project-static/docs/development/apps/api/platform-features/jobs.html +1 -1
- nautobot/project-static/docs/development/core/application-registry.html +126 -84
- nautobot/project-static/docs/development/core/model-checklist.html +49 -1
- nautobot/project-static/docs/development/core/model-features.html +1 -1
- nautobot/project-static/docs/development/jobs/index.html +334 -58
- nautobot/project-static/docs/development/jobs/migration/from-v1.html +1 -1
- nautobot/project-static/docs/objects.inv +0 -0
- nautobot/project-static/docs/release-notes/version-2.2.html +237 -55
- nautobot/project-static/docs/search/search_index.json +1 -1
- nautobot/project-static/docs/sitemap.xml +254 -254
- nautobot/project-static/docs/sitemap.xml.gz +0 -0
- nautobot/project-static/docs/user-guide/administration/upgrading/from-v1/upgrading-from-nautobot-v1.html +7 -4
- nautobot/project-static/docs/user-guide/core-data-model/ipam/vlan.html +111 -0
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/index.html +15 -28
- nautobot/project-static/docs/user-guide/platform-functionality/jobs/models.html +4 -4
- nautobot/project-static/js/forms.js +18 -11
- {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/METADATA +3 -3
- {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/RECORD +87 -81
- nautobot/extras/test_jobs/job_variables.py +0 -93
- {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/LICENSE.txt +0 -0
- {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/NOTICE +0 -0
- {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/WHEEL +0 -0
- {nautobot-2.2.2.dist-info → nautobot-2.2.3.dist-info}/entry_points.txt +0 -0
|
@@ -7712,6 +7712,15 @@
|
|
|
7712
7712
|
</span>
|
|
7713
7713
|
</a>
|
|
7714
7714
|
|
|
7715
|
+
</li>
|
|
7716
|
+
|
|
7717
|
+
<li class="md-nav__item">
|
|
7718
|
+
<a href="#installing-jobs" class="md-nav__link">
|
|
7719
|
+
<span class="md-ellipsis">
|
|
7720
|
+
Installing Jobs
|
|
7721
|
+
</span>
|
|
7722
|
+
</a>
|
|
7723
|
+
|
|
7715
7724
|
</li>
|
|
7716
7725
|
|
|
7717
7726
|
<li class="md-nav__item">
|
|
@@ -7755,6 +7764,15 @@
|
|
|
7755
7764
|
</ul>
|
|
7756
7765
|
</nav>
|
|
7757
7766
|
|
|
7767
|
+
</li>
|
|
7768
|
+
|
|
7769
|
+
<li class="md-nav__item">
|
|
7770
|
+
<a href="#reserved-attribute-names" class="md-nav__link">
|
|
7771
|
+
<span class="md-ellipsis">
|
|
7772
|
+
Reserved Attribute Names
|
|
7773
|
+
</span>
|
|
7774
|
+
</a>
|
|
7775
|
+
|
|
7758
7776
|
</li>
|
|
7759
7777
|
|
|
7760
7778
|
<li class="md-nav__item">
|
|
@@ -8052,6 +8070,25 @@
|
|
|
8052
8070
|
</ul>
|
|
8053
8071
|
</nav>
|
|
8054
8072
|
|
|
8073
|
+
</li>
|
|
8074
|
+
|
|
8075
|
+
<li class="md-nav__item">
|
|
8076
|
+
<a href="#special-methods" class="md-nav__link">
|
|
8077
|
+
<span class="md-ellipsis">
|
|
8078
|
+
Special Methods
|
|
8079
|
+
</span>
|
|
8080
|
+
</a>
|
|
8081
|
+
|
|
8082
|
+
<nav class="md-nav" aria-label="Special Methods">
|
|
8083
|
+
<ul class="md-nav__list">
|
|
8084
|
+
|
|
8085
|
+
<li class="md-nav__item">
|
|
8086
|
+
<a href="#the-before_start-method" class="md-nav__link">
|
|
8087
|
+
<span class="md-ellipsis">
|
|
8088
|
+
The before_start() Method
|
|
8089
|
+
</span>
|
|
8090
|
+
</a>
|
|
8091
|
+
|
|
8055
8092
|
</li>
|
|
8056
8093
|
|
|
8057
8094
|
<li class="md-nav__item">
|
|
@@ -8061,6 +8098,38 @@
|
|
|
8061
8098
|
</span>
|
|
8062
8099
|
</a>
|
|
8063
8100
|
|
|
8101
|
+
</li>
|
|
8102
|
+
|
|
8103
|
+
<li class="md-nav__item">
|
|
8104
|
+
<a href="#the-on_success-method" class="md-nav__link">
|
|
8105
|
+
<span class="md-ellipsis">
|
|
8106
|
+
The on_success() Method
|
|
8107
|
+
</span>
|
|
8108
|
+
</a>
|
|
8109
|
+
|
|
8110
|
+
</li>
|
|
8111
|
+
|
|
8112
|
+
<li class="md-nav__item">
|
|
8113
|
+
<a href="#the-on_failure-method" class="md-nav__link">
|
|
8114
|
+
<span class="md-ellipsis">
|
|
8115
|
+
The on_failure() Method
|
|
8116
|
+
</span>
|
|
8117
|
+
</a>
|
|
8118
|
+
|
|
8119
|
+
</li>
|
|
8120
|
+
|
|
8121
|
+
<li class="md-nav__item">
|
|
8122
|
+
<a href="#the-after_return-method" class="md-nav__link">
|
|
8123
|
+
<span class="md-ellipsis">
|
|
8124
|
+
The after_return() Method
|
|
8125
|
+
</span>
|
|
8126
|
+
</a>
|
|
8127
|
+
|
|
8128
|
+
</li>
|
|
8129
|
+
|
|
8130
|
+
</ul>
|
|
8131
|
+
</nav>
|
|
8132
|
+
|
|
8064
8133
|
</li>
|
|
8065
8134
|
|
|
8066
8135
|
<li class="md-nav__item">
|
|
@@ -8273,22 +8342,30 @@
|
|
|
8273
8342
|
|
|
8274
8343
|
|
|
8275
8344
|
<h1 id="jobs">Jobs<a class="headerlink" href="#jobs" title="Permanent link">¶</a></h1>
|
|
8276
|
-
<p>
|
|
8345
|
+
<p>Familiarity with the basic concepts of <a href="../../user-guide/platform-functionality/jobs/index.html">Jobs</a>, especially the distinction between Job classes (Python code) and Job records (Nautobot database records), is recommended before authoring your first Job.</p>
|
|
8346
|
+
<div class="admonition tip">
|
|
8347
|
+
<p class="admonition-title">Tip</p>
|
|
8348
|
+
<p>From a development standpoint, it's especially important to understand that the Job database record never stores the Job class code. It only describes the <strong>existence</strong> of a Job class. The actual Job class source code is loaded into memory only.</p>
|
|
8349
|
+
</div>
|
|
8350
|
+
<div class="admonition info">
|
|
8351
|
+
<p class="admonition-title">Info</p>
|
|
8352
|
+
<p>As an implementation detail in Nautobot 2.2.3 and later, all known Job <strong>classes</strong> are cached in the <a href="../core/application-registry.html#jobs">application registry</a>, which is refreshed at various times including Nautobot application startup and immediately prior to actually executing any given Job by a worker. This implementation detail should not be relied on directly; instead you should always use the <code>get_job()</code> and/or <code>get_jobs()</code> APIs to obtain a Job class when needed.</p>
|
|
8353
|
+
</div>
|
|
8277
8354
|
<h2 id="migrating-jobs-from-v1-to-v2">Migrating Jobs from v1 to v2<a class="headerlink" href="#migrating-jobs-from-v1-to-v2" title="Permanent link">¶</a></h2>
|
|
8278
8355
|
<div class="admonition version-changed">
|
|
8279
8356
|
<p class="admonition-title">Changed in version 2.0.0</p>
|
|
8280
8357
|
<p>See <a href="migration/from-v1.html">Migrating Jobs From Nautobot v1</a> for more information on how to migrate your existing jobs to Nautobot v2.</p>
|
|
8281
8358
|
</div>
|
|
8282
|
-
<h2 id="
|
|
8359
|
+
<h2 id="installing-jobs">Installing Jobs<a class="headerlink" href="#installing-jobs" title="Permanent link">¶</a></h2>
|
|
8283
8360
|
<p>Jobs may be installed in one of three ways:</p>
|
|
8284
8361
|
<ul>
|
|
8285
8362
|
<li>Manually installed as files in the <a href="../../user-guide/administration/configuration/optional-settings.html#jobs_root"><code>JOBS_ROOT</code></a> path (which defaults to <code>$NAUTOBOT_ROOT/jobs/</code>).<ul>
|
|
8286
|
-
<li>
|
|
8363
|
+
<li>Python files and subdirectories containing Python files will be dynamically loaded at Nautobot startup in order to discover and register available Job classes. For example, a job class named <code>MyJobClass</code> in <code>$JOBS_ROOT/my_job.py</code> will be loaded into Nautobot as <code>my_job.MyJobClass</code>.</li>
|
|
8287
8364
|
<li>All Python modules in this directory are imported by Nautobot and all worker processes at startup. If you have a <code>custom_jobs.py</code> and a <code>custom_jobs_module/__init__.py</code> file in your <code>JOBS_ROOT</code>, both of these files will be imported at startup.</li>
|
|
8288
8365
|
</ul>
|
|
8289
8366
|
</li>
|
|
8290
8367
|
<li>Imported from an external <a href="../../user-guide/platform-functionality/gitrepository.html#jobs">Git repository</a>.<ul>
|
|
8291
|
-
<li>Git repositories are loaded into the module namespace of the <code>GitRepository.slug</code> value at startup. For example, if your <code>slug</code> value is <code>my_git_jobs</code> your jobs will be loaded into Python as <code>my_git_jobs.jobs</code>.</li>
|
|
8368
|
+
<li>Git repositories are loaded into the module namespace of the <code>GitRepository.slug</code> value at startup. For example, if your <code>slug</code> value is <code>my_git_jobs</code> your jobs will be loaded into Python as <code>my_git_jobs.jobs.MyJobClass</code>.</li>
|
|
8292
8369
|
<li>All git repositories providing jobs must include a <code>__init__.py</code> file at the root of the repository.</li>
|
|
8293
8370
|
<li>Nautobot and all worker processes will import the git repository's <code>jobs</code> module at startup so a <code>jobs.py</code> or <code>jobs/__init__.py</code> file must exist in the root of the repository.</li>
|
|
8294
8371
|
</ul>
|
|
@@ -8298,15 +8375,16 @@
|
|
|
8298
8375
|
</ul>
|
|
8299
8376
|
</li>
|
|
8300
8377
|
</ul>
|
|
8301
|
-
<p>In any case, each module holds one or more
|
|
8378
|
+
<p>In any case, each module holds one or more Job classes (Python classes), each of which serves a specific purpose. The logic of each job can be split into a number of distinct methods, each of which performs a discrete portion of the overall job logic.</p>
|
|
8302
8379
|
<p>For example, we can create a module named <code>devices.py</code> to hold all of our jobs which pertain to devices in Nautobot. Within that module, we might define several jobs. Each job is defined as a Python class inheriting from <code>nautobot.apps.jobs.Job</code>, which provides the base functionality needed to accept user input and log activity.</p>
|
|
8303
8380
|
<div class="admonition version-changed">
|
|
8304
8381
|
<p class="admonition-title">Changed in version 2.0.0</p>
|
|
8305
|
-
<p>All job classes must now be registered
|
|
8382
|
+
<p>All job classes that are intended to be runnable must now be registered by a call to <code>nautobot.apps.jobs.register_jobs()</code> on module import. This allows for a module to, if desired, define "abstract" base Job classes that are defined in code but are not registered (and therefore are not runnable in Nautobot). The <code>register_jobs</code> method accepts one or more job classes as arguments.</p>
|
|
8306
8383
|
</div>
|
|
8384
|
+
<h2 id="writing-jobs">Writing Jobs<a class="headerlink" href="#writing-jobs" title="Permanent link">¶</a></h2>
|
|
8307
8385
|
<div class="admonition warning">
|
|
8308
8386
|
<p class="admonition-title">Warning</p>
|
|
8309
|
-
<p>Make sure
|
|
8387
|
+
<p>Make sure your Job subclasses inherit from <code>nautobot.apps.Job</code> and <em>not</em> from <code>nautobot.extras.models.Job</code> instead; if you mistakenly inherit from the latter, Django will think you want to define a new database model.</p>
|
|
8310
8388
|
</div>
|
|
8311
8389
|
<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">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
|
|
8312
8390
|
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>
|
|
@@ -8325,21 +8403,22 @@
|
|
|
8325
8403
|
<ul>
|
|
8326
8404
|
<li>Module and class attributes, providing for default behavior, documentation and discoverability</li>
|
|
8327
8405
|
<li>a set of variables for user input via the Nautobot UI (if your job requires any user inputs)</li>
|
|
8328
|
-
<li>a <code>run()</code> method, which is the only required attribute on a Job class and receives the user input values, if any
|
|
8406
|
+
<li>a <code>run()</code> method, which is the only required attribute on a Job class and receives the user input values, if any, as keyword arguments.</li>
|
|
8407
|
+
<li>Optionally, any of the special methods <code>before_start()</code>, <code>on_success()</code>, <code>on_failure()</code>, and/or <code>after_return()</code> (more on these later).</li>
|
|
8329
8408
|
</ul>
|
|
8330
8409
|
<p>It's important to understand that jobs execute on the server asynchronously as background tasks; they log messages and report their status to the database by updating <a href="../../user-guide/platform-functionality/jobs/models.html#job-results"><code>JobResult</code></a> records and creating <a href="../../user-guide/platform-functionality/jobs/models.html#job-log-entry"><code>JobLogEntry</code></a> records.</p>
|
|
8331
8410
|
<div class="admonition note">
|
|
8332
8411
|
<p class="admonition-title">Note</p>
|
|
8333
|
-
<p>When actively developing a Job utilizing a development environment it's important to understand that the "automatically reload when code changes are detected" debugging functionality provided by <code>nautobot-server runserver</code> does <strong>not</strong> automatically restart the Celery <code>worker</code> process when code changes are made; therefore, it is required to restart the <code>worker</code> after each update to your Job source code or else it will continue to run the version of the Job code that was present when it first started.</p>
|
|
8334
|
-
<p>Additionally, as of Nautobot 1.3, the Job database records corresponding to installed Jobs are <em>not</em> automatically refreshed when the development server auto-restarts. If you make changes to any of the class and module metadata attributes described in the following sections, the database will be refreshed to reflect these changes only after running <code>nautobot-server migrate</code> or <code>nautobot-server post_upgrade</code> (recommended) or if you manually edit a Job database record to force it to be refreshed.</p>
|
|
8412
|
+
<p>When actively developing a Job utilizing a development environment it's important to understand that the "automatically reload when code changes are detected" debugging functionality provided by <code>nautobot-server runserver</code> does <strong>not</strong> automatically restart the Celery <code>worker</code> process when code changes are made; therefore, it is required to restart the <code>worker</code> after each update to your Job source code or else it will continue to run the version of the Job code that was present when it first started. In the Nautobot core development environment, we use <code>watchmedo auto-restart</code> as a helper tool to auto-restart the workers as well on code changes; you may wish to configure your local development environment similarly for convenience.</p>
|
|
8413
|
+
<p>Additionally, as of Nautobot 1.3, the Job database records corresponding to installed Jobs are <em>not</em> automatically refreshed when the development server auto-restarts. If you make changes to any of the class and module metadata attributes described in the following sections, the database will be refreshed to reflect these changes only after running <code>nautobot-server migrate</code> or <code>nautobot-server post_upgrade</code> (recommended) or if you manually edit a Job database record to force it to be refreshed. The exception here is Git-repository-provided Jobs; resyncing the Git repository through Nautobot will also trigger a refresh of the Job records corresponding to this repository's contents.</p>
|
|
8335
8414
|
</div>
|
|
8336
8415
|
<h3 id="job-registration">Job Registration<a class="headerlink" href="#job-registration" title="Permanent link">¶</a></h3>
|
|
8337
8416
|
<div class="admonition version-changed">
|
|
8338
8417
|
<p class="admonition-title">Changed in version 2.0.0</p>
|
|
8339
8418
|
</div>
|
|
8340
8419
|
<p>All Job classes, including <code>JobHookReceiver</code> and <code>JobButtonReceiver</code> classes must be registered at <strong>import time</strong> using the <code>nautobot.apps.jobs.register_jobs</code> method. This method accepts one or more job classes as arguments. You must account for how your jobs are imported when deciding where to call this method.</p>
|
|
8341
|
-
<h4 id="registering-jobs-in-jobs_root-or-git-repositories">Registering Jobs in JOBS_ROOT or Git Repositories<a class="headerlink" href="#registering-jobs-in-jobs_root-or-git-repositories" title="Permanent link">¶</a></h4>
|
|
8342
|
-
<p>Only top level module names within JOBS_ROOT are imported by Nautobot at runtime. This means that if you're using submodules, you need to ensure that your jobs are either registered in your top level <code>__init__.py</code> or that this file imports your submodules where the jobs are registered:</p>
|
|
8420
|
+
<h4 id="registering-jobs-in-jobs_root-or-git-repositories">Registering Jobs in <code>JOBS_ROOT</code> or Git Repositories<a class="headerlink" href="#registering-jobs-in-jobs_root-or-git-repositories" title="Permanent link">¶</a></h4>
|
|
8421
|
+
<p>Only top level module names within <code>JOBS_ROOT</code> are imported by Nautobot at runtime. This means that if you're using submodules, you need to ensure that your jobs are either registered in your top level <code>__init__.py</code> or that this file imports your submodules where the jobs are registered:</p>
|
|
8343
8422
|
<div class="highlight"><span class="filename">$JOBS_ROOT/my_jobs/__init__.py</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">my_job_module</span>
|
|
8344
8423
|
</code></pre></div>
|
|
8345
8424
|
<div class="highlight"><span class="filename">$JOBS_ROOT/my_jobs/my_job_module.py</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
|
|
@@ -8353,6 +8432,183 @@
|
|
|
8353
8432
|
<p>If not using submodules, you should register your job in the file where your job is defined.</p>
|
|
8354
8433
|
<h4 id="registering-jobs-in-an-app">Registering Jobs in an App<a class="headerlink" href="#registering-jobs-in-an-app" title="Permanent link">¶</a></h4>
|
|
8355
8434
|
<p>Apps should register jobs in the module defined in their <a href="../apps/api/nautobot-app-config.html#nautobotappconfig-code-location-attributes"><code>NautobotAppConfig.jobs</code></a> property. This defaults to the <code>jobs</code> module of the App.</p>
|
|
8435
|
+
<h3 id="reserved-attribute-names">Reserved Attribute Names<a class="headerlink" href="#reserved-attribute-names" title="Permanent link">¶</a></h3>
|
|
8436
|
+
<p>There are many attributes and methods of the Job class that serve as reserved names. You must be careful when implementing custom methods or defining the user input <a href="#variables">variables</a> for your Job that you do not inadvertently "step on" one of these reserved attributes causing unexpected behavior or errors.</p>
|
|
8437
|
+
<div class="admonition example">
|
|
8438
|
+
<p class="admonition-title">Example</p>
|
|
8439
|
+
<p>One classic pitfall here is the the reserved <code>name</code> metadata attribute - if you attempt to redefine <code>name</code> as a user input variable, your Job will not work.</p>
|
|
8440
|
+
</div>
|
|
8441
|
+
<p>As of Nautobot 2.2.3, the current list of reserved names (not including low-level Python built-ins such as <code>__dict__</code> or <code>__str__</code> includes:</p>
|
|
8442
|
+
<table>
|
|
8443
|
+
<thead>
|
|
8444
|
+
<tr>
|
|
8445
|
+
<th>Reserved Name</th>
|
|
8446
|
+
<th>Purpose</th>
|
|
8447
|
+
</tr>
|
|
8448
|
+
</thead>
|
|
8449
|
+
<tbody>
|
|
8450
|
+
<tr>
|
|
8451
|
+
<td><code>after_return</code></td>
|
|
8452
|
+
<td><a href="#special-methods">special method</a></td>
|
|
8453
|
+
</tr>
|
|
8454
|
+
<tr>
|
|
8455
|
+
<td><code>approval_required</code></td>
|
|
8456
|
+
<td><a href="#approval_required">metadata property</a></td>
|
|
8457
|
+
</tr>
|
|
8458
|
+
<tr>
|
|
8459
|
+
<td><code>as_form</code></td>
|
|
8460
|
+
<td>class method</td>
|
|
8461
|
+
</tr>
|
|
8462
|
+
<tr>
|
|
8463
|
+
<td><code>as_form_class</code></td>
|
|
8464
|
+
<td>class method</td>
|
|
8465
|
+
</tr>
|
|
8466
|
+
<tr>
|
|
8467
|
+
<td><code>before_start</code></td>
|
|
8468
|
+
<td><a href="#special-methods">special method</a></td>
|
|
8469
|
+
</tr>
|
|
8470
|
+
<tr>
|
|
8471
|
+
<td><code>celery_kwargs</code></td>
|
|
8472
|
+
<td>property</td>
|
|
8473
|
+
</tr>
|
|
8474
|
+
<tr>
|
|
8475
|
+
<td><code>class_path</code></td>
|
|
8476
|
+
<td>class property</td>
|
|
8477
|
+
</tr>
|
|
8478
|
+
<tr>
|
|
8479
|
+
<td><code>class_path_dotted</code></td>
|
|
8480
|
+
<td>deprecated class property</td>
|
|
8481
|
+
</tr>
|
|
8482
|
+
<tr>
|
|
8483
|
+
<td><code>class_path_js_escaped</code></td>
|
|
8484
|
+
<td>class property</td>
|
|
8485
|
+
</tr>
|
|
8486
|
+
<tr>
|
|
8487
|
+
<td><code>create_file</code></td>
|
|
8488
|
+
<td><a href="#file-output">helper method</a></td>
|
|
8489
|
+
</tr>
|
|
8490
|
+
<tr>
|
|
8491
|
+
<td><code>description</code></td>
|
|
8492
|
+
<td><a href="#description">metadata property</a></td>
|
|
8493
|
+
</tr>
|
|
8494
|
+
<tr>
|
|
8495
|
+
<td><code>description_first_line</code></td>
|
|
8496
|
+
<td><a href="#description">metadata property</a></td>
|
|
8497
|
+
</tr>
|
|
8498
|
+
<tr>
|
|
8499
|
+
<td><code>deserialize_data</code></td>
|
|
8500
|
+
<td>internal class method</td>
|
|
8501
|
+
</tr>
|
|
8502
|
+
<tr>
|
|
8503
|
+
<td><code>dryrun_default</code></td>
|
|
8504
|
+
<td><a href="#dryrun_default">metadata property</a></td>
|
|
8505
|
+
</tr>
|
|
8506
|
+
<tr>
|
|
8507
|
+
<td><code>file_path</code></td>
|
|
8508
|
+
<td>deprecated class property</td>
|
|
8509
|
+
</tr>
|
|
8510
|
+
<tr>
|
|
8511
|
+
<td><code>field_order</code></td>
|
|
8512
|
+
<td><a href="#field_order">metadata property</a></td>
|
|
8513
|
+
</tr>
|
|
8514
|
+
<tr>
|
|
8515
|
+
<td><code>grouping</code></td>
|
|
8516
|
+
<td><a href="#module-metadata-attributes">module metadata property</a></td>
|
|
8517
|
+
</tr>
|
|
8518
|
+
<tr>
|
|
8519
|
+
<td><code>has_sensitive_variables</code></td>
|
|
8520
|
+
<td><a href="#has_sensitive_variables">metadata property</a></td>
|
|
8521
|
+
</tr>
|
|
8522
|
+
<tr>
|
|
8523
|
+
<td><code>hidden</code></td>
|
|
8524
|
+
<td><a href="#hidden">metadata property</a></td>
|
|
8525
|
+
</tr>
|
|
8526
|
+
<tr>
|
|
8527
|
+
<td><code>job_model</code></td>
|
|
8528
|
+
<td>property</td>
|
|
8529
|
+
</tr>
|
|
8530
|
+
<tr>
|
|
8531
|
+
<td><code>job_result</code></td>
|
|
8532
|
+
<td>property</td>
|
|
8533
|
+
</tr>
|
|
8534
|
+
<tr>
|
|
8535
|
+
<td><code>load_json</code></td>
|
|
8536
|
+
<td><a href="#reading-data-from-files">helper method</a></td>
|
|
8537
|
+
</tr>
|
|
8538
|
+
<tr>
|
|
8539
|
+
<td><code>load_yaml</code></td>
|
|
8540
|
+
<td><a href="#reading-data-from-files">helper method</a></td>
|
|
8541
|
+
</tr>
|
|
8542
|
+
<tr>
|
|
8543
|
+
<td><code>name</code></td>
|
|
8544
|
+
<td><a href="#name">metadata property</a></td>
|
|
8545
|
+
</tr>
|
|
8546
|
+
<tr>
|
|
8547
|
+
<td><code>on_failure</code></td>
|
|
8548
|
+
<td><a href="#special-methods">special method</a></td>
|
|
8549
|
+
</tr>
|
|
8550
|
+
<tr>
|
|
8551
|
+
<td><code>on_retry</code></td>
|
|
8552
|
+
<td>reserved as a future <a href="#special-methods">special method</a></td>
|
|
8553
|
+
</tr>
|
|
8554
|
+
<tr>
|
|
8555
|
+
<td><code>on_success</code></td>
|
|
8556
|
+
<td><a href="#special-methods">special method</a></td>
|
|
8557
|
+
</tr>
|
|
8558
|
+
<tr>
|
|
8559
|
+
<td><code>prepare_job_kwargs</code></td>
|
|
8560
|
+
<td>internal class method</td>
|
|
8561
|
+
</tr>
|
|
8562
|
+
<tr>
|
|
8563
|
+
<td><code>properties_dict</code></td>
|
|
8564
|
+
<td>class property</td>
|
|
8565
|
+
</tr>
|
|
8566
|
+
<tr>
|
|
8567
|
+
<td><code>read_only</code></td>
|
|
8568
|
+
<td><a href="#read_only">metadata property</a></td>
|
|
8569
|
+
</tr>
|
|
8570
|
+
<tr>
|
|
8571
|
+
<td><code>registered_name</code></td>
|
|
8572
|
+
<td>deprecated class property</td>
|
|
8573
|
+
</tr>
|
|
8574
|
+
<tr>
|
|
8575
|
+
<td><code>run</code></td>
|
|
8576
|
+
<td><a href="#special-methods">special method</a></td>
|
|
8577
|
+
</tr>
|
|
8578
|
+
<tr>
|
|
8579
|
+
<td><code>serialize_data</code></td>
|
|
8580
|
+
<td>internal method</td>
|
|
8581
|
+
</tr>
|
|
8582
|
+
<tr>
|
|
8583
|
+
<td><code>soft_time_limit</code></td>
|
|
8584
|
+
<td><a href="#soft_time_limit">metadata property</a></td>
|
|
8585
|
+
</tr>
|
|
8586
|
+
<tr>
|
|
8587
|
+
<td><code>supports_dryrun</code></td>
|
|
8588
|
+
<td>class property</td>
|
|
8589
|
+
</tr>
|
|
8590
|
+
<tr>
|
|
8591
|
+
<td><code>task_queues</code></td>
|
|
8592
|
+
<td><a href="#task_queues">metadata property</a></td>
|
|
8593
|
+
</tr>
|
|
8594
|
+
<tr>
|
|
8595
|
+
<td><code>template_name</code></td>
|
|
8596
|
+
<td><a href="#template_name">metadata property</a></td>
|
|
8597
|
+
</tr>
|
|
8598
|
+
<tr>
|
|
8599
|
+
<td><code>time_limit</code></td>
|
|
8600
|
+
<td><a href="#time_limit">metadata property</a></td>
|
|
8601
|
+
</tr>
|
|
8602
|
+
<tr>
|
|
8603
|
+
<td><code>user</code></td>
|
|
8604
|
+
<td>property</td>
|
|
8605
|
+
</tr>
|
|
8606
|
+
<tr>
|
|
8607
|
+
<td><code>validate_data</code></td>
|
|
8608
|
+
<td>internal class method</td>
|
|
8609
|
+
</tr>
|
|
8610
|
+
</tbody>
|
|
8611
|
+
</table>
|
|
8356
8612
|
<h3 id="module-metadata-attributes">Module Metadata Attributes<a class="headerlink" href="#module-metadata-attributes" title="Permanent link">¶</a></h3>
|
|
8357
8613
|
<h4 id="name-grouping"><code>name</code> (Grouping)<a class="headerlink" href="#name-grouping" title="Permanent link">¶</a></h4>
|
|
8358
8614
|
<p>You can define a global constant called <code>name</code> within a job module (the Python file which contains one or more job classes) to set the default grouping under which jobs in this module will be displayed in the Nautobot UI. If this value is not defined, the module's file name will be used. This "grouping" value may also be defined or overridden when editing Job records in the database.</p>
|
|
@@ -8657,8 +8913,18 @@ Another example of using the nested reference would be to access <a href="../../
|
|
|
8657
8913
|
<li><code>min_prefix_length</code> - Minimum length of the mask</li>
|
|
8658
8914
|
<li><code>max_prefix_length</code> - Maximum length of the mask</li>
|
|
8659
8915
|
</ul>
|
|
8660
|
-
<h3 id="
|
|
8661
|
-
<p>
|
|
8916
|
+
<h3 id="special-methods">Special Methods<a class="headerlink" href="#special-methods" title="Permanent link">¶</a></h3>
|
|
8917
|
+
<p>Nautobot Jobs when executed will be instantiated by Nautobot, then Nautobot will call in order the special API methods <code>before_start()</code>, <code>run()</code>, <code>on_success()</code>/<code>on_failure()</code>, and <code>after_return()</code>. You must implement the <code>run()</code> method; the other methods have default implementations that do nothing.</p>
|
|
8918
|
+
<p>As Jobs are Python classes, you are of course free to define any number of other helper methods or functions that you call yourself from within any of the above special methods, but the above are the only ones that will be automatically called.</p>
|
|
8919
|
+
<div class="admonition version-removed">
|
|
8920
|
+
<p class="admonition-title">Removed in version 2.0.0</p>
|
|
8921
|
+
<p>The NetBox backwards compatible <code>test_*()</code> and <code>post_run()</code> special methods have been removed.</p>
|
|
8922
|
+
</div>
|
|
8923
|
+
<h4 id="the-before_start-method">The <code>before_start()</code> Method<a class="headerlink" href="#the-before_start-method" title="Permanent link">¶</a></h4>
|
|
8924
|
+
<p>The <code>before_start()</code> method may optionally be implemented to perform any appropriate Job-specific setup before the <code>run()</code> method is called. It has the signature <code>before_start(self, task_id, args, kwargs)</code> for historical reasons; the <code>task_id</code> parameter will always be identical to <code>self.request.id</code>, the <code>args</code> parameter will generally be empty, and any user-specified variables passed into the Job execution will be present in the <code>kwargs</code> parameter.</p>
|
|
8925
|
+
<p>The return value from <code>before_start()</code> is ignored, but if it raises any exception, the Job execution will be marked as a failure and <code>run()</code> will not be called.</p>
|
|
8926
|
+
<h4 id="the-run-method">The <code>run()</code> Method<a class="headerlink" href="#the-run-method" title="Permanent link">¶</a></h4>
|
|
8927
|
+
<p>The <code>run()</code> method is the primary worker of any Job, and must be implemented. After the <code>self</code> argument, it should accept keyword arguments for any variables defined on the job:</p>
|
|
8662
8928
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span>
|
|
8663
8929
|
<a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a>
|
|
8664
8930
|
<a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="k">class</span> <span class="nc">CreateDevices</span><span class="p">(</span><span class="n">Job</span><span class="p">):</span>
|
|
@@ -8666,7 +8932,7 @@ Another example of using the nested reference would be to access <a href="../../
|
|
|
8666
8932
|
<a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a> <span class="n">var2</span> <span class="o">=</span> <span class="n">IntegerVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
|
8667
8933
|
<a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a> <span class="n">var3</span> <span class="o">=</span> <span class="n">ObjectVar</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
|
8668
8934
|
<a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a>
|
|
8669
|
-
<a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">var1</span><span class="p">,</span> <span class="n">var2</span><span class="p">,</span> <span class="n">var3</span><span class="p">):</span>
|
|
8935
|
+
<a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">var1</span><span class="p">,</span> <span class="n">var2</span><span class="p">,</span> <span class="n">var3</span><span class="p">):</span>
|
|
8670
8936
|
<a id="__codelineno-16-9" name="__codelineno-16-9" href="#__codelineno-16-9"></a> <span class="o">...</span>
|
|
8671
8937
|
</code></pre></div>
|
|
8672
8938
|
<p>Again, defining user variables is totally optional; you may create a job with a <code>run()</code> method with only the <code>self</code> argument if no user input is needed.</p>
|
|
@@ -8678,10 +8944,13 @@ Another example of using the nested reference would be to access <a href="../../
|
|
|
8678
8944
|
<p class="admonition-title">Warning</p>
|
|
8679
8945
|
<p>The Django ORM provides methods to create/edit many objects at once, namely <code>bulk_create()</code> and <code>update()</code>. These are best avoided in most cases as they bypass a model's built-in validation and can easily lead to database corruption if not used carefully.</p>
|
|
8680
8946
|
</div>
|
|
8681
|
-
<
|
|
8682
|
-
<
|
|
8683
|
-
<p>
|
|
8684
|
-
</
|
|
8947
|
+
<p>If <code>run()</code> returns any value (even the implicit <code>None</code>), the Job execution will be marked as a success and the returned value will be stored in the associated JobResult database record. Conversely, if <code>run()</code> raises any exception, the Job execution will be marked as a failure and the traceback will be stored in the JobResult.</p>
|
|
8948
|
+
<h4 id="the-on_success-method">The <code>on_success()</code> Method<a class="headerlink" href="#the-on_success-method" title="Permanent link">¶</a></h4>
|
|
8949
|
+
<p>If both <code>before_start()</code> and <code>run()</code> are successful, the <code>on_success()</code> method will be called next, if implemented. It has the signature <code>on_success(self, retval, task_id, args, kwargs)</code>; as with <code>before_start()</code> the <code>task_id</code> and <code>args</code> parameters can generally be ignored, while <code>retval</code> is the return value from <code>run()</code>, and <code>kwargs</code> will contain the user-specified variables passed into the Job execution.</p>
|
|
8950
|
+
<h4 id="the-on_failure-method">The <code>on_failure()</code> Method<a class="headerlink" href="#the-on_failure-method" title="Permanent link">¶</a></h4>
|
|
8951
|
+
<p>If either <code>before_start()</code> or <code>run()</code> raises any unhandled exception, the <code>on_failure()</code> method will be called next, if implemented. It has the signature <code>on_failure(self, exc, task_id, args, kwargs, einfo)</code>; of these parameters, the <code>exc</code> will contain the exception that was raised, and <code>kwargs</code> will contain the user-specified variables passed into the Job.</p>
|
|
8952
|
+
<h4 id="the-after_return-method">The <code>after_return()</code> Method<a class="headerlink" href="#the-after_return-method" title="Permanent link">¶</a></h4>
|
|
8953
|
+
<p>Regardless of the overall Job execution success or failure, the <code>after_return()</code> method will be called after <code>on_success()</code> or <code>on_failure()</code>. It has the signature <code>after_return(self, status, retval, task_id, args, kwargs, einfo)</code>; the <code>status</code> will indicate success or failure (using the <code>JobResultStatusChoices</code> enum), <code>retval</code> is <em>either</em> the return value from <code>run()</code> (on success) or the exception raised (on failure), and once again <code>kwargs</code> contains the user variables.</p>
|
|
8685
8954
|
<h3 id="logging">Logging<a class="headerlink" href="#logging" title="Permanent link">¶</a></h3>
|
|
8686
8955
|
<div class="admonition version-changed">
|
|
8687
8956
|
<p class="admonition-title">Changed in version 2.0.0</p>
|
|
@@ -8832,7 +9101,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
8832
9101
|
<p>These variables are presented as a web form to be completed by the user. Once submitted, the job's <code>run()</code> method is called to create the appropriate objects, and it returns simple CSV output to the user summarizing the created objects.</p>
|
|
8833
9102
|
<div class="highlight"><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="kn">from</span> <span class="nn">django.contrib.contenttypes.models</span> <span class="kn">import</span> <span class="n">ContentType</span>
|
|
8834
9103
|
<a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>
|
|
8835
|
-
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span>
|
|
9104
|
+
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">StringVar</span><span class="p">,</span> <span class="n">IntegerVar</span><span class="p">,</span> <span class="n">ObjectVar</span><span class="p">,</span> <span class="n">register_jobs</span>
|
|
8836
9105
|
<a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Location</span><span class="p">,</span> <span class="n">LocationType</span><span class="p">,</span> <span class="n">Device</span><span class="p">,</span> <span class="n">Manufacturer</span><span class="p">,</span> <span class="n">DeviceType</span>
|
|
8837
9106
|
<a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span><span class="p">,</span> <span class="n">Role</span>
|
|
8838
9107
|
<a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a>
|
|
@@ -8885,10 +9154,13 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
8885
9154
|
<a id="__codelineno-24-53" name="__codelineno-24-53" href="#__codelineno-24-53"></a> <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">attrs</span><span class="p">))</span>
|
|
8886
9155
|
<a id="__codelineno-24-54" name="__codelineno-24-54" href="#__codelineno-24-54"></a>
|
|
8887
9156
|
<a id="__codelineno-24-55" name="__codelineno-24-55" href="#__codelineno-24-55"></a> <span class="k">return</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
|
|
9157
|
+
<a id="__codelineno-24-56" name="__codelineno-24-56" href="#__codelineno-24-56"></a>
|
|
9158
|
+
<a id="__codelineno-24-57" name="__codelineno-24-57" href="#__codelineno-24-57"></a>
|
|
9159
|
+
<a id="__codelineno-24-58" name="__codelineno-24-58" href="#__codelineno-24-58"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">NewBranch</span><span class="p">)</span>
|
|
8888
9160
|
</code></pre></div>
|
|
8889
9161
|
<h3 id="device-validation">Device validation<a class="headerlink" href="#device-validation" title="Permanent link">¶</a></h3>
|
|
8890
|
-
<p>A job to perform various validation of Device data in Nautobot. As this job does not require any user input, it does not define any variables
|
|
8891
|
-
<div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span>
|
|
9162
|
+
<p>A job to perform various validation of Device data in Nautobot. As this job does not require any user input, it does not define any variables.</p>
|
|
9163
|
+
<div class="highlight"><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">Job</span><span class="p">,</span> <span class="n">register_jobs</span>
|
|
8892
9164
|
<a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">ConsolePort</span><span class="p">,</span> <span class="n">Device</span><span class="p">,</span> <span class="n">PowerPort</span>
|
|
8893
9165
|
<a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="kn">from</span> <span class="nn">nautobot.extras.models</span> <span class="kn">import</span> <span class="n">Status</span>
|
|
8894
9166
|
<a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a>
|
|
@@ -8907,42 +9179,37 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
8907
9179
|
<a id="__codelineno-25-17" name="__codelineno-25-17" href="#__codelineno-25-17"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
|
8908
9180
|
<a id="__codelineno-25-18" name="__codelineno-25-18" href="#__codelineno-25-18"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
|
|
8909
9181
|
<a id="__codelineno-25-19" name="__codelineno-25-19" href="#__codelineno-25-19"></a> <span class="p">)</span>
|
|
8910
|
-
<a id="__codelineno-25-20" name="__codelineno-25-20" href="#__codelineno-25-20"></a> <span class="k">
|
|
8911
|
-
<a id="__codelineno-25-21" name="__codelineno-25-21" href="#__codelineno-25-21"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">
|
|
8912
|
-
<a id="__codelineno-25-22" name="__codelineno-25-22" href="#__codelineno-25-22"></a> <span class="s2">"Console
|
|
9182
|
+
<a id="__codelineno-25-20" name="__codelineno-25-20" href="#__codelineno-25-20"></a> <span class="k">else</span><span class="p">:</span>
|
|
9183
|
+
<a id="__codelineno-25-21" name="__codelineno-25-21" href="#__codelineno-25-21"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
|
|
9184
|
+
<a id="__codelineno-25-22" name="__codelineno-25-22" href="#__codelineno-25-22"></a> <span class="s2">"Console port </span><span class="si">%s</span><span class="s2"> has a connection defined"</span><span class="p">,</span>
|
|
8913
9185
|
<a id="__codelineno-25-23" name="__codelineno-25-23" href="#__codelineno-25-23"></a> <span class="n">console_port</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
|
8914
9186
|
<a id="__codelineno-25-24" name="__codelineno-25-24" href="#__codelineno-25-24"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">console_port</span><span class="o">.</span><span class="n">device</span><span class="p">},</span>
|
|
8915
9187
|
<a id="__codelineno-25-25" name="__codelineno-25-25" href="#__codelineno-25-25"></a> <span class="p">)</span>
|
|
8916
|
-
<a id="__codelineno-25-26" name="__codelineno-25-26" href="#__codelineno-25-26"></a>
|
|
8917
|
-
<a id="__codelineno-25-27" name="__codelineno-25-27" href="#__codelineno-25-27"></a>
|
|
8918
|
-
<a id="__codelineno-25-28" name="__codelineno-25-28" href="#__codelineno-25-28"></a>
|
|
8919
|
-
<a id="__codelineno-25-29" name="__codelineno-25-29" href="#__codelineno-25-29"></a>
|
|
8920
|
-
<a id="__codelineno-25-30" name="__codelineno-25-30" href="#__codelineno-25-30"></a>
|
|
8921
|
-
<a id="__codelineno-25-31" name="__codelineno-25-31" href="#__codelineno-25-31"></a>
|
|
8922
|
-
<a id="__codelineno-25-32" name="__codelineno-25-32" href="#__codelineno-25-32"></a>
|
|
8923
|
-
<a id="__codelineno-25-33" name="__codelineno-25-33" href="#__codelineno-25-33"></a>
|
|
8924
|
-
<a id="__codelineno-25-34" name="__codelineno-25-34" href="#__codelineno-25-34"></a>
|
|
8925
|
-
<a id="__codelineno-25-35" name="__codelineno-25-35" href="#__codelineno-25-35"></a>
|
|
8926
|
-
<a id="__codelineno-25-36" name="__codelineno-25-36" href="#__codelineno-25-36"></a>
|
|
8927
|
-
<a id="__codelineno-25-37" name="__codelineno-25-37" href="#__codelineno-25-37"></a>
|
|
8928
|
-
<a id="__codelineno-25-38" name="__codelineno-25-38" href="#__codelineno-25-38"></a>
|
|
8929
|
-
<a id="__codelineno-25-39" name="__codelineno-25-39" href="#__codelineno-25-39"></a>
|
|
8930
|
-
<a id="__codelineno-25-40" name="__codelineno-25-40" href="#__codelineno-25-40"></a>
|
|
8931
|
-
<a id="__codelineno-25-41" name="__codelineno-25-41" href="#__codelineno-25-41"></a>
|
|
8932
|
-
<a id="__codelineno-25-42" name="__codelineno-25-42" href="#__codelineno-25-42"></a>
|
|
8933
|
-
<a id="__codelineno-25-43" name="__codelineno-25-43" href="#__codelineno-25-43"></a>
|
|
8934
|
-
<a id="__codelineno-25-44" name="__codelineno-25-44" href="#__codelineno-25-44"></a>
|
|
8935
|
-
<a id="__codelineno-25-45" name="__codelineno-25-45" href="#__codelineno-25-45"></a>
|
|
8936
|
-
<a id="__codelineno-25-46" name="__codelineno-25-46" href="#__codelineno-25-46"></a>
|
|
8937
|
-
<a id="__codelineno-25-47" name="__codelineno-25-47" href="#__codelineno-25-47"></a>
|
|
8938
|
-
<a id="__codelineno-25-48" name="__codelineno-25-48" href="#__codelineno-25-48"></a>
|
|
8939
|
-
<a id="__codelineno-25-49" name="__codelineno-25-49" href="#__codelineno-25-49"></a>
|
|
8940
|
-
<a id="__codelineno-25-50" name="__codelineno-25-50" href="#__codelineno-25-50"></a
|
|
8941
|
-
<a id="__codelineno-25-51" name="__codelineno-25-51" href="#__codelineno-25-51"></a> <span class="n">connected_ports</span><span class="p">,</span>
|
|
8942
|
-
<a id="__codelineno-25-52" name="__codelineno-25-52" href="#__codelineno-25-52"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">device</span><span class="p">},</span>
|
|
8943
|
-
<a id="__codelineno-25-53" name="__codelineno-25-53" href="#__codelineno-25-53"></a> <span class="p">)</span>
|
|
8944
|
-
<a id="__codelineno-25-54" name="__codelineno-25-54" href="#__codelineno-25-54"></a> <span class="k">else</span><span class="p">:</span>
|
|
8945
|
-
<a id="__codelineno-25-55" name="__codelineno-25-55" href="#__codelineno-25-55"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"At least two connected power supplies found"</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">device</span><span class="p">})</span>
|
|
9188
|
+
<a id="__codelineno-25-26" name="__codelineno-25-26" href="#__codelineno-25-26"></a>
|
|
9189
|
+
<a id="__codelineno-25-27" name="__codelineno-25-27" href="#__codelineno-25-27"></a> <span class="k">def</span> <span class="nf">test_power_connections</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
9190
|
+
<a id="__codelineno-25-28" name="__codelineno-25-28" href="#__codelineno-25-28"></a> <span class="n">STATUS_ACTIVE</span> <span class="o">=</span> <span class="n">Status</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="n">name</span><span class="o">=</span><span class="s1">'Active'</span><span class="p">)</span>
|
|
9191
|
+
<a id="__codelineno-25-29" name="__codelineno-25-29" href="#__codelineno-25-29"></a>
|
|
9192
|
+
<a id="__codelineno-25-30" name="__codelineno-25-30" href="#__codelineno-25-30"></a> <span class="c1"># Check that every active device has at least two connected power supplies.</span>
|
|
9193
|
+
<a id="__codelineno-25-31" name="__codelineno-25-31" href="#__codelineno-25-31"></a> <span class="k">for</span> <span class="n">device</span> <span class="ow">in</span> <span class="n">Device</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">status</span><span class="o">=</span><span class="n">STATUS_ACTIVE</span><span class="p">):</span>
|
|
9194
|
+
<a id="__codelineno-25-32" name="__codelineno-25-32" href="#__codelineno-25-32"></a> <span class="n">connected_ports</span> <span class="o">=</span> <span class="mi">0</span>
|
|
9195
|
+
<a id="__codelineno-25-33" name="__codelineno-25-33" href="#__codelineno-25-33"></a> <span class="k">for</span> <span class="n">power_port</span> <span class="ow">in</span> <span class="n">PowerPort</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">device</span><span class="o">=</span><span class="n">device</span><span class="p">):</span>
|
|
9196
|
+
<a id="__codelineno-25-34" name="__codelineno-25-34" href="#__codelineno-25-34"></a> <span class="k">if</span> <span class="n">power_port</span><span class="o">.</span><span class="n">connected_endpoint</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
9197
|
+
<a id="__codelineno-25-35" name="__codelineno-25-35" href="#__codelineno-25-35"></a> <span class="n">connected_ports</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
9198
|
+
<a id="__codelineno-25-36" name="__codelineno-25-36" href="#__codelineno-25-36"></a> <span class="k">if</span> <span class="n">connected_ports</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span>
|
|
9199
|
+
<a id="__codelineno-25-37" name="__codelineno-25-37" href="#__codelineno-25-37"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
|
|
9200
|
+
<a id="__codelineno-25-38" name="__codelineno-25-38" href="#__codelineno-25-38"></a> <span class="s2">"</span><span class="si">%s</span><span class="s2"> connected power supplies found (2 needed)"</span><span class="p">,</span>
|
|
9201
|
+
<a id="__codelineno-25-39" name="__codelineno-25-39" href="#__codelineno-25-39"></a> <span class="n">connected_ports</span><span class="p">,</span>
|
|
9202
|
+
<a id="__codelineno-25-40" name="__codelineno-25-40" href="#__codelineno-25-40"></a> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">device</span><span class="p">},</span>
|
|
9203
|
+
<a id="__codelineno-25-41" name="__codelineno-25-41" href="#__codelineno-25-41"></a> <span class="p">)</span>
|
|
9204
|
+
<a id="__codelineno-25-42" name="__codelineno-25-42" href="#__codelineno-25-42"></a> <span class="k">else</span><span class="p">:</span>
|
|
9205
|
+
<a id="__codelineno-25-43" name="__codelineno-25-43" href="#__codelineno-25-43"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"At least two connected power supplies found"</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">device</span><span class="p">})</span>
|
|
9206
|
+
<a id="__codelineno-25-44" name="__codelineno-25-44" href="#__codelineno-25-44"></a>
|
|
9207
|
+
<a id="__codelineno-25-45" name="__codelineno-25-45" href="#__codelineno-25-45"></a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
9208
|
+
<a id="__codelineno-25-46" name="__codelineno-25-46" href="#__codelineno-25-46"></a> <span class="bp">self</span><span class="o">.</span><span class="n">test_console_connection</span><span class="p">()</span>
|
|
9209
|
+
<a id="__codelineno-25-47" name="__codelineno-25-47" href="#__codelineno-25-47"></a> <span class="bp">self</span><span class="o">.</span><span class="n">test_power_connections</span><span class="p">()</span>
|
|
9210
|
+
<a id="__codelineno-25-48" name="__codelineno-25-48" href="#__codelineno-25-48"></a>
|
|
9211
|
+
<a id="__codelineno-25-49" name="__codelineno-25-49" href="#__codelineno-25-49"></a>
|
|
9212
|
+
<a id="__codelineno-25-50" name="__codelineno-25-50" href="#__codelineno-25-50"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">DeviceConnectionsReport</span><span class="p">)</span>
|
|
8946
9213
|
</code></pre></div>
|
|
8947
9214
|
<h2 id="job-button-receivers">Job Button Receivers<a class="headerlink" href="#job-button-receivers" title="Permanent link">¶</a></h2>
|
|
8948
9215
|
<p>Job Buttons are only able to initiate a specific type of job called a <strong>Job Button Receiver</strong>. These are jobs that subclass the <code>nautobot.apps.jobs.JobButtonReceiver</code> class. Job Button Receivers are similar to normal jobs except they are hard coded to accept only <code>object_pk</code> and <code>object_model_name</code> <a href="#variables">variables</a>. Job Button Receivers are hidden from the jobs listing UI by default but otherwise function similarly to other jobs. The <code>JobButtonReceiver</code> class only implements one method called <code>receive_job_button</code>.</p>
|
|
@@ -8956,7 +9223,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
8956
9223
|
<li><code>obj</code> - An instance of the object where the button was pressed</li>
|
|
8957
9224
|
</ol>
|
|
8958
9225
|
<h3 id="example-job-button-receiver">Example Job Button Receiver<a class="headerlink" href="#example-job-button-receiver" title="Permanent link">¶</a></h3>
|
|
8959
|
-
<div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span>
|
|
9226
|
+
<div class="highlight"><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
|
|
8960
9227
|
<a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>
|
|
8961
9228
|
<a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a>
|
|
8962
9229
|
<a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="k">class</span> <span class="nc">ExampleSimpleJobButtonReceiver</span><span class="p">(</span><span class="n">JobButtonReceiver</span><span class="p">):</span>
|
|
@@ -8966,10 +9233,13 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
8966
9233
|
<a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a> <span class="k">def</span> <span class="nf">receive_job_button</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
|
|
8967
9234
|
<a id="__codelineno-26-9" name="__codelineno-26-9" href="#__codelineno-26-9"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">"Running Job Button Receiver."</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
|
|
8968
9235
|
<a id="__codelineno-26-10" name="__codelineno-26-10" href="#__codelineno-26-10"></a> <span class="c1"># Add job logic here</span>
|
|
9236
|
+
<a id="__codelineno-26-11" name="__codelineno-26-11" href="#__codelineno-26-11"></a>
|
|
9237
|
+
<a id="__codelineno-26-12" name="__codelineno-26-12" href="#__codelineno-26-12"></a>
|
|
9238
|
+
<a id="__codelineno-26-13" name="__codelineno-26-13" href="#__codelineno-26-13"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleSimpleJobButtonReceiver</span><span class="p">)</span>
|
|
8969
9239
|
</code></pre></div>
|
|
8970
9240
|
<h3 id="job-buttons-for-multiple-types">Job Buttons for Multiple Types<a class="headerlink" href="#job-buttons-for-multiple-types" title="Permanent link">¶</a></h3>
|
|
8971
9241
|
<p>Since Job Buttons can be associated to multiple object types, it would be trivial to create a Job that can change what it runs based on the object type.</p>
|
|
8972
|
-
<div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span>
|
|
9242
|
+
<div class="highlight"><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobButtonReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
|
|
8973
9243
|
<a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a><span class="kn">from</span> <span class="nn">nautobot.dcim.models</span> <span class="kn">import</span> <span class="n">Device</span><span class="p">,</span> <span class="n">Location</span>
|
|
8974
9244
|
<a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>
|
|
8975
9245
|
<a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a>
|
|
@@ -9002,6 +9272,9 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
9002
9272
|
<a id="__codelineno-27-31" name="__codelineno-27-31" href="#__codelineno-27-31"></a> <span class="k">else</span><span class="p">:</span>
|
|
9003
9273
|
<a id="__codelineno-27-32" name="__codelineno-27-32" href="#__codelineno-27-32"></a> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">"Unable to run Job Button for type </span><span class="si">%s</span><span class="s2">."</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="p">{</span><span class="s2">"object"</span><span class="p">:</span> <span class="n">obj</span><span class="p">})</span>
|
|
9004
9274
|
<a id="__codelineno-27-33" name="__codelineno-27-33" href="#__codelineno-27-33"></a> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"Job button called on unsupported object type."</span><span class="p">)</span>
|
|
9275
|
+
<a id="__codelineno-27-34" name="__codelineno-27-34" href="#__codelineno-27-34"></a>
|
|
9276
|
+
<a id="__codelineno-27-35" name="__codelineno-27-35" href="#__codelineno-27-35"></a>
|
|
9277
|
+
<a id="__codelineno-27-36" name="__codelineno-27-36" href="#__codelineno-27-36"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleComplexJobButtonReceiver</span><span class="p">)</span>
|
|
9005
9278
|
</code></pre></div>
|
|
9006
9279
|
<h2 id="job-hook-receivers">Job Hook Receivers<a class="headerlink" href="#job-hook-receivers" title="Permanent link">¶</a></h2>
|
|
9007
9280
|
<p>Job Hooks are only able to initiate a specific type of job called a <strong>Job Hook Receiver</strong>. These are jobs that subclass the <code>nautobot.apps.jobs.JobHookReceiver</code> class. Job hook receivers are similar to normal jobs except they are hard coded to accept only an <code>object_change</code> <a href="#variables">variable</a>. Job Hook Receivers are hidden from the jobs listing UI by default but otherwise function similarly to other jobs. The <code>JobHookReceiver</code> class only implements one method called <code>receive_job_hook</code>.</p>
|
|
@@ -9014,7 +9287,7 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
9014
9287
|
<p>To prevent negatively impacting system performance through an infinite loop, a change that was made by a <code>JobHookReceiver</code> job will not trigger another <code>JobHookReceiver</code> job to run.</p>
|
|
9015
9288
|
</div>
|
|
9016
9289
|
<h3 id="example-job-hook-receiver">Example Job Hook Receiver<a class="headerlink" href="#example-job-hook-receiver" title="Permanent link">¶</a></h3>
|
|
9017
|
-
<div class="highlight"><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobHookReceiver</span>
|
|
9290
|
+
<div class="highlight"><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="kn">from</span> <span class="nn">nautobot.apps.jobs</span> <span class="kn">import</span> <span class="n">JobHookReceiver</span><span class="p">,</span> <span class="n">register_jobs</span>
|
|
9018
9291
|
<a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a><span class="kn">from</span> <span class="nn">nautobot.extras.choices</span> <span class="kn">import</span> <span class="n">ObjectChangeActionChoices</span>
|
|
9019
9292
|
<a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a>
|
|
9020
9293
|
<a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a>
|
|
@@ -9045,6 +9318,9 @@ However the import paths used in the examples requires 1.5.2 and newer.</p>
|
|
|
9045
9318
|
<a id="__codelineno-28-29" name="__codelineno-28-29" href="#__codelineno-28-29"></a> <span class="k">def</span> <span class="nf">validate_serial</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">serial</span><span class="p">):</span>
|
|
9046
9319
|
<a id="__codelineno-28-30" name="__codelineno-28-30" href="#__codelineno-28-30"></a> <span class="c1"># add business logic to validate serial</span>
|
|
9047
9320
|
<a id="__codelineno-28-31" name="__codelineno-28-31" href="#__codelineno-28-31"></a> <span class="k">return</span> <span class="kc">False</span>
|
|
9321
|
+
<a id="__codelineno-28-32" name="__codelineno-28-32" href="#__codelineno-28-32"></a>
|
|
9322
|
+
<a id="__codelineno-28-33" name="__codelineno-28-33" href="#__codelineno-28-33"></a>
|
|
9323
|
+
<a id="__codelineno-28-34" name="__codelineno-28-34" href="#__codelineno-28-34"></a><span class="n">register_jobs</span><span class="p">(</span><span class="n">ExampleJobHookReceiver</span><span class="p">)</span>
|
|
9048
9324
|
</code></pre></div>
|
|
9049
9325
|
<h3 id="the-receive_job_hook-method">The <code>receive_job_hook()</code> Method<a class="headerlink" href="#the-receive_job_hook-method" title="Permanent link">¶</a></h3>
|
|
9050
9326
|
<p>All <code>JobHookReceiver</code> subclasses must implement a <code>receive_job_hook()</code> method. This method accepts three arguments:</p>
|