Skip to content
This repository was archived by the owner on Sep 6, 2025. It is now read-only.

Commit 94538f0

Browse files
authored
New VPC Endpoint in API (#78)
* Implemented new VPC endpoint queries * Related VPC properties now available in: Droplets, DatabaseClusters, KubernetesClusters, LoadBalancers * Unit tests for VpcClient
1 parent 3066185 commit 94538f0

20 files changed

Lines changed: 427 additions & 4 deletions
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System.Collections.Generic;
2+
using DigitalOcean.API.Clients;
3+
using DigitalOcean.API.Http;
4+
using DigitalOcean.API.Models.Responses;
5+
using NSubstitute;
6+
using RestSharp;
7+
using Xunit;
8+
9+
namespace DigitalOcean.API.Tests.Clients {
10+
public class VpcClientTest {
11+
[Fact]
12+
public void CorrectRequestForGetAll() {
13+
var factory = Substitute.For<IConnection>();
14+
var client = new VpcClient(factory);
15+
16+
client.GetAll();
17+
18+
factory.Received().GetPaginated<Vpc>("vpcs", null, "vpcs");
19+
}
20+
21+
[Fact]
22+
public void CorrectRequestForCreate() {
23+
var factory = Substitute.For<IConnection>();
24+
var client = new VpcClient(factory);
25+
26+
var body = new Models.Requests.Vpc();
27+
client.Create(body);
28+
29+
factory.Received().ExecuteRequest<Vpc>("vpcs", null, body, "vpc", Method.POST);
30+
}
31+
32+
[Fact]
33+
public void CorrectRequestForGet() {
34+
var factory = Substitute.For<IConnection>();
35+
var client = new VpcClient(factory);
36+
37+
client.Get("abcdefg");
38+
39+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "abcdefg");
40+
factory.Received().ExecuteRequest<Vpc>("vpcs/{id}", parameters, null, "vpc");
41+
}
42+
43+
[Fact]
44+
public void CorrectRequestForDelete() {
45+
var factory = Substitute.For<IConnection>();
46+
var client = new VpcClient(factory);
47+
48+
client.Delete("abcdefg");
49+
50+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "abcdefg");
51+
factory.Received().ExecuteRaw("vpcs/{id}", parameters, null, Method.DELETE);
52+
}
53+
54+
[Fact]
55+
public void CorrectRequestForUpdate() {
56+
var factory = Substitute.For<IConnection>();
57+
var client = new VpcClient(factory);
58+
59+
var body = new Models.Requests.UpdateVpc();
60+
client.Update("abcdefg", body);
61+
62+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "abcdefg");
63+
factory.Received().ExecuteRequest<Vpc>("vpcs/{id}", parameters, body, "vpc", Method.PUT);
64+
}
65+
66+
[Fact]
67+
public void CorrectRequestForPartialUpdate() {
68+
var factory = Substitute.For<IConnection>();
69+
var client = new VpcClient(factory);
70+
71+
var body = new Models.Requests.UpdateVpc();
72+
client.PartialUpdate("abcdefg", body);
73+
74+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "abcdefg");
75+
factory.Received().ExecuteRequest<Vpc>("vpcs/{id}", parameters, body, "vpc", Method.PATCH);
76+
}
77+
78+
[Fact]
79+
public void CorrectRequestForListMembers() {
80+
var factory = Substitute.For<IConnection>();
81+
var client = new VpcClient(factory);
82+
83+
client.ListMembers("abcdefg");
84+
85+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "abcdefg");
86+
factory.Received().GetPaginated<VpcMember>("vpcs/{id}/members", parameters, "members");
87+
}
88+
}
89+
}

DigitalOcean.API/Clients/IDropletActionsClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public interface IDropletActionsClient {
7878

7979
/// <summary>
8080
/// Enable private networking on a droplet
81+
/// When VPC is enabled on your account, this will add the Droplet to your account's default VPC for the region.
8182
/// </summary>
8283
Task<Action> EnablePrivateNetworking(long dropletId);
8384

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System.Collections.Generic;
2+
using System.Threading.Tasks;
3+
using DigitalOcean.API.Models.Responses;
4+
5+
namespace DigitalOcean.API.Clients {
6+
public interface IVpcClient {
7+
/// <summary>
8+
/// To list all of the VPCs on your account.
9+
/// </summary>
10+
Task<IReadOnlyList<Vpc>> GetAll();
11+
12+
/// <summary>
13+
/// To create a VPC.
14+
/// </summary>
15+
Task<Vpc> Create(Models.Requests.Vpc vpc);
16+
17+
/// <summary>
18+
/// To show information about an existing VPC.
19+
/// </summary>
20+
Task<Vpc> Get(string vpcId);
21+
22+
/// <summary>
23+
/// To delete a VPC.
24+
/// The default VPC for a region can not be deleted.
25+
/// Additionally, a VPC can only be deleted if it does not contain any member resources.
26+
/// Attempting to delete a region's default VPC or a VPC that still has members will result in an error response.
27+
/// </summary>
28+
Task Delete(string vpcId);
29+
30+
/// <summary>
31+
/// To update information about a VPC.
32+
/// Currently, only the name and description attributes can be updated.
33+
/// Excluding an attribute will reset it to its default.
34+
/// </summary>
35+
Task<Vpc> Update(string vpcId, Models.Requests.UpdateVpc updateVpc);
36+
37+
/// <summary>
38+
/// To update a subset of information about a VPC.
39+
/// Currently, only the name and description attributes can be updated.
40+
/// </summary>
41+
Task<Vpc> PartialUpdate(string vpcId, Models.Requests.UpdateVpc updateVpc);
42+
43+
/// <summary>
44+
/// To list all of the resources that are members of a VPC.
45+
/// To only list resources of a specific type that are members of the VPC, included a resource_type query parameter.
46+
/// </summary>
47+
Task<IReadOnlyList<VpcMember>> ListMembers(string vpcId, string resourceType = null);
48+
}
49+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using DigitalOcean.API.Http;
5+
using DigitalOcean.API.Models.Responses;
6+
using RestSharp;
7+
8+
namespace DigitalOcean.API.Clients {
9+
public class VpcClient : IVpcClient {
10+
private readonly IConnection _connection;
11+
12+
public VpcClient(IConnection connection) {
13+
_connection = connection;
14+
}
15+
16+
/// <summary>
17+
/// To list all of the VPCs on your account.
18+
/// </summary>
19+
public Task<IReadOnlyList<Vpc>> GetAll() {
20+
return _connection.GetPaginated<Vpc>("vpcs", null, "vpcs");
21+
}
22+
23+
/// <summary>
24+
/// To create a VPC.
25+
/// </summary>
26+
public Task<Vpc> Create(Models.Requests.Vpc vpc) {
27+
return _connection.ExecuteRequest<Vpc>("vpcs", null, vpc, "vpc", Method.POST);
28+
}
29+
30+
/// <summary>
31+
/// To show information about an existing VPC.
32+
/// </summary>
33+
public Task<Vpc> Get(string vpcId) {
34+
var parameters = new List<Parameter> {
35+
new Parameter("id", vpcId, ParameterType.UrlSegment)
36+
};
37+
return _connection.ExecuteRequest<Vpc>("vpcs/{id}", parameters, null, "vpc");
38+
}
39+
40+
/// <summary>
41+
/// To delete a VPC.
42+
/// The default VPC for a region can not be deleted.
43+
/// Additionally, a VPC can only be deleted if it does not contain any member resources.
44+
/// Attempting to delete a region's default VPC or a VPC that still has members will result in an error response.
45+
/// </summary>
46+
public Task Delete(string vpcId) {
47+
var parameters = new List<Parameter> {
48+
new Parameter("id", vpcId, ParameterType.UrlSegment)
49+
};
50+
return _connection.ExecuteRaw("vpcs/{id}", parameters, null, Method.DELETE);
51+
}
52+
53+
/// <summary>
54+
/// To update information about a VPC.
55+
/// Currently, only the name and description attributes can be updated.
56+
/// Excluding an attribute will reset it to its default.
57+
/// </summary>
58+
public Task<Vpc> Update(string vpcId, Models.Requests.UpdateVpc updateVpc) {
59+
var parameters = new List<Parameter> {
60+
new Parameter("id", vpcId, ParameterType.UrlSegment)
61+
};
62+
return _connection.ExecuteRequest<Vpc>("vpcs/{id}", parameters, updateVpc, "vpc", Method.PUT);
63+
}
64+
65+
/// <summary>
66+
/// To update a subset of information about a VPC.
67+
/// Currently, only the name and description attributes can be updated.
68+
/// </summary>
69+
public Task<Vpc> PartialUpdate(string vpcId, Models.Requests.UpdateVpc updateVpc) {
70+
var parameters = new List<Parameter> {
71+
new Parameter("id", vpcId, ParameterType.UrlSegment)
72+
};
73+
return _connection.ExecuteRequest<Vpc>("vpcs/{id}", parameters, updateVpc, "vpc", Method.PATCH);
74+
}
75+
76+
/// <summary>
77+
/// To list all of the resources that are members of a VPC.
78+
/// To only list resources of a specific type that are members of the VPC, included a resource_type query parameter.
79+
/// </summary>
80+
public Task<IReadOnlyList<VpcMember>> ListMembers(string vpcId, string resourceType = null) {
81+
var parameters = new List<Parameter> {
82+
new Parameter("id", vpcId, ParameterType.UrlSegment)
83+
};
84+
if (!String.IsNullOrEmpty(resourceType)) {
85+
parameters.Add(new Parameter("resource_type", resourceType, ParameterType.QueryString));
86+
}
87+
return _connection.GetPaginated<VpcMember>("vpcs/{id}/members", parameters, "members");
88+
}
89+
}
90+
}

DigitalOcean.API/DigitalOceanClient.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public DigitalOceanClient(string token) {
4141
Volumes = new VolumesClient(_connection);
4242
VolumeActions = new VolumeActionsClient(_connection);
4343
BalanceClient = new BalanceClient(_connection);
44+
Vpc = new VpcClient(_connection);
4445
}
4546

4647
#region IDigitalOceanClient Members
@@ -75,6 +76,7 @@ public IRateLimit Rates {
7576
public IVolumesClient Volumes { get; private set; }
7677
public IVolumeActionsClient VolumeActions { get; private set; }
7778
public IBalanceClient BalanceClient { get; private set; }
79+
public IVpcClient Vpc { get; private set; }
7880

7981
#endregion
8082
}

DigitalOcean.API/IDigitalOceanClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public interface IDigitalOceanClient {
2929
IVolumesClient Volumes { get; }
3030
IVolumeActionsClient VolumeActions { get; }
3131
IBalanceClient BalanceClient { get; }
32+
IVpcClient Vpc { get; }
3233

3334
IRateLimit Rates { get; }
3435
}

DigitalOcean.API/Models/Requests/DatabaseBackup.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ public class DatabaseBackup {
4545
[JsonProperty("tags")]
4646
public List<string> Tags { get; set; }
4747

48+
/// <summary>
49+
/// A string specifying the UUID of the VPC to which the database cluster will be assigned.
50+
/// If excluded, the cluster will be assigned to your account's default VPC for the region.
51+
/// </summary>
52+
[JsonProperty("private_network_uuid")]
53+
public string PrivateNetworkUuid { get; set; }
54+
4855
/// <summary>
4956
/// An embedded object containing two attributes specifying the name of the original database cluster and the timestamp of the backup to restore (see below).
5057
/// </summary>

DigitalOcean.API/Models/Requests/DatabaseCluster.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,12 @@ public class DatabaseCluster {
4444
/// </summary>
4545
[JsonProperty("tags")]
4646
public List<string> Tags { get; set; }
47+
48+
/// <summary>
49+
/// A string specifying the UUID of the VPC to which the database cluster will be assigned.
50+
/// If excluded, the cluster will be assigned to your account's default VPC for the region.
51+
/// </summary>
52+
[JsonProperty("private_network_uuid")]
53+
public string PrivateNetworkUuid { get; set; }
4754
}
4855
}

DigitalOcean.API/Models/Requests/Droplet.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ public class Droplet {
5151
public bool? Ipv6 { get; set; }
5252

5353
/// <summary>
54-
/// A boolean indicating whether private networking is enabled for the Droplet. Private networking is currently only
55-
/// available in certain regions.
54+
/// A boolean indicating whether private networking is enabled.
55+
/// When VPC is enabled on an account, this will provision the Droplet inside of your account's default VPC for the region.
56+
/// Use the "vpc_uuid" attribute to specify a different VPC.
5657
/// </summary>
5758
[JsonProperty("private_networking")]
5859
public bool? PrivateNetworking { get; set; }
@@ -83,5 +84,12 @@ public class Droplet {
8384
/// </summary>
8485
[JsonProperty("volumes")]
8586
public List<string> Volumes { get; set; }
87+
88+
/// <summary>
89+
/// A string specifying the UUID of the VPC to which the Droplet will be assigned.
90+
/// If excluded, beginning on April 7th, 2020, the Droplet will be assigned to your account's default VPC for the region.
91+
/// </summary>
92+
[JsonProperty("vpc_uuid")]
93+
public string VpcUuid { get; set; }
8694
}
8795
}

DigitalOcean.API/Models/Requests/Droplets.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ public class Droplets {
5151
public bool? Ipv6 { get; set; }
5252

5353
/// <summary>
54-
/// A boolean indicating whether private networking is enabled for the Droplet. Private networking is currently only
55-
/// available in certain regions.
54+
/// A boolean indicating whether private networking is enabled.
55+
/// When VPC is enabled on an account, this will provision the Droplet inside of your account's default VPC for the region.
56+
/// Use the "vpc_uuid" attribute to specify a different VPC.
5657
/// </summary>
5758
[JsonProperty("private_networking")]
5859
public bool? PrivateNetworking { get; set; }
@@ -76,5 +77,12 @@ public class Droplets {
7677
/// </summary>
7778
[JsonProperty("tags")]
7879
public List<string> Tags { get; set; }
80+
81+
/// <summary>
82+
/// A string specifying the UUID of the VPC to which the Droplet will be assigned.
83+
/// If excluded, beginning on April 7th, 2020, the Droplet will be assigned to your account's default VPC for the region.
84+
/// </summary>
85+
[JsonProperty("vpc_uuid")]
86+
public string VpcUuid { get; set; }
7987
}
8088
}

0 commit comments

Comments
 (0)