Skip to content

Commit 7c5aae4

Browse files
committed
Merge pull request #609 from openstacknetsdk/floating-ips-44
Implement Layer3 Networking Extension
2 parents 82d943e + b70add3 commit 7c5aae4

46 files changed

Lines changed: 2064 additions & 90 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
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: 12 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,18 @@ 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+
220+
/// <inheritdoc cref="ComputeApi.DisassociateFloatingIPAsync" />
221+
public virtual Task DisassociateFloatingIPAsync(Identifier serverId, string floatingIPAddress, CancellationToken cancellationToken = default(CancellationToken))
222+
{
223+
return _computeApi.DisassociateFloatingIPAsync(serverId, floatingIPAddress, cancellationToken);
224+
}
225+
215226
/// <inheritdoc cref="ComputeApi.ListServerActionSummariesAsync{T}" />
216227
public virtual async Task<IEnumerable<ServerActionSummary>> ListServerActionSummariesAsync(Identifier serverId, CancellationToken cancellationToken = default(CancellationToken))
217228
{

src/corelib/Compute/v2_1/ComputeServiceExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,18 @@ public static void CancelResizeServer(this ComputeService service, Identifier se
181181
service.CancelResizeServerAsync(serverId).ForceSynchronous();
182182
}
183183

184+
/// <inheritdoc cref="ComputeService.AssociateFloatingIPAddressAsync" />
185+
public static void AssociateFloatingIPAddressAsync(this ComputeService service, Identifier serverId, AssociateFloatingIPRequest request)
186+
{
187+
service.AssociateFloatingIPAddressAsync(serverId, request).ForceSynchronous();
188+
}
189+
190+
/// <inheritdoc cref="ComputeService.DisassociateFloatingIPAsync" />
191+
public static void DisassociateFloatingIPAsync(this ComputeService service, Identifier serverId, string floatingIPAddress)
192+
{
193+
service.DisassociateFloatingIPAsync(serverId, floatingIPAddress).ForceSynchronous();
194+
}
195+
184196
/// <inheritdoc cref="ComputeService.ListServerActionSummariesAsync" />
185197
public static IEnumerable<ServerActionSummary> ListServerActions(this ComputeService service, Identifier serverId)
186198
{

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

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

768+
/// <summary>
769+
/// Associates a floating IP address to the server.
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+
/// <exception cref="ArgumentNullException"></exception>
775+
public virtual Task AssociateFloatingIPAsync(string serverId, object request, CancellationToken cancellationToken = default(CancellationToken))
776+
{
777+
return BuildServerActionRequest(serverId, request, cancellationToken).SendAsync();
778+
}
779+
780+
/// <summary>
781+
/// Disassociate a floating IP address from a server.
782+
/// </summary>
783+
/// <param name="serverId">The server identifier.</param>
784+
/// <param name="floatingIPAddress">The floating IP address to remove.</param>
785+
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
786+
/// <exception cref="ArgumentNullException"></exception>
787+
public virtual Task DisassociateFloatingIPAsync(string serverId, string floatingIPAddress, CancellationToken cancellationToken = default(CancellationToken))
788+
{
789+
var request = new
790+
{
791+
removeFloatingIp = new
792+
{
793+
address = floatingIPAddress
794+
}
795+
};
796+
return BuildServerActionRequest(serverId, request, cancellationToken).SendAsync();
797+
}
798+
768799
/// <summary>
769800
/// Builds a server action request, where the server operation is specified in the request body.
770801
/// </summary>

src/corelib/Compute/v2_1/Server.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Extensions;
4+
using System.Linq;
45
using System.Runtime.Serialization;
56
using System.Threading;
67
using System.Threading.Tasks;
@@ -231,15 +232,46 @@ public string AdminPassword
231232

232233
/// <inheritdoc cref="ComputeApi.AttachVolumeAsync{T}" />
233234
/// <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))
235+
public async Task<ServerVolume> AttachVolumeAsync(ServerVolumeDefinition volume, CancellationToken cancellationToken = default(CancellationToken))
235236
{
236237
var compute = this.GetOwnerOrThrow<ComputeApi>();
237238
var result = await compute.AttachVolumeAsync<ServerVolume>(Id, volume, cancellationToken).ConfigureAwait(false);
238239
AttachedVolumes.Add(result);
239240
((IChildResource)result).SetParent(this);
240241
return result;
241242
}
242-
243+
244+
/// <inheritdoc cref="ComputeApi.AssociateFloatingIPAsync" />
245+
/// <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>
246+
public virtual async Task AssociateFloatingIPAsync(AssociateFloatingIPRequest request, CancellationToken cancellationToken = default(CancellationToken))
247+
{
248+
var compute = this.GetOwnerOrThrow<ComputeApi>();
249+
await compute.AssociateFloatingIPAsync(Id, request, cancellationToken);
250+
251+
Addresses = await compute.ListServerAddressesAsync<ServerAddressCollection>(Id, cancellationToken);
252+
}
253+
254+
/// <inheritdoc cref="ComputeApi.DisassociateFloatingIPAsync" />
255+
/// <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>
256+
public virtual async Task DisassociateFloatingIPAsync(string floatingIPAddress, CancellationToken cancellationToken = default(CancellationToken))
257+
{
258+
var compute = this.GetOwnerOrThrow<ComputeApi>();
259+
await compute.DisassociateFloatingIPAsync(Id, floatingIPAddress, cancellationToken);
260+
261+
// Remove the address from the current instance immediately
262+
foreach (KeyValuePair<string, IList<ServerAddress>> group in Addresses)
263+
{
264+
foreach (ServerAddress address in group.Value)
265+
{
266+
if (address.Type == AddressType.Floating && address.IP == floatingIPAddress)
267+
{
268+
Addresses[group.Key].Remove(address);
269+
return;
270+
}
271+
}
272+
}
273+
}
274+
243275
/// <summary />
244276
[OnDeserialized]
245277
private void OnDeserializedMethod(StreamingContext context)

src/corelib/Compute/v2_1/ServerExtensions.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ 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+
194+
/// <inheritdoc cref="Server.DisassociateFloatingIPAsync"/>
195+
public static void DisassociateFloatingIP(this Server server, string floatingIPAddress)
196+
{
197+
server.DisassociateFloatingIPAsync(floatingIPAddress).ForceSynchronous();
198+
}
199+
188200
/// <inheritdoc cref="ServerReference.ListActionSummariesAsync"/>
189201
public static IEnumerable<ServerActionSummary> ListActionSummaries(this ServerReference server)
190202
{
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace OpenStack.Networking.v2.Layer3
5+
{
6+
/// <summary>
7+
/// Defines a connection from a router to an external network.
8+
/// </summary>
9+
public class ExternalGateway
10+
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="ExternalGateway"/> class.
13+
/// </summary>
14+
public ExternalGateway()
15+
{
16+
ExternalFixedIPs = new List<IPAddressAssociation>();
17+
}
18+
19+
/// <summary>
20+
/// The external network identifier.
21+
/// </summary>
22+
[JsonProperty("network_id")]
23+
public Identifier ExternalNetworkId { get; set; }
24+
25+
/// <summary>
26+
/// Specifies if source NAT is enabled
27+
/// </summary>
28+
[JsonProperty("enable_snat")]
29+
public bool IsSourceNATEnabled { get; set; }
30+
31+
/// <summary>
32+
/// External fixed IP addresses assigned to the router.
33+
/// </summary>
34+
[JsonProperty("external_fixed_ips")]
35+
public IList<IPAddressAssociation> ExternalFixedIPs { get; set; }
36+
}
37+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace OpenStack.Networking.v2.Layer3
5+
{
6+
/// <summary>
7+
/// Defines the set of fields that can be updated on an external gateway resource.
8+
/// </summary>
9+
public class ExternalGatewayDefinition
10+
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="ExternalGateway"/> class.
13+
/// </summary>
14+
public ExternalGatewayDefinition(Identifier externalNetworkId)
15+
{
16+
ExternalNetworkId = externalNetworkId;
17+
ExternalFixedIPs = new List<IPAddressAssociation>();
18+
}
19+
20+
/// <summary>
21+
/// The external network identifier.
22+
/// </summary>
23+
[JsonProperty("network_id")]
24+
public Identifier ExternalNetworkId { get; set; }
25+
26+
/// <summary>
27+
/// Specifies if source NAT is enabled
28+
/// </summary>
29+
[JsonProperty("enable_snat")]
30+
public bool? IsSourceNATEnabled { get; set; }
31+
32+
/// <summary>
33+
/// External fixed IP addresses assigned to the router.
34+
/// </summary>
35+
[JsonProperty("external_fixed_ips")]
36+
public IList<IPAddressAssociation> ExternalFixedIPs { get; set; }
37+
}
38+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Extensions;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using Newtonsoft.Json;
7+
using Newtonsoft.Json.Linq;
8+
using OpenStack.Serialization;
9+
10+
namespace OpenStack.Networking.v2.Layer3
11+
{
12+
/// <summary>
13+
/// An external IP address that you map to a port in an internal network
14+
/// </summary>
15+
[JsonConverterWithConstructor(typeof(RootWrapperConverter), "floatingip")]
16+
public class FloatingIP : IHaveExtraData, IServiceResource
17+
{
18+
/// <summary>
19+
/// The floating IP identifier.
20+
/// </summary>
21+
[JsonProperty("id")]
22+
public Identifier Id { get; set; }
23+
24+
/// <summary>
25+
/// The associated router.
26+
/// </summary>
27+
[JsonProperty("router_id")]
28+
public Identifier RouterId { get; set; }
29+
30+
/// <summary>
31+
/// The network associated with the floating IP.
32+
/// </summary>
33+
[JsonProperty("floating_network_id")]
34+
public Identifier NetworkId { get; set; }
35+
36+
/// <summary>
37+
/// The fixed IP address that is associated with the floating IP address.
38+
/// </summary>
39+
[JsonProperty("fixed_ip_address")]
40+
public string FixedIPAddress { get; set; }
41+
42+
/// <summary>
43+
/// The floating IP address.
44+
/// </summary>
45+
[JsonProperty("floating_ip_address")]
46+
public string FloatingIPAddress { get; set; }
47+
48+
/// <summary>
49+
/// The associated port.
50+
/// </summary>
51+
[JsonProperty("port_id")]
52+
public Identifier PortId { get; set; }
53+
54+
/// <summary>
55+
/// The status of the floating IP address.
56+
/// </summary>
57+
[JsonProperty("status")]
58+
public FloatingIPStatus Status { get; set; }
59+
60+
[JsonExtensionData]
61+
IDictionary<string, JToken> IHaveExtraData.Data { get; set; } = new Dictionary<string, JToken>();
62+
63+
object IServiceResource.Owner { get; set; }
64+
65+
/// <inheritdoc cref="NetworkingApiBuilder.DeleteFloatingIPAsync"/>
66+
/// <exception cref="InvalidOperationException">Thrown when a resource as not constructed by the SDK.</exception>
67+
public Task DeleteAsync(CancellationToken cancellationToken = default(CancellationToken))
68+
{
69+
var networking = this.GetOwnerOrThrow<NetworkingApiBuilder>();
70+
return networking.DeleteFloatingIPAsync(Id, cancellationToken);
71+
}
72+
73+
/// <summary>
74+
/// Associates the floating IP withe the specified port.
75+
/// </summary>
76+
/// <param name="portId">The port identifier.</param>
77+
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
78+
/// <exception cref="InvalidOperationException">Thrown when a resource as not constructed by the SDK.</exception>
79+
public async Task AssociateAsync(Identifier portId, CancellationToken cancellationToken = default(CancellationToken))
80+
{
81+
var networking = this.GetOwnerOrThrow<NetworkingApiBuilder>();
82+
var request = new FloatingIPUpdateDefinition { PortId = portId };
83+
var result = await networking.UpdateFloatingIPAsync<FloatingIP>(Id, request, cancellationToken).ConfigureAwait(false);
84+
result.CopyProperties(this);
85+
}
86+
87+
/// <summary>
88+
/// Frees the floating IP from any associations.
89+
/// </summary>
90+
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
91+
/// <exception cref="InvalidOperationException">Thrown when a resource as not constructed by the SDK.</exception>
92+
public async Task DisassociateAsync(CancellationToken cancellationToken = default(CancellationToken))
93+
{
94+
var networking = this.GetOwnerOrThrow<NetworkingApiBuilder>();
95+
var request = new FloatingIPUpdateDefinition { PortId = null };
96+
var result = await networking.UpdateFloatingIPAsync<FloatingIP>(Id, request, cancellationToken).ConfigureAwait(false);
97+
result.CopyProperties(this);
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)