diff options
author | mortzu <mortzu@users.noreply.github.com> | 2017-11-08 22:48:51 +0100 |
---|---|---|
committer | Neil Lathwood <neil@lathwood.co.uk> | 2017-11-08 21:48:51 +0000 |
commit | 853480fca54492a38feaa4fa76941e88f54f11a8 (patch) | |
tree | ab35a950fb20994efe1d854df02858bc6793c472 | |
parent | b19721a62aff7112c891ef13ebaa4fa944d6cb5b (diff) |
feature: Added hook for XMPP MUC (#951)
* Added hook for XMPP MUC
* Updated dockerfile
* Added timeout to prevent oxidized to stop on XMPP error
* Updated README
-rw-r--r-- | Dockerfile | 1 | ||||
-rw-r--r-- | docs/Hooks.md | 25 | ||||
-rw-r--r-- | lib/oxidized/hook/xmppdiff.rb | 60 |
3 files changed, 86 insertions, 0 deletions
@@ -18,6 +18,7 @@ RUN gem install oxidized-web --no-ri --no-rdoc # dependencies for hooks RUN gem install aws-sdk RUN gem install slack-api +RUN gem install xmpp4r RUN rm -rf /tmp/oxidized diff --git a/docs/Hooks.md b/docs/Hooks.md index 12e3ab7..bf6ea54 100644 --- a/docs/Hooks.md +++ b/docs/Hooks.md @@ -141,3 +141,28 @@ hooks: ``` Note the channel name must be in quotes. + +## Hook type: xmppdiff + +The `xmppdiff` hook posts config diffs to a [XMPP](https://en.wikipedia.org/wiki/XMPP) chatroom of your choice. It only triggers for `post_store` events. + +You will need to manually install the `xmpp4r` gem on your system: + +``` +gem install xmpp4r +``` + +Configuration example: + +``` yaml +hooks: + slack: + type: xmppdiff + events: [post_store] + jid: "user@server.tld/resource" + password: "password" + channel: "room@server.tld" + nick: "nickname" +``` + +Note the channel name must be in quotes. diff --git a/lib/oxidized/hook/xmppdiff.rb b/lib/oxidized/hook/xmppdiff.rb new file mode 100644 index 0000000..396d1b3 --- /dev/null +++ b/lib/oxidized/hook/xmppdiff.rb @@ -0,0 +1,60 @@ +require 'xmpp4r' +require 'xmpp4r/muc/helper/simplemucclient' + +class XMPPDiff < Oxidized::Hook + def validate_cfg! + raise KeyError, 'hook.jid is required' unless cfg.has_key?('jid') + raise KeyError, 'hook.password is required' unless cfg.has_key?('password') + raise KeyError, 'hook.channel is required' unless cfg.has_key?('channel') + raise KeyError, 'hook.nick is required' unless cfg.has_key?('nick') + end + + def run_hook(ctx) + if ctx.node + if ctx.event.to_s == "post_store" + begin + Timeout::timeout(15) do + gitoutput = ctx.node.output.new + diff = gitoutput.get_diff ctx.node, ctx.node.group, ctx.commitref, nil + + interesting = diff[:patch].lines.to_a[4..-1].any? { |line| + ["+", "-"].include?(line[0]) and not ["#", "!"].include?(line[1]) + } + interesting &&= diff[:patch].lines.to_a[5..-1].any? { |line| line[0] == '-' } + interesting &&= diff[:patch].lines.to_a[5..-1].any? { |line| line[0] == '+' } + + if interesting + log "Connecting to XMPP" + client = Jabber::Client.new(Jabber::JID.new(cfg.jid)) + client.connect + sleep 1 + client.auth(cfg.password) + sleep 1 + + log "Connected" + + m = Jabber::MUC::SimpleMUCClient.new(client) + m.join(cfg.channel + "/" + cfg.nick) + + log "Joined" + + title = "#{ctx.node.name.to_s} #{ctx.node.group.to_s} #{ctx.node.model.class.name.to_s.downcase}" + log "Posting diff as snippet to #{cfg.channel}" + + m.say(title + "\n\n" + diff[:patch].lines.to_a[4..-1].join) + + sleep 1 + + client.close + + log "Finished" + + end + end + rescue Timeout::Error + log "timed out" + end + end + end + end +end |