From: Lukas Wagner <l.wagner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH proxmox 04/18] notification: implement gotify endpoint
Date: Mon, 27 Mar 2023 17:18:43 +0200 [thread overview]
Message-ID: <20230327151857.495565-5-l.wagner@proxmox.com> (raw)
In-Reply-To: <20230327151857.495565-1-l.wagner@proxmox.com>
Add an endpoint for Gotify [1], showing the how easy it is to add new
endpoint implementations.
[1] https://gotify.net/
Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
---
proxmox-notification/src/config.rs | 9 +++
proxmox-notification/src/endpoints/gotify.rs | 80 ++++++++++++++++++++
proxmox-notification/src/endpoints/mod.rs | 1 +
proxmox-notification/src/filter.rs | 1 +
proxmox-notification/src/lib.rs | 13 +++-
5 files changed, 103 insertions(+), 1 deletion(-)
create mode 100644 proxmox-notification/src/endpoints/gotify.rs
diff --git a/proxmox-notification/src/config.rs b/proxmox-notification/src/config.rs
index 939bdb6..e2454b6 100644
--- a/proxmox-notification/src/config.rs
+++ b/proxmox-notification/src/config.rs
@@ -3,6 +3,8 @@ use lazy_static::lazy_static;
use proxmox_schema::{const_regex, ApiStringFormat, ApiType, ObjectSchema, Schema, StringSchema};
use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
+use crate::endpoints::gotify::GotifyConfig;
+use crate::endpoints::gotify::GOTIFY_TYPENAME;
use crate::endpoints::sendmail::SendmailConfig;
use crate::endpoints::sendmail::SENDMAIL_TYPENAME;
use crate::filter::{FilterConfig, FILTER_TYPENAME};
@@ -33,6 +35,7 @@ fn init() -> SectionConfig {
let mut config = SectionConfig::new(&BACKEND_NAME_SCHEMA);
const SENDMAIL_SCHEMA: &ObjectSchema = SendmailConfig::API_SCHEMA.unwrap_object_schema();
+ const GOTIFY_SCHEMA: &ObjectSchema = GotifyConfig::API_SCHEMA.unwrap_object_schema();
const FILTER_SCHEMA: &ObjectSchema = FilterConfig::API_SCHEMA.unwrap_object_schema();
@@ -42,6 +45,12 @@ fn init() -> SectionConfig {
SENDMAIL_SCHEMA,
));
+ config.register_plugin(SectionConfigPlugin::new(
+ GOTIFY_TYPENAME.to_string(),
+ Some(String::from("name")),
+ GOTIFY_SCHEMA,
+ ));
+
config.register_plugin(SectionConfigPlugin::new(
FILTER_TYPENAME.to_string(),
Some(String::from("name")),
diff --git a/proxmox-notification/src/endpoints/gotify.rs b/proxmox-notification/src/endpoints/gotify.rs
new file mode 100644
index 0000000..3972bfe
--- /dev/null
+++ b/proxmox-notification/src/endpoints/gotify.rs
@@ -0,0 +1,80 @@
+use std::collections::HashMap;
+
+use crate::{Endpoint, Notification, Severity};
+use anyhow::Error;
+
+use proxmox_schema::{api, Updater};
+use serde::{Deserialize, Serialize};
+
+use proxmox_http::client::sync::Client;
+use proxmox_http::{HttpClient, HttpOptions};
+
+#[derive(Serialize)]
+struct GotifyMessageBody<'a> {
+ title: &'a str,
+ message: &'a str,
+ priority: u32,
+}
+
+fn severity_to_priority(level: Severity) -> u32 {
+ match level {
+ Severity::Info => 1,
+ Severity::Notice => 3,
+ Severity::Warning => 5,
+ Severity::Error => 9,
+ }
+}
+
+pub(crate) const GOTIFY_TYPENAME: &str = "gotify";
+
+#[api()]
+#[derive(Serialize, Deserialize, Updater)]
+#[serde(rename_all = "kebab-case")]
+/// Config for Gotify notification endpoints
+pub struct GotifyConfig {
+ /// Name of the endpoint
+ pub name: String,
+ /// Gotify Server URL
+ pub server: String,
+ /// Authentication token
+ pub token: String,
+ /// Filter to apply
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub filter: Option<String>,
+}
+
+impl Endpoint for GotifyConfig {
+ fn send(&self, notification: &Notification) -> Result<(), Error> {
+ // TODO: What about proxy configuration?
+ let client = Client::new(HttpOptions::default());
+
+ let uri = format!("{}/message", self.server);
+
+ let body = GotifyMessageBody {
+ title: ¬ification.title,
+ message: ¬ification.body,
+ priority: severity_to_priority(notification.severity),
+ };
+
+ let body = serde_json::to_vec(&body)?;
+ let extra_headers =
+ HashMap::from([("Authorization".into(), format!("Bearer {}", self.token))]);
+
+ client.post(
+ &uri,
+ Some(body.as_slice()),
+ Some("application/json"),
+ Some(&extra_headers),
+ )?;
+
+ Ok(())
+ }
+
+ fn name(&self) -> &str {
+ &self.name
+ }
+
+ fn filter(&self) -> Option<&str> {
+ self.filter.as_deref()
+ }
+}
diff --git a/proxmox-notification/src/endpoints/mod.rs b/proxmox-notification/src/endpoints/mod.rs
index 2d7b9ba..481d75b 100644
--- a/proxmox-notification/src/endpoints/mod.rs
+++ b/proxmox-notification/src/endpoints/mod.rs
@@ -1 +1,2 @@
+pub(crate) mod gotify;
pub(crate) mod sendmail;
diff --git a/proxmox-notification/src/filter.rs b/proxmox-notification/src/filter.rs
index 9846e93..3b7b19d 100644
--- a/proxmox-notification/src/filter.rs
+++ b/proxmox-notification/src/filter.rs
@@ -74,6 +74,7 @@ pub struct FilterConfig {
pub name: String,
/// Minimum severity to match
+ #[serde(skip_serializing_if = "Option::is_none")]
pub min_severity: Option<Severity>,
/// Subfilter, allows arbitrary nesting (no recursion allowed)
diff --git a/proxmox-notification/src/lib.rs b/proxmox-notification/src/lib.rs
index c688a10..fc724dd 100644
--- a/proxmox-notification/src/lib.rs
+++ b/proxmox-notification/src/lib.rs
@@ -2,6 +2,8 @@ use std::collections::HashMap;
use anyhow::Error;
+use endpoints::gotify::GotifyConfig;
+use endpoints::gotify::GOTIFY_TYPENAME;
use endpoints::sendmail::SendmailConfig;
use endpoints::sendmail::SENDMAIL_TYPENAME;
use filter::{FilterConfig, FilterMatcher, FILTER_TYPENAME};
@@ -11,7 +13,7 @@ use serde::{Deserialize, Serialize};
mod config;
mod endpoints;
-mod filter;
+pub mod filter;
#[api()]
#[derive(Clone, Debug, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd)]
@@ -86,6 +88,8 @@ impl Config {
let sendmail_endpoints: Vec<SendmailConfig> =
self.0.convert_to_typed_array(SENDMAIL_TYPENAME)?;
+ let gotify_endpoints: Vec<GotifyConfig> = self.0.convert_to_typed_array(GOTIFY_TYPENAME)?;
+
endpoints.extend(
sendmail_endpoints
.into_iter()
@@ -93,6 +97,13 @@ impl Config {
.map(|e| e as Box<dyn Endpoint>),
);
+ endpoints.extend(
+ gotify_endpoints
+ .into_iter()
+ .map(Box::new)
+ .map(|e| e as Box<dyn Endpoint>),
+ );
+
let filters = self.0.convert_to_typed_array(FILTER_TYPENAME)?;
Ok(Bus { endpoints, filters })
--
2.30.2
next prev parent reply other threads:[~2023-03-27 15:20 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-27 15:18 [pve-devel] [PATCH cluster/manager/ha-manager/proxmox{, -perl-rs} 00/18] fix #4156: introduce new notification module Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH proxmox 01/18] add proxmox-notification crate Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH proxmox 02/18] notification: implement sendmail endpoint Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH proxmox 03/18] notification: add notification filter mechanism Lukas Wagner
2023-03-27 15:18 ` Lukas Wagner [this message]
2023-03-27 15:18 ` [pve-devel] [PATCH proxmox 05/18] notification: allow adding new sendmail endpoints / filters Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH proxmox 06/18] notification: add debian packaging Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH proxmox-perl-rs 07/18] log: set default log level to 'info', add product specfig logging env var1 Lukas Wagner
2023-03-31 9:17 ` Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH proxmox-perl-rs 08/18] add basic bindings for the proxmox_notification crate Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-cluster 09/18] cluster files: add notifications.cfg Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-manager 10/18] test: fix names of .PHONY targets Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-manager 11/18] add PVE::Notification module Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-manager 12/18] vzdump: send notifications via new notification module Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-manager 13/18] vzdump: rename 'sendmail' sub to 'send_notification' Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-manager 14/18] test: rename mail_test.pl to vzdump_notification_test.pl Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-manager 15/18] api: apt: send notification via new notification module Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-manager 16/18] api: replication: send notifications " Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-ha-manager 17/18] manager: " Lukas Wagner
2023-03-27 15:18 ` [pve-devel] [PATCH pve-ha-manager 18/18] manager: rename 'sendmail' --> 'send_notification' Lukas Wagner
2023-04-14 6:19 ` [pve-devel] [PATCH cluster/manager/ha-manager/proxmox{, -perl-rs} 00/18] fix #4156: introduce new notification module Thomas Lamprecht
2023-04-14 9:47 ` Lukas Wagner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230327151857.495565-5-l.wagner@proxmox.com \
--to=l.wagner@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.