public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Shannon Sterz <s.sterz@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [PATCH datacenter-manager 09/10] cli: expose certificate management endpoints via the cli
Date: Tue,  7 Apr 2026 15:57:13 +0200	[thread overview]
Message-ID: <20260407135714.490747-10-s.sterz@proxmox.com> (raw)
In-Reply-To: <20260407135714.490747-1-s.sterz@proxmox.com>

analogous to how this is handled in proxmox-backup-server.

Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
 cli/admin/Cargo.toml  |  2 +
 cli/admin/src/cert.rs | 86 +++++++++++++++++++++++++++++++++++++++++++
 cli/admin/src/main.rs |  2 +
 3 files changed, 90 insertions(+)
 create mode 100644 cli/admin/src/cert.rs

diff --git a/cli/admin/Cargo.toml b/cli/admin/Cargo.toml
index 01afc88..7aa0d2e 100644
--- a/cli/admin/Cargo.toml
+++ b/cli/admin/Cargo.toml
@@ -10,6 +10,7 @@ repository.workspace = true
 
 [dependencies]
 anyhow.workspace = true
+openssl.workspace = true
 serde.workspace = true
 serde_json.workspace = true
 
@@ -29,3 +30,4 @@ pdm-api-types.workspace = true
 pdm-config.workspace = true
 pdm-buildcfg.workspace = true
 server.workspace = true
+proxmox-time.workspace = true
diff --git a/cli/admin/src/cert.rs b/cli/admin/src/cert.rs
new file mode 100644
index 0000000..358ab56
--- /dev/null
+++ b/cli/admin/src/cert.rs
@@ -0,0 +1,86 @@
+use anyhow::{bail, Error};
+
+use proxmox_router::cli::*;
+use proxmox_schema::api;
+use server::api;
+use server::auth::certs::update_self_signed_cert;
+use server::auth::csrf::generate_csrf_key;
+use server::auth::key::generate_auth_key;
+
+#[api]
+/// Display node certificate information.
+fn cert_info() -> Result<(), Error> {
+    let Some(cert) = api::nodes::certificates::get_info()?.pop() else {
+        return Ok(());
+    };
+
+    println!("Subject: {}", cert.subject);
+
+    for name in cert.san {
+        println!("    {name}");
+    }
+
+    let not_before = cert
+        .notbefore
+        .and_then(|e| proxmox_time::strftime_utc("%b %e %T %Y %Z", e).ok());
+
+    let not_after = cert
+        .notafter
+        .and_then(|e| proxmox_time::strftime_utc("%b %e %T %Y %Z", e).ok());
+
+    println!("Issuer: {}", cert.issuer);
+    println!("Validity:");
+    println!("    Not Before: {}", not_before.unwrap_or_default());
+    println!("    Not After : {}", not_after.unwrap_or_default());
+
+    println!(
+        "Fingerprint (sha256): {}",
+        cert.fingerprint.unwrap_or_default()
+    );
+
+    println!("Public key type: {}", cert.public_key_type);
+    println!(
+        "Public key bits: {}",
+        cert.public_key_bits.unwrap_or_default()
+    );
+
+    Ok(())
+}
+
+#[api(
+    input: {
+        properties: {
+            force: {
+                description: "Force generation of new SSL certificate.",
+                type:  Boolean,
+                optional:true,
+            },
+        }
+    },
+)]
+/// Update node certificates and generate all needed files/directories.
+/// If no authentication key or CSRF secret key exist, this will also generate new ones. These two
+/// keys will go into effect the next time the `proxmox-backup.service` is started.
+fn update_certs(force: Option<bool>) -> Result<(), Error> {
+    pdm_config::setup::create_configdir()?;
+
+    if let Err(err) = generate_auth_key() {
+        bail!("unable to generate auth key - {err}");
+    }
+
+    if let Err(err) = generate_csrf_key() {
+        bail!("unable to generate csrf key - {err}");
+    }
+
+    update_self_signed_cert(force.unwrap_or(false))?;
+
+    Ok(())
+}
+
+pub fn cert_mgmt_cli() -> CommandLineInterface {
+    let cmd_def = CliCommandMap::new()
+        .insert("info", CliCommand::new(&API_METHOD_CERT_INFO))
+        .insert("update", CliCommand::new(&API_METHOD_UPDATE_CERTS));
+
+    cmd_def.into()
+}
diff --git a/cli/admin/src/main.rs b/cli/admin/src/main.rs
index 7f0b339..66d5423 100644
--- a/cli/admin/src/main.rs
+++ b/cli/admin/src/main.rs
@@ -12,6 +12,7 @@ use proxmox_schema::api;
 use proxmox_sys::fs::CreateOptions;
 
 mod acme;
+mod cert;
 mod remotes;
 mod support_status;
 
@@ -38,6 +39,7 @@ async fn run() -> Result<(), Error> {
 
     let cmd_def = CliCommandMap::new()
         .insert("acme", acme::acme_mgmt_cli())
+        .insert("cert", cert::cert_mgmt_cli())
         .insert("remote", remotes::cli())
         .insert(
             "report",
-- 
2.47.3





  parent reply	other threads:[~2026-04-07 13:57 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-07 13:57 [RFC datacenter-manager/proxmox{,-backup} 00/10] TLS Certificate Rotation Shannon Sterz
2026-04-07 13:57 ` [PATCH proxmox 01/10] acme-api: make self-signed certificate expiry configurable Shannon Sterz
2026-04-07 13:57 ` [PATCH proxmox-backup 02/10] config: use proxmox_acme_api for generating self-signed certificates Shannon Sterz
2026-04-07 13:57 ` [PATCH proxmox-backup 03/10] config: adapt to api change in proxmox_acme_api, add expiry paramter Shannon Sterz
2026-04-07 13:57 ` [PATCH proxmox-backup 04/10] config/server/api: add certificate renewal logic including notifications Shannon Sterz
2026-04-07 13:57 ` [PATCH proxmox-backup 05/10] daily-update/docs: warn on excessive self-signed certificate lifetime Shannon Sterz
2026-04-07 13:57 ` [PATCH proxmox-backup 06/10] backup-manager cli: `cert update` can create auth and csrf key Shannon Sterz
2026-04-07 13:57 ` [PATCH datacenter-manager 07/10] certs: adapt to api change in proxmox_acme_api, add expiry paramter Shannon Sterz
2026-04-07 13:57 ` [PATCH datacenter-manager 08/10] api/auth/bin: add certificate renewal logic Shannon Sterz
2026-04-07 13:57 ` Shannon Sterz [this message]
2026-04-07 13:57 ` [PATCH datacenter-manager 10/10] daily-update/docs: warn on excessive tls certificate validity periods Shannon Sterz
2026-04-07 15:29   ` Shannon Sterz

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=20260407135714.490747-10-s.sterz@proxmox.com \
    --to=s.sterz@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal