Helper Class Implementation
Prev | Chapter 3. Writing New Modules | Next

## Helper Class Implementation

Splat Helper Modules are implemented as a Python module containing a single subclass of `splat.plugin.Helper`. The subclass must implement three methods: `parseOptions`, `work`, and `attributes`.

For a working example, refer to the SSH public key helper located in `splat/helpers/sshPublicKeys.py`.

Example 3.1. Skeleton of Splat Helper Module

    class MyHelper(splat.plugin.Helper):
        @classmethod
        def attributes(self):
            ...
        @classmethod
        def parseOptions(self, options):
            ...
        def work(self, context, ldapEntry, modified):
            ...

### Error Handling and Logging

If an error occurs, your module must raise an exception of type `splat.plugin.SplatPluginError`, with an error message provided as the second argument. This error will be presented to the user by the splat daemon.

    raise splat.plugin.SplatPluginError, "No such user"

Logging is provided by the standard logging module. To find the Splat logger, use `splat.LOG_NAME`:

    logger = logging.getLogger(splat.LOG_NAME)

### Parsing Configuration Options

Helper-specific configuration options may be specified in the `splat.conf` configuration file. These options are passed to the helper's `parseOptions` method as a dictionary of key/value strings. These options are not validated by the configuration parser -- it is your responsibility to validate these strings and convert them to the appropriate data type.

Example 3.2. Helper Module parseOptions() Method

    def parseOptions(self, options):
        context = {}

        for key in options.keys():
            if (key == 'minuid'):
                context['minuid'] = int(options[key])
                continue
            raise splat.plugin.SplatPluginError, "Invalid options '%s' specified." % key

        return context

### Handling LDAP Entries

The splat daemon will perform an LDAP search on the helper's behalf, filter based on group restrictions, and pass individual LDAP `Entry` instances to the `work` method. The following method arguments are provided:

context

  The opaque configuration context corresponding with the supplied entry.

entry

  An LDAP `Entry` instance..

modified

  If true, the supplied LDAP entry has been modified since the last successful helper iteration. This can be used to avoid doing unnecessary work in the helper, such as overwriting identical ssh keys. `modified` will also be set to true if the `modifyTimestamp` attribute was not found in an LDAP entry. This helps ensure that helpers will still be able to function when this attribute is not available for whatever reason.

The `Entry` class provides two instance variables: `dn` and `attributes`. The `dn` variable provides the corresponding LDAP object's full `DN`, while `attributes` provides a dictionary of LDAP attributes and corresponding lists of values. The desired LDAP object attributes must be provided by the `attributes()` method of your `splat.plugin.Helper` subclass; these LDAP attributes will used in the LDAP search and will be returned if available.

In addition to any requested attributes, the `modifyTimestamp` operational attribute will always be returned. This can be used by your helper to determine if any work should be done; For example, the SSH Public Key helper will `stat()` the user's key file and compare the two modification dates to determine whether the key should be updated.

### Caution

The helper's `attributes()` method defines the LDAP object attributes that you are interested in -- an LDAP Entry will still be returned if it does not contain all of your requested attributes, and/or the `modifyTimestamp` attribute. It is your responsibility to ensure that any attributes required by your helper are supplied.

Example 3.3. Helper Module attributes() and work() Methods

    class MyHelper(splat.plugin.Helper):
        def attributes(self):
            return ('uid', 'sshPublicKey')
        def work(self, context, ldapEntry, modified):
            # If the entry has not been modified since our last run, skip it.
            if (not modified):
                return

            if (not ldapEntry.attributes.has_key('sshPublicKey'))
                return

            key = attributes.get('sshPublicKey')[0]

Prev | Up | Next
Chapter 3. Writing New Modules | Home | Splat Man Pages