Skip to content

Commit 850bf33

Browse files
committed
Merge pull request #62 from rackspace/AddCloudNetworkSupport
Add cloud network support
2 parents e6db62c + 9247ecd commit 850bf33

21 files changed

Lines changed: 776 additions & 6 deletions
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace net.openstack.Core.Domain
4+
{
5+
[DataContract]
6+
public class CloudNetwork
7+
{
8+
/// <summary>
9+
/// The network ID.
10+
/// </summary>
11+
[DataMember]
12+
public string Id { get; set; }
13+
14+
/// <summary>
15+
/// The CIDR for an isolated network.
16+
/// </summary>
17+
[DataMember]
18+
public string Cidr { get; set; }
19+
20+
/// <summary>
21+
/// The name of the network. ServiceNet is labeled as private and PublicNet
22+
/// is labeled as public in the network list.
23+
/// </summary>
24+
[DataMember]
25+
public string Label { get; set; }
26+
}
27+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System;
2+
3+
namespace net.openstack.Core.Exceptions
4+
{
5+
public class CidrFormatException : Exception
6+
{
7+
public CidrFormatException() { }
8+
public CidrFormatException(string message) : base(message) { }
9+
}
10+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using net.openstack.Core.Domain;
6+
7+
namespace net.openstack.Core
8+
{
9+
public interface ICloudNetworksProvider
10+
{
11+
/// <summary>
12+
/// List the networks configured for the account.
13+
/// </summary>
14+
/// <param name="region">The region in which to retrieve the networks.<remarks>[Optional]: If not specified, the users default region will be used.</remarks></param>
15+
/// <param name="identity">The users Cloud Identity <see cref="net.openstack.Core.Domain.CloudIdentity" /><remarks>[Optional]: If not specified, the default identity given in the constructor will be used.</remarks></param>
16+
/// <returns>A list of networks <see cref="net.openstack.Core.Domain.CloudNetwork" /></returns>
17+
IEnumerable<CloudNetwork> ListNetworks(string region = null, CloudIdentity identity = null);
18+
19+
/// <summary>
20+
/// Create a network with the given IP block.
21+
/// </summary>
22+
/// <param name="cidr">The IP block from which to allocate the network. For example, 172.16.0.0/24 or 2001:DB8::/64</param>
23+
/// <param name="label">The name of the new network. For example, my_new_network.</param>
24+
/// <param name="region">The region in which to create the network.<remarks>[Optional]: If not specified, the users default region will be used.</remarks></param>
25+
/// <param name="identity">The users Cloud Identity <see cref="net.openstack.Core.Domain.CloudIdentity" /><remarks>[Optional]: If not specified, the default identity given in the constructor will be used.</remarks></param>
26+
/// <returns>Details for the newly created network <see cref="net.openstack.Core.Domain.CloudNetwork" /></returns>
27+
CloudNetwork CreateNetwork(string cidr, string label, string region = null, CloudIdentity identity = null);
28+
29+
/// <summary>
30+
/// Retrieve details for the specified network
31+
/// </summary>
32+
/// <param name="network_id">ID (uuid) of the network to retrieve</param>
33+
/// <param name="region">The region in which to retrieve the network details.<remarks>[Optional]: If not specified, the users default region will be used.</remarks></param>
34+
/// <param name="identity">The users Cloud Identity <see cref="net.openstack.Core.Domain.CloudIdentity" /><remarks>[Optional]: If not specified, the default identity given in the constructor will be used.</remarks></param>
35+
/// <returns>Details for the specified network <see cref="net.openstack.Core.Domain.CloudNetwork" /></returns>
36+
CloudNetwork ShowNetwork(string network_id, string region = null, CloudIdentity identity = null);
37+
38+
39+
/// <summary>
40+
/// Deletes the specified network. <remarks>You cannot delete an isolated network unless the network is not attached to any server.</remarks>
41+
/// </summary>
42+
/// <param name="network_id">ID (uuid) of the network to delete</param>
43+
/// <param name="region">The region in which to specify the delete.<remarks>[Optional]: If not specified, the users default region will be used.</remarks></param>
44+
/// <param name="identity">The users Cloud Identity <see cref="net.openstack.Core.Domain.CloudIdentity" /><remarks>[Optional]: If not specified, the default identity given in the constructor will be used.</remarks></param>
45+
/// <returns><c>bool</c> indicating if the delete was successful</returns>
46+
bool DeleteNetwork(string network_id, string region = null, CloudIdentity identity = null);
47+
}
48+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace net.openstack.Core
7+
{
8+
public interface ICloudNetworksValidator
9+
{
10+
void ValidateCidr(string cidr);
11+
}
12+
}

src/corelib/Providers/Rackspace/CloudFilesProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using net.openstack.Core.Domain;
1212
using net.openstack.Core.Exceptions;
1313
using net.openstack.Providers.Rackspace.Exceptions;
14+
using net.openstack.Providers.Rackspace.Validators;
1415

1516
namespace net.openstack.Providers.Rackspace
1617
{
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Security.Cryptography;
7+
using System.Text;
8+
using JSIStudios.SimpleRESTServices.Client;
9+
using JSIStudios.SimpleRESTServices.Client.Json;
10+
using net.openstack.Core;
11+
using net.openstack.Core.Domain;
12+
using net.openstack.Core.Exceptions;
13+
using net.openstack.Core.Exceptions.Response;
14+
using net.openstack.Providers.Rackspace.Exceptions;
15+
using net.openstack.Providers.Rackspace.Objects.Request;
16+
using net.openstack.Providers.Rackspace.Objects.Response;
17+
18+
namespace net.openstack.Providers.Rackspace
19+
{
20+
public class CloudNetworksProvider : ProviderBase, ICloudNetworksProvider
21+
{
22+
private readonly int[] _validResponseCode = new[] { 200, 201, 202 };
23+
24+
#region Constructors
25+
26+
/// <summary>
27+
/// Creates a new instance of the Rackspace <see cref="net.openstack.Providers.Rackspace.CloudNetworksProvider"/> class.
28+
/// </summary>
29+
public CloudNetworksProvider()
30+
: this(null) { }
31+
32+
/// <summary>
33+
/// Creates a new instance of the Rackspace <see cref="net.openstack.Providers.Rackspace.CloudNetworksProvider"/> class.
34+
/// </summary>
35+
/// <param name="identity">An instance of a <see cref="net.openstack.Core.Domain.CloudIdentity"/> object.<remarks>[Optional]: If not provided, the user will be required to pass a <see cref="net.openstack.Core.Domain.CloudIdentity"/> object to each method individually.</remarks></param>
36+
public CloudNetworksProvider(CloudIdentity identity)
37+
: base(identity, new CloudIdentityProvider(), new JsonRestServices()) { }
38+
39+
#endregion
40+
41+
42+
#region Networks
43+
44+
public IEnumerable<CloudNetwork> ListNetworks(string region = null, CloudIdentity identity = null)
45+
{
46+
var urlPath = new Uri(string.Format("{0}/os-networksv2", GetServiceEndpoint(identity, region)));
47+
var response = ExecuteRESTRequest<ListCloudNetworksResponse>(identity, urlPath, HttpMethod.GET);
48+
49+
if (response == null || response.Data == null)
50+
return null;
51+
52+
return response.Data.Networks;
53+
}
54+
55+
56+
public CloudNetwork CreateNetwork(string cidr, string label, string region = null, CloudIdentity identity = null)
57+
{
58+
var urlPath = new Uri(string.Format("{0}/os-networksv2", GetServiceEndpoint(identity, region)));
59+
var cloudNetworkRequest = new CreateCloudNetworkRequest { Details = new CreateCloudNetworksDetails { Cidr = cidr, Label = label } };
60+
61+
var response = ExecuteRESTRequest<CloudNetworkResponse>(identity, urlPath, HttpMethod.POST, cloudNetworkRequest);
62+
63+
if (response == null || response.Data == null)
64+
return null;
65+
66+
return response.Data.Network;
67+
}
68+
69+
public CloudNetwork ShowNetwork(string network_id, string region = null, CloudIdentity identity = null)
70+
{
71+
var urlPath = new Uri(string.Format("{0}/os-networksv2/{1}", GetServiceEndpoint(identity, region), network_id));
72+
var response = ExecuteRESTRequest<CloudNetworkResponse>(identity, urlPath, HttpMethod.GET);
73+
74+
if (response == null || response.Data == null)
75+
return null;
76+
77+
return response.Data.Network;
78+
}
79+
80+
public bool DeleteNetwork(string network_id, string region = null, CloudIdentity identity = null)
81+
{
82+
var urlPath = new Uri(string.Format("{0}/os-networksv2/{1}", GetServiceEndpoint(identity, region), network_id));
83+
84+
Response response = null;
85+
try
86+
{
87+
response = ExecuteRESTRequest(identity, urlPath, HttpMethod.DELETE);
88+
}
89+
catch(UserNotAuthorizedException ex)
90+
{
91+
if(ex.Response.StatusCode == 403)
92+
throw new UserAuthorizationException("ERROR: Cannot delete network. Ensure that all servers are removed from this network first.");
93+
}
94+
95+
return response != null && _validResponseCode.Contains(response.StatusCode);
96+
}
97+
98+
#endregion
99+
100+
101+
#region Private methods
102+
103+
protected string GetServiceEndpoint(CloudIdentity identity = null, string region = null)
104+
{
105+
return base.GetPublicServiceEndpoint(identity, "cloudServersOpenStack", region);
106+
}
107+
108+
#endregion
109+
110+
}
111+
}

src/corelib/Providers/Rackspace/CloudServersProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public NewServer CreateServer(string cloudServerName, string imageName, string f
8181

8282
NewServerNetwork[] networksToAttach = null;
8383

84-
if (attachToServiceNetwork || attachToPublicNetwork)
84+
if (attachToServiceNetwork || attachToPublicNetwork || networks.Any())
8585
{
8686
var networkList = new List<NewServerNetwork>();
8787

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace net.openstack.Providers.Rackspace.Objects.Request
4+
{
5+
[DataContract]
6+
internal class CreateCloudNetworkRequest
7+
{
8+
[DataMember(Name = "network")]
9+
public CreateCloudNetworksDetails Details { get; set; }
10+
}
11+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace net.openstack.Providers.Rackspace.Objects.Request
4+
{
5+
[DataContract]
6+
public class CreateCloudNetworksDetails
7+
{
8+
[DataMember(Name = "cidr")]
9+
public string Cidr { get; set; }
10+
11+
[DataMember(Name = "label")]
12+
public string Label { get; set; }
13+
}
14+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.Serialization;
5+
using System.Text;
6+
using net.openstack.Core.Domain;
7+
8+
namespace net.openstack.Providers.Rackspace.Objects.Response
9+
{
10+
[DataContract]
11+
internal class CloudNetworkResponse
12+
{
13+
[DataMember(Name = "network")]
14+
public CloudNetwork Network { get; set; }
15+
}
16+
}

0 commit comments

Comments
 (0)