summaryrefslogtreecommitdiffstats
path: root/modules/etcd
diff options
context:
space:
mode:
Diffstat (limited to 'modules/etcd')
-rw-r--r--modules/etcd/README.rst44
-rw-r--r--modules/etcd/etcd.lua55
-rw-r--r--modules/etcd/etcd.mk2
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)