diff --git a/DigitalOcean.API/Clients/DropletsClient.cs b/DigitalOcean.API/Clients/DropletsClient.cs index 9369448..081ee1a 100644 --- a/DigitalOcean.API/Clients/DropletsClient.cs +++ b/DigitalOcean.API/Clients/DropletsClient.cs @@ -131,6 +131,34 @@ public Task DeleteByTag(string tagName) { return _connection.ExecuteRaw("droplets", parameters, null, Method.Delete); } + public Task GetDestroyResources(long dropletId) { + var parameters = new List { + new UrlSegmentParameter ("droplet_id", dropletId.ToString()) + }; + return _connection.ExecuteRequest("droplets/{droplet_id}/destroy_with_associated_resources", parameters); + } + + public Task Destroy(long dropletId, Models.Requests.DestroyResources resources) { + var parameters = new List { + new UrlSegmentParameter ("droplet_id", dropletId.ToString()) + }; + return _connection.ExecuteRaw("droplets/{droplet_id}/destroy_with_associated_resources/selective", parameters, resources, Method.Delete); + } + + public Task GetDestroyStatus(long dropletId) { + var parameters = new List { + new UrlSegmentParameter ("droplet_id", dropletId.ToString()) + }; + return _connection.ExecuteRequest("droplets/{droplet_id}/destroy_with_associated_resources/status", parameters); + } + + public Task RetryDestroy(long dropletId) { + var parameters = new List { + new UrlSegmentParameter ("droplet_id", dropletId.ToString()) + }; + return _connection.ExecuteRaw("droplets/{droplet_id}/destroy_with_associated_resources/retry", parameters, method: Method.Post); + } + /// /// To retrieve a list of any Droplets that are running on the same physical hardware. /// diff --git a/DigitalOcean.API/Clients/IDropletsClient.cs b/DigitalOcean.API/Clients/IDropletsClient.cs index 16a0061..cd46ff5 100644 --- a/DigitalOcean.API/Clients/IDropletsClient.cs +++ b/DigitalOcean.API/Clients/IDropletsClient.cs @@ -66,6 +66,32 @@ public interface IDropletsClient { /// Task DeleteByTag(string tagName); + /// + /// To list the associated billable resources that can be destroyed along with a Droplet. + /// The response will contain snapshots, volumes, and volume_snapshots keys. + /// Each will be set to an array of objects containing information about the associated resources. + /// + Task GetDestroyResources(long dropletId); + + /// + /// To destroy a Droplet along with a sub-set of its associated resources. + /// The body of the request should include reserved_ips, snapshots, volumes, or volume_snapshots keys each set to an array of IDs for the associated resources to be destroyed. + /// The IDs can be found by querying the Droplet's associated resources. Any associated resource not included in the request will remain and continue to accrue changes on your account. + /// Use the status endpoint to check on the success or failure of the destruction of the individual resources. + /// + Task Destroy(long dropletId, Models.Requests.DestroyResources resources); + + /// + /// To check on the status of a request to destroy a Droplet with its associated resources. + /// + Task GetDestroyStatus(long dropletId); + + /// + /// If the status of a request to destroy a Droplet with its associated resources reported any errors, it can be retried. + /// Only one destroy can be active at a time per Droplet. + /// + Task RetryDestroy(long dropletId); + /// /// To retrieve a list of any Droplets that are running on the same physical hardware. /// diff --git a/DigitalOcean.API/DigitalOcean.API.csproj b/DigitalOcean.API/DigitalOcean.API.csproj index 05aa6c2..d6bcf74 100644 --- a/DigitalOcean.API/DigitalOcean.API.csproj +++ b/DigitalOcean.API/DigitalOcean.API.csproj @@ -3,6 +3,7 @@ net6.0 true vevix + 5.3.0-rc3 5.3.0-rc2 .NET wrapper of the DigitalOcean API 2019 diff --git a/DigitalOcean.API/Models/Requests/DestroyResources.cs b/DigitalOcean.API/Models/Requests/DestroyResources.cs new file mode 100644 index 0000000..31cfd1d --- /dev/null +++ b/DigitalOcean.API/Models/Requests/DestroyResources.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace DigitalOcean.API.Models.Requests; + +public class DestroyResources { + + // DEPRECATED + //[JsonProperty("floating_ips")] + //public List FloatingIps { get; set; } + + /// + /// An array of unique identifiers for the reserved IPs to be scheduled for deletion. + /// + [JsonProperty("reserved_ips")] + public List ReservedIps { get; set; } + + /// + /// An array of unique identifiers for the snapshots to be scheduled for deletion. + /// + [JsonProperty("snapshots")] + public List Snapshots { get; set; } + + /// + /// An array of unique identifiers for the volumes to be scheduled for deletion. + /// + [JsonProperty("volumes")] + public List Volumes { get; set; } + + /// + /// An array of unique identifiers for the volume snapshots to be scheduled for deletion. + /// + [JsonProperty("volume_snapshots")] + public List VolumeSnapshots { get; set; } +} diff --git a/DigitalOcean.API/Models/Responses/DestroyResources.cs b/DigitalOcean.API/Models/Responses/DestroyResources.cs new file mode 100644 index 0000000..a95ba55 --- /dev/null +++ b/DigitalOcean.API/Models/Responses/DestroyResources.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace DigitalOcean.API.Models.Responses; + +public class DestroyResources { + + [JsonProperty("floating_ips")] + public List FloatingIps { get; set; } + + [JsonProperty("reserved_ips")] + public List ReservedIps { get; set; } + + [JsonProperty("snapshots")] + public List Snapshots { get; set; } + + [JsonProperty("volumes")] + public List Volumes { get; set; } + + [JsonProperty("volume_snapshots")] + public List VolumeSnapshots { get; set; } +} + +public class DestroyResource { + /// + /// The unique identifier for the resource associated with the Droplet. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// The name of the resource associated with the Droplet. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// The cost of the resource in USD per month if the resource is retained after the Droplet is destroyed. + /// + [JsonProperty("cost")] + public string Cost { get; set; } +} diff --git a/DigitalOcean.API/Models/Responses/DestroyStatus.cs b/DigitalOcean.API/Models/Responses/DestroyStatus.cs new file mode 100644 index 0000000..2ca2918 --- /dev/null +++ b/DigitalOcean.API/Models/Responses/DestroyStatus.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace DigitalOcean.API.Models.Responses; + +public class DestroyStatus { + + /// + /// An object containing information about a resource scheduled for deletion. + /// + [JsonProperty("droplet")] + public DestroyItemStatus Droplet { get; set; } + + /// + /// An object containing additional information about resource related to a Droplet requested to be destroyed. + /// + [JsonProperty("resources")] + public DestroyStatusResources Resources { get; set; } + + /// + /// A time value given in ISO8601 combined date and time format indicating when the requested action was completed. + /// + [JsonProperty("completed_at")] + public string CompletedAt { get; set; } + + /// + /// A count of the associated resources that failed to be destroyed, if any. + /// + [JsonProperty("failures")] + public int Failures { get; set; } +} + +public class DestroyItemStatus { + + /// + /// The unique identifier for the resource scheduled for deletion. + /// + [JsonProperty("id")] + public string Id { get; set; } + + /// + /// The name of the resource scheduled for deletion. + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// A time value given in ISO8601 combined date and time format indicating when the resource was destroyed if the request was successful. + /// + [JsonProperty("destroyed_at")] + public string DestroyedAt { get; set; } + + /// + /// A string indicating that the resource was not successfully destroyed and providing additional information. + /// + [JsonProperty("error_message")] + public string ErrorMessage { get; set; } +} + +public class DestroyStatusResources { + + [JsonProperty("floating_ips")] + public List FloatingIps { get; set; } + + [JsonProperty("reserved_ips")] + public List ReservedIps { get; set; } + + [JsonProperty("snapshots")] + public List Snapshots { get; set; } + + [JsonProperty("volumes")] + public List Volumes { get; set; } + + [JsonProperty("volume_snapshots")] + public List VolumeSnapshots { get; set; } +}