From: Lukas Wagner <l.wagner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v2 proxmox 12/42] notify: add gotify endpoint
Date: Wed, 24 May 2023 15:56:19 +0200 [thread overview]
Message-ID: <20230524135649.934881-13-l.wagner@proxmox.com> (raw)
In-Reply-To: <20230524135649.934881-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-notify/Cargo.toml | 6 +-
proxmox-notify/src/config.rs | 22 +++++
proxmox-notify/src/endpoints/gotify.rs | 116 +++++++++++++++++++++++++
proxmox-notify/src/endpoints/mod.rs | 2 +
proxmox-notify/src/lib.rs | 17 +++-
5 files changed, 160 insertions(+), 3 deletions(-)
create mode 100644 proxmox-notify/src/endpoints/gotify.rs
diff --git a/proxmox-notify/Cargo.toml b/proxmox-notify/Cargo.toml
index f7329295..738674ae 100644
--- a/proxmox-notify/Cargo.toml
+++ b/proxmox-notify/Cargo.toml
@@ -12,6 +12,7 @@ handlebars = { workspace = true, optional = true }
lazy_static.workspace = true
log.workspace = true
openssl.workspace = true
+proxmox-http = { workspace = true, features = ["client-sync"], optional = true }
proxmox-schema = { workspace = true, features = ["api-macro"]}
proxmox-section-config = { workspace = true }
proxmox-sys = { workspace = true, optional = true }
@@ -20,5 +21,6 @@ serde = { workspace = true, features = ["derive"]}
serde_json.workspace = true
[features]
-default = ["sendmail"]
-sendmail = ["dep:handlebars", "dep:proxmox-sys"]
\ No newline at end of file
+default = ["sendmail", "gotify"]
+sendmail = ["dep:handlebars", "dep:proxmox-sys"]
+gotify = ["dep:proxmox-http"]
diff --git a/proxmox-notify/src/config.rs b/proxmox-notify/src/config.rs
index 2ef237fa..a73b7849 100644
--- a/proxmox-notify/src/config.rs
+++ b/proxmox-notify/src/config.rs
@@ -25,7 +25,17 @@ fn config_init() -> SectionConfig {
SENDMAIL_SCHEMA,
));
}
+ #[cfg(feature = "gotify")]
+ {
+ use crate::endpoints::gotify::{GotifyConfig, GOTIFY_TYPENAME};
+ const GOTIFY_SCHEMA: &ObjectSchema = GotifyConfig::API_SCHEMA.unwrap_object_schema();
+ config.register_plugin(SectionConfigPlugin::new(
+ GOTIFY_TYPENAME.to_string(),
+ Some(String::from("name")),
+ GOTIFY_SCHEMA,
+ ));
+ }
const CHANNEL_SCHEMA: &ObjectSchema = ChannelConfig::API_SCHEMA.unwrap_object_schema();
config.register_plugin(SectionConfigPlugin::new(
@@ -40,6 +50,18 @@ fn config_init() -> SectionConfig {
fn private_config_init() -> SectionConfig {
let mut config = SectionConfig::new(&BACKEND_NAME_SCHEMA);
+ #[cfg(feature = "gotify")]
+ {
+ use crate::endpoints::gotify::{GotifyPrivateConfig, GOTIFY_TYPENAME};
+
+ const GOTIFY_SCHEMA: &ObjectSchema = GotifyPrivateConfig::API_SCHEMA.unwrap_object_schema();
+ config.register_plugin(SectionConfigPlugin::new(
+ GOTIFY_TYPENAME.to_string(),
+ Some(String::from("name")),
+ GOTIFY_SCHEMA,
+ ));
+ }
+
config
}
diff --git a/proxmox-notify/src/endpoints/gotify.rs b/proxmox-notify/src/endpoints/gotify.rs
new file mode 100644
index 00000000..74dd4868
--- /dev/null
+++ b/proxmox-notify/src/endpoints/gotify.rs
@@ -0,0 +1,116 @@
+use std::collections::HashMap;
+
+use crate::schema::{COMMENT_SCHEMA, ENTITY_NAME_SCHEMA};
+use crate::{Endpoint, Error, Notification, Severity};
+
+use serde::{Deserialize, Serialize};
+
+use proxmox_http::client::sync::Client;
+use proxmox_http::{HttpClient, HttpOptions};
+use proxmox_schema::{api, Updater};
+
+#[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(
+ properties: {
+ name: {
+ schema: ENTITY_NAME_SCHEMA,
+ },
+ comment: {
+ optional: true,
+ schema: COMMENT_SCHEMA,
+ },
+ }
+)]
+#[derive(Serialize, Deserialize, Updater)]
+#[serde(rename_all = "kebab-case")]
+/// Config for Gotify notification endpoints
+pub struct GotifyConfig {
+ /// Name of the endpoint
+ #[updater(skip)]
+ pub name: String,
+ /// Gotify Server URL
+ pub server: String,
+ /// Comment
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub comment: Option<String>,
+}
+
+#[api()]
+#[derive(Serialize, Deserialize, Clone, Updater)]
+#[serde(rename_all = "kebab-case")]
+/// Private configuration for Gotify notification endpoints.
+/// This config will be saved to a separate configuration file with stricter
+/// permissions (root:root 0600)
+pub struct GotifyPrivateConfig {
+ /// Name of the endpoint
+ #[updater(skip)]
+ pub name: String,
+ /// Authentication token
+ pub token: String,
+}
+
+/// A Gotify notification endpoint.
+pub struct GotifyEndpoint {
+ pub config: GotifyConfig,
+ pub private_config: GotifyPrivateConfig,
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+pub enum DeleteableGotifyProperty {
+ Comment,
+}
+
+impl Endpoint for GotifyEndpoint {
+ fn send(&self, notification: &Notification) -> Result<(), Error> {
+ // TODO: What about proxy configuration?
+ let client = Client::new(HttpOptions::default());
+
+ let uri = format!("{}/message", self.config.server);
+
+ let body = GotifyMessageBody {
+ title: ¬ification.title,
+ message: ¬ification.body,
+ priority: severity_to_priority(notification.severity),
+ };
+
+ let body = serde_json::to_vec(&body)
+ .map_err(|err| Error::NotifyFailed(self.name().to_string(), err.into()))?;
+ let extra_headers = HashMap::from([(
+ "Authorization".into(),
+ format!("Bearer {}", self.private_config.token),
+ )]);
+
+ client
+ .post(
+ &uri,
+ Some(body.as_slice()),
+ Some("application/json"),
+ Some(&extra_headers),
+ )
+ .map_err(|err| Error::NotifyFailed(self.name().to_string(), err.into()))?;
+
+ Ok(())
+ }
+
+ fn name(&self) -> &str {
+ &self.config.name
+ }
+}
diff --git a/proxmox-notify/src/endpoints/mod.rs b/proxmox-notify/src/endpoints/mod.rs
index dd80d9bc..d1cec654 100644
--- a/proxmox-notify/src/endpoints/mod.rs
+++ b/proxmox-notify/src/endpoints/mod.rs
@@ -1,2 +1,4 @@
+#[cfg(feature = "gotify")]
+pub mod gotify;
#[cfg(feature = "sendmail")]
pub mod sendmail;
diff --git a/proxmox-notify/src/lib.rs b/proxmox-notify/src/lib.rs
index ee89d100..147dbc3c 100644
--- a/proxmox-notify/src/lib.rs
+++ b/proxmox-notify/src/lib.rs
@@ -213,7 +213,6 @@ impl Bus {
let mut endpoints = Vec::new();
// Instantiate endpoints
-
#[cfg(feature = "sendmail")]
{
use endpoints::sendmail::SENDMAIL_TYPENAME;
@@ -229,6 +228,22 @@ impl Bus {
);
}
+ #[cfg(features = "gotify")]
+ {
+ use endpoints::sendmail::GOTIFY_TYPENAME;
+ use endpoints::sendmail::{GotifyConfig, GotifyEndpoint, GotifyPriateConfig};
+ endpoints.extend(
+ parse_endpoints_with_private_config!(
+ config,
+ GotifyConfig,
+ GotifyPrivateConfig,
+ GotifyEndpoint,
+ GOTIFY_TYPENAME
+ )?
+ .into_iter(),
+ );
+ }
+
let channels = config
.config
.convert_to_typed_array(CHANNEL_TYPENAME)
--
2.30.2
next prev parent reply other threads:[~2023-05-24 13:58 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-24 13:56 [pve-devel] [PATCH v2 cluster/guest-common/manager/ha-manager/proxmox{, -perl-rs} 00/42] fix #4156: introduce new notification module Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 01/42] add `proxmox-human-byte` crate Lukas Wagner
2023-06-26 11:58 ` Wolfgang Bumiller
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 02/42] human-byte: move tests to their own sub-module Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 03/42] add proxmox-notify crate Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 04/42] notify: add debian packaging Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 05/42] notify: preparation for the first endpoint plugin Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 06/42] notify: preparation for the API Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 07/42] notify: api: add API for sending notifications/testing endpoints Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 08/42] notify: add notification channels Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 09/42] notify: api: add API for channels Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 10/42] notify: add sendmail plugin Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 11/42] notify: api: add API for sendmail endpoints Lukas Wagner
2023-05-24 13:56 ` Lukas Wagner [this message]
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 13/42] notify: api: add API for gotify endpoints Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 14/42] notify: add notification filter mechanism Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 15/42] notify: api: add API for filters Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 16/42] notify: add template rendering Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox 17/42] notify: add example for " Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox-perl-rs 18/42] log: set default log level to 'info', add product specific logging env var Lukas Wagner
2023-06-05 7:27 ` Wolfgang Bumiller
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox-perl-rs 19/42] add PVE::RS::Notify module Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox-perl-rs 20/42] notify: add api for sending notifications/testing endpoints Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox-perl-rs 21/42] notify: add api for notification channels Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox-perl-rs 22/42] notify: add api for sendmail endpoints Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox-perl-rs 23/42] notify: add api for gotify endpoints Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 proxmox-perl-rs 24/42] notify: add api for notification filters Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-cluster 25/42] cluster files: add notifications.cfg Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-guest-common 26/42] vzdump: add config options for new notification backend Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 27/42] test: fix names of .PHONY targets Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 28/42] add PVE::Notify module Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 29/42] vzdump: send notifications via new notification module Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 30/42] test: rename mail_test.pl to vzdump_notification_test.pl Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 31/42] api: apt: send notification via new notification module Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 32/42] api: replication: send notifications " Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 33/42] ui: backup: allow to select notification channel for notifications Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 34/42] ui: backup: adapt backup job details to new notification params Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 35/42] ui: backup: allow to set notification-{channel, mode} for one-off backups Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 36/42] api: prepare api handler module for notification config Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 37/42] api: add api routes for notification channels Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 38/42] api: add api routes for sendmail endpoints Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 39/42] api: add api routes for gotify endpoints Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 40/42] api: add api routes for notification filters Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-manager 41/42] ui: backup: disable notification mode selector for now Lukas Wagner
2023-05-24 13:56 ` [pve-devel] [PATCH v2 pve-ha-manager 42/42] manager: send notifications via new notification module Lukas Wagner
2023-05-26 8:31 ` [pve-devel] [PATCH v2 cluster/guest-common/manager/ha-manager/proxmox{, -perl-rs} 00/42] fix #4156: introduce " 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=20230524135649.934881-13-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.