[PATCH proxmox-backup v4 5/8] config: use moved NodeConfig definitions in pbs-api-types

Christian Ebner
2026-03-27T12:13:51Z

These have been moved as preparation in an effort to move the node
config to pbs-config. That is required in order to read the node's
proxy config from the datastore implementation.

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
Reviewed-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
---
src/api2/node/config.rs | 3 +-
src/config/node.rs | 259 +---------------------------------------
src/tools/config.rs | 4 +-
3 files changed, 6 insertions(+), 260 deletions(-)

diff --git a/src/api2/node/config.rs b/src/api2/node/config.rs
index 19ede24b7..619e2b022 100644
--- a/src/api2/node/config.rs
+++ b/src/api2/node/config.rs
@@ -5,10 +5,9 @@ use hex::FromHex;
use proxmox_router::{Permission, Router, RpcEnvironment};
use proxmox_schema::api;

-use pbs_api_types::{NODE_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
+use pbs_api_types::{NodeConfig, NodeConfigUpdater, NODE_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};

use crate::api2::node::apt::update_apt_proxy_config;
-use crate::config::node::{NodeConfig, NodeConfigUpdater};

pub const ROUTER: Router = Router::new()
.get(&API_METHOD_GET_NODE_CONFIG)
diff --git a/src/config/node.rs b/src/config/node.rs
index 93173e66f..6e44495f8 100644
--- a/src/config/node.rs
+++ b/src/config/node.rs
@@ -2,15 +2,10 @@ use std::collections::HashSet;

use anyhow::{bail, Error};
use openssl::ssl::{SslAcceptor, SslMethod};
-use serde::{Deserialize, Serialize};

-use pbs_api_types::{
- EMAIL_SCHEMA, MULTI_LINE_COMMENT_SCHEMA, OPENSSL_CIPHERS_TLS_1_2_SCHEMA,
- OPENSSL_CIPHERS_TLS_1_3_SCHEMA,
-};
-use proxmox_acme_api::{AcmeConfig, AcmeDomain, ACME_DOMAIN_PROPERTY_SCHEMA};
-use proxmox_http::{ProxyConfig, HTTP_PROXY_SCHEMA};
-use proxmox_schema::{api, ApiStringFormat, ApiType, Updater};
+use pbs_api_types::NodeConfig;
+use proxmox_http::ProxyConfig;
+use proxmox_schema::ApiType;

use pbs_buildcfg::configdir;
use pbs_config::{open_backup_lockfile, BackupLockGuard};
@@ -53,254 +48,6 @@ pub fn save_config(config: &NodeConfig) -> Result<(), Error> {
pbs_config::replace_backup_config(CONF_FILE, &raw)
}

-/// All available languages in Proxmox. Taken from proxmox-i18n repository.
-/// pt_BR, zh_CN, and zh_TW use the same case in the translation files.
-// TODO: auto-generate from available translations
-#[api]
-#[derive(Serialize, Deserialize)]
-#[serde(rename_all = "lowercase")]
-pub enum Translation {
- /// Arabic
- Ar,
- /// Catalan
- Ca,
- /// Danish
- Da,
- /// German
- De,
- /// English
- En,
- /// Spanish
- Es,
- /// Euskera
- Eu,
- /// Persian (Farsi)
- Fa,
- /// French
- Fr,
- /// Galician
- Gl,
- /// Hebrew
- He,
- /// Hungarian
- Hu,
- /// Italian
- It,
- /// Japanese
- Ja,
- /// Korean
- Kr,
- /// Norwegian (Bokmal)
- Nb,
- /// Dutch
- Nl,
- /// Norwegian (Nynorsk)
- Nn,
- /// Polish
- Pl,
- /// Portuguese (Brazil)
- #[serde(rename = "pt_BR")]
- PtBr,
- /// Russian
- Ru,
- /// Slovenian
- Sl,
- /// Swedish
- Sv,
- /// Turkish
- Tr,
- /// Chinese (simplified)
- #[serde(rename = "zh_CN")]
- ZhCn,
- /// Chinese (traditional)
- #[serde(rename = "zh_TW")]
- ZhTw,
-}
-
-#[api(
- properties: {
- acme: {
- optional: true,
- type: String,
- format: &ApiStringFormat::PropertyString(&AcmeConfig::API_SCHEMA),
- },
- acmedomain0: {
- schema: ACME_DOMAIN_PROPERTY_SCHEMA,
- optional: true,
- },
- acmedomain1: {
- schema: ACME_DOMAIN_PROPERTY_SCHEMA,
- optional: true,
- },
- acmedomain2: {
- schema: ACME_DOMAIN_PROPERTY_SCHEMA,
- optional: true,
- },
- acmedomain3: {
- schema: ACME_DOMAIN_PROPERTY_SCHEMA,
- optional: true,
- },
- acmedomain4: {
- schema: ACME_DOMAIN_PROPERTY_SCHEMA,
- optional: true,
- },
- "http-proxy": {
- schema: HTTP_PROXY_SCHEMA,
- optional: true,
- },
- "email-from": {
- schema: EMAIL_SCHEMA,
- optional: true,
- },
- "ciphers-tls-1.3": {
- schema: OPENSSL_CIPHERS_TLS_1_3_SCHEMA,
- optional: true,
- },
- "ciphers-tls-1.2": {
- schema: OPENSSL_CIPHERS_TLS_1_2_SCHEMA,
- optional: true,
- },
- "default-lang" : {
- schema: Translation::API_SCHEMA,
- optional: true,
- },
- "description" : {
- optional: true,
- schema: MULTI_LINE_COMMENT_SCHEMA,
- },
- "consent-text" : {
- optional: true,
- type: String,
- max_length: 64 * 1024,
- }
- },
-)]
-#[derive(Deserialize, Serialize, Updater)]
-#[serde(rename_all = "kebab-case")]
-/// Node specific configuration.
-pub struct NodeConfig {
- /// The acme account to use on this node.
- #[serde(skip_serializing_if = "Option::is_none")]
- pub acme: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub acmedomain0: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub acmedomain1: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub acmedomain2: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub acmedomain3: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub acmedomain4: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub http_proxy: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub email_from: Option<String>,
-
- /// List of TLS ciphers for TLS 1.3 that will be used by the proxy. (Proxy has to be restarted for changes to take effect)
- #[serde(skip_serializing_if = "Option::is_none", rename = "ciphers-tls-1.3")]
- pub ciphers_tls_1_3: Option<String>,
-
- /// List of TLS ciphers for TLS <= 1.2 that will be used by the proxy. (Proxy has to be restarted for changes to take effect)
- #[serde(skip_serializing_if = "Option::is_none", rename = "ciphers-tls-1.2")]
- pub ciphers_tls_1_2: Option<String>,
-
- /// Default language used in the GUI
- #[serde(skip_serializing_if = "Option::is_none")]
- pub default_lang: Option<String>,
-
- /// Node description
- #[serde(skip_serializing_if = "Option::is_none")]
- pub description: Option<String>,
-
- /// Maximum days to keep Task logs
- #[serde(skip_serializing_if = "Option::is_none")]
- pub task_log_max_days: Option<usize>,
-
- /// Consent banner text
- #[serde(skip_serializing_if = "Option::is_none")]
- pub consent_text: Option<String>,
-}
-
-impl NodeConfig {
- pub fn acme_config(&self) -> Result<AcmeConfig, Error> {
- self.acme
- .as_deref()
- .map(|config| {
- crate::tools::config::from_property_string::<AcmeConfig>(
- config,
- &AcmeConfig::API_SCHEMA,
- )
- })
- .unwrap_or_else(|| proxmox_acme_api::parse_acme_config_string("account=default"))
- }
-
- pub fn acme_domains(&'_ self) -> AcmeDomainIter<'_> {
- AcmeDomainIter::new(self)
- }
-
- /// Returns the parsed ProxyConfig
- pub fn http_proxy(&self) -> Option<ProxyConfig> {
- if let Some(http_proxy) = &self.http_proxy {
- ProxyConfig::parse_proxy_url(http_proxy).ok()
- } else {
- None
- }
- }
-
- /// Sets the HTTP proxy configuration
- pub fn set_http_proxy(&mut self, http_proxy: Option<String>) {
- self.http_proxy = http_proxy;
- }
-}
-
-pub struct AcmeDomainIter<'a> {
- config: &'a NodeConfig,
- index: usize,
-}
-
-impl<'a> AcmeDomainIter<'a> {
- fn new(config: &'a NodeConfig) -> Self {
- Self { config, index: 0 }
- }
-}
-
-impl Iterator for AcmeDomainIter<'_> {
- type Item = Result<AcmeDomain, Error>;
-
- fn next(&mut self) -> Option<Self::Item> {
- let domain = loop {
- let index = self.index;
- self.index += 1;
-
- let domain = match index {
- 0 => self.config.acmedomain0.as_deref(),
- 1 => self.config.acmedomain1.as_deref(),
- 2 => self.config.acmedomain2.as_deref(),
- 3 => self.config.acmedomain3.as_deref(),
- 4 => self.config.acmedomain4.as_deref(),
- _ => return None,
- };
-
- if let Some(domain) = domain {
- break domain;
- }
- };
-
- Some(crate::tools::config::from_property_string(
- domain,
- &AcmeDomain::API_SCHEMA,
- ))
- }
-}
-
pub(crate) fn node_http_proxy_config() -> Result<Option<ProxyConfig>, Error> {
let (node_config, _digest) = self::config()?;
Ok(node_config.http_proxy())
diff --git a/src/tools/config.rs b/src/tools/config.rs
index 64fe981aa..2c1078676 100644
--- a/src/tools/config.rs
+++ b/src/tools/config.rs
@@ -177,7 +177,7 @@ fn test() {
use proxmox_schema::ApiType;

// let's just reuse some schema we actually have available:
- use crate::config::node::NodeConfig;
+ use pbs_api_types::NodeConfig;

const NODE_CONFIG: &str = "\
acme: account=pebble\n\
@@ -198,7 +198,7 @@ fn test_with_comment() {
use proxmox_schema::ApiType;

// let's just reuse some schema we actually have available:
- use crate::config::node::NodeConfig;
+ use pbs_api_types::NodeConfig;

const NODE_INPUT: &str = "\
#this should\n\
--
2.47.3