6 This basic example shows how to create simple python module which will pass on the requests to the iterator.
8 How to enable python module
9 ----------------------------
10 If you look into unbound configuration file, you can find the option `module-config` which specifies the names and the order of modules to be used.
11 Example configuration::
13 module-config: "validator python iterator"
15 As soon as the DNS query arrives, Unbound calls modules starting from leftmost - the validator *(it is the first module on the list)*.
16 The validator does not know the answer *(it can only validate)*, thus it will pass on the event to the next module.
17 Next module is python which can
19 a) generate answer *(response)*
20 When python module generates the response unbound calls validator. Validator grabs the answer and determines the security flag.
22 b) pass on the event to the iterator.
23 When iterator resolves the query, Unbound informs python module (event :data:`module_event_moddone`). In the end, when the python module is done, validator is called.
25 Note that the python module is called with :data:`module_event_pass` event, because new DNS event was already handled by validator.
27 Another situation occurs when we use the following configuration::
29 module-config: "python validator iterator"
31 Python module is the first module here, so it's invoked with :data:`module_event_new` event *(new query)*.
33 On Python module initialization, module loads script from `python-script` option::
35 python-script: "/unbound/test/ubmodule.py"
37 Simple python module step by step
38 ---------------------------------
40 Script file must contain four compulsory functions:
42 .. function:: init(id, cfg)
44 Initialize module internals, like database etc.
45 Called just once on module load.
47 :param id: module identifier (integer)
48 :param cfg: :class:`config_file` configuration structure
53 log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
57 .. function:: init_standard(id, env)
59 Initialize module internals, like database etc.
60 Called just once on module load.
62 *Preferred* over the init() function above as this function's signature is the
63 same as the C counterpart and allows for extra functionality during init.
64 The previously accessible configuration options can now be found in env.cfg.
66 :param id: module identifier (integer)
67 :param env: :class:`module_env` module environment
71 def init_standard(id, env):
72 log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, env.cfg.port, mod_env['script']))
76 .. function:: deinit(id)
78 Deinitialize module internals.
79 Called just once on module unload.
81 :param id: module identifier (integer)
86 log_info("pythonmod: deinit called, module id is %d" % id)
90 .. function:: inform_super(id, qstate, superqstate, qdata)
92 Inform super querystate about the results from this subquerystate.
93 Is called when the querystate is finished.
95 :param id: module identifier (integer)
96 :param qstate: :class:`module_qstate` Query state
97 :param superqstate: :class:`pythonmod_qstate` Mesh state
98 :param qdata: :class:`query_info` Query data
102 def inform_super(id, qstate, superqstate, qdata):
107 .. function:: operate(id, event, qstate, qdata)
109 Perform action on pending query. Accepts a new query, or work on pending query.
111 You have to set qstate.ext_state on exit.
112 The state informs unbound about result and controls the following states.
114 :param id: module identifier (integer)
115 :param qstate: :class:`module_qstate` query state structure
116 :param qdata: :class:`query_info` per query data, here you can store your own data
120 def operate(id, event, qstate, qdata):
121 log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
122 if event == MODULE_EVENT_NEW:
123 qstate.ext_state[id] = MODULE_WAIT_MODULE
126 if event == MODULE_EVENT_MODDONE:
127 qstate.ext_state[id] = MODULE_FINISHED
130 if event == MODULE_EVENT_PASS:
131 qstate.ext_state[id] = MODULE_WAIT_MODULE
134 log_err("pythonmod: BAD event")
135 qstate.ext_state[id] = MODULE_ERROR
142 .. literalinclude:: example0-1.py
145 As you can see, the source code is much more flexible in contrast to C modules.
146 Moreover, compulsory functions called on appropriate module events allows to handle almost
147 anything from web control to query analysis.