mirror of
https://github.com/tribufu/proxmox-sharp
synced 2026-05-06 06:47:29 +00:00
193 lines
7.3 KiB
C#
193 lines
7.3 KiB
C#
// Copyright (c) Tribufu. All Rights Reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
using ProxmoxSharp.Interfaces;
|
|
using ProxmoxSharp.Models;
|
|
using RestSharp;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace ProxmoxSharp
|
|
{
|
|
public class ProxmoxClient : IProxmoxClient
|
|
{
|
|
private readonly RestClient _client;
|
|
|
|
private string _ticket;
|
|
|
|
private string _csrfToken;
|
|
|
|
public ProxmoxClient(string baseUrl, string tokenId, string secret)
|
|
{
|
|
var options = new RestClientOptions(baseUrl.TrimEnd('/') + "/api2/json/")
|
|
{
|
|
RemoteCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
|
|
};
|
|
|
|
_client = new RestClient(options);
|
|
|
|
if (!string.IsNullOrEmpty(tokenId) && !string.IsNullOrEmpty(secret))
|
|
{
|
|
_client.AddDefaultHeader("Authorization", $"PVEAPIToken={tokenId}={secret}");
|
|
}
|
|
}
|
|
|
|
public async Task<bool> LoginAsync(string username, string password)
|
|
{
|
|
var request = new RestRequest("access/ticket", Method.Post);
|
|
request.AddParameter("username", username);
|
|
request.AddParameter("password", password);
|
|
|
|
var response = await _client.ExecuteAsync(request);
|
|
if (response.IsSuccessful)
|
|
{
|
|
var json = JObject.Parse(response.Content);
|
|
var data = json["data"];
|
|
_ticket = data["ticket"].ToString();
|
|
_csrfToken = data["CSRFPreventionToken"].ToString();
|
|
|
|
_client.AddDefaultHeader("Cookie", $"PVEAuthCookie={_ticket}");
|
|
_client.AddDefaultHeader("CSRFPreventionToken", _csrfToken);
|
|
}
|
|
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<List<ProxmoxNode>> ListNodesAsync()
|
|
{
|
|
var request = new RestRequest($"nodes", Method.Get);
|
|
|
|
var response = await _client.ExecuteAsync(request);
|
|
if (!response.IsSuccessful)
|
|
{
|
|
throw new Exception($"Failed to list nodes: {response.StatusCode}");
|
|
}
|
|
|
|
var json = JObject.Parse(response.Content);
|
|
return json["data"].ToObject<List<ProxmoxNode>>();
|
|
}
|
|
|
|
public async Task<ProxmoxNodeStatus> GetNodeStatusAsync(string node)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/status", Method.Get);
|
|
|
|
var response = await _client.ExecuteAsync(request);
|
|
if (!response.IsSuccessful)
|
|
{
|
|
throw new Exception($"Failed to get node {node}: {response.StatusCode}");
|
|
}
|
|
|
|
var json = JObject.Parse(response.Content);
|
|
return json["data"].ToObject<ProxmoxNodeStatus>();
|
|
}
|
|
|
|
public async Task<bool> CreateVirtualMachineAsync(string node, int vmid, string name, int memoryMb, int cores, string storage, string iso, string netConfig = "virtio,bridge=vmbr0")
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu", Method.Post);
|
|
request.AddParameter("vmid", vmid);
|
|
request.AddParameter("name", name);
|
|
request.AddParameter("memory", memoryMb);
|
|
request.AddParameter("cores", cores);
|
|
request.AddParameter("ide2", iso + ",media=cdrom");
|
|
request.AddParameter("scsihw", "virtio-scsi-pci");
|
|
request.AddParameter("scsi0", $"{storage}:32");
|
|
request.AddParameter("net0", netConfig);
|
|
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<List<ProxmoxVirtualMachine>> ListVirtualMachinesAsync(string node)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu", Method.Get);
|
|
|
|
var response = await _client.ExecuteAsync(request);
|
|
if (!response.IsSuccessful)
|
|
{
|
|
throw new Exception($"Failed to list VMs: {response.StatusCode}");
|
|
}
|
|
|
|
var json = JObject.Parse(response.Content);
|
|
return json["data"].ToObject<List<ProxmoxVirtualMachine>>();
|
|
}
|
|
|
|
public async Task<ProxmoxVirtualMachineStatus> GetVirtualMachineStatusAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/current", Method.Get);
|
|
|
|
var response = await _client.ExecuteAsync(request);
|
|
if (!response.IsSuccessful)
|
|
{
|
|
throw new Exception($"Failed to start VM {vmid}: {response.StatusCode}");
|
|
}
|
|
|
|
var json = JObject.Parse(response.Content);
|
|
return json["data"].ToObject<ProxmoxVirtualMachineStatus>();
|
|
}
|
|
|
|
public async Task<bool> StartVirtualMachineAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/start", Method.Post);
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<bool> RebootVirtualMachineAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/reboot", Method.Post);
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<bool> ResetVirtualMachineAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/reset", Method.Post);
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<bool> SuspendVirtualMachineAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/suspend", Method.Post);
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<bool> ResumeVirtualMachineAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/resume", Method.Post);
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<bool> ShutdownVirtualMachineAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/shutdown", Method.Post);
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<bool> StopVirtualMachineAsync(string node, int vmid)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/qemu/{vmid}/status/stop", Method.Post);
|
|
var response = await _client.ExecuteAsync(request);
|
|
return response.IsSuccessful;
|
|
}
|
|
|
|
public async Task<List<ProxmoxContainer>> ListContainersAsync(string node)
|
|
{
|
|
var request = new RestRequest($"nodes/{node}/lxc", Method.Get);
|
|
|
|
var response = await _client.ExecuteAsync(request);
|
|
if (!response.IsSuccessful)
|
|
{
|
|
throw new Exception($"Failed to list LXC containers: {response.StatusCode}");
|
|
}
|
|
|
|
var json = JObject.Parse(response.Content);
|
|
return json["data"].ToObject<List<ProxmoxContainer>>();
|
|
}
|
|
}
|
|
}
|