* Add the mvt.plugin import surface
mvt.plugin re-exports the names a plugin needs from MVT under one import
path. It holds the module base classes and Command, the alert and result
types, the database errors a module raises, the timestamp converters, the
plugin settings API, MVT's settings, get_plugin_logger() and MVT_VERSION.
The names it exports are kept working on a best-effort basis. Changes to
them are announced in the release notes. Anything else in mvt can still be
imported, and may change between releases without notice.
get_plugin_logger(__name__) returns a logger under mvt.ext for plugin code
outside a module class. Its records then reach the console and the
command.log file of a run. A file loaded with --load-module or
--load-command is named after the file.
* Document how to write MVT plugins
The custom modules page now leads with plugin packages. Loading module
files with --load-module and MVT_CUSTOM_MODULES moves to a section on
developing a module locally.
A new "Writing a module" section shows a module which subclasses
IOSExtraction. It lists each base class, the command pair it serves and the
helpers it provides. "Depending on a built-in module" says to import a
built-in class from its family package.
"Importing from MVT" says what mvt.plugin exports and what importing from
it means. The custom commands page shows a Command subclass which lists its
own modules. The sysdiagnose and plugin configuration pages import from
mvt.plugin.
* Load installed module packages via entry points
Python packages can already register custom CLI commands which load
automatically, but custom modules still require --load-module or the
MVT_CUSTOM_MODULES environment variable on every invocation.
Add an mvt.modules entry-point group so installed packages can register
forensic modules which load automatically into every module-running
check-* command. An entry point resolves to an iterable of MVTModule
subclasses, or a callable returning one. Broken entry points are
skipped with a warning so a faulty package cannot break MVT.
* Record the source of loaded modules for auditability
Now that installed module packages load automatically, record where every
module came from:
- --list-modules groups the available modules by source, one line per
source with the modules comma-separated: MVT itself with its version,
each installed package with its version and VCS commit when recorded
(PEP 610 direct_url.json), and each --load-module/MVT_CUSTOM_MODULES
file with its SHA-256 hash.
- Commands log one line per module source with its version or hash and
the modules loaded from it, so command.log records exactly which
modules ran and where they came from.
- Make init_logging() idempotent: a loaded module package importing an
MVT CLI module would previously add a second console handler and
duplicate every console log line.
* Route loaded module logging under the mvt.ext namespace
Modules loaded from installed packages or file paths live outside the
mvt logger hierarchy, so their log records never reach MVT's console
and file handlers and instead fall through to logging.lastResort:
alerts print as bare unformatted lines and INFO messages are dropped
entirely.
Add get_module_logger() and use it everywhere module loggers are
created. Built-in mvt.* modules keep their existing logger names, and
everything external is parented under a dedicated mvt.ext namespace so
records reach the handlers and external names can never collide with
MVT's internal logger tree. File-path modules are named after their
file (mvt.ext.<stem>) instead of the mangled internal import name.
Document a naming convention for community module packages:
distribute as mvt-plugin-<name> with import package mvt_plugin_<name>,
including the publishing organization in the name. The prefix is
advisory (loading is by entry point, and it is no mark of
authenticity), but conforming packages get a cleaner logger namespace:
the mvt_plugin_ prefix is stripped, so mvt_plugin_amnesty_custom logs
as mvt.ext.amnesty_custom.