Merge pull request 'fix(proxmox): fix add-remote IPC failure and URL construction' (#122) from fix/proxmox-add-remote into beta
All checks were successful
Release Beta / autotag (push) Successful in 9s
Release Beta / changelog (push) Successful in 1m30s
Test / frontend-tests (push) Successful in 1m50s
Test / frontend-typecheck (push) Successful in 2m2s
Release Beta / build-macos-arm64 (push) Successful in 9m23s
Release Beta / build-linux-amd64 (push) Successful in 10m10s
Release Beta / build-windows-amd64 (push) Successful in 11m58s
Release Beta / build-linux-arm64 (push) Successful in 13m10s
Test / rust-fmt-check (push) Successful in 18m36s
Test / rust-clippy (push) Successful in 20m9s
Test / rust-tests (push) Successful in 22m35s

Reviewed-on: #122
This commit is contained in:
sarman 2026-06-19 22:03:58 +00:00
commit bb5c820881
3 changed files with 19 additions and 11 deletions

View File

@ -38,7 +38,7 @@ pub async fn add_proxmox_cluster(
cluster_type: ClusterType,
connection: ClusterConnection,
username: String,
password: &str,
password: String,
state: State<'_, AppState>,
) -> Result<ClusterInfo, String> {
// Create client (no live auth — credentials stored and used on first connect)

View File

@ -57,7 +57,10 @@ impl ProxmoxClient {
/// Authenticate with root username and password
/// Returns the API ticket for subsequent requests
pub async fn authenticate(&self, password: &str) -> Result<String> {
let url = format!("{}/api2/json/access/ticket", self.base_url);
let url = format!(
"https://{}:{}/api2/json/access/ticket",
self.base_url, self.port
);
let params = vec![("username", self.username.as_str()), ("password", password)];
@ -95,8 +98,9 @@ impl ProxmoxClient {
/// Get the full API URL for a given path
fn get_api_url(&self, path: &str) -> String {
format!(
"{}/api2/json/{}",
"https://{}:{}/api2/json/{}",
self.base_url,
self.port,
path.trim_start_matches('/')
)
}
@ -266,30 +270,34 @@ impl ProxmoxClient {
mod tests {
use super::*;
// The frontend strips the protocol via parseRemoteUrl before sending to the backend,
// so ProxmoxClient always receives a bare hostname (no scheme, no port).
// get_api_url() is responsible for constructing the full https URL with port.
#[test]
fn test_proxmox_client_new() {
let client = ProxmoxClient::new("https://pve.example.com", 8006, "root@pam");
assert_eq!(client.base_url(), "https://pve.example.com");
let client = ProxmoxClient::new("pve.example.com", 8006, "root@pam");
assert_eq!(client.base_url(), "pve.example.com");
assert_eq!(client.port(), 8006);
assert_eq!(client.username(), "root@pam");
}
#[test]
fn test_proxmox_client_with_trailing_slash() {
let client = ProxmoxClient::new("https://pve.example.com/", 8006, "root@pam");
assert_eq!(client.base_url(), "https://pve.example.com");
let client = ProxmoxClient::new("pve.example.com/", 8006, "root@pam");
assert_eq!(client.base_url(), "pve.example.com");
}
#[test]
fn test_get_api_url() {
let client = ProxmoxClient::new("https://pve.example.com", 8006, "root@pam");
let client = ProxmoxClient::new("pve.example.com", 8006, "root@pam");
assert_eq!(
client.get_api_url("cluster/resources"),
"https://pve.example.com/api2/json/cluster/resources"
"https://pve.example.com:8006/api2/json/cluster/resources"
);
assert_eq!(
client.get_api_url("/cluster/resources"),
"https://pve.example.com/api2/json/cluster/resources"
"https://pve.example.com:8006/api2/json/cluster/resources"
);
}
}

View File

@ -61,7 +61,7 @@ export function AddRemoteForm({ onAdd, onCancel }: AddRemoteFormProps) {
try {
await onAdd(config);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to add remote');
setError(String(err));
} finally {
setLoading(false);
}