From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 7A1FA1FF13E for ; Fri, 03 Apr 2026 18:57:58 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 3FF15949E; Fri, 3 Apr 2026 18:58:29 +0200 (CEST) From: Christoph Heiss To: pdm-devel@lists.proxmox.com Subject: [PATCH installer v3 36/38] fetch-answer: send auto-installer HTTP authorization token if set Date: Fri, 3 Apr 2026 18:54:08 +0200 Message-ID: <20260403165437.2166551-37-c.heiss@proxmox.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260403165437.2166551-1-c.heiss@proxmox.com> References: <20260403165437.2166551-1-c.heiss@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1775235411758 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.068 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: Z3IK6O4IHHOMY74TDJCVMBN55TB7GSYT X-Message-ID-Hash: Z3IK6O4IHHOMY74TDJCVMBN55TB7GSYT X-MailFrom: c.heiss@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: If an authorization token is present in the internal auto-installer HTTP configuration, add it as Authorization: ProxmoxInstallerToken header to the POST HTTP request when retrieving the answer. Signed-off-by: Christoph Heiss --- Changes v2 -> v3: * new patch .../src/fetch_plugins/http.rs | 8 +++++++ proxmox-fetch-answer/src/main.rs | 22 ++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/proxmox-fetch-answer/src/fetch_plugins/http.rs b/proxmox-fetch-answer/src/fetch_plugins/http.rs index 6508721..121b620 100644 --- a/proxmox-fetch-answer/src/fetch_plugins/http.rs +++ b/proxmox-fetch-answer/src/fetch_plugins/http.rs @@ -95,6 +95,14 @@ impl FetchFromHTTP { HeaderValue::from_str("application/json, application/toml;q=0.5")?, ); + if let Some(token) = &settings.token { + info!("Authentication token provided through ISO."); + headers.insert( + http::header::AUTHORIZATION, + HeaderValue::from_str(&format!("ProxmoxInstallerToken {token}"))?, + ); + } + let (body, content_type) = http::post(&answer_url, fingerprint.as_deref(), headers, payload)?; diff --git a/proxmox-fetch-answer/src/main.rs b/proxmox-fetch-answer/src/main.rs index 18b27e7..2e399d1 100644 --- a/proxmox-fetch-answer/src/main.rs +++ b/proxmox-fetch-answer/src/main.rs @@ -23,8 +23,13 @@ const CLI_USAGE_HELPTEXT: &str = concat!( Commands: iso Fetch the builtin answer file from the ISO + http Fetch the answer file via HTTP(S) - Additional parameters: [] [] + Additional parameters: [] [] [] + + To provide an authentication token without a certificate fingerprint, pass an + empty string to . + partition Fetch the answer file from a mountable partition Additional parameters: [] @@ -47,18 +52,18 @@ fn fetch_answer(install_settings: &AutoInstSettings) -> Result { let answer_path = PathBuf::from("/cdrom/answer.toml"); match fs::read_to_string(answer_path) { Ok(answer) => return Ok(answer), - Err(err) => info!("Fetching answer file from ISO failed: {err}"), + Err(err) => info!("Fetching answer file from ISO failed: {err:#}"), } } FetchAnswerFrom::Partition => { match FetchFromPartition::get_answer(&install_settings.partition_label) { Ok(answer) => return Ok(answer), - Err(err) => info!("Fetching answer file from partition failed: {err}"), + Err(err) => info!("Fetching answer file from partition failed: {err:#}"), } } FetchAnswerFrom::Http => match FetchFromHTTP::get_answer(&install_settings.http) { Ok(answer) => return Ok(answer), - Err(err) => info!("Fetching answer file via HTTP failed: {err}"), + Err(err) => info!("Fetching answer file via HTTP failed: {err:#}"), }, } bail!("Could not find any answer file!"); @@ -80,8 +85,8 @@ fn settings_from_cli_args(args: &[String]) -> Result { FetchAnswerFrom::Iso if args.len() > 2 => { bail!("'iso' mode does not take any additional arguments") } - FetchAnswerFrom::Http if args.len() > 4 => { - bail!("'http' mode takes at most 2 additional arguments") + FetchAnswerFrom::Http if args.len() > 5 => { + bail!("'http' mode takes at most 3 additional arguments") } FetchAnswerFrom::Partition if args.len() > 3 => { bail!("'partition' mode takes at most 1 additional argument") @@ -97,8 +102,9 @@ fn settings_from_cli_args(args: &[String]) -> Result { .cloned()?, http: HttpOptions { url: args.get(2).cloned(), - cert_fingerprint: args.get(3).cloned(), - token: None, + // treat empty value as not existing + cert_fingerprint: args.get(3).cloned().filter(|s| !s.is_empty()), + token: args.get(4).cloned(), }, }) } -- 2.53.0