Mercurial > prosody-modules
view mod_pubsub_alertmanager/mod_pubsub_alertmanager.lua @ 5406:b86d80e21c60
mod_http_oauth2: Validate consistency of response and grant types
Ensure that these correlated fields make sense per RFC 7591 ยง 2.1, even
though we currently only check the response type during authorization.
This could probably all be deleted if (when!) we remove the implicit
grant, since then these things don't make any sense anymore.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 02 May 2023 16:34:31 +0200 |
parents | adda872fa9e1 |
children | 67190744b1eb |
line wrap: on
line source
local st = require "util.stanza"; local json = require "util.json"; local filters = { --[[ TODO what's useful? ]] }; local render = require "util.interpolation".new("%b{}", tostring, filters); local uuid_generate = require "util.uuid".generate; -- TODO alertmanager supports inclusion of HTTP auth and OAuth, worth looking -- into for using instead of request IP module:depends("http"); local pubsub_service = module:depends("pubsub").service; local error_mapping = { ["forbidden"] = 403; ["item-not-found"] = 404; ["internal-server-error"] = 500; ["conflict"] = 409; }; local function publish_payload(node, actor, item_id, payload) local post_item = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = item_id, }) :add_child(payload); local ok, err = pubsub_service:publish(node, actor, item_id, post_item); module:log("debug", ":publish(%q, true, %q, %s) -> %q", node, item_id, payload:top_tag(), err or ""); if not ok then return error_mapping[err] or 500; end return 202; end local node_template = module:get_option_string("alertmanager_node_template", "{path?alerts}"); function handle_POST(event, path) local request = event.request; local payload = json.decode(event.request.body); if type(payload) ~= "table" then return 400; end if payload.version ~= "4" then return 501; end for _, alert in ipairs(payload.alerts) do local item = st.stanza("alerts", {xmlns = "urn:uuid:e3bec775-c607-4e9b-9a3f-94de1316d861:v4", status=alert.status}); for k, v in pairs(alert.annotations) do item:text_tag("annotation", v, { name=k }); end for k, v in pairs(alert.labels) do item:text_tag("label", v, { name=k }); end item:tag("starts", { at = alert.startsAt}):up(); if alert.endsAt and alert.status == "resolved" then item:tag("ends", { at = alert.endsAt }):up(); end if alert.generatorURL then item:tag("link", { href=alert.generatorURL }):up(); end local node = render(node_template, {alert = alert, path = path, payload = payload, request = request}); local ret = publish_payload(node, request.ip, uuid_generate(), item); if ret ~= 202 then return ret end end return 202; end local template = module:get_option_string("alertmanager_body_template", [[ *ALARM!* Status: {status} Starts at: {startsAt}{endsAt& Ends at: {endsAt}} Labels: {labels% {idx}: {item}} Annotations: {annotations% {idx}: {item}} ]]); module:hook("pubsub-summary/urn:uuid:e3bec775-c607-4e9b-9a3f-94de1316d861:v4", function(event) local payload = event.payload; local data = { status = payload.attr.status, firing = "firing" == payload.attr.status, resolved = "resolved" == payload.attr.status, annotations = {}, labels = {}, endsAt = payload:find("ends/@at"), startsAt = payload:find("starts/@at"), }; for label in payload:childtags("label") do data.labels[tostring(label.attr.name)] = label:get_text(); end for annotation in payload:childtags("annotation") do data.annotations[tostring(annotation.attr.name)] = annotation:get_text(); end return render(template, data); end); module:provides("http", { route = { ["POST /*"] = handle_POST; ["POST"] = handle_POST; }; });