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);
});
}
}
}