This page is for developers
This page explains how to create new jobs for integration into the project. It is aimed to show to a developer some steps to successfully make a new job.
The plugin architecture of this project relies on the jobs folder(s), configurable through the
--jobs option of the basic options (see the Server tuning section). These jobs folders are Python packages to be imported by the main application.
A folder can contain job class definitions in Python modules that will be dynamically loaded. The API for job class' definition is slightly enhanced regarding this of NdScheduler, for the sake of simplicity.
Job class template¶
On the contrary of NdScheduler, in this project,
ndscheduler.job.JobBase can be subclassed as many times as needed without having each proxy class being captured as a usable job class. In other words, only leaf job classes in the inheritance tree are loaded.
The following snippet shows a job class template:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
In this template, we notice:
- The wildcard import from
botscheduler, required for the
JobBase, particular decorators and report object classes.
- The job metadata in the
infodictionary, holding job's information for display in the WUI.
runmethod, decorated with the
reportdecorator, returning a list of report objects.
For the job information, note that:
job_class_nameis displayed in the dropdown list when adding or modifying a job. Beware of name clashes as multiple classes can be defined at different locations, thus having a unique job class string (e.g.
myjob.ShellCommand) while being displayed as the same name in the WUI.
argumentsis a list of dictionaries, one per argument, with the
descriptionfields. These are displayed in the WUI as help when adding or modifying a job.
report_titleholds a static report title but can be omitted if the first return value of the
runmethod is itself a title report object.
Trueby default for any job class. It can thus be omitted for enabled jobs but must be included for disabling one (e.g.
A job that has its
enabled property set to
False will not be visible at all in the WUI, that is, in the Jobs section but in the Executions and Logs sections as well.
|In this example, job executions and related audit logs will be viewable.||In this example, job executions and related audit logs will NOT be viewable.|
As mentioned before, report objects can be used to tune report's layout to be displayed for an execution in the WUI. The following screenshot shows where a report is generated and how it looks like.
A report is an assembly of objects from Tinyscript's report feature. For a complete list of report objects and more, please refer to this documentation. The most relevant report object classes in this project are:
||Code block, taking 1 argument: the [c]ode|
||Data [d]ictionary ; its HTML is generated using json2html|
||Image reference, taking up to 4 arguments: the [s]ource and optionally a [d]escription, the [w]idth and the [h]eight|
||List of [i]tems that can be ordered or not|
||Table with column and row headers, taking 3 arguments : a list of rows as the [d]ata, a list of [c]olumn [h]eaders, a list of [r]ow [h]eaders and a list of [c]olumn [f]ooters|
||Text paragraph, taking 1 argument : the [c]ontent to be displayed as a paragraph or any user-defined [t]ag|
||Bold section title line, taking 1 argument : section title's [t]ext|
||Bold section title line, taking 1 argument : subsection title's [t]ext|
By convention, the available jobs use the
Section object class for their report title. For instance, in the case of
haveibeenpwned.PwnedPasswordsJob, the return list of the
run method holding the report objects simply consist of:
Report object nesting
Report objects can be nested, e.g.
Another interesting example is this of
The robot getting the pwned passwords per email address formats it as a dictionary, suitable for use with the
Data report object, hence the simplicity in its definition as here before.
Defining a job class is one issue, writing robot classes in PyBots is another. Of course, the
run method can always contain machinery to perform complex network communication tasks, but PyBots is aimed at standardizing the way robots are made and used through context managers. If you would like to get a new robot implemented for use in a Bots Scheduler job, please submit an enhancement issue or implement it yourself, preferably sending a pull request for incrementing the library.
The way robots from PyBots can be used is particularly convenient for sparing lines of code in job class definitions. For instance,
run method starts with:
1 2 3 4 5
The whole work is done by the
NuclearLeaksBot that exposes a very simple interface for getting its result.
Another example is
shodan.ShodanHostsCheckJob that calls
ShodanBot, itself relying on
ShodanAPI that implements the full API as of this documentation.