public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Manuel Federanko <m.federanko@proxmox.com>
To: pbs-devel@lists.proxmox.com, pdm-devel@lists.proxmox.com
Subject: [PATCH proxmox 3/7] acme: allow specifying the certificate that is replaced by an order
Date: Thu, 25 Jun 2026 16:13:33 +0200	[thread overview]
Message-ID: <20260625141337.181684-4-m.federanko@proxmox.com> (raw)
In-Reply-To: <20260625141337.181684-1-m.federanko@proxmox.com>

There isn't a foolproof way of determining if the id should be sent
along yet. If the request fails try again without the ari id.

Signed-off-by: Manuel Federanko <m.federanko@proxmox.com>
---
 proxmox-acme-api/src/certificate_helpers.rs | 27 ++++++++++++++++++---
 proxmox-acme/src/async_client.rs            | 18 +++++++++++---
 proxmox-acme/src/order.rs                   | 13 ++++++++++
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/proxmox-acme-api/src/certificate_helpers.rs b/proxmox-acme-api/src/certificate_helpers.rs
index 7dc06c2d..5d35f86a 100644
--- a/proxmox-acme-api/src/certificate_helpers.rs
+++ b/proxmox-acme-api/src/certificate_helpers.rs
@@ -65,6 +65,7 @@ pub async fn order_certificate(
     worker: Arc<WorkerTask>,
     acme_config: &AcmeConfig,
     domains: &[AcmeDomain],
+    replaces_certificate_id: Option<&str>,
 ) -> Result<Option<OrderedCertificate>, Error> {
     use proxmox_acme::authorization::Status;
     use proxmox_acme::order::Identifier;
@@ -88,10 +89,30 @@ pub async fn order_certificate(
     let (plugins, _) = super::plugin_config::plugin_config()?;
 
     info!("Placing ACME order");
-
     let order = acme
-        .new_order(domains.iter().map(|d| d.domain.to_ascii_lowercase()))
-        .await?;
+        .new_order(
+            domains.iter().map(|d| d.domain.to_ascii_lowercase()),
+            replaces_certificate_id,
+        )
+        .await;
+    // there isn't really a nice way to know if a specific certificate
+    // is issued by the acme server, retry without specifying the id
+    // on failures
+    let order = match order {
+        Ok(o) => o,
+        Err(e) => if replaces_certificate_id.is_some() {
+            info!("Failed to place order, retrying without ARI id: {}", e);
+            acme
+                .new_order(
+                    domains.iter().map(|d| d.domain.to_ascii_lowercase()),
+                    None,
+                )
+                .await?
+        } else {
+            Err(e)?
+        },
+
+    };
 
     info!("Order URL: {}", order.location);
 
diff --git a/proxmox-acme/src/async_client.rs b/proxmox-acme/src/async_client.rs
index c133a54e..7738346e 100644
--- a/proxmox-acme/src/async_client.rs
+++ b/proxmox-acme/src/async_client.rs
@@ -172,15 +172,25 @@ impl AcmeClient {
     ///
     /// Please remember to persist the order somewhere (ideally along with the account data) in
     /// order to finish & query it later on.
-    pub async fn new_order<I>(&mut self, domains: I) -> Result<Order, anyhow::Error>
+    pub async fn new_order<I>(
+        &mut self,
+        domains: I,
+        replaces_certificate_id: Option<&str>,
+    ) -> Result<Order, anyhow::Error>
     where
         I: IntoIterator<Item = String>,
     {
         let account = Self::need_account(&self.account)?;
 
-        let order = domains
-            .into_iter()
-            .fold(OrderData::new(), |order, domain| order.domain(domain));
+        let order = {
+            let mut order = domains
+                .into_iter()
+                .fold(OrderData::new(), |order, domain| order.domain(domain));
+            if let Some(replaces_certificate_id) = replaces_certificate_id {
+                order = order.replaces(replaces_certificate_id);
+            }
+            order
+        };
 
         let mut retry = retry();
         loop {
diff --git a/proxmox-acme/src/order.rs b/proxmox-acme/src/order.rs
index d75fbde1..36ee5fe1 100644
--- a/proxmox-acme/src/order.rs
+++ b/proxmox-acme/src/order.rs
@@ -81,6 +81,10 @@ pub struct OrderData {
     /// List of identifiers to order for the certificate.
     pub identifiers: Vec<Identifier>,
 
+    /// Reference to the certificate being replaced
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub replaces: Option<String>,
+
     /// An RFC3339 formatted time string. It is up to the user to choose a dev dependency for this
     /// shit.
     #[serde(skip_serializing_if = "Option::is_none")]
@@ -120,6 +124,15 @@ impl OrderData {
         self.identifiers.push(Identifier::Dns(domain));
         self
     }
+
+    /// Builder-style method to specify which certificate this order replaces.
+    pub fn replaces<K>(mut self, ari_id: K) -> Self
+    where
+        K: ToString,
+    {
+        self.replaces = Some(ari_id.to_string());
+        self
+    }
 }
 
 /// Represents an order for a new certificate. This combines the order's own location (URL) with
-- 
2.47.3




  parent reply	other threads:[~2026-06-25 14:14 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-25 14:13 [PATCH proxmox{,-backup,-datacenter-manager} 0/7] acme: fix #6372 implement basic ARI support Manuel Federanko
2026-06-25 14:13 ` [PATCH proxmox 1/7] acme: client: add methods to fetch renewal information Manuel Federanko
2026-06-25 14:13 ` [PATCH proxmox 2/7] acme: add retry-after header to " Manuel Federanko
2026-06-25 14:13 ` Manuel Federanko [this message]
2026-06-25 14:13 ` [PATCH proxmox 4/7] acme: cert: add dedicated ari_id field to the certificate info Manuel Federanko
2026-06-25 14:13 ` [PATCH proxmox-backup 5/7] acme: add ari_id to cert info Manuel Federanko
2026-06-25 14:13 ` [PATCH proxmox-backup 6/7] acme: fix #6372 implement ARI renewal information fetching Manuel Federanko
2026-06-25 14:13 ` [PATCH proxmox-datacenter-manager 7/7] acme: fix #6372 use ARI for renewal if available Manuel Federanko

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=20260625141337.181684-4-m.federanko@proxmox.com \
    --to=m.federanko@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    --cc=pdm-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