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; using PSProxmoxVE.Core.Utilities; namespace PSProxmoxVE.Core.Services { /// /// Service for Proxmox VE Backup (vzdump) and backup job API operations. /// public class BackupService : PveServiceBase { /// /// Initializes a new instance of with no injected client. /// Each method will create and dispose its own . /// public BackupService() { } /// /// Initializes a new instance of with an injected HTTP client. /// The caller owns the client's lifetime; this service will not dispose it. /// /// The HTTP client to use for all requests. public BackupService(IPveHttpClient client) : base(client) { } // ------------------------------------------------------------------------- // 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)); return Invoke(session, client => { var response = client.PostAsync($"nodes/{Uri.EscapeDataString(node)}/vzdump", config) .GetAwaiter().GetResult(); return PveTaskResponse.Parse(response, node); }); } // ------------------------------------------------------------------------- // Backup jobs (scheduled) // ------------------------------------------------------------------------- /// /// Returns all scheduled backup jobs. /// public PveBackupJob[] GetBackupJobs(PveSession session) { if (session == null) throw new ArgumentNullException(nameof(session)); return Invoke(session, client => { 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)); return Invoke(session, client => { 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)); Invoke(session, client => { 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)); Invoke(session, client => { 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)); Invoke(session, client => { client.DeleteAsync($"cluster/backup/{Uri.EscapeDataString(id)}") .GetAwaiter().GetResult(); }); } // ------------------------------------------------------------------------- // Backup compliance info // ------------------------------------------------------------------------- /// /// Returns the list of guests not covered by any backup job. /// public List> GetNotBackedUp(PveSession session) { if (session == null) throw new ArgumentNullException(nameof(session)); return Invoke(session, client => { var response = client.GetAsync("cluster/backup-info/not-backed-up") .GetAwaiter().GetResult(); var data = JObject.Parse(response)["data"]; return JsonHelper.ToListOfDictionaries(data as JArray); }); } } }