all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Hannes Laimer <h.laimer@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup 1/3] report: add api endpoint and function to generate report
Date: Tue,  3 Nov 2020 13:29:06 +0100	[thread overview]
Message-ID: <20201103122908.114524-2-h.laimer@proxmox.com> (raw)
In-Reply-To: <20201103122908.114524-1-h.laimer@proxmox.com>

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
 src/api2/node.rs        |  2 ++
 src/api2/node/report.rs | 35 +++++++++++++++++++
 src/server.rs           |  3 ++
 src/server/report.rs    | 77 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 117 insertions(+)
 create mode 100644 src/api2/node/report.rs
 create mode 100644 src/server/report.rs

diff --git a/src/api2/node.rs b/src/api2/node.rs
index 30800d05..a19bea7e 100644
--- a/src/api2/node.rs
+++ b/src/api2/node.rs
@@ -38,6 +38,7 @@ mod services;
 mod status;
 mod syslog;
 mod time;
+mod report;
 
 pub const SHELL_CMD_SCHEMA: Schema = StringSchema::new("The command to run.")
     .format(&ApiStringFormat::Enum(&[
@@ -310,6 +311,7 @@ pub const SUBDIRS: SubdirMap = &[
     ("dns", &dns::ROUTER),
     ("journal", &journal::ROUTER),
     ("network", &network::ROUTER),
+    ("report", &report::ROUTER),
     ("rrd", &rrd::ROUTER),
     ("services", &services::ROUTER),
     ("status", &status::ROUTER),
diff --git a/src/api2/node/report.rs b/src/api2/node/report.rs
new file mode 100644
index 00000000..b58427d7
--- /dev/null
+++ b/src/api2/node/report.rs
@@ -0,0 +1,35 @@
+use anyhow::Error;
+use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment};
+use serde_json::{json, Value};
+
+use crate::api2::types::*;
+use crate::config::acl::PRIV_SYS_AUDIT;
+use crate::server::generate_report;
+
+#[api(
+    input: {
+        properties: {
+            node: {
+                schema: NODE_SCHEMA,
+            },
+        },
+    },
+    returns: {
+        type: String,
+        description: "Returns report of the node"
+    },
+    access: {
+        permission: &Permission::Privilege(&["system", "status"], PRIV_SYS_AUDIT, false),
+    },
+)]
+/// Generate a report
+fn get_report(
+    _param: Value,
+    _info: &ApiMethod,
+    _rpcenv: &mut dyn RpcEnvironment,
+) -> Result<Value, Error> {
+    Ok(json!(generate_report()))
+}
+
+pub const ROUTER: Router = Router::new()
+    .get(&API_METHOD_GET_REPORT);
diff --git a/src/server.rs b/src/server.rs
index 05fd25d9..983a300d 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -84,3 +84,6 @@ pub use gc_job::*;
 
 mod email_notifications;
 pub use email_notifications::*;
+
+mod report;
+pub use report::*;
diff --git a/src/server/report.rs b/src/server/report.rs
new file mode 100644
index 00000000..8c109660
--- /dev/null
+++ b/src/server/report.rs
@@ -0,0 +1,77 @@
+use std::path::Path;
+use std::process::Command;
+
+use lazy_static::lazy_static;
+
+use crate::config::datastore;
+use crate::tools::subscription::read_subscription;
+
+lazy_static! {
+    static ref FILES: Vec<&'static str> = vec!["/etc/hosts", "/etc/network/interfaces"];
+
+    // (<command>, <arg [, arg]>)
+    static ref COMMANDS: Vec<(&'static str, Vec<&'static str>)> = vec![
+        ("/usr/bin/df", vec!["-h"]),
+        ("/usr/bin/lsblk", vec!["-ascii"])
+    ];
+
+    // (<description>, <function to call>)
+    static ref FUNCTION_CALLS: Vec<(&'static str, fn() -> String)> = vec![
+        ("Subscription status", || match read_subscription() {
+            Ok(Some(sub_info)) => sub_info.status.to_string(),
+            _ => String::from("No subscription found"),
+        }),
+        ("Datastores", || {
+            let config = match datastore::config() {
+                Ok((config, _digest)) => config,
+                _ => return String::from("could not read datastore config"),
+            };
+
+            let mut list = Vec::new();
+            for (store, _) in &config.sections {
+                list.push(store.as_str());
+            }
+            list.join(", ")
+        })
+    ];
+}
+
+pub fn generate_report() -> String {
+    use proxmox::tools::fs::file_read_optional_string;
+
+    let file_contents = FILES
+        .iter()
+        .map(|file_name| {
+            let content = match file_read_optional_string(Path::new(file_name)) {
+                Ok(Some(content)) => content,
+                Err(err) => err.to_string(),
+                _ => String::from("Could not be read!"),
+            };
+            format!("# {}\n{}", file_name, content)
+        })
+        .collect::<Vec<String>>()
+        .join("\n\n");
+
+    let command_outputs = COMMANDS
+        .iter()
+        .map(|(command, args)| {
+            let output = match Command::new(command).args(args).output() {
+                Ok(output) => String::from_utf8_lossy(&output.stdout).to_string(),
+                Err(err) => err.to_string(),
+            };
+            format!("# {} {}\n{}", command, args.join(" "), output)
+        })
+        .collect::<Vec<String>>()
+        .join("\n\n");
+
+    let function_outputs = FUNCTION_CALLS
+        .iter()
+        .map(|(desc, function)| format!("# {}\n{}", desc, function()))
+        .collect::<Vec<String>>()
+        .join("\n\n");
+
+    format!(
+        " FILES\n{}\n COMMANDS\n{}\n FUNCTIONS\n{}",
+        file_contents, command_outputs, function_outputs
+    )
+}
-- 
2.20.1





  reply	other threads:[~2020-11-03 12:29 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-03 12:29 [pbs-devel] [PATCH proxmox-backup 0/3] add system report Hannes Laimer
2020-11-03 12:29 ` Hannes Laimer [this message]
2020-11-03 12:29 ` [pbs-devel] [PATCH proxmox-backup 2/3] report: add webui button for " Hannes Laimer
2020-11-03 12:29 ` [pbs-devel] [PATCH proxmox-backup 3/3] manager: add report cli command Hannes Laimer
2020-11-04  7:49 ` [pbs-devel] applied-series: [PATCH proxmox-backup 0/3] add system report Thomas Lamprecht

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=20201103122908.114524-2-h.laimer@proxmox.com \
    --to=h.laimer@proxmox.com \
    --cc=pbs-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.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal