Plugin development

A plugin is the component in charge of detect one software and its version. Since a software could have many different signatures, every plugin has test files associated to assure version integrity and add new signatures without breaking the working ones.

Let’s see how to write your own plugin.

Requirements

The plugin has to:

  • Be compliant with IPlugin interface.

  • Be a subclass of Plugin.

  • Have a test file at tests/plugins/fixtures/<plugin_name>.yml.

To make it faster, there’s a script called add_new_plugin.py which creates both plugin and test file.

$ python scripts/add_new_plugin.py --matcher=url example

Created plugin file at detectem/detectem/plugins/example.py
Created test file at detectem/tests/plugins/fixtures/example.yml

Plugin file

We’re creating an example plugin for a ficticious software called examplelib. We can detect it easily since it’s included as an external library and in its URL it contains the version. Then we will use the URL matcher for this case.

from detectem.plugin import Plugin


class ExamplePlugin(Plugin):
    name = 'example'
    homepage = 'http://example.org'
    matchers = [
        {'url': '/examplelib\.v(?P<version>[0-9\.]+)-min\.js$'},
    ]

Review matchers page to meet the available matchers to write your own plugin.

Test file

This is the test file for our example plugin:

- plugin: example
  matches:
    - url: http://domain.tld/examplelib.v1.1.3-min.js
      version: 1.1.3

Then running the test is simple:

$ pytest tests/plugins/test_common.py --plugin example

When you need to support a new signature and it’s not supported by current signatures, you must modify your plugin file and add a new test to the list to see that your changes don’t break previous detected versions.

References

interface detectem.plugin.IPlugin[source]
homepage = <zope.interface.interface.Attribute object at 0x7f65c4d8b950 detectem.plugin.IPlugin.homepage>

Plugin homepage.

matchers = <zope.interface.interface.Attribute object at 0x7f65c4d11c10 detectem.plugin.IPlugin.matchers>

List of matchers

name = <zope.interface.interface.Attribute object at 0x7f65c4d8b350 detectem.plugin.IPlugin.name>

Name to identify the plugin.

tags = <zope.interface.interface.Attribute object at 0x7f65c4d11dd0 detectem.plugin.IPlugin.tags>

Tags to categorize plugins

class detectem.plugin.Plugin[source]

Class used by normal plugins. It implements IPlugin.