Python modules

Igor comes with a number of Python extension modules to access and control the database. These modules actually also implement the functionality of the corresponding Igor command line tools.

igorVar

igorVar is the main module used to access the database from Python programs. It allows getting and setting of database variables in various different formats (text, xml, json, python).

exception igorVar.IgorError

Exception raised by this module when an error occurs

class igorVar.IgorServer(url, bearer_token=None, access_token=None, credentials=None, certificate=None, noverify=False, printmessages=False)

Main object used to access an Igor server.

The object is instantiated with parameters that specify how to contact Igor. After that it provides an interface similar to requests to allow REST operations on the Igor database.

Parameters:
  • url (str) – URL of Igor, including the /data/ bit. For example https://igor.local:9333/data/.
  • bearer_token (str) – An Igor external capability that has been supplied to your program and that governs which access rights your program has. Passed to Igor in the http Authorization: Bearer header.
  • access_token (str) – An alternative (and possibly less safe) way to pass an external capability to Igor, through an access_token query parameter in the URL.
  • credentials (str) – A username:password string used to authenticate your program to Igor and thereby govern which access rights you have. Passed to Igor in the http Authorization: Basic header.
  • certificate (str) – If the certificate of the Igor to contact is not trusted system-wide you can supply it here.
  • noverify (bool) – If you want to use https but bypass certificate verification you can pass True here.
  • printmessages (bool) – Be a bit more verbose (on stderr).
_action(method, item, variant, format=None, data=None, datatype=None, query=None)

Low-level REST interface to the database, can be used to do GET, PUT, POST, DELETE and other calls under program control.

Parameters:
  • method (str) – the REST method to call.
  • item (str) – the XPath expression defining the item to operate on.
  • variant (str) – Same as for get().
  • format (str) – Same as for get().
  • data (str) – new value for the item, same as for put().
  • datatype (str) – mimetype of the data argument, same as for put().
  • query (dict) – Same as for get().
Returns:

The REST call result.

Raises:

IgorError – in case of both communication errors and http errors returned by Igor.

delete(item, variant=None, format=None, query=None)

Delete an item in the database.

Parameters:
  • item (str) – the XPath expression defining the item to delete.
  • variant (str) – Same as for get() but not generally useful.
  • format (str) – Same as for get() but not generally useful.
  • query (dict) – Same as for get() but not generally useful.
Returns:

An empty string in case of success (or in case of the item not existing)

Raises:

IgorError – in case of both communication errors and http errors returned by Igor.

get(item, variant=None, format=None, query=None)

Get a value (or values) from the database.

Relative item names are relative to the toplevel /data element in the database. Absolute names are also allowed (so /data/environment is equivalent to environment).

Access to non-database portions of the REST API is allowed, so getting /action/save will have the side-effect of saving the database.

Full XPath syntax is allowed, so something like actions/action[name='save'] will retrieve the definition of the save action. For XPath expressions matching multiple elements you must specify variant=’multi’.

Parameters:
  • item (str) – The XPath expression defining the value(s) to get.
  • variant (str) –

    An optional modifier to specify which data you want returned:

    • multi allows the query to match multiple elements and return all of them (otherwise this is an error)
    • raw also returns attributes and access-control information (for XML only)
    • multiraw combines those two
    • ref returns an XPath reference in stead of the value(s) found
  • format (str) –

    The mimetype you want returned. Supported are:

    • text/plain plaintext without any structuring information
    • application/xml an XML string (default)
    • application/json a JSON string
  • query (dict) – An optional http query to pass in the request. Useful mainly when accessing non-database entrypoints in Igor, such as /action or /plugin entries.
Returns:

The value of the item, as a string in the format specified by format.

Raises:

IgorError – in case of both communication errors and http errors returned by Igor.

post(item, data, datatype, variant=None, format=None, query=None)

Create an item in the database.

Even if item refers to an existing location in the database a new item is created, after all items with the same name.

Parameters:
  • item (str) – the XPath expression defining the item to delete.
  • data (str) – new value for the item.
  • datatype (str) –

    mimetype of the data argument:

    • text/plain plaintext without any structuring information (default)
    • application/xml an XML string
    • application/json a JSON string
  • variant (str) – Same as for get() but not generally useful.
  • format (str) – Same as for get() but not generally useful.
  • query (dict) – Same as for get() but not generally useful.
Returns:

The XPath of the element created.

Raises:

IgorError – in case of both communication errors and http errors returned by Igor.

put(item, data, datatype, variant=None, format=None, query=None)

Replace or create an item in the database.

If item refers to a non-existing location in the database the item is created, if the item already exists it is replaced. It is an error to refer to multiple existing items.

Parameters:
  • item (str) – the XPath expression defining the item to delete.
  • data (str) – new value for the item.
  • datatype (str) –

    mimetype of the data argument:

    • text/plain plaintext without any structuring information (default)
    • application/xml an XML string
    • application/json a JSON string
  • variant (str) – Same as for get() but not generally useful.
  • format (str) – Same as for get() but not generally useful.
  • query (dict) – Same as for get() but not generally useful.
Returns:

The XPath of the element created (or modified).

Raises:

IgorError – in case of both communication errors and http errors returned by Igor.

igorCA

igorCA is the Python interface to using Igor as a Certificate Authority. It can run all needed openssl commands locally, but will usually be used to communicate with another igorCA embedded in Igor through the REST interface.

class igorCA.IgorCA(argv0, igorServer=None, keysize=None, database=None)

Interface to Certificate Authority for Igor.

Parameters:
  • argv0 (str) – program name (for error messages and such)
  • igorServer (str) – optional URL for Igor server to use as CA (default: use local CA through openSSL commands)
  • keySize (int) – default keysize (default default: 2048 bits)
  • database (str) – for local CA: the location of the Igor database (default: ~/.igor)
do_csrtemplate()

Return template config file for for openSSL CSR request

do_dn()

Return CA distinghuished name as a JSON structure

do_genCSR(keyFile, csrFile, csrConfigFile, allNames=[], keysize=None)

Create key and CSR for a service. Returns CSR.

do_getRoot()

Returns the signing certificate chain (for installation in browser or operating system)

do_list(cn=None)

Return list of certificates signed.

do_revoke(number)

Revoke a certificate. Argument is the number of the certificate to revoke (see list).

do_signCSR(csr)

Sign a CSR. Returns certificate.

do_status()

Returns nothing if CA status is ok, otherwise error message

igorServlet

This module allows you to easily create a REST microservice that supports Igor capability-based access control. You create an IgorServlet object passing all the parameters needed to listen for requests and check capabilities.

You supply callback methods for the REST endpoints and start the service.

Then, as requests come in, capabilities are checked, the REST parameters are decoded and passed as arguments to your callback methods, the return value of your callback is optionally JSON-encoded and sent back to the caller.

Intended use is that the requests come from the Igor server, and the microservice implements a device or sensor (or group of sensors), or is used to check the status of a service.

class igorServlet.IgorServlet(port=8080, name='igorServlet', nossl=False, capabilities=None, noCapabilities=None, database='.', sslname='igor', nolog=False, audience=None, issuer=None, issuerSharedKey=None, **kwargs)

Class implementing a REST server for use with Igor.

Objects of this class implement a simple REST server, which can optionally be run in a separate thread. After creating the server object (either before the service is running or while it is running) the calling application can use addEndpoint() to create endpoints with callbacks for the various http(s) verbs.

The service understands Igor access control (external capabilities and issuer shared secret keys) and takes care of implementing the access control policy set by the issuer. Callbacks are only made when the REST call carries a capability that allows the specific operation.

The service is implemented using Flask and gevent.pywsgi.

The service can by used by calling run(), which will run forever in the current thread and not return. Alternatively you can call start() which will run the service in a separate thread until stop() is called.

Parameters:
  • port (int) – the TCP port the service will listen to.
  • name (str) – name of the service.
  • nossl (bool) – set to True to serve http (default: serve https).
  • capabilities (bool) – set to True to enable using Igor capability-based access control.
  • noCapabilities (bool) – set to True to disable using Igor capability-based access control. The default for those two arguments is currently to not use capabilities but this is expected to change in a future release.
  • database (str) – the directory containing the SSL key sslname.key and certificate sslname.crt. Default is '.', but argumentParser() will return database='~/.igor'. This is because certificates contain only a host name, not a port or protocol, hence if IgorServlet is running on the same machine as Igor they must share a certificate.
  • sslname (str) – The name used in the key and certificate filename. Default is igor for reasons explained above.
  • nolog (bool) – Set to True to disable gevent.pywsgi apache-style logging of incoming requests to stdout
  • audience (str) – The <aud> value trusted in the capabilities. Usually either the hostname or the base URL of this service.
  • issuer (str) – The <iss> value trusted in the capabilities. Usually the URL for the Igor running the issuer with /issuer as endpoint. Can be set after creation.
  • issuerSharedKey (str) – The secret symmetric key shared between the audience (this program) and the issuer. Can be set after creation.

Note that while it is possible to specify capabilities=True and nossl=True at the same time this is not a good idea: the capabilities are encrypted but have a known structure, and therefore the issuerSharedKey would be open to a brute-force attack.

addEndpoint(path, mimetype='application/json', get=None, put=None, post=None, delete=None)

Add REST endpoint.

Use this call to add an endpoint to this service and supply the corresponding callback methods.

When a REST request is made to this endpoint the first things that happens (if capability support has been enabled) is that a capability is carried in the request and that it is valid (using audience, issuer and issuerSecretKey). Then it is checked that the capability gives the right to execute this operation.

Arguments to the REST call (and passed to the callback method) can be supplied in three different ways:

  • if the request carries a URL query the values are supplied to the callback as named parameters.
  • otherwise, if the request contains JSON data this should be an object, and the items in the object are passed as named parameters.
  • otherwise, if the request contains data that is not JSON this data is passed (as a string) as the data argument.
Parameters:
  • path (str) – The new endpoint, starting with /.
  • mimetype (str) – How the return value of the callback should be encoded. Currently application/json and text/plain are supported.
  • get – Callback for GET calls.
  • put – Callback for PUT calls.
  • post – Callback for POST calls.
  • delete – Callback for DELETE calls.
static argumentParser(parser=None, description=None, port=None, name=None)

Static method to create ArgumentParser with common arguments for IgorServlet.

Programs using IgorServlet as their REST interface will likely share a number of command line arguments (to allow setting of port, protocol, capability support, etc). This method returns such a parser, which will return (from parse_args()) a namespace with arguments suitable for IgorServlet.

Parameters:
  • parser (argparse.ArgumentParser) – optional parser (by default one is created)
  • description (str) – description for the parser constructor (if one is created)
  • port (int) – default for the --port argument (the port the service listens to)
  • name (str) – name of the service (default taken from sys.argv[0])
Returns:

A pre-populated argparse.ArgumentParser

hasIssuer()

Return True if this IgorServlet has an issuer and shared key

run()

Run the REST service.

This will start serving and never return, until stop() is called (in a callback or from another thread).

setIssuer(issuer, issuerSharedKey)

Set URL of issuer trusted by this service and shared symmetric key.

If the issuer and shared key are not known yet during IgorServlet creation they can be set later using this method, or changed.

Parameters:
  • issuer (str) – The <iss> value trusted in the capabilities. Usually the URL for the Igor running the issuer with /issuer as endpoint.
  • issuerSharedKey (str) – The secret symmetric key shared between the audience (this program) and the issuer.
stop()

Stop the REST service.

This will stop the service and join() the thread that was running it.

argumentParser arguments

If you use igorServlet.IgorServlet.argumentParser() to create your argparse parser your program will have the following arguments (aside from any you add yourself):

Mini-server for use with Igor

usage: igorServlet [-h] [--database DIR] [--name NAME] [--sslname NAME]
                   [--port PORT] [--nossl] [--nolog] [--noCapabilities]
                   [--capabilities] [--audience URL] [--issuer URL]
                   [--sharedKey B64STRING]

Named Arguments

--database

Config and logfiles in DIR (default: /home/docs/.igor, environment IGORSERVER_DIR)

Default: “/home/docs/.igor”

--name

Program name for use in log and config filenames in database dir(default: __main__)

Default: “__main__”

--sslname

Program name to look up SSL certificate and key in database dir (default: igor)

Default: “igor”

--port

Port to serve on (default: 8080)

Default: 8080

--nossl Do no use https (ssl) on the service, even if certificates are available
--nolog Disable http server logging to stdout
--noCapabilities
 Disable access control via capabilities (allowing all access)
--capabilities Enable access control via capabilities
--audience Audience string for this servlet (for checking capabilities and their signature)
--issuer Issuer string for this servlet (for checking capabilities and their signature)
--sharedKey Secret key shared with issuer (for checking capabilities and their signature)