diff options
Diffstat (limited to 'modules/etcd')
-rw-r--r-- | modules/etcd/README.rst | 44 | ||||
-rw-r--r-- | modules/etcd/etcd.lua | 55 | ||||
-rw-r--r-- | modules/etcd/etcd.mk | 2 |
3 files changed, 101 insertions, 0 deletions
diff --git a/modules/etcd/README.rst b/modules/etcd/README.rst new file mode 100644 index 0000000..5de55c2 --- /dev/null +++ b/modules/etcd/README.rst @@ -0,0 +1,44 @@ +.. _mod-etcd: + +Etcd module +----------- + +The module connects to Etcd peers and watches for configuration change. +By default, the module looks for the subtree under ``/knot-resolver`` directory, +but you can change this `in the configuration <https://github.com/mah0x211/lua-etcd#cli-err--etcdnew-optiontable->`_. + +The subtree structure corresponds to the configuration variables in the declarative style. + +.. code-block:: bash + + $ etcdctl set /knot-resolvevr/net/127.0.0.1 53 + $ etcdctl set /knot-resolver/cache/size 10000000 + +Configures all listening nodes to following configuration: + +.. code-block:: lua + + net = { '127.0.0.1' } + cache.size = 10000000 + +Example configuration +^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: lua + + modules = { + etcd = { + prefix = '/knot-resolver', + peer = 'http://127.0.0.1:7001' + } + } + +.. warning:: Work in progress! + +Dependencies +^^^^^^^^^^^^ + +* `lua-etcd <https://github.com/mah0x211/lua-etcd>`_ available in LuaRocks + + ``$ luarocks install etcd --from=https://mah0x211.github.io/rocks/`` + diff --git a/modules/etcd/etcd.lua b/modules/etcd/etcd.lua new file mode 100644 index 0000000..4d4bbfb --- /dev/null +++ b/modules/etcd/etcd.lua @@ -0,0 +1,55 @@ +--- @module etcd +local etcd = {} + +-- @function update subtree configuration +local function update_subtree(tree) + if not tree then return end + for _, k in pairs(tree) do + if k.dir then + update_subtree(k.nodes) + else + local key,opt = k.key:gmatch('([^/]+)/([^/]+)$')() + if _G[key][opt] ~= k.value then + _G[key][opt] = k.value + end + end + end +end + +-- @function reload whole configuration +function etcd.reload() + local res, err = etcd.cli:readdir('/', true) + if err then + error(err) + end + update_subtree(res.body.node.nodes) +end + +function etcd.init() + etcd.Etcd = require('etcd.luasocket') + etcd.defaults = { prefix = '/knot-resolver' } +end + +function etcd.deinit() + if etcd.ev then event.cancel(etcd.ev) end +end + +function etcd.config(conf) + local options = etcd.defaults + if type(conf) == 'table' then + for k,v in pairs(conf) do options[k] = v end + end + -- create connection + local cli, err = etcd.Etcd.new(options) + if err then + error(err) + end + etcd.cli = cli + -- schedule recurrent polling + -- @todo: the etcd has watch() API, but this requires + -- coroutines on socket operations + if etcd.ev then event.cancel(etcd.ev) end + etcd.ev = event.recurrent(5 * sec, etcd.reload) +end + +return etcd diff --git a/modules/etcd/etcd.mk b/modules/etcd/etcd.mk new file mode 100644 index 0000000..0b8d244 --- /dev/null +++ b/modules/etcd/etcd.mk @@ -0,0 +1,2 @@ +etcd_SOURCES := etcd.lua +$(call make_lua_module,etcd) |