Skip to content

Commit 067ee4d

Browse files
committed
Merge pull request #592 from carolynvs/server-metadata
Support Server Metadata
2 parents 26ccd15 + d6dc7ff commit 067ee4d

14 files changed

Lines changed: 511 additions & 23 deletions

src/corelib/Compute/v2_1/ComputeService.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,30 @@ public ComputeService(IAuthenticationProvider authenticationProvider, string reg
3636
return _computeApi.GetServerAsync<Server>(serverId, cancellationToken);
3737
}
3838

39+
/// <inheritdoc cref="ComputeApi.GetServerMetadataAsync{T}" />
40+
public Task<ServerMetadata> GetServerMetadataAsync(Identifier serverId, CancellationToken cancellationToken = default(CancellationToken))
41+
{
42+
return _computeApi.GetServerMetadataAsync<ServerMetadata>(serverId, cancellationToken);
43+
}
44+
45+
/// <inheritdoc cref="ComputeApi.GetServerMetadataItemAsync" />
46+
public Task<string> GetServerMetadataItemAsync(Identifier serverId, string key, CancellationToken cancellationToken = default(CancellationToken))
47+
{
48+
return _computeApi.GetServerMetadataItemAsync(serverId, key, cancellationToken);
49+
}
50+
3951
/// <inheritdoc cref="ComputeApi.CreateServerAsync{T}" />
4052
public Task<Server> CreateServerAsync(ServerCreateDefinition server, CancellationToken cancellationToken = default(CancellationToken))
4153
{
4254
return _computeApi.CreateServerAsync<Server>(server, cancellationToken);
4355
}
4456

57+
/// <inheritdoc cref="ComputeApi.CreateServerMetadataAsync" />
58+
public Task CreateServerMetadataAsync(Identifier serverId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
59+
{
60+
return _computeApi.CreateServerMetadataAsync(serverId, key, value, cancellationToken);
61+
}
62+
4563
/// <inheritdoc cref="ComputeApi.WaitForServerStatusAsync{TServer,TStatus}(string,TStatus,TimeSpan?,TimeSpan?,IProgress{bool},CancellationToken)" />
4664
public Task<Server> WaitForServerStatusAsync(Identifier serverId, ServerStatus status, TimeSpan? refreshDelay = null, TimeSpan? timeout = null, IProgress<bool> progress = null, CancellationToken cancellationToken = default(CancellationToken))
4765
{
@@ -72,12 +90,25 @@ public ComputeService(IAuthenticationProvider authenticationProvider, string reg
7290
return _computeApi.UpdateServerAsync<Server>(serverid, server, cancellationToken);
7391
}
7492

93+
/// <inheritdoc cref="ComputeApi.UpdateServerMetadataAsync{T}" />
94+
public Task<ServerMetadata> UpdateServerMetadataAsync(Identifier serverId, ServerMetadata metadata, bool overwrite = false, CancellationToken cancellationToken = default(CancellationToken))
95+
{
96+
return _computeApi.UpdateServerMetadataAsync<ServerMetadata>(serverId, metadata, overwrite, cancellationToken);
97+
}
98+
7599
/// <inheritdoc cref="ComputeApi.DeleteServerAsync" />
76100
public Task DeleteServerAsync(Identifier serverId, CancellationToken cancellationToken = default(CancellationToken))
77101
{
78102
return _computeApi.DeleteServerAsync(serverId, cancellationToken);
79103
}
80104

105+
/// <inheritdoc cref="ComputeApi.DeleteServerMetadataAsync" />
106+
public Task DeleteServerMetadataAsync(Identifier serverId, string key, CancellationToken cancellationToken = default(CancellationToken))
107+
{
108+
return _computeApi.DeleteServerMetadataAsync(serverId, key, cancellationToken);
109+
}
110+
111+
81112
/// <inheritdoc cref="ComputeApi.WaitUntilServerIsDeletedAsync{TServer,TStatus}" />
82113
public Task WaitUntilServerIsDeletedAsync(Identifier serverId, TimeSpan? refreshDelay = null, TimeSpan? timeout = null, IProgress<bool> progress = null, CancellationToken cancellationToken = default(CancellationToken))
83114
{
@@ -235,10 +266,10 @@ public ComputeService(IAuthenticationProvider authenticationProvider, string reg
235266
return _computeApi.WaitForImageStatusAsync<Image, ImageStatus>(imageId, status, refreshDelay, timeout, progress, cancellationToken);
236267
}
237268

238-
/// <inheritdoc cref="ComputeApi.CreateImagMetadataAsync" />
239-
public Task CreateImagMetadataAsync(Identifier imageId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
269+
/// <inheritdoc cref="ComputeApi.CreateImageMetadataAsync" />
270+
public Task CreateImageMetadataAsync(Identifier imageId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
240271
{
241-
return _computeApi.CreateImagMetadataAsync(imageId, key, value, cancellationToken);
272+
return _computeApi.CreateImageMetadataAsync(imageId, key, value, cancellationToken);
242273
}
243274

244275
/// <inheritdoc cref="ComputeApi.ListImageSummariesAsync{TPage}" />

src/corelib/Compute/v2_1/ComputeServiceExtensions.cs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,30 @@ public static Server GetServer(this ComputeService service, Identifier serverId)
1818
return service.GetServerAsync(serverId).ForceSynchronous();
1919
}
2020

21+
/// <inheritdoc cref="ComputeService.GetServerAsync" />
22+
public static ServerMetadata GetServerMetadata(this ComputeService service, Identifier serverId)
23+
{
24+
return service.GetServerMetadataAsync(serverId).ForceSynchronous();
25+
}
26+
27+
/// <inheritdoc cref="ComputeService.GetServerMetadataItemAsync" />
28+
public static string GetServerMetadataItem(this ComputeService service, Identifier serverId, string key)
29+
{
30+
return service.GetServerMetadataItemAsync(serverId, key).ForceSynchronous();
31+
}
32+
2133
/// <inheritdoc cref="ComputeService.CreateServerAsync" />
2234
public static Server CreateServer(this ComputeService service, ServerCreateDefinition server)
2335
{
2436
return service.CreateServerAsync(server).ForceSynchronous();
2537
}
2638

39+
/// <inheritdoc cref="ComputeService.CreateServerMetadataAsync" />
40+
public static void CreateServerMetadata(this ComputeService service, Identifier serverId, string key, string value)
41+
{
42+
service.CreateServerMetadataAsync(serverId, key, value).ForceSynchronous();
43+
}
44+
2745
/// <inheritdoc cref="ComputeService.WaitForServerStatusAsync(Identifier,ServerStatus,TimeSpan?,TimeSpan?,IProgress{bool},System.Threading.CancellationToken)" />
2846
public static Server WaitForServerStatus(this ComputeService service, Identifier serverId, ServerStatus status, TimeSpan? refreshDelay = null, TimeSpan? timeout = null, IProgress<bool> progress = null)
2947
{
@@ -54,12 +72,24 @@ public static Server UpdateServer(this ComputeService service, Identifier server
5472
return service.UpdateServerAsync(serverid, server).ForceSynchronous();
5573
}
5674

75+
/// <inheritdoc cref="ComputeService.UpdateServerMetadataAsync" />
76+
public static ServerMetadata UpdateServerMetadata(this ComputeService service, Identifier serverId, ServerMetadata metadata, bool overwrite = false)
77+
{
78+
return service.UpdateServerMetadataAsync(serverId, metadata, overwrite).ForceSynchronous();
79+
}
80+
5781
/// <inheritdoc cref="ComputeService.DeleteServerAsync" />
5882
public static void DeleteServer(this ComputeService service, Identifier serverId)
5983
{
6084
service.DeleteServerAsync(serverId).ForceSynchronous();
6185
}
6286

87+
/// <inheritdoc cref="ComputeService.DeleteServerMetadataAsync" />
88+
public static void DeleteServerMetadata(this ComputeService service, Identifier serverId, string key)
89+
{
90+
service.DeleteServerMetadataAsync(serverId, key).ForceSynchronous();
91+
}
92+
6393
/// <inheritdoc cref="ComputeService.WaitUntilServerIsDeletedAsync" />
6494
public static void WaitUntilServerIsDeleted(this ComputeService service, Identifier serverId, TimeSpan? refreshDelay = null, TimeSpan? timeout = null, IProgress<bool> progress = null)
6595
{
@@ -214,10 +244,10 @@ public static void WaitForImageStatus(this ComputeService service, Identifier im
214244
service.WaitForImageStatusAsync(imageId, status, refreshDelay, timeout, progress).ForceSynchronous();
215245
}
216246

217-
/// <inheritdoc cref="ComputeService.CreateImagMetadataAsync" />
218-
public static void CreateImagMetadata(this ComputeService service, Identifier imageId, string key, string value)
247+
/// <inheritdoc cref="ComputeService.CreateImageMetadataAsync" />
248+
public static void CreateImageMetadata(this ComputeService service, Identifier imageId, string key, string value)
219249
{
220-
service.CreateImagMetadataAsync(imageId, key, value).ForceSynchronous();
250+
service.CreateImageMetadataAsync(imageId, key, value).ForceSynchronous();
221251
}
222252

223253
/// <inheritdoc cref="ComputeService.ListImageSummariesAsync" />

src/corelib/Compute/v2_1/ImageMetadata.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,36 +32,36 @@ protected internal void SetParent(ImageReference parent)
3232

3333
void IChildResource.SetParent(string parentId)
3434
{
35-
SetParent(new Image {Id = parentId});
35+
SetParent(new ImageReference { Id = parentId});
3636
}
3737

3838
void IChildResource.SetParent(object parent)
3939
{
40-
SetParent((Image)parent);
40+
SetParent((ImageReference)parent);
4141
}
4242

4343
/// <summary />
44-
protected void AssertImageIsSet([CallerMemberName]string callerName = "")
44+
protected void AssertParentIsSet([CallerMemberName]string callerName = "")
4545
{
4646
if (Image != null)
4747
return;
4848

49-
throw new InvalidOperationException(string.Format($"{callerName} can only be used on instances which were constructed by the ComputeServer. Use ComputeService.{callerName} instead."));
49+
throw new InvalidOperationException(string.Format($"{callerName} can only be used on instances which were constructed by the ComputeService. Use ComputeService.{callerName} instead."));
5050
}
5151

5252
/// <summary />
5353
public async Task CreateAsync(string key, string value, CancellationToken cancellationToken = default(CancellationToken))
5454
{
55-
AssertImageIsSet();
55+
AssertParentIsSet();
5656
var compute = this.GetOwnerOrThrow<ComputeApi>();
57-
await compute.CreateImagMetadataAsync(Image.Id, key, value, cancellationToken);
57+
await compute.CreateImageMetadataAsync(Image.Id, key, value, cancellationToken);
5858
this[key] = value;
5959
}
6060

6161
/// <summary />
6262
public async Task UpdateAsync(bool overwrite = false, CancellationToken cancellationToken = default(CancellationToken))
6363
{
64-
AssertImageIsSet();
64+
AssertParentIsSet();
6565
var compute = this.GetOwnerOrThrow<ComputeApi>();
6666
var results = await compute.UpdateImageMetadataAsync<ImageMetadata>(Image.Id, this, overwrite, cancellationToken);
6767
Clear();
@@ -77,7 +77,7 @@ protected void AssertImageIsSet([CallerMemberName]string callerName = "")
7777
if (!ContainsKey(key))
7878
return;
7979

80-
AssertImageIsSet();
80+
AssertParentIsSet();
8181
var compute = this.GetOwnerOrThrow<ComputeApi>();
8282
await compute.DeleteImageMetadataAsync(Image.Id, key, cancellationToken);
8383
Remove(key);

src/corelib/Compute/v2_1/Serialization/ComputeApi.cs

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,40 @@ protected ComputeApi(IServiceType serviceType, IAuthenticationProvider authentic
8282
return Endpoint.PrepareGetResourceRequest($"servers/{serverId}", cancellationToken);
8383
}
8484

85+
/// <summary />
86+
public virtual async Task<T> GetServerMetadataAsync<T>(string serverId, CancellationToken cancellationToken = default(CancellationToken))
87+
where T : IChildResource
88+
{
89+
return await BuildGetServerMetadataRequest(serverId, cancellationToken)
90+
.SendAsync()
91+
.ReceiveJson<T>()
92+
.PropogateOwner(this)
93+
.SetParent(serverId);
94+
}
95+
96+
/// <summary />
97+
public virtual Task<PreparedRequest> BuildGetServerMetadataRequest(string serverId, CancellationToken cancellationToken = default(CancellationToken))
98+
{
99+
return Endpoint.PrepareGetResourceRequest($"servers/{serverId}/metadata", cancellationToken);
100+
}
101+
102+
/// <summary />
103+
public virtual async Task<string> GetServerMetadataItemAsync(string serverId, string key, CancellationToken cancellationToken = default(CancellationToken))
104+
{
105+
dynamic result = await BuildGetServerMetadataItemRequest(serverId, key, cancellationToken)
106+
.SendAsync()
107+
.ReceiveJson();
108+
109+
var meta = (IDictionary<string, object>)result.meta;
110+
return meta[key]?.ToString();
111+
}
112+
113+
/// <summary />
114+
public virtual Task<PreparedRequest> BuildGetServerMetadataItemRequest(string serverId, string key, CancellationToken cancellationToken = default(CancellationToken))
115+
{
116+
return Endpoint.PrepareGetResourceRequest($"servers/{serverId}/metadata/{key}", cancellationToken);
117+
}
118+
85119
/// <summary />
86120
public virtual Task<PreparedRequest> BuildCreateServerRequest(object server, CancellationToken cancellationToken = default(CancellationToken))
87121
{
@@ -98,6 +132,27 @@ protected ComputeApi(IServiceType serviceType, IAuthenticationProvider authentic
98132
.PropogateOwner(this);
99133
}
100134

135+
/// <summary />
136+
public virtual Task CreateServerMetadataAsync(string serverId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
137+
{
138+
return BuildCreateServerMetadataRequest(serverId, key, value, cancellationToken).SendAsync();
139+
}
140+
141+
/// <summary />
142+
public virtual async Task<PreparedRequest> BuildCreateServerMetadataRequest(string serverId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
143+
{
144+
var serverMetadata = new
145+
{
146+
meta = new Dictionary<string, string>
147+
{
148+
[key] = value
149+
}
150+
};
151+
152+
PreparedRequest request = await Endpoint.PrepareRequest($"servers/{serverId}/metadata/{key}", cancellationToken);
153+
return request.PreparePutJson(serverMetadata, cancellationToken);
154+
}
155+
101156
/// <summary>
102157
/// Waits for the server to reach the specified status.
103158
/// </summary>
@@ -213,6 +268,27 @@ protected ComputeApi(IServiceType serviceType, IAuthenticationProvider authentic
213268
.PropogateOwner(this);
214269
}
215270

271+
/// <summary /> // this keeps existing, but omitted values
272+
public virtual async Task<T> UpdateServerMetadataAsync<T>(string serverId, object metadata, bool overwrite = false, CancellationToken cancellationToken = default(CancellationToken))
273+
where T : IServiceResource
274+
{
275+
return await BuildUpdateServerMetadataRequest(serverId, metadata, overwrite, cancellationToken)
276+
.SendAsync()
277+
.ReceiveJson<T>()
278+
.PropogateOwner(this);
279+
}
280+
281+
/// <summary />
282+
public virtual async Task<PreparedRequest> BuildUpdateServerMetadataRequest(string serverId, object metadata, bool overwrite = false, CancellationToken cancellationToken = default(CancellationToken))
283+
{
284+
PreparedRequest request = await Endpoint.PrepareRequest($"servers/{serverId}/metadata", cancellationToken);
285+
286+
if (overwrite)
287+
return request.PreparePutJson(metadata, cancellationToken);
288+
289+
return request.PreparePostJson(metadata, cancellationToken);
290+
}
291+
216292
/// <summary />
217293
public virtual Task DeleteServerAsync(string serverId, CancellationToken cancellationToken = default(CancellationToken))
218294
{
@@ -225,6 +301,24 @@ protected ComputeApi(IServiceType serviceType, IAuthenticationProvider authentic
225301
return Endpoint.PrepareDeleteResourceRequest($"servers/{serverId}", cancellationToken);
226302
}
227303

304+
/// <summary />
305+
public virtual Task DeleteServerMetadataAsync(string serverId, string key, CancellationToken cancellationToken = default(CancellationToken))
306+
{
307+
return BuildDeleteServerMetadataRequest(serverId, key, cancellationToken).SendAsync();
308+
}
309+
310+
/// <summary />
311+
public virtual Task<PreparedRequest> BuildDeleteServerMetadataRequest(string serverId, string key, CancellationToken cancellationToken = default(CancellationToken))
312+
{
313+
if (serverId == null)
314+
throw new ArgumentNullException("serverId");
315+
316+
if (key == null)
317+
throw new ArgumentNullException("key");
318+
319+
return Endpoint.PrepareDeleteResourceRequest($"servers/{serverId}/metadata/{key}", cancellationToken);
320+
}
321+
228322
/// <summary>
229323
/// Waits for an image to reach the specified state.
230324
/// </summary>
@@ -555,13 +649,13 @@ protected ComputeApi(IServiceType serviceType, IAuthenticationProvider authentic
555649
}
556650

557651
/// <summary />
558-
public virtual Task CreateImagMetadataAsync(string imageId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
652+
public virtual Task CreateImageMetadataAsync(string imageId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
559653
{
560-
return BuildCreateImagMetadataRequest(imageId, key, value, cancellationToken).SendAsync();
654+
return BuildCreateImageMetadataRequest(imageId, key, value, cancellationToken).SendAsync();
561655
}
562656

563657
/// <summary />
564-
public virtual async Task<PreparedRequest> BuildCreateImagMetadataRequest(string imageId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
658+
public virtual async Task<PreparedRequest> BuildCreateImageMetadataRequest(string imageId, string key, string value, CancellationToken cancellationToken = default(CancellationToken))
565659
{
566660
var imageMetadata = new
567661
{

src/corelib/Compute/v2_1/Server.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public Server()
1919
{
2020
Addresses = new Dictionary<string, IList<ServerAddress>>();
2121
AttachedVolumes = new List<ServerVolumeReference>();
22+
Metadata = new ServerMetadata();
2223
SecurityGroups = new List<SecurityGroupReference>();
2324
}
2425

@@ -58,7 +59,7 @@ public string AdminPassword
5859

5960
/// <summary />
6061
[JsonProperty("metadata")]
61-
public IDictionary<string, string> Metadata { get; set; }
62+
public ServerMetadata Metadata { get; set; }
6263

6364
/// <summary />
6465
[JsonProperty("accessIPv4")]
@@ -191,6 +192,7 @@ public string AdminPassword
191192
[OnDeserialized]
192193
private void OnDeserializedMethod(StreamingContext context)
193194
{
195+
Metadata.SetParent(this);
194196
foreach (var volume in AttachedVolumes)
195197
{
196198
volume.SetParent(this);

src/corelib/Compute/v2_1/ServerExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ public static IList<ServerAddress> GetAddress(this ServerReference server, strin
2121
return server.GetAddressAsync(key).ForceSynchronous();
2222
}
2323

24+
/// <inheritdoc cref="ServerReference.GetMetadataAsync"/>
25+
public static ServerMetadata GetMetadata(this ServerReference server)
26+
{
27+
return server.GetMetadataAsync().ForceSynchronous();
28+
}
29+
30+
/// <inheritdoc cref="ServerReference.GetMetadataItemAsync"/>
31+
public static string GetMetadataItem(this ServerReference server, string key)
32+
{
33+
return server.GetMetadataItemAsync(key).ForceSynchronous();
34+
}
35+
2436
/// <inheritdoc cref="ServerReference.GetServerAsync"/>
2537
public static IDictionary<string, IList<ServerAddress>> ListAddresses(this ServerReference server)
2638
{

0 commit comments

Comments
 (0)