[PATCH datacenter-manager v3 20/38] client: add bindings for auto-installer endpoints

Christoph Heiss
2026-04-03T16:56:04Z

lib/pdm-client/src/lib.rs | 232 ++++++++++++++++++++++++++++++++++++++
1 file changed, 232 insertions(+)

diff --git a/lib/pdm-client/src/lib.rs b/lib/pdm-client/src/lib.rs
index 1565869..190d1f5 100644
--- a/lib/pdm-client/src/lib.rs
+++ b/lib/pdm-client/src/lib.rs
@@ -3,6 +3,11 @@
use std::collections::HashMap;
use std::time::Duration;

+use pdm_api_types::auto_installer::{
+ AnswerAuthToken, AnswerAuthTokenUpdater, DeletableAnswerAuthTokenProperty,
+ DeletablePreparedInstallationConfigProperty, Installation, PreparedInstallationConfig,
+ PreparedInstallationConfigUpdater,
+};
use pdm_api_types::remote_updates::RemoteUpdateSummary;
use pdm_api_types::remotes::{RemoteType, TlsProbeOutcome};
use pdm_api_types::resource::{PveResource, RemoteResources, ResourceType, TopEntities};
@@ -1376,6 +1381,233 @@ impl<T: HttpApiClient> PdmClient<T> {
.expect_json()?
.data)
}
+
+ /// Retrieves all known installations done by auto-installer.
+ pub async fn get_autoinst_installations(&self) -> Result<Vec<Installation>, Error> {
+ Ok(self
+ .0
+ .get("/api2/extjs/auto-install/installations")
+ .await?
+ .expect_json()?
+ .data)
+ }
+
+ /// Deletes a saved auto-installation.
+ ///
+ /// # Parameters
+ ///
+ /// * `id` - ID of the entry to delete. Must be percent-encoded.
+ pub async fn delete_autoinst_installation(&self, id: &str) -> Result<(), Error> {
+ self.0
+ .delete(&format!("/api2/extjs/auto-install/installations/{id}"))
+ .await?
+ .nodata()?;
+ Ok(())
+ }
+
+ /// Retrieves all prepared answer configurations.
+ pub async fn get_autoinst_prepared_answers(
+ &self,
+ ) -> Result<Vec<PreparedInstallationConfig>, Error> {
+ Ok(self
+ .0
+ .get("/api2/extjs/auto-install/prepared")
+ .await?
+ .expect_json()?
+ .data)
+ }
+
+ /// Adds a new prepared answer file configuration for automated installations.
+ ///
+ /// # Arguments
+ ///
+ /// * `answer` - Answer to create.
+ pub async fn add_autoinst_prepared_answer(
+ &self,
+ answer: &PreparedInstallationConfig,
+ ) -> Result<(), Error> {
+ self.0
+ .post("/api2/extjs/auto-install/prepared", answer)
+ .await?
+ .nodata()
+ }
+
+ /// Update an existing prepared answer file configuration for automated installations.
+ ///
+ /// # Arguments
+ ///
+ /// * `id` - ID of the entry to delete. Must be percent-encoded.
+ /// * `updater` - Field values to update.
+ /// * `root_password` - Optional root password to set for this answer.
+ /// * `delete` - List of properties to delete.
+ pub async fn update_autoinst_prepared_answer(
+ &self,
+ id: &str,
+ updater: &PreparedInstallationConfigUpdater,
+ root_password: Option<&str>,
+ delete: &[DeletablePreparedInstallationConfigProperty],
+ ) -> Result<(), Error> {
+ #[derive(Serialize)]
+ struct UpdatePreparedAnswer<'a> {
+ #[serde(flatten)]
+ updater: &'a PreparedInstallationConfigUpdater,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ root_password: Option<&'a str>,
+ #[serde(skip_serializing_if = "Vec::is_empty")]
+ delete: Vec<String>,
+ }
+
+ let delete = delete
+ .iter()
+ .map(DeletablePreparedInstallationConfigProperty::to_string)
+ .collect();
+
+ self.0
+ .put(
+ &format!("/api2/extjs/auto-install/prepared/{id}"),
+ &UpdatePreparedAnswer {
+ updater,
+ root_password,
+ delete,
+ },
+ )
+ .await?
+ .nodata()
+ }
+
+ /// Deletes a prepared answer for automated installations.
+ ///
+ /// # Parameters
+ ///
+ /// * `id` - ID of the entry to delete. Must be percent-encoded.
+ pub async fn delete_autoinst_prepared_answer(&self, id: &str) -> Result<(), Error> {
+ self.0
+ .delete(&format!("/api2/extjs/auto-install/prepared/{id}"))
+ .await?
+ .nodata()?;
+ Ok(())
+ }
+
+ /// Retrieves all access tokens for the auto-installer server.
+ pub async fn get_autoinst_auth_tokens(&self) -> Result<Vec<AnswerAuthToken>, Error> {
+ Ok(self
+ .0
+ .get("/api2/extjs/auto-install/tokens")
+ .await?
+ .expect_json()?
+ .data)
+ }
+
+ /// Adds a new access token for authenticating requests from the automated installer.
+ ///
+ /// # Parameters
+ ///
+ /// * `id` - Name of the token to create.
+ /// * `comment` - Optional comment for the token.
+ /// * `enabled` - Whether this token is enabled.
+ /// * `expire_at` - Optional expiration date for this token.
+ pub async fn add_autoinst_auth_token(
+ &self,
+ id: &str,
+ comment: Option<String>,
+ enabled: Option<bool>,
+ expire_at: Option<i64>,
+ ) -> Result<(AnswerAuthToken, String), Error> {
+ #[derive(Serialize)]
+ #[serde(rename_all = "kebab-case")]
+ struct CreateTokenRequest<'a> {
+ id: &'a str,
+ comment: &'a Option<String>,
+ enabled: Option<bool>,
+ expire_at: Option<i64>,
+ }
+
+ #[derive(Deserialize)]
+ struct CreateTokenResponse {
+ token: AnswerAuthToken,
+ secret: String,
+ }
+
+ let response = self
+ .0
+ .post(
+ "/api2/extjs/auto-install/tokens",
+ &CreateTokenRequest {
+ id,
+ comment: &comment,
+ enabled,
+ expire_at,
+ },
+ )
+ .await?
+ .expect_json::<CreateTokenResponse>()?;
+
+ Ok((response.data.token, response.data.secret))
+ }
+
+ /// Updates an existing access token for authenticating requests from the automated installer.
+ ///
+ /// # Parameters
+ ///
+ /// * `id` - Name of the token to update.
+ /// * `updater` - Fields to update.
+ /// * `delete` - Fields to delete.
+ pub async fn update_autoinst_auth_token(
+ &self,
+ id: &str,
+ updater: &AnswerAuthTokenUpdater,
+ delete: &[DeletableAnswerAuthTokenProperty],
+ regenerate_secret: bool,
+ ) -> Result<(AnswerAuthToken, Option<String>), Error> {
+ #[derive(Serialize)]
+ #[serde(rename_all = "kebab-case")]
+ struct UpdateToken<'a> {
+ #[serde(flatten)]
+ updater: &'a AnswerAuthTokenUpdater,
+ #[serde(skip_serializing_if = "Vec::is_empty")]
+ delete: Vec<String>,
+ regenerate_secret: bool,
+ }
+
+ #[derive(Deserialize)]
+ struct UpdateTokenResponse {
+ token: AnswerAuthToken,
+ secret: Option<String>,
+ }
+
+ let delete = delete
+ .iter()
+ .map(DeletableAnswerAuthTokenProperty::to_string)
+ .collect();
+
+ let response = self
+ .0
+ .put(
+ &format!("/api2/extjs/auto-install/tokens/{id}"),
+ &UpdateToken {
+ updater,
+ delete,
+ regenerate_secret,
+ },
+ )
+ .await?
+ .expect_json::<UpdateTokenResponse>()?;
+
+ Ok((response.data.token, response.data.secret))
+ }
+
+ /// Deletes an access token used for authenticating automated installations.
+ ///
+ /// # Parameters
+ ///
+ /// * `id` - Name of the token to delete.
+ pub async fn delete_autoinst_auth_token(&self, id: &str) -> Result<(), Error> {
+ self.0
+ .delete(&format!("/api2/extjs/auto-install/tokens/{id}"))
+ .await?
+ .nodata()?;
+ Ok(())
+ }
}

/// Builder for migration parameters.
--
2.53.0