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

Commit 8a74e1a

Browse files
authored
Added ContainerRegistry client. (#93)
1 parent 15918b9 commit 8a74e1a

19 files changed

Lines changed: 824 additions & 4 deletions

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,15 @@ charset = utf-8
99
[*.cs]
1010
indent_size = 4
1111
indent_style = space
12+
csharp_new_line_before_open_brace = none
13+
14+
# Private members with underscore.
15+
dotnet_naming_rule.private_members_with_underscore.symbols = private_fields
16+
dotnet_naming_rule.private_members_with_underscore.style = prefix_underscore
17+
dotnet_naming_rule.private_members_with_underscore.severity = error
18+
19+
dotnet_naming_symbols.private_fields.applicable_kinds = field
20+
dotnet_naming_symbols.private_fields.applicable_accessibilities = private
21+
22+
dotnet_naming_style.prefix_underscore.capitalization = camel_case
23+
dotnet_naming_style.prefix_underscore.required_prefix = _
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
using DigitalOcean.API.Clients;
2+
using DigitalOcean.API.Http;
3+
using DigitalOcean.API.Models.Requests;
4+
using DigitalOcean.API.Models.Responses;
5+
using Newtonsoft.Json.Linq;
6+
using NSubstitute;
7+
using RestSharp;
8+
using System;
9+
using System.Collections.Generic;
10+
using System.Linq;
11+
using System.Text;
12+
using System.Threading.Tasks;
13+
using Xunit;
14+
15+
namespace DigitalOcean.API.Tests.Clients {
16+
public class ContainerRegistryClientTest {
17+
[Fact]
18+
public void CorrectRequestForConfigure() {
19+
var factory = Substitute.For<IConnection>();
20+
var client = new ContainerRegistryClient(factory);
21+
22+
var data = new Models.Requests.ContainerRegistryConfigure();
23+
client.Configure(data);
24+
factory.Received().ExecuteRequest<Models.Responses.ContainerRegistryConfigure>("registry", null, data, null, Method.POST);
25+
}
26+
27+
[Fact]
28+
public void CorrectRequestForGet() {
29+
var factory = Substitute.For<IConnection>();
30+
var client = new ContainerRegistryClient(factory);
31+
32+
client.Get();
33+
factory.Received().ExecuteRequest<ContainerRegistry>("registry", null, null, "registry");
34+
}
35+
36+
[Fact]
37+
public void CorrectRequestForGetDockerCredentials() {
38+
var factory = Substitute.For<IConnection>();
39+
var client = new ContainerRegistryClient(factory);
40+
41+
client.GetDockerCredentials();
42+
factory.Received().ExecuteRequest<JObject>("registry/docker-credentials", null, null, "auths");
43+
}
44+
45+
[Fact]
46+
public void CorrectRequestForGetSubscription() {
47+
var factory = Substitute.For<IConnection>();
48+
var client = new ContainerRegistryClient(factory);
49+
50+
client.GetSubscription();
51+
factory.Received().ExecuteRequest<Subscription>("registry/subscription", null, null, "subscription");
52+
}
53+
54+
[Fact]
55+
public void CorrectRequestForUpdateSubscriptionTier() {
56+
var factory = Substitute.For<IConnection>();
57+
var client = new ContainerRegistryClient(factory);
58+
59+
var data = new UpdateSubscriptionTier();
60+
client.UpdateSubscriptionTier(data);
61+
factory.Received().ExecuteRequest<SubscriptionTierUpdate>("registry/subscription", null, data, "subscription", Method.POST);
62+
}
63+
64+
[Fact]
65+
public void CorrectRequestForDelete() {
66+
var factory = Substitute.For<IConnection>();
67+
var client = new ContainerRegistryClient(factory);
68+
69+
client.Delete();
70+
factory.Received().ExecuteRaw("registry", null, null, Method.DELETE);
71+
}
72+
73+
[Fact]
74+
public void CorrectRequestForValidateName() {
75+
var factory = Substitute.For<IConnection>();
76+
var client = new ContainerRegistryClient(factory);
77+
78+
var data = new ContainerRegistryValidateName();
79+
client.ValidateName(data);
80+
factory.Received().ExecuteRaw("registry/validate-name", null, data, Method.POST);
81+
}
82+
83+
[Fact]
84+
public void CorrectRequestForGetAllRepositories() {
85+
var factory = Substitute.For<IConnection>();
86+
var client = new ContainerRegistryClient(factory);
87+
88+
client.GetAllRepositories("registryName");
89+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName");
90+
factory.Received().GetPaginated<ContainerRegistryRepository>("registry/{registryName}/repositories", parameters, "repositories");
91+
}
92+
93+
[Fact]
94+
public void CorrectRequestForGetAllRepositoryTags() {
95+
var factory = Substitute.For<IConnection>();
96+
var client = new ContainerRegistryClient(factory);
97+
98+
client.GetAllRepositoryTags("registryName", "repositoryName");
99+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName" && (string)list[1].Value == "repositoryName");
100+
factory.Received().GetPaginated<ContainerRegistryTag>("registry/{registryName}/repositories/{repositoryName}/tags", parameters, "tags");
101+
}
102+
103+
[Fact]
104+
public void CorrectRequestForDeleteRepositoryTag() {
105+
var factory = Substitute.For<IConnection>();
106+
var client = new ContainerRegistryClient(factory);
107+
108+
client.DeleteRepositoryTag("registryName", "repositoryName", "tag");
109+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName" && (string)list[1].Value == "repositoryName" && (string)list[2].Value == "tag");
110+
factory.Received().ExecuteRaw("registry/{registryName}/repositories/{repositoryName}/tags/{tag}", parameters, null, Method.DELETE);
111+
}
112+
113+
[Fact]
114+
public void CorrectRequestForDeleteRepositoryManifest() {
115+
var factory = Substitute.For<IConnection>();
116+
var client = new ContainerRegistryClient(factory);
117+
118+
client.DeleteRepositoryManifest("registryName", "repositoryName", "manifestDigest");
119+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName" && (string)list[1].Value == "repositoryName" && (string)list[2].Value == "manifestDigest");
120+
factory.Received().ExecuteRaw("registry/{registryName}/repositories/{repositoryName}/digests/{manifestDigest}", parameters, null, Method.DELETE);
121+
}
122+
123+
[Fact]
124+
public void CorrectRequestForStartGarbageCollection() {
125+
var factory = Substitute.For<IConnection>();
126+
var client = new ContainerRegistryClient(factory);
127+
128+
client.StartGarbageCollection("registryName");
129+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName");
130+
factory.Received().ExecuteRequest<GarbageCollection>("registry/{registryName}/garbage-collection", parameters, null, "garbage_collections", Method.POST);
131+
}
132+
133+
[Fact]
134+
public void CorrectRequestForGetActiveGarbageCollection() {
135+
var factory = Substitute.For<IConnection>();
136+
var client = new ContainerRegistryClient(factory);
137+
138+
client.GetActiveGarbageCollection("registryName");
139+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName");
140+
factory.Received().ExecuteRequest<GarbageCollection>("registry/{registryName}/garbage-collection", parameters, null, "garbage_collections");
141+
}
142+
143+
[Fact]
144+
public void CorrectRequestForGetAllGarbageCollections() {
145+
var factory = Substitute.For<IConnection>();
146+
var client = new ContainerRegistryClient(factory);
147+
148+
client.GetAllGarbageCollections("registryName");
149+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName");
150+
factory.Received().GetPaginated<GarbageCollection>("registry/{registryName}/garbage-collections", parameters, "garbage_collections");
151+
}
152+
153+
[Fact]
154+
public void CorrectRequestForUpdateGarbageCollection() {
155+
var factory = Substitute.For<IConnection>();
156+
var client = new ContainerRegistryClient(factory);
157+
158+
var data = new UpdateGarbageCollection();
159+
client.UpdateGarbageCollection("registryName", "uuid", data);
160+
var parameters = Arg.Is<List<Parameter>>(list => (string)list[0].Value == "registryName" && (string)list[1].Value == "uuid");
161+
factory.Received().ExecuteRequest<GarbageCollection>("registry/{registryName}/garbage-collection/{uuid}", parameters, data, "garbage_collections", Method.PUT);
162+
}
163+
164+
[Fact]
165+
public void CorrectRequestForGetAllSubscriptionTiers() {
166+
var factory = Substitute.For<IConnection>();
167+
var client = new ContainerRegistryClient(factory);
168+
169+
client.GetAllSubscriptionTiers();
170+
factory.Received().GetPaginated<SubscriptionTier>("registry/options", null, "subscription_tiers");
171+
}
172+
}
173+
}

DigitalOcean.API.sln

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 15
4-
VisualStudioVersion = 15.0.25920.0
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.30104.148
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalOcean.API", "DigitalOcean.API\DigitalOcean.API.csproj", "{D47040D1-8B8E-4181-BE29-E767CE098DF1}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalOcean.API", "DigitalOcean.API\DigitalOcean.API.csproj", "{D47040D1-8B8E-4181-BE29-E767CE098DF1}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalOcean.API.Tests", "DigitalOcean.API.Tests\DigitalOcean.API.Tests.csproj", "{2AB266F6-A06B-4F22-AFE9-9545DB05227E}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalOcean.API.Tests", "DigitalOcean.API.Tests\DigitalOcean.API.Tests.csproj", "{2AB266F6-A06B-4F22-AFE9-9545DB05227E}"
9+
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4A364A11-7B2A-40A3-83FB-4FBAE2A9E684}"
11+
ProjectSection(SolutionItems) = preProject
12+
.editorconfig = .editorconfig
13+
.gitattributes = .gitattributes
14+
.gitignore = .gitignore
15+
CHANGELOG.md = CHANGELOG.md
16+
LICENSE.md = LICENSE.md
17+
omnisharp.json = omnisharp.json
18+
README.md = README.md
19+
EndProjectSection
920
EndProject
1021
Global
1122
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -25,4 +36,7 @@ Global
2536
GlobalSection(SolutionProperties) = preSolution
2637
HideSolutionNode = FALSE
2738
EndGlobalSection
39+
GlobalSection(ExtensibilityGlobals) = postSolution
40+
SolutionGuid = {E42AA15E-219D-489D-9E59-9DFC049ED67C}
41+
EndGlobalSection
2842
EndGlobal
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
using DigitalOcean.API.Http;
2+
using DigitalOcean.API.Models.Requests;
3+
using DigitalOcean.API.Models.Responses;
4+
using Newtonsoft.Json.Linq;
5+
using RestSharp;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
12+
namespace DigitalOcean.API.Clients {
13+
public class ContainerRegistryClient : IContainerRegistryClient {
14+
private readonly IConnection _connection;
15+
16+
public ContainerRegistryClient(IConnection connection) {
17+
_connection = connection;
18+
}
19+
20+
/// <summary>
21+
/// Configure your container registry.
22+
/// </summary>
23+
public Task<Models.Responses.ContainerRegistryConfigure> Configure(Models.Requests.ContainerRegistryConfigure containerRegistryConfigure) {
24+
return _connection.ExecuteRequest<Models.Responses.ContainerRegistryConfigure>("registry", null, containerRegistryConfigure, null, Method.POST);
25+
}
26+
27+
/// <summary>
28+
/// Gets information for youre container registry.
29+
/// </summary>
30+
public Task<ContainerRegistry> Get() {
31+
return _connection.ExecuteRequest<ContainerRegistry>("registry", null, null, "registry");
32+
}
33+
34+
/// <summary>
35+
/// Gets docker credentials for your container registry.
36+
/// </summary>
37+
public Task<JObject> GetDockerCredentials() {
38+
return _connection.ExecuteRequest<JObject>("registry/docker-credentials", null, null, "auths");
39+
}
40+
41+
/// <summary>
42+
/// Gets your subscription information.
43+
/// </summary>
44+
public Task<Subscription> GetSubscription() {
45+
return _connection.ExecuteRequest<Subscription>("registry/subscription", null, null, "subscription");
46+
}
47+
48+
/// <summary>
49+
/// Updates your subscription tier.
50+
/// </summary>
51+
public Task<SubscriptionTierUpdate> UpdateSubscriptionTier(UpdateSubscriptionTier updateSubscriptionTier) {
52+
return _connection.ExecuteRequest<SubscriptionTierUpdate>("registry/subscription", null, updateSubscriptionTier, "subscription", Method.POST);
53+
}
54+
55+
/// <summary>
56+
/// Deletes your container registry.
57+
/// </summary>
58+
public Task Delete() {
59+
return _connection.ExecuteRaw("registry", null, null, Method.DELETE);
60+
}
61+
62+
/// <summary>
63+
/// Validates a container registry name.
64+
/// </summary>
65+
public Task ValidateName(ContainerRegistryValidateName containerRegistryValidateName) {
66+
return _connection.ExecuteRaw("registry/validate-name", null, containerRegistryValidateName, Method.POST);
67+
}
68+
69+
/// <summary>
70+
/// Gets all of your container registry repositories.
71+
/// </summary>
72+
public Task<IReadOnlyList<ContainerRegistryRepository>> GetAllRepositories(string registryName) {
73+
var parameters = new List<Parameter> {
74+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment)
75+
};
76+
77+
return _connection.GetPaginated<ContainerRegistryRepository>($"registry/{{{nameof(registryName)}}}/repositories", parameters, "repositories");
78+
}
79+
80+
/// <summary>
81+
/// Gets all of your container registry repository tags.
82+
/// </summary>
83+
public Task<IReadOnlyList<ContainerRegistryTag>> GetAllRepositoryTags(string registryName, string repositoryName) {
84+
var parameters = new List<Parameter> {
85+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment),
86+
new Parameter(nameof(repositoryName), repositoryName, ParameterType.UrlSegment),
87+
};
88+
89+
return _connection.GetPaginated<ContainerRegistryTag>($"registry/{{{nameof(registryName)}}}/repositories/{{{nameof(repositoryName)}}}/tags", parameters, "tags");
90+
}
91+
92+
/// <summary>
93+
/// Deletes a container registry repository tag.
94+
/// </summary>
95+
public Task DeleteRepositoryTag(string registryName, string repositoryName, string tag) {
96+
var parameters = new List<Parameter> {
97+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment),
98+
new Parameter(nameof(repositoryName), repositoryName, ParameterType.UrlSegment),
99+
new Parameter(nameof(tag), tag, ParameterType.UrlSegment),
100+
};
101+
102+
return _connection.ExecuteRaw($"registry/{{{nameof(registryName)}}}/repositories/{{{nameof(repositoryName)}}}/tags/{{{nameof(tag)}}}", parameters, null, Method.DELETE);
103+
}
104+
105+
/// <summary>
106+
/// Deletes a container registry repository manifest.
107+
/// </summary>
108+
public Task DeleteRepositoryManifest(string registryName, string repositoryName, string manifestDigest) {
109+
var parameters = new List<Parameter> {
110+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment),
111+
new Parameter(nameof(repositoryName), repositoryName, ParameterType.UrlSegment),
112+
new Parameter(nameof(manifestDigest), manifestDigest, ParameterType.UrlSegment),
113+
};
114+
115+
return _connection.ExecuteRaw($"registry/{{{nameof(registryName)}}}/repositories/{{{nameof(repositoryName)}}}/digests/{{{nameof(manifestDigest)}}}", parameters, null, Method.DELETE);
116+
}
117+
118+
/// <summary>
119+
/// Starts your container registry garbage collection.
120+
/// </summary>
121+
public Task<GarbageCollection> StartGarbageCollection(string registryName) {
122+
var parameters = new List<Parameter> {
123+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment),
124+
};
125+
126+
return _connection.ExecuteRequest<GarbageCollection>($"registry/{{{nameof(registryName)}}}/garbage-collection", parameters, null, "garbage_collections", Method.POST);
127+
}
128+
129+
/// <summary>
130+
/// Gets your active container registry garbage collection.
131+
/// </summary>
132+
public Task<GarbageCollection> GetActiveGarbageCollection(string registryName) {
133+
var parameters = new List<Parameter> {
134+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment),
135+
};
136+
137+
return _connection.ExecuteRequest<GarbageCollection>($"registry/{{{nameof(registryName)}}}/garbage-collection", parameters, null, "garbage_collections");
138+
}
139+
140+
/// <summary>
141+
/// Gets all your container registry garbage collections.
142+
/// </summary>
143+
public Task<IReadOnlyList<GarbageCollection>> GetAllGarbageCollections(string registryName) {
144+
var parameters = new List<Parameter> {
145+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment),
146+
};
147+
148+
return _connection.GetPaginated<GarbageCollection>($"registry/{{{nameof(registryName)}}}/garbage-collections", parameters, "garbage_collections");
149+
}
150+
151+
/// <summary>
152+
/// Updates a container registry garbage collection.
153+
/// </summary>
154+
public Task<GarbageCollection> UpdateGarbageCollection(string registryName, string uuid, UpdateGarbageCollection updateGarbageCollection) {
155+
var parameters = new List<Parameter> {
156+
new Parameter(nameof(registryName), registryName, ParameterType.UrlSegment),
157+
new Parameter(nameof(uuid), uuid, ParameterType.UrlSegment),
158+
};
159+
160+
return _connection.ExecuteRequest<GarbageCollection>($"registry/{{{nameof(registryName)}}}/garbage-collection/{{{nameof(uuid)}}}", parameters, updateGarbageCollection, "garbage_collections", Method.PUT);
161+
}
162+
163+
/// <summary>
164+
/// Gets all your available subscription tiers.
165+
/// </summary>
166+
public Task<IReadOnlyList<SubscriptionTier>> GetAllSubscriptionTiers() {
167+
return _connection.GetPaginated<SubscriptionTier>($"registry/options", null, "subscription_tiers");
168+
}
169+
}
170+
}

0 commit comments

Comments
 (0)