Skip to content

Commit 3b27e6b

Browse files
committed
Support server.AssociateFloatingIP action
1 parent ae5d303 commit 3b27e6b

7 files changed

Lines changed: 122 additions & 3 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Newtonsoft.Json;
2+
using OpenStack.Serialization;
3+
4+
namespace OpenStack.Compute.v2_1
5+
{
6+
/// <summary>
7+
/// Associates a floating IP address to a server.
8+
/// </summary>
9+
[JsonConverterWithConstructor(typeof(RootWrapperConverter), "addFloatingIp")]
10+
public class AssociateFloatingIPRequest
11+
{
12+
/// <summary>
13+
/// Initializes a new instance of the <see cref="AssociateFloatingIPRequest"/> class.
14+
/// </summary>
15+
/// <param name="floatingIPAddress">The floating ip address.</param>
16+
public AssociateFloatingIPRequest(string floatingIPAddress)
17+
{
18+
FloatingIPAddress = floatingIPAddress;
19+
}
20+
21+
/// <summary>
22+
/// The floating IP address.
23+
/// </summary>
24+
[JsonProperty("address")]
25+
public string FloatingIPAddress { get; set; }
26+
27+
/// <summary>
28+
/// The fixed IP address with which you want to associate the floating IP address.
29+
/// </summary>
30+
[JsonProperty("fixed_address")]
31+
public string FixedIPAddress { get; set; }
32+
}
33+
}

src/corelib/Compute/v2_1/ComputeService.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ public ComputeService(IAuthenticationProvider authenticationProvider, string reg
109109
return _computeApi.DeleteServerMetadataAsync(serverId, key, cancellationToken);
110110
}
111111

112-
113112
/// <inheritdoc cref="ComputeApi.WaitUntilServerIsDeletedAsync{TServer,TStatus}" />
114113
public Task WaitUntilServerIsDeletedAsync(Identifier serverId, TimeSpan? refreshDelay = null, TimeSpan? timeout = null, IProgress<bool> progress = null, CancellationToken cancellationToken = default(CancellationToken))
115114
{
@@ -212,6 +211,12 @@ public ComputeService(IAuthenticationProvider authenticationProvider, string reg
212211
return _computeApi.CancelResizeServerAsync(serverId, cancellationToken);
213212
}
214213

214+
/// <inheritdoc cref="ComputeApi.AssociateFloatingIPAsync" />
215+
public virtual Task AssociateFloatingIPAddressAsync(Identifier serverId, AssociateFloatingIPRequest request, CancellationToken cancellationToken = default(CancellationToken))
216+
{
217+
return _computeApi.AssociateFloatingIPAsync(serverId, request, cancellationToken);
218+
}
219+
215220
/// <inheritdoc cref="ComputeApi.ListServerActionSummariesAsync{T}" />
216221
public virtual async Task<IEnumerable<ServerActionSummary>> ListServerActionSummariesAsync(Identifier serverId, CancellationToken cancellationToken = default(CancellationToken))
217222
{

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,17 @@ protected ComputeApi(IServiceType serviceType, IAuthenticationProvider authentic
765765
.SendAsync();
766766
}
767767

768+
/// <summary>
769+
/// Associates a floating IP address to the server instance.
770+
/// </summary>
771+
/// <param name="serverId">The server identifier.</param>
772+
/// <param name="request">The request.</param>
773+
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
774+
public virtual Task AssociateFloatingIPAsync(string serverId, object request, CancellationToken cancellationToken = default(CancellationToken))
775+
{
776+
return BuildServerActionRequest(serverId, request, cancellationToken).SendAsync();
777+
}
778+
768779
/// <summary>
769780
/// Builds a server action request, where the server operation is specified in the request body.
770781
/// </summary>

src/corelib/Compute/v2_1/Server.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,15 +231,23 @@ public string AdminPassword
231231

232232
/// <inheritdoc cref="ComputeApi.AttachVolumeAsync{T}" />
233233
/// <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>
234-
public virtual async Task<ServerVolume> AttachVolumeAsync(ServerVolumeDefinition volume, CancellationToken cancellationToken = default(CancellationToken))
234+
public async Task<ServerVolume> AttachVolumeAsync(ServerVolumeDefinition volume, CancellationToken cancellationToken = default(CancellationToken))
235235
{
236236
var compute = this.GetOwnerOrThrow<ComputeApi>();
237237
var result = await compute.AttachVolumeAsync<ServerVolume>(Id, volume, cancellationToken).ConfigureAwait(false);
238238
AttachedVolumes.Add(result);
239239
((IChildResource)result).SetParent(this);
240240
return result;
241241
}
242-
242+
243+
/// <inheritdoc cref="ComputeApi.AssociateFloatingIPAsync" />
244+
/// <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>
245+
public virtual Task AssociateFloatingIPAsync(AssociateFloatingIPRequest request, CancellationToken cancellationToken = default(CancellationToken))
246+
{
247+
var compute = this.GetOwnerOrThrow<ComputeApi>();
248+
return compute.AssociateFloatingIPAsync(Id, request, cancellationToken);
249+
}
250+
243251
/// <summary />
244252
[OnDeserialized]
245253
private void OnDeserializedMethod(StreamingContext context)

src/corelib/Compute/v2_1/ServerExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ public static void CancelResize(this ServerReference server)
185185
server.CancelResizeAsync().ForceSynchronous();
186186
}
187187

188+
/// <inheritdoc cref="Server.AssociateFloatingIPAsync"/>
189+
public static void AssociateFloatingIP(this Server server, AssociateFloatingIPRequest request)
190+
{
191+
server.AssociateFloatingIPAsync(request).ForceSynchronous();
192+
}
193+
188194
/// <inheritdoc cref="ServerReference.ListActionSummariesAsync"/>
189195
public static IEnumerable<ServerActionSummary> ListActionSummaries(this ServerReference server)
190196
{

src/corelib/OpenStack.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
<Compile Include="BlockStorage\v2\VolumeStatus.cs" />
8989
<Compile Include="Compute\ComputeOperationFailedException.cs" />
9090
<Compile Include="Compute\NamespaceDoc.cs" />
91+
<Compile Include="Compute\v2_1\Actions\AssociateFloatingIPRequest.cs" />
9192
<Compile Include="Compute\v2_1\Actions\RescueServerRequest.cs" />
9293
<Compile Include="Compute\v2_1\Actions\RebootServerRequest.cs" />
9394
<Compile Include="Compute\v2_1\Actions\RebootType.cs" />

src/testing/unit/Networking/v2/Layer3/Level3ExtensionTests.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,32 @@ public void AssociateFloatingIP()
9393
}
9494
}
9595

96+
[Fact]
97+
public void AssociateFloatingIPToServer()
98+
{
99+
var compute = new ComputeService(Stubs.AuthenticationProvider, "region");
100+
101+
using (var httpTest = new HttpTest())
102+
{
103+
Identifier serverId = Guid.NewGuid();
104+
const string ip = "10.0.0.1";
105+
httpTest.RespondWithJson(new Server { Id = serverId });
106+
httpTest.RespondWith((int)HttpStatusCode.OK, "ip associated!");
107+
httpTest.RespondWithJson(new ServerAddressCollection
108+
{
109+
["network1"] = new List<ServerAddress>
110+
{
111+
new ServerAddress {IP = ip, Type = AddressType.Floating}
112+
}
113+
});
114+
115+
var server = compute.GetServer(serverId);
116+
server.AssociateFloatingIP(new AssociateFloatingIPRequest(ip));
117+
118+
Assert.NotNull(server.Addresses["network1"].Single(a => a.IP == ip && a.Type == AddressType.Floating));
119+
}
120+
}
121+
96122
[Fact]
97123
public void DisassociateFloatingIP()
98124
{
@@ -111,6 +137,35 @@ public void DisassociateFloatingIP()
111137
}
112138
}
113139

140+
[Fact]
141+
public void DisassociateFloatingIPFromServer()
142+
{
143+
var compute = new ComputeService(Stubs.AuthenticationProvider, "region");
144+
145+
using (var httpTest = new HttpTest())
146+
{
147+
Identifier serverId = Guid.NewGuid();
148+
const string ip = "10.0.0.1";
149+
httpTest.RespondWithJson(new Server
150+
{
151+
Id = serverId,
152+
Addresses =
153+
{
154+
["network1"] = new List<ServerAddress>
155+
{
156+
new ServerAddress {IP = ip, Type = AddressType.Floating}
157+
}
158+
}
159+
});
160+
httpTest.RespondWith((int)HttpStatusCode.OK, "ip disassociated!");
161+
162+
var server = compute.GetServer(serverId);
163+
server.DisassociateFloatingIP(ip);
164+
165+
Assert.Null(server.Addresses["network1"].FirstOrDefault(a => a.IP == ip && a.Type == AddressType.Floating));
166+
}
167+
}
168+
114169
[Theory]
115170
[InlineData(HttpStatusCode.Accepted)]
116171
[InlineData(HttpStatusCode.NotFound)]

0 commit comments

Comments
 (0)