using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; using PSProxmoxVE.Core.Authentication; using PSProxmoxVE.Core.Client; using PSProxmoxVE.Core.Models.Backup; using PSProxmoxVE.Core.Models.Vms; namespace PSProxmoxVE.Core.Services { /// /// Service for Proxmox VE Backup (vzdump) and backup job API operations. /// public class BackupService { // ------------------------------------------------------------------------- // Ad-hoc backup (vzdump) // ------------------------------------------------------------------------- /// /// Creates an ad-hoc backup via vzdump. Returns the task UPID. /// /// The authenticated PVE session. /// The node to run the backup on. /// Backup configuration parameters. public PveTask CreateBackup(PveSession session, string node, Dictionary config) { if (session == null) throw new ArgumentNullException(nameof(session)); if (string.IsNullOrWhiteSpace(node)) throw new ArgumentNullException(nameof(node)); if (config == null) throw new ArgumentNullException(nameof(config)); using var client = new PveHttpClient(session); var response = client.PostAsync($"nodes/{Uri.EscapeDataString(node)}/vzdump", config) .GetAwaiter().GetResult(); return ParseTask(response, node); } // ------------------------------------------------------------------------- // Backup jobs (scheduled) // ------------------------------------------------------------------------- /// /// Returns all scheduled backup jobs. /// public PveBackupJob[] GetBackupJobs(PveSession session) { if (session == null) throw new ArgumentNullException(nameof(session)); using var client = new PveHttpClient(session); var response = client.GetAsync("cluster/backup").GetAwaiter().GetResult(); var data = JObject.Parse(response)["data"]; return data?.ToObject() ?? Array.Empty(); } /// /// Returns a single scheduled backup job by ID. /// public PveBackupJob? GetBackupJob(PveSession session, string id) { if (session == null) throw new ArgumentNullException(nameof(session)); if (string.IsNullOrWhiteSpace(id)) throw new ArgumentNullException(nameof(id)); using var client = new PveHttpClient(session); var response = client.GetAsync($"cluster/backup/{Uri.EscapeDataString(id)}") .GetAwaiter().GetResult(); var data = JObject.Parse(response)["data"]; return data?.ToObject(); } /// /// Creates a scheduled backup job. /// public void CreateBackupJob(PveSession session, Dictionary config) { if (session == null) throw new ArgumentNullException(nameof(session)); if (config == null) throw new ArgumentNullException(nameof(config)); using var client = new PveHttpClient(session); client.PostAsync("cluster/backup", config).GetAwaiter().GetResult(); } /// /// Updates a scheduled backup job. /// public void UpdateBackupJob(PveSession session, string id, Dictionary config) { if (session == null) throw new ArgumentNullException(nameof(session)); if (string.IsNullOrWhiteSpace(id)) throw new ArgumentNullException(nameof(id)); if (config == null) throw new ArgumentNullException(nameof(config)); using var client = new PveHttpClient(session); client.PutAsync($"cluster/backup/{Uri.EscapeDataString(id)}", config) .GetAwaiter().GetResult(); } /// /// Removes a scheduled backup job. /// public void RemoveBackupJob(PveSession session, string id) { if (session == null) throw new ArgumentNullException(nameof(session)); if (string.IsNullOrWhiteSpace(id)) throw new ArgumentNullException(nameof(id)); using var client = new PveHttpClient(session); client.DeleteAsync($"cluster/backup/{Uri.EscapeDataString(id)}") .GetAwaiter().GetResult(); } // ------------------------------------------------------------------------- // Private helpers // ------------------------------------------------------------------------- private static PveTask ParseTask(string response, string node) { var data = JObject.Parse(response)["data"]; if (data?.Type == JTokenType.String) return new PveTask { Upid = data.ToString(), Node = node }; var task = data?.ToObject() ?? new PveTask(); task.Node = node; return task; } } }