Skip to content

Commit 3f0a9ab

Browse files
committed
Compute.Suspend/ResumeServer
1 parent d2093d0 commit 3f0a9ab

9 files changed

Lines changed: 143 additions & 1 deletion

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Newtonsoft.Json;
2+
3+
namespace OpenStack.Compute.v2_1
4+
{
5+
/// <summary>
6+
/// Resumes a suspended server and changes its status to ACTIVE.
7+
/// </summary>
8+
public class ResumeServerRequest
9+
{
10+
/// <summary />
11+
[JsonProperty("resume", DefaultValueHandling = DefaultValueHandling.Include, NullValueHandling = NullValueHandling.Include)]
12+
public string Action { get; set; }
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Newtonsoft.Json;
2+
3+
namespace OpenStack.Compute.v2_1
4+
{
5+
/// <summary>
6+
/// Suspends a server and changes its status to SUSPENDED.
7+
/// </summary>
8+
public class SuspendServerRequest
9+
{
10+
/// <summary />
11+
[JsonProperty("suspend", DefaultValueHandling = DefaultValueHandling.Include, NullValueHandling = NullValueHandling.Include)]
12+
public string Action { get; set; }
13+
}
14+
}

src/corelib/Compute/v2_1/ComputeService.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,18 @@ public ComputeService(IAuthenticationProvider authenticationProvider, string reg
134134
return _computeApi.StopServerAsync(serverId, cancellationToken);
135135
}
136136

137+
/// <inheritdoc cref="ComputeApi.SuspendServerAsync" />
138+
public Task SuspendServerAsync(Identifier serverId, CancellationToken cancellationToken = default(CancellationToken))
139+
{
140+
return _computeApi.SuspendServerAsync(serverId, cancellationToken);
141+
}
142+
143+
/// <inheritdoc cref="ComputeApi.ResumeServerAsync" />
144+
public Task ResumeServerAsync(Identifier serverId, CancellationToken cancellationToken = default(CancellationToken))
145+
{
146+
return _computeApi.ResumeServerAsync(serverId, cancellationToken);
147+
}
148+
137149
/// <inheritdoc cref="ComputeApi.RebootServerAsync{TRequest}" />
138150
public Task RebootServerAsync(Identifier serverId, RebootServerRequest request = null, CancellationToken cancellationToken = default(CancellationToken))
139151
{

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,28 @@ protected ComputeApi(IServiceType serviceType, IAuthenticationProvider authentic
554554
return BuildServerActionRequest(serverId, request, cancellationToken).SendAsync();
555555
}
556556

557+
/// <summary>
558+
/// Suspends a server and changes its status to SUSPENDED.
559+
/// </summary>
560+
/// <param name="serverId">The server identifier.</param>
561+
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
562+
public virtual Task SuspendServerAsync(string serverId, CancellationToken cancellationToken = default(CancellationToken))
563+
{
564+
var request = new SuspendServerRequest();
565+
return BuildServerActionRequest(serverId, request, cancellationToken).SendAsync();
566+
}
567+
568+
/// <summary>
569+
/// Resumes a suspended server and changes its status to ACTIVE.
570+
/// </summary>
571+
/// <param name="serverId">The server identifier.</param>
572+
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
573+
public virtual Task ResumeServerAsync(string serverId, CancellationToken cancellationToken = default(CancellationToken))
574+
{
575+
var request = new ResumeServerRequest();
576+
return BuildServerActionRequest(serverId, request, cancellationToken).SendAsync();
577+
}
578+
557579
/// <summary>
558580
/// Reboots a server.
559581
/// </summary>

src/corelib/Compute/v2_1/ServerExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ public static void Stop(this ServerReference server)
9595
server.StopAsync().ForceSynchronous();
9696
}
9797

98+
/// <inheritdoc cref="ServerReference.SuspendAsync"/>
99+
public static void Suspend(this ServerReference server)
100+
{
101+
server.SuspendAsync().ForceSynchronous();
102+
}
103+
104+
/// <inheritdoc cref="ServerReference.ResumeAsync"/>
105+
public static void Resume(this ServerReference server)
106+
{
107+
server.ResumeAsync().ForceSynchronous();
108+
}
109+
98110
/// <inheritdoc cref="ServerReference.RebootAsync"/>
99111
public static void Reboot(this ServerReference server, RebootServerRequest request = null)
100112
{

src/corelib/Compute/v2_1/ServerReference.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,22 @@ public class ServerReference : IHaveExtraData, IServiceResource
103103
await compute.StopServerAsync(Id, cancellationToken).ConfigureAwait(false);
104104
}
105105

106+
/// <inheritdoc cref="ComputeApi.SuspendServerAsync" />
107+
/// <exception cref="InvalidOperationException">When this instance was not constructed by the <see cref="ComputeService"/>, as it is missing the appropriate internal state to execute service calls.</exception>
108+
public async Task SuspendAsync(CancellationToken cancellationToken = default(CancellationToken))
109+
{
110+
var compute = this.GetOwnerOrThrow<ComputeApi>();
111+
await compute.SuspendServerAsync(Id, cancellationToken).ConfigureAwait(false);
112+
}
113+
114+
/// <inheritdoc cref="ComputeApi.ResumeServerAsync" />
115+
/// <exception cref="InvalidOperationException">When this instance was not constructed by the <see cref="ComputeService"/>, as it is missing the appropriate internal state to execute service calls.</exception>
116+
public async Task ResumeAsync(CancellationToken cancellationToken = default(CancellationToken))
117+
{
118+
var compute = this.GetOwnerOrThrow<ComputeApi>();
119+
await compute.ResumeServerAsync(Id, cancellationToken).ConfigureAwait(false);
120+
}
121+
106122
/// <inheritdoc cref="ComputeApi.RebootServerAsync{T}" />
107123
/// <exception cref="InvalidOperationException">When this instance was not constructed by the <see cref="ComputeService"/>, as it is missing the appropriate internal state to execute service calls.</exception>
108124
public async Task RebootAsync(RebootServerRequest request = null, CancellationToken cancellationToken = default(CancellationToken))

src/corelib/OpenStack.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@
9191
<Compile Include="Compute\v2_1\Actions\RescueServerRequest.cs" />
9292
<Compile Include="Compute\v2_1\Actions\RebootServerRequest.cs" />
9393
<Compile Include="Compute\v2_1\Actions\RebootType.cs" />
94+
<Compile Include="Compute\v2_1\Actions\ResumeServerRequest.cs" />
9495
<Compile Include="Compute\v2_1\Actions\SnapshotServerRequest.cs" />
9596
<Compile Include="Compute\v2_1\Actions\StartServerRequest.cs" />
9697
<Compile Include="Compute\v2_1\Actions\StopServerRequest.cs" />
98+
<Compile Include="Compute\v2_1\Actions\SuspendServerRequest.cs" />
9799
<Compile Include="Compute\v2_1\AddressType.cs" />
98100
<Compile Include="Compute\v2_1\Flavor.cs" />
99101
<Compile Include="Compute\v2_1\FlavorReference.cs" />

src/testing/integration/Compute/v2_1/ServerTests.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,23 @@ public async Task RebootServerTest()
323323
await server.WaitForStatusAsync(ServerStatus.Reboot);
324324
await server.WaitUntilActiveAsync();
325325
}
326-
326+
327+
[Fact]
328+
public async Task ResumeServerTest()
329+
{
330+
Trace.WriteLine("Creating server...");
331+
var server = await _testData.CreateServer();
332+
await server.WaitUntilActiveAsync();
333+
334+
Trace.WriteLine("Suspending the server...");
335+
await server.SuspendAsync();
336+
await server.WaitForStatusAsync(ServerStatus.Suspended);
337+
338+
Trace.WriteLine("Resuming the server...");
339+
await server.ResumeAsync();
340+
await server.WaitUntilActiveAsync();
341+
}
342+
327343
[Fact]
328344
public async Task ServerVolumesTest()
329345
{

src/testing/unit/Compute/v2_1/ServerTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,40 @@ public void StopServer()
484484
}
485485
}
486486

487+
[Fact]
488+
public void SuspendServer()
489+
{
490+
using (var httpTest = new HttpTest())
491+
{
492+
Identifier serverId = Guid.NewGuid();
493+
httpTest.RespondWithJson(new Server { Id = serverId });
494+
httpTest.RespondWith((int)HttpStatusCode.Accepted, "Roger that, boss");
495+
496+
var server = _compute.GetServer(serverId);
497+
server.Suspend();
498+
499+
httpTest.ShouldHaveCalled($"*/servers/{serverId}/action");
500+
Assert.True(httpTest.CallLog.Last().RequestBody.Contains("suspend"));
501+
}
502+
}
503+
504+
[Fact]
505+
public void ResumeServer()
506+
{
507+
using (var httpTest = new HttpTest())
508+
{
509+
Identifier serverId = Guid.NewGuid();
510+
httpTest.RespondWithJson(new Server { Id = serverId });
511+
httpTest.RespondWith((int)HttpStatusCode.Accepted, "Roger that, boss");
512+
513+
var server = _compute.GetServer(serverId);
514+
server.Resume();
515+
516+
httpTest.ShouldHaveCalled($"*/servers/{serverId}/action");
517+
Assert.True(httpTest.CallLog.Last().RequestBody.Contains("resume"));
518+
}
519+
}
520+
487521
[Fact]
488522
public void RebootServer()
489523
{

0 commit comments

Comments
 (0)