Merge "Adding support for listing, getting, and creating floating ip addresses Fixed minor documentation typos."
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
// /* ============================================================================
|
||||
// Copyright 2014 Hewlett Packard
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ============================================================================ */
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using OpenStack.Compute;
|
||||
using OpenStack.Network;
|
||||
|
||||
namespace OpenStack.Test.Network
|
||||
{
|
||||
[TestClass]
|
||||
public class FloatingIpPayloadConverterTests
|
||||
{
|
||||
internal string CreateFloatingIpJsonFixtrue(string id, string ipAddress, FloatingIpStatus status)
|
||||
{
|
||||
var payloadFixture = @"{{
|
||||
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
|
||||
""status"": ""{1}"",
|
||||
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
|
||||
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
|
||||
""fixed_ip_address"": ""10.0.0.2"",
|
||||
""floating_ip_address"": ""{2}"",
|
||||
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
|
||||
""id"": ""{0}""
|
||||
}}";
|
||||
|
||||
return string.Format(payloadFixture, id, status, ipAddress);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CanParseValidFloatingIpsJsonPayloadWithMultipleIps()
|
||||
{
|
||||
var validMultipleIpJsonFixture = @"{{ ""floatingips"": [ {0} ] }}";
|
||||
var firstIp = CreateFloatingIpJsonFixtrue("12345", "172.0.0.1", FloatingIpStatus.Active);
|
||||
var secondIp = CreateFloatingIpJsonFixtrue("54321", "172.0.0.2", FloatingIpStatus.Down);
|
||||
|
||||
var validMultipleIpsJson = string.Format(validMultipleIpJsonFixture,
|
||||
string.Join(",", new List<string>() { firstIp, secondIp }));
|
||||
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
var floatingIps = converter.ConvertFloatingIps(validMultipleIpsJson).ToList();
|
||||
|
||||
Assert.AreEqual(2, floatingIps.Count());
|
||||
var ip1 =
|
||||
floatingIps.First(o => string.Equals(o.Id, "12345", StringComparison.InvariantCultureIgnoreCase));
|
||||
var ip2 =
|
||||
floatingIps.First(o => string.Equals(o.Id, "54321", StringComparison.InvariantCultureIgnoreCase));
|
||||
Assert.IsNotNull(ip1);
|
||||
Assert.IsNotNull(ip2);
|
||||
|
||||
Assert.AreEqual("12345", ip1.Id);
|
||||
Assert.AreEqual("172.0.0.1", ip1.FloatingIpAddress);
|
||||
Assert.AreEqual(FloatingIpStatus.Active, ip1.Status);
|
||||
|
||||
Assert.AreEqual("54321", ip2.Id);
|
||||
Assert.AreEqual("172.0.0.2", ip2.FloatingIpAddress);
|
||||
Assert.AreEqual(FloatingIpStatus.Down, ip2.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CanConvertValidFloatingIpsJsonPayloadWithSingleNetwork()
|
||||
{
|
||||
var validSingleIpJsonPayload = @"{{ ""floatingips"": [ {0} ] }}";
|
||||
var firstIp = CreateFloatingIpJsonFixtrue("12345", "172.0.0.1", FloatingIpStatus.Active);
|
||||
|
||||
var validSingleIpPayload = string.Format(validSingleIpJsonPayload,
|
||||
string.Join(",", new List<string>() { firstIp }));
|
||||
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
var floatingIps = converter.ConvertFloatingIps(validSingleIpPayload).ToList();
|
||||
|
||||
Assert.AreEqual(1, floatingIps.Count());
|
||||
var ip1 =
|
||||
floatingIps.First(o => string.Equals(o.Id, "12345", StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
Assert.IsNotNull(ip1);
|
||||
|
||||
Assert.AreEqual("12345", ip1.Id);
|
||||
Assert.AreEqual("172.0.0.1", ip1.FloatingIpAddress);
|
||||
Assert.AreEqual(FloatingIpStatus.Active, ip1.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CanParseValidFloatingIpsPayloadWithEmptyJsonArray()
|
||||
{
|
||||
var emptyJsonArray = @"{ ""floatingips"": [ ] }";
|
||||
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
var networks = converter.ConvertFloatingIps(emptyJsonArray).ToList();
|
||||
|
||||
Assert.AreEqual(0, networks.Count());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CanParseAnEmptyFloatingIpsPayload()
|
||||
{
|
||||
var payload = string.Empty;
|
||||
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
var networks = converter.ConvertFloatingIps(payload).ToList();
|
||||
|
||||
Assert.AreEqual(0, networks.Count());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void CannotParseANullFloatingIpsPayload()
|
||||
{
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
converter.ConvertFloatingIps(null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void CannotParseInvalidFloatingIpsJsonPayload()
|
||||
{
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
converter.ConvertFloatingIps("[ { \"SomeAtrib\" }]");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void CannotParseInvalidFloatingIpsPayload()
|
||||
{
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
converter.ConvertFloatingIps("NOT JSON");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CanConvertValidFloatingIpJsonPayload()
|
||||
{
|
||||
var validSingleIpJsonPayload = @"{{ ""floatingip"": {0} }}";
|
||||
var firstIp = CreateFloatingIpJsonFixtrue("12345", "172.0.0.1", FloatingIpStatus.Active);
|
||||
|
||||
var validSingleIpPayload = string.Format(validSingleIpJsonPayload,
|
||||
string.Join(",", new List<string>() { firstIp }));
|
||||
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
var ip1 = converter.Convert(validSingleIpPayload);
|
||||
|
||||
Assert.IsNotNull(ip1);
|
||||
Assert.AreEqual("12345", ip1.Id);
|
||||
Assert.AreEqual("172.0.0.1", ip1.FloatingIpAddress);
|
||||
Assert.AreEqual(FloatingIpStatus.Active, ip1.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void CannotParseANullFloatingIpPayload()
|
||||
{
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
converter.Convert(null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void CannotParseInvalidFloatingIpJsonPayload()
|
||||
{
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
converter.Convert("[ { \"SomeAtrib\" }]");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void CannotParseInvalidFloatingIpPayload()
|
||||
{
|
||||
var converter = new FloatingIpPayloadConverter();
|
||||
converter.Convert("NOT JSON");
|
||||
}
|
||||
}
|
||||
}
|
@@ -15,6 +15,7 @@
|
||||
// ============================================================================ */
|
||||
|
||||
using System;
|
||||
using System.CodeDom.Compiler;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -34,9 +35,12 @@ namespace OpenStack.Test.Network
|
||||
{
|
||||
internal ICollection<OpenStack.Network.Network> Networks { get; private set; }
|
||||
|
||||
internal ICollection<FloatingIp> FloatingIps { get; private set; }
|
||||
|
||||
public NetworkRestSimulator() : base()
|
||||
{
|
||||
this.Networks = new List<OpenStack.Network.Network>();
|
||||
this.FloatingIps = new List<OpenStack.Network.FloatingIp>();
|
||||
}
|
||||
|
||||
public NetworkRestSimulator(CancellationToken token)
|
||||
@@ -46,12 +50,14 @@ namespace OpenStack.Test.Network
|
||||
|
||||
protected override IHttpResponseAbstraction HandleGet()
|
||||
{
|
||||
if (this.Uri.Segments.Count() >= 4)
|
||||
if (this.Uri.Segments.Count() >= 3)
|
||||
{
|
||||
switch (this.Uri.Segments[3].TrimEnd('/').ToLower())
|
||||
switch (this.Uri.Segments[2].TrimEnd('/').ToLower())
|
||||
{
|
||||
case "networks":
|
||||
return HandleGetNetworks();
|
||||
case "floatingips":
|
||||
return HandleGetFloatingIps();
|
||||
}
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
@@ -62,9 +68,9 @@ namespace OpenStack.Test.Network
|
||||
Stream networkContent;
|
||||
switch (this.Uri.Segments.Count())
|
||||
{
|
||||
case 4:
|
||||
case 3:
|
||||
//no flavor id given, list all flavors
|
||||
networkContent = TestHelper.CreateStream(GenerateNetworksPayload(this.Networks));
|
||||
networkContent = TestHelper.CreateStream(GenerateCollectionPayload(this.Networks, this.GenerateNetworkPayload, "networks"));
|
||||
break;
|
||||
default:
|
||||
//Unknown Uri format
|
||||
@@ -74,11 +80,66 @@ namespace OpenStack.Test.Network
|
||||
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), networkContent);
|
||||
}
|
||||
|
||||
internal IHttpResponseAbstraction HandleGetFloatingIps()
|
||||
{
|
||||
Stream floatingIpContent;
|
||||
switch (this.Uri.Segments.Count())
|
||||
{
|
||||
case 3:
|
||||
floatingIpContent = TestHelper.CreateStream(GenerateCollectionPayload(this.FloatingIps, this.GenerateFloatingIpPayload, "floatingips"));
|
||||
break;
|
||||
case 4:
|
||||
var floatId = this.Uri.Segments[3].TrimEnd('/').ToLower();
|
||||
return HandleGetFloatingIp(floatId);
|
||||
default:
|
||||
//Unknown Uri format
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), floatingIpContent);
|
||||
}
|
||||
|
||||
internal IHttpResponseAbstraction HandleGetFloatingIp(string floatingIpId)
|
||||
{
|
||||
var payloadFixture = @"{{
|
||||
""floatingip"": {0}
|
||||
}}";
|
||||
|
||||
var floatIp = this.FloatingIps.FirstOrDefault(ip => ip.Id == floatingIpId);
|
||||
if (floatIp == null)
|
||||
{
|
||||
return TestHelper.CreateResponse(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
var floatIpContent = string.Format(payloadFixture, GenerateFloatingIpPayload(floatIp)).ConvertToStream();
|
||||
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), floatIpContent);
|
||||
}
|
||||
|
||||
protected override IHttpResponseAbstraction HandlePost()
|
||||
{
|
||||
if (this.Uri.Segments.Count() >= 3)
|
||||
{
|
||||
switch (this.Uri.Segments[2].TrimEnd('/').ToLower())
|
||||
{
|
||||
case "floatingips":
|
||||
return HandleCreateFloatingIp();
|
||||
}
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
internal IHttpResponseAbstraction HandleCreateFloatingIp()
|
||||
{
|
||||
var payloadFixture = @"{{
|
||||
""floatingip"": {0}
|
||||
}}";
|
||||
|
||||
var ip = new FloatingIp(Guid.NewGuid().ToString(), "172.0.0." +(this.FloatingIps.Count +1), FloatingIpStatus.Active);
|
||||
this.FloatingIps.Add(ip);
|
||||
var floatIpContent = string.Format(payloadFixture, GenerateFloatingIpPayload(ip)).ConvertToStream();
|
||||
return TestHelper.CreateResponse(HttpStatusCode.OK, new Dictionary<string, string>(), floatIpContent);
|
||||
}
|
||||
|
||||
protected override IHttpResponseAbstraction HandlePut()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
@@ -99,19 +160,20 @@ namespace OpenStack.Test.Network
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private string GenerateNetworksPayload(IEnumerable<OpenStack.Network.Network> networks)
|
||||
private string GenerateCollectionPayload<T>(IEnumerable<T> collection, Func<T, string> genFunc,
|
||||
string collectionName)
|
||||
{
|
||||
var payload = new StringBuilder();
|
||||
payload.Append("{{ \"networks\": [");
|
||||
payload.Append(string.Format("{{ \"{0}\": [", collectionName));
|
||||
var first = true;
|
||||
foreach (var item in networks)
|
||||
foreach (var item in collection)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
payload.Append(",");
|
||||
}
|
||||
|
||||
payload.Append(GenerateNetworkPayload(item));
|
||||
payload.Append(genFunc(item));
|
||||
first = false;
|
||||
}
|
||||
payload.Append("] }");
|
||||
@@ -134,6 +196,21 @@ namespace OpenStack.Test.Network
|
||||
}}";
|
||||
return string.Format(payloadFixture, network.Name, network.Id, network.Status.ToString().ToUpper());
|
||||
}
|
||||
|
||||
private string GenerateFloatingIpPayload(FloatingIp floatingIp)
|
||||
{
|
||||
var payloadFixture = @"{{
|
||||
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
|
||||
""status"": ""{1}"",
|
||||
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
|
||||
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
|
||||
""fixed_ip_address"": ""10.0.0.2"",
|
||||
""floating_ip_address"": ""{2}"",
|
||||
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
|
||||
""id"": ""{0}""
|
||||
}}";
|
||||
return string.Format(payloadFixture, floatingIp.Id, floatingIp.Status.ToString().ToUpper(), floatingIp.FloatingIpAddress);
|
||||
}
|
||||
}
|
||||
|
||||
public class NetworkRestSimulatorFactory : IHttpAbstractionClientFactory
|
||||
|
@@ -68,7 +68,7 @@ namespace OpenStack.Test.Network
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanGetFlavors()
|
||||
public async Task CanGetNetworks()
|
||||
{
|
||||
var ntw1 = new OpenStack.Network.Network("12345","MyNetwork", NetworkStatus.Active);
|
||||
var ntw2 = new OpenStack.Network.Network("54321", "NetworkMy", NetworkStatus.Down);
|
||||
@@ -85,5 +85,82 @@ namespace OpenStack.Test.Network
|
||||
Assert.AreEqual(ntw1, respNetworks[0]);
|
||||
Assert.AreEqual(ntw2, respNetworks[1]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanGetFloatingIps()
|
||||
{
|
||||
var ip1 = new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active);
|
||||
var ip2 = new OpenStack.Network.FloatingIp("54321", "172.0.0.2", FloatingIpStatus.Down);
|
||||
var ips = new List<OpenStack.Network.FloatingIp>() { ip1, ip2 };
|
||||
|
||||
this.ServicePocoClient.GetFloatingIpsDelegate = () => Task.Factory.StartNew(() => (IEnumerable<OpenStack.Network.FloatingIp>)ips);
|
||||
|
||||
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
|
||||
var resp = await client.GetFloatingIps();
|
||||
Assert.IsNotNull(resp);
|
||||
|
||||
var respIps = resp.ToList();
|
||||
Assert.AreEqual(2, respIps.Count());
|
||||
Assert.AreEqual(ip1, respIps[0]);
|
||||
Assert.AreEqual(ip2, respIps[1]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanGetFloatingIp()
|
||||
{
|
||||
var ip1 = new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active);
|
||||
|
||||
this.ServicePocoClient.GetFloatingIpDelegate = (ip) => Task.Factory.StartNew(() => ip1);
|
||||
|
||||
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
|
||||
var resp = await client.GetFloatingIp("12345");
|
||||
Assert.IsNotNull(resp);
|
||||
Assert.AreEqual(ip1, resp);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public async Task GetFloatingIpWithNullFloatingIpIdThrows()
|
||||
{
|
||||
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
|
||||
await client.GetFloatingIp(null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentException))]
|
||||
public async Task GetFloatingIpWithEmptyFloatingIpIdThrows()
|
||||
{
|
||||
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
|
||||
await client.GetFloatingIp(string.Empty);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanCreateFloatingIp()
|
||||
{
|
||||
var ip1 = new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active);
|
||||
|
||||
this.ServicePocoClient.CreateFloatingIpDelegate = (ip) => Task.Factory.StartNew(() => ip1);
|
||||
|
||||
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
|
||||
var resp = await client.CreateFloatingIp("12345");
|
||||
Assert.IsNotNull(resp);
|
||||
Assert.AreEqual(ip1, resp);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public async Task CreateFloatingIpWithNullNetworkIdThrows()
|
||||
{
|
||||
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
|
||||
await client.CreateFloatingIp(null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentException))]
|
||||
public async Task CreateFloatingIpWithEmptyNetworkIdThrows()
|
||||
{
|
||||
var client = new NetworkServiceClient(GetValidCreds(), "Neutron", CancellationToken.None, this.ServiceLocator);
|
||||
await client.CreateFloatingIp(string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -142,5 +142,184 @@ namespace OpenStack.Test.Network
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Floating IPs Tests
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanGetFloatingIpsWithOkResponse()
|
||||
{
|
||||
var payload = @"{
|
||||
""floatingips"": [
|
||||
{
|
||||
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
|
||||
""status"": ""ACTIVE"",
|
||||
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
|
||||
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
|
||||
""fixed_ip_address"": ""10.0.0.2"",
|
||||
""floating_ip_address"": ""172.0.0.1"",
|
||||
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
|
||||
""id"": ""12345""
|
||||
}
|
||||
]
|
||||
}";
|
||||
|
||||
var content = TestHelper.CreateStream(payload);
|
||||
|
||||
var restResp = new HttpResponseAbstraction(content, new HttpHeadersAbstraction(), HttpStatusCode.OK);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
var result = await client.GetFloatingIps();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
var floatingIps = result.ToList();
|
||||
Assert.AreEqual(1, floatingIps.Count());
|
||||
|
||||
var floatingIp = floatingIps.First();
|
||||
Assert.AreEqual("12345", floatingIp.Id);
|
||||
Assert.AreEqual("172.0.0.1", floatingIp.FloatingIpAddress);
|
||||
Assert.AreEqual(FloatingIpStatus.Active, floatingIp.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public async Task ExceptionthrownWhenGettingFloatingIpsAndNotAuthed()
|
||||
{
|
||||
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.Unauthorized);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
await client.GetFloatingIps();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public async Task ExceptionthrownWhenGettingFloatingIpsAndServerError()
|
||||
{
|
||||
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.InternalServerError);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
await client.GetFloatingIps();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Floating IP Tests
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanGetFloatingIpWithOkResponse()
|
||||
{
|
||||
var payload = @"{
|
||||
""floatingip"":
|
||||
{
|
||||
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
|
||||
""status"": ""ACTIVE"",
|
||||
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
|
||||
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
|
||||
""fixed_ip_address"": ""10.0.0.2"",
|
||||
""floating_ip_address"": ""172.0.0.1"",
|
||||
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
|
||||
""id"": ""12345""
|
||||
}
|
||||
}";
|
||||
|
||||
var content = TestHelper.CreateStream(payload);
|
||||
|
||||
var restResp = new HttpResponseAbstraction(content, new HttpHeadersAbstraction(), HttpStatusCode.OK);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
var result = await client.GetFloatingIp("12345");
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual("12345", result.Id);
|
||||
Assert.AreEqual("172.0.0.1", result.FloatingIpAddress);
|
||||
Assert.AreEqual(FloatingIpStatus.Active, result.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public async Task ExceptionthrownWhenGettingFloatingIpAndNotAuthed()
|
||||
{
|
||||
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.Unauthorized);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
await client.GetFloatingIp("12345");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public async Task ExceptionthrownWhenGettingFloatingIpAndServerError()
|
||||
{
|
||||
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.InternalServerError);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
await client.GetFloatingIp("12345");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Create Floating IP Tests
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanCreateFloatingIpWithOkResponse()
|
||||
{
|
||||
var payload = @"{
|
||||
""floatingip"":
|
||||
{
|
||||
""router_id"": ""fafac59b-a94a-4525-8700-f4f448e0ac97"",
|
||||
""status"": ""ACTIVE"",
|
||||
""tenant_id"": ""ffe683d1060449d09dac0bf9d7a371cd"",
|
||||
""floating_network_id"": ""3eaab3f7-d3f2-430f-aa73-d07f39aae8f4"",
|
||||
""fixed_ip_address"": ""10.0.0.2"",
|
||||
""floating_ip_address"": ""172.0.0.1"",
|
||||
""port_id"": ""9da94672-6e6b-446c-9579-3dd5484b31fd"",
|
||||
""id"": ""12345""
|
||||
}
|
||||
}";
|
||||
|
||||
var content = TestHelper.CreateStream(payload);
|
||||
|
||||
var restResp = new HttpResponseAbstraction(content, new HttpHeadersAbstraction(), HttpStatusCode.OK);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
var result = await client.CreateFloatingIp("12345");
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
||||
Assert.AreEqual("12345", result.Id);
|
||||
Assert.AreEqual("172.0.0.1", result.FloatingIpAddress);
|
||||
Assert.AreEqual(FloatingIpStatus.Active, result.Status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public async Task ExceptionthrownWhenCreatingFloatingIpAndNotAuthed()
|
||||
{
|
||||
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.Unauthorized);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
await client.CreateFloatingIp("12345");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(InvalidOperationException))]
|
||||
public async Task ExceptionthrownWhenCreatingFloatingIpAndServerError()
|
||||
{
|
||||
var restResp = new HttpResponseAbstraction(new MemoryStream(), new HttpHeadersAbstraction(), HttpStatusCode.InternalServerError);
|
||||
this.NetworkServiceRestClient.Responses.Enqueue(restResp);
|
||||
|
||||
var client = new NetworkServicePocoClient(GetValidContext(), this.ServiceLocator);
|
||||
await client.CreateFloatingIp("12345");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,7 @@ namespace OpenStack.Test.Network
|
||||
{
|
||||
internal NetworkRestSimulator simulator;
|
||||
internal string authId = "12345";
|
||||
internal Uri endpoint = new Uri("http://testnetworkendpoint.com/v2/1234567890");
|
||||
internal Uri endpoint = new Uri("http://testnetworkendpoint.com");
|
||||
internal IServiceLocator ServiceLocator;
|
||||
|
||||
[TestInitialize]
|
||||
@@ -91,7 +91,7 @@ namespace OpenStack.Test.Network
|
||||
|
||||
await client.GetNetworks();
|
||||
|
||||
Assert.AreEqual(string.Format("{0}/networks", endpoint), this.simulator.Uri.ToString());
|
||||
Assert.AreEqual(string.Format("{0}/networks", endpoint +"v2.0"), this.simulator.Uri.ToString());
|
||||
Assert.AreEqual(HttpMethod.Get, this.simulator.Method);
|
||||
}
|
||||
|
||||
@@ -112,5 +112,154 @@ namespace OpenStack.Test.Network
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get FloatingIps Tests
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetFloatingIpsIncludesAuthHeader()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
await client.GetFloatingIps();
|
||||
|
||||
Assert.IsTrue(this.simulator.Headers.ContainsKey("X-Auth-Token"));
|
||||
Assert.AreEqual(this.authId, this.simulator.Headers["X-Auth-Token"]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetFloatingIpsFormsCorrectUrlAndMethod()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
await client.GetFloatingIps();
|
||||
|
||||
Assert.AreEqual(string.Format("{0}/floatingips", endpoint + "v2.0"), this.simulator.Uri.ToString());
|
||||
Assert.AreEqual(HttpMethod.Get, this.simulator.Method);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanGetFloatingIps()
|
||||
{
|
||||
this.simulator.FloatingIps.Add(new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active));
|
||||
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
var resp = await client.GetFloatingIps();
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
|
||||
|
||||
var respContent = TestHelper.GetStringFromStream(resp.Content);
|
||||
Assert.IsTrue(respContent.Length > 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get FloatingIp Tests
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetFloatingIpIncludesAuthHeader()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
await client.GetNetworks();
|
||||
|
||||
Assert.IsTrue(this.simulator.Headers.ContainsKey("X-Auth-Token"));
|
||||
Assert.AreEqual(this.authId, this.simulator.Headers["X-Auth-Token"]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task GetFloatingIpFormsCorrectUrlAndMethod()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
await client.GetFloatingIp("12345");
|
||||
|
||||
Assert.AreEqual(string.Format("{0}/floatingips/12345", endpoint + "v2.0"), this.simulator.Uri.ToString());
|
||||
Assert.AreEqual(HttpMethod.Get, this.simulator.Method);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanGetFloatinIp()
|
||||
{
|
||||
this.simulator.FloatingIps.Add(new OpenStack.Network.FloatingIp("12345", "172.0.0.1", FloatingIpStatus.Active));
|
||||
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
var resp = await client.GetFloatingIp("12345");
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
|
||||
|
||||
var respContent = TestHelper.GetStringFromStream(resp.Content);
|
||||
Assert.IsTrue(respContent.Length > 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Create FloatingIp Tests
|
||||
|
||||
[TestMethod]
|
||||
public async Task CreateFloatingIpIncludesAuthHeader()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
await client.CreateFloatingIp("12345");
|
||||
|
||||
Assert.IsTrue(this.simulator.Headers.ContainsKey("X-Auth-Token"));
|
||||
Assert.AreEqual(this.authId, this.simulator.Headers["X-Auth-Token"]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CreateFloatingIpFormsCorrectUrlAndMethod()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
await client.CreateFloatingIp("12345");
|
||||
|
||||
Assert.AreEqual(string.Format("{0}/floatingips", endpoint + "v2.0"), this.simulator.Uri.ToString());
|
||||
Assert.AreEqual(HttpMethod.Post, this.simulator.Method);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CanCreateFloatinIp()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
var resp = await client.CreateFloatingIp("12345");
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
|
||||
|
||||
var respContent = TestHelper.GetStringFromStream(resp.Content);
|
||||
Assert.IsTrue(respContent.Length > 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task CreateFloatinIpFormCorrectBody()
|
||||
{
|
||||
var client =
|
||||
new NetworkServiceRestClient(GetValidContext(), this.ServiceLocator);
|
||||
|
||||
var resp = await client.CreateFloatingIp("12345");
|
||||
|
||||
Assert.AreEqual(HttpStatusCode.OK, resp.StatusCode);
|
||||
|
||||
this.simulator.Content.Position = 0;
|
||||
var body = TestHelper.GetStringFromStream(this.simulator.Content);
|
||||
var ipObj = JObject.Parse(body);
|
||||
Assert.IsNotNull(ipObj);
|
||||
Assert.IsNotNull(ipObj["floatingip"]);
|
||||
Assert.IsNotNull(ipObj["floatingip"]["floating_network_id"]);
|
||||
Assert.AreEqual("12345", (string)ipObj["floatingip"]["floating_network_id"]);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@@ -26,11 +26,31 @@ namespace OpenStack.Test.Network
|
||||
{
|
||||
public Func<Task<IEnumerable<OpenStack.Network.Network>>> GetNetworksDelegate { get; set; }
|
||||
|
||||
public Func<Task<IEnumerable<OpenStack.Network.FloatingIp>>> GetFloatingIpsDelegate { get; set; }
|
||||
|
||||
public Func<string, Task<OpenStack.Network.FloatingIp>> GetFloatingIpDelegate { get; set; }
|
||||
|
||||
public Func<string, Task<OpenStack.Network.FloatingIp>> CreateFloatingIpDelegate { get; set; }
|
||||
|
||||
public async Task<IEnumerable<OpenStack.Network.Network>> GetNetworks()
|
||||
{
|
||||
return await this.GetNetworksDelegate();
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<FloatingIp>> GetFloatingIps()
|
||||
{
|
||||
return await GetFloatingIpsDelegate();
|
||||
}
|
||||
|
||||
public async Task<FloatingIp> GetFloatingIp(string floatingIpId)
|
||||
{
|
||||
return await GetFloatingIpDelegate(floatingIpId);
|
||||
}
|
||||
|
||||
public async Task<FloatingIp> CreateFloatingIp(string networkId)
|
||||
{
|
||||
return await CreateFloatingIpDelegate(networkId);
|
||||
}
|
||||
}
|
||||
|
||||
public class TestNetworkServicePocoClientFactory : INetworkServicePocoClientFactory
|
||||
|
@@ -35,6 +35,21 @@ namespace OpenStack.Test.Network
|
||||
{
|
||||
return Task.Factory.StartNew(() => Responses.Dequeue());
|
||||
}
|
||||
|
||||
public Task<IHttpResponseAbstraction> GetFloatingIps()
|
||||
{
|
||||
return Task.Factory.StartNew(() => Responses.Dequeue());
|
||||
}
|
||||
|
||||
public Task<IHttpResponseAbstraction> GetFloatingIp(string floatingIpId)
|
||||
{
|
||||
return Task.Factory.StartNew(() => Responses.Dequeue());
|
||||
}
|
||||
|
||||
public Task<IHttpResponseAbstraction> CreateFloatingIp(string networkId)
|
||||
{
|
||||
return Task.Factory.StartNew(() => Responses.Dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
public class TestNetworkServiceRestClientFactory : INetworkServiceRestClientFactory
|
||||
|
@@ -83,6 +83,7 @@
|
||||
<Compile Include="Identity\OpenStackServiceCatalogTests.cs" />
|
||||
<Compile Include="Identity\IdentityServiceClientDefinitionTests.cs" />
|
||||
<Compile Include="Identity\OpenStackRegionResolverTests.cs" />
|
||||
<Compile Include="Network\FloatingIpPayloadConverterTests.cs" />
|
||||
<Compile Include="Network\NetworkServiceClientTests.cs" />
|
||||
<Compile Include="Network\NetworkServicePocoClientTests.cs" />
|
||||
<Compile Include="Network\NetworkPayloadConverterTests.cs" />
|
||||
|
@@ -63,7 +63,7 @@ namespace OpenStack.Common
|
||||
/// <returns>A complete request Uri.</returns>
|
||||
internal Uri CreateRequestUri(Uri endpoint, params string[] values)
|
||||
{
|
||||
var temp = new List<string> { endpoint.AbsoluteUri };
|
||||
var temp = new List<string> { endpoint.AbsoluteUri.TrimEnd('/') };
|
||||
temp.AddRange(values);
|
||||
return new Uri(string.Join("/", temp.ToArray()));
|
||||
}
|
||||
|
52
OpenStack/OpenStack/Network/FloatingIp.cs
Normal file
52
OpenStack/OpenStack/Network/FloatingIp.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
// /* ============================================================================
|
||||
// Copyright 2014 Hewlett Packard
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ============================================================================ */
|
||||
|
||||
namespace OpenStack.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Floating IP address on the remote OpenStack instance.
|
||||
/// </summary>
|
||||
public class FloatingIp
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the id of the FloatingIp.
|
||||
/// </summary>
|
||||
public string Id { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the status of the FloatingIp.
|
||||
/// </summary>
|
||||
public FloatingIpStatus Status { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the floating ip address of the FloatingIp.
|
||||
/// </summary>
|
||||
public string FloatingIpAddress { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of the FloatingIp class.
|
||||
/// </summary>
|
||||
/// <param name="id">The Id of the floating ip.</param>
|
||||
/// <param name="FloatingIpAddress">The floating ip address of the floating ip.</param>
|
||||
/// <param name="status">The status of the floating ip.</param>
|
||||
internal FloatingIp(string id, string FloatingIpAddress, FloatingIpStatus status)
|
||||
{
|
||||
this.Id = id;
|
||||
this.FloatingIpAddress = FloatingIpAddress;
|
||||
this.Status = status;
|
||||
}
|
||||
}
|
||||
}
|
122
OpenStack/OpenStack/Network/FloatingIpPayloadConverter.cs
Normal file
122
OpenStack/OpenStack/Network/FloatingIpPayloadConverter.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
// /* ============================================================================
|
||||
// Copyright 2014 Hewlett Packard
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ============================================================================ */
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OpenStack.Common;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenStack.Network
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <inheritdoc/>
|
||||
internal class FloatingIpPayloadConverter : IFloatingIpPayloadConverter
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public FloatingIp Convert(string payload)
|
||||
{
|
||||
payload.AssertIsNotNullOrEmpty("payload", "A null or empty floating ip payload cannot be converted.");
|
||||
|
||||
try
|
||||
{
|
||||
var token = JToken.Parse(payload);
|
||||
return ConvertFloatingIp(token["floatingip"]);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new FormatException(
|
||||
string.Format("Floating IP payload could not be parsed. Payload: '{0}'", payload), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a json token into a FloatingIp object.
|
||||
/// </summary>
|
||||
/// <param name="floatingIpToken">The json Token to convert.</param>
|
||||
/// <returns>A FloatingIp object.</returns>
|
||||
internal FloatingIp ConvertFloatingIp(JToken floatingIpToken)
|
||||
{
|
||||
var floatingIpAddress = string.Empty;
|
||||
var id = string.Empty;
|
||||
var status = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
floatingIpAddress = (string)floatingIpToken["floating_ip_address"];
|
||||
id = (string)floatingIpToken["id"];
|
||||
status = (string) floatingIpToken["status"];
|
||||
|
||||
if (string.IsNullOrEmpty(floatingIpAddress) || string.IsNullOrEmpty(id) || string.IsNullOrEmpty(status))
|
||||
{
|
||||
throw new FormatException();
|
||||
}
|
||||
|
||||
return new FloatingIp(id, floatingIpAddress, status.GetFloatingIpStatus());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = "Floating IP payload could not be parsed.";
|
||||
if (!string.IsNullOrEmpty(id) && floatingIpToken != null)
|
||||
{
|
||||
msg = string.Format(
|
||||
"Floating IP with Id '{0}' payload could not be parsed. Payload: '{1}'", id, floatingIpToken);
|
||||
}
|
||||
else if (floatingIpToken != null)
|
||||
{
|
||||
msg = string.Format("Floating IP payload could not be parsed. Payload: '{0}'", floatingIpToken);
|
||||
}
|
||||
|
||||
throw new FormatException(msg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<FloatingIp> ConvertFloatingIps(string payload)
|
||||
{
|
||||
payload.AssertIsNotNull("payload", "A null floating IPs payload cannot be converted.");
|
||||
|
||||
var floatingIps = new List<FloatingIp>();
|
||||
|
||||
if (String.IsNullOrEmpty(payload))
|
||||
{
|
||||
return floatingIps;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var payloadToken = JToken.Parse(payload);
|
||||
var floatingIpArray = payloadToken["floatingips"];
|
||||
floatingIps.AddRange(floatingIpArray.Select(ConvertFloatingIp));
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new FormatException(
|
||||
string.Format("Floating IPs payload could not be parsed. Payload: '{0}'", payload), ex);
|
||||
}
|
||||
|
||||
return floatingIps;
|
||||
}
|
||||
}
|
||||
}
|
67
OpenStack/OpenStack/Network/FloatingIpStatus.cs
Normal file
67
OpenStack/OpenStack/Network/FloatingIpStatus.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
// /* ============================================================================
|
||||
// Copyright 2014 Hewlett Packard
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ============================================================================ */
|
||||
|
||||
using OpenStack.Common;
|
||||
|
||||
namespace OpenStack.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the states that a Floating IP can be in.
|
||||
/// </summary>
|
||||
public enum FloatingIpStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The Floating IP is active and available.
|
||||
/// </summary>
|
||||
Active,
|
||||
|
||||
/// <summary>
|
||||
/// The Floating IP is down and unavailable.
|
||||
/// </summary>
|
||||
Down,
|
||||
|
||||
/// <summary>
|
||||
/// The Floating IP is in an unknown state.
|
||||
/// </summary>
|
||||
Unknown
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Static class for holding FloatingIpStatus related extention methods.
|
||||
/// </summary>
|
||||
public static class FloatingIpStatusExtentions
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a FloatingIpStatus enum from a string.
|
||||
/// </summary>
|
||||
/// <param name="input">The input string.</param>
|
||||
/// <returns>A FloatingIpStatus enum.</returns>
|
||||
public static FloatingIpStatus GetFloatingIpStatus(this string input)
|
||||
{
|
||||
input.AssertIsNotNullOrEmpty("input", "Cannot get Floating IP status with null or empty value.");
|
||||
|
||||
switch (input.ToLowerInvariant())
|
||||
{
|
||||
case "active":
|
||||
return FloatingIpStatus.Active;
|
||||
case "down":
|
||||
return FloatingIpStatus.Down;
|
||||
default:
|
||||
return FloatingIpStatus.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
OpenStack/OpenStack/Network/IFloatingIpPayloadConverter.cs
Normal file
40
OpenStack/OpenStack/Network/IFloatingIpPayloadConverter.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
// /* ============================================================================
|
||||
// Copyright 2014 Hewlett Packard
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ============================================================================ */
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenStack.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Converter that can be used to convert an HTTP payload into a FloatingIp Poco object.
|
||||
/// </summary>
|
||||
public interface IFloatingIpPayloadConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts an HTTP payload into a FloatingIp object.
|
||||
/// </summary>
|
||||
/// <param name="payload">The HTTP payload to convert. </param>
|
||||
/// <returns>A FloatingIp object.</returns>
|
||||
FloatingIp Convert(string payload);
|
||||
|
||||
/// <summary>
|
||||
/// Converts an HTTP payload into a list of FloatingIp objects.
|
||||
/// </summary>
|
||||
/// <param name="payload">The HTTP payload to convert.</param>
|
||||
/// <returns>An enumerable list of FloatingIp objects.</returns>
|
||||
IEnumerable<FloatingIp> ConvertFloatingIps(string payload);
|
||||
}
|
||||
}
|
@@ -29,5 +29,25 @@ namespace OpenStack.Network
|
||||
/// </summary>
|
||||
/// <returns>An enumerable list of networks.</returns>
|
||||
Task<IEnumerable<Network>> GetNetworks();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of Floating IPs from the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <returns>An enumerable list of floating ips.</returns>
|
||||
Task<IEnumerable<FloatingIp>> GetFloatingIps();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the details of a Floating IP from the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <param name="floatingIpId">The id of the target floating ip.</param>
|
||||
/// <returns>A FloatingIp object.</returns>
|
||||
Task<FloatingIp> GetFloatingIp(string floatingIpId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Floating IP on the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <param name="networkId">The network id to use when creating the new ip address.</param>
|
||||
/// <returns>A FloatingIp object.</returns>
|
||||
Task<FloatingIp> CreateFloatingIp(string networkId);
|
||||
}
|
||||
}
|
||||
|
@@ -29,5 +29,25 @@ namespace OpenStack.Network
|
||||
/// </summary>
|
||||
/// <returns>An enumerable list of networks.</returns>
|
||||
Task<IEnumerable<Network>> GetNetworks();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of Floating IPs from the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <returns>An enumerable list of floating ips.</returns>
|
||||
Task<IEnumerable<FloatingIp>> GetFloatingIps();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the details of a Floating IP from the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <param name="floatingIpId">The id of the target floating ip.</param>
|
||||
/// <returns>A FloatingIp object.</returns>
|
||||
Task<FloatingIp> GetFloatingIp(string floatingIpId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Floating IP on the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <param name="networkId">The network id to use when creating the new ip address.</param>
|
||||
/// <returns>A FloatingIp object.</returns>
|
||||
Task<FloatingIp> CreateFloatingIp(string networkId);
|
||||
}
|
||||
}
|
||||
|
@@ -29,5 +29,25 @@ namespace OpenStack.Network
|
||||
/// </summary>
|
||||
/// <returns>An HTTP response from the remote server.</returns>
|
||||
Task<IHttpResponseAbstraction> GetNetworks();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of Floating IPs from the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <returns>An HTTP response from the remote server.</returns>
|
||||
Task<IHttpResponseAbstraction> GetFloatingIps();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the details of a Floating IP from the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <param name="floatingIpId">The id of the target floating ip.</param>
|
||||
/// <returns>An HTTP response from the remote server.</returns>
|
||||
Task<IHttpResponseAbstraction> GetFloatingIp(string floatingIpId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Floating IP on the remote OpenStack instance.
|
||||
/// </summary>
|
||||
/// <param name="networkId">The network id to use when creating the new ip address.</param>
|
||||
/// <returns>An HTTP response from the remote server.</returns>
|
||||
Task<IHttpResponseAbstraction> CreateFloatingIp(string networkId);
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ namespace OpenStack.Network
|
||||
public NetworkStatus Status { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of the ComputeItem class.
|
||||
/// Create a new instance of the Network class.
|
||||
/// </summary>
|
||||
/// <param name="id">The Id of the network.</param>
|
||||
/// <param name="name">The name of the network.</param>
|
||||
|
@@ -53,6 +53,31 @@ namespace OpenStack.Network
|
||||
return await client.GetNetworks();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<FloatingIp>> GetFloatingIps()
|
||||
{
|
||||
var client = this.GetPocoClient();
|
||||
return await client.GetFloatingIps();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<FloatingIp> GetFloatingIp(string floatingIpId)
|
||||
{
|
||||
floatingIpId.AssertIsNotNullOrEmpty("floatingIpId", "Cannot get a floating ip with a null or empty id.");
|
||||
|
||||
var client = this.GetPocoClient();
|
||||
return await client.GetFloatingIp(floatingIpId);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<FloatingIp> CreateFloatingIp(string networkId)
|
||||
{
|
||||
networkId.AssertIsNotNullOrEmpty("networkId", "Cannot create a floating ip with a null or empty network id.");
|
||||
|
||||
var client = this.GetPocoClient();
|
||||
return await client.CreateFloatingIp(networkId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a client to interact with the remote OpenStack instance.
|
||||
/// </summary>
|
||||
|
@@ -59,6 +59,57 @@ namespace OpenStack.Network
|
||||
return networks;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IEnumerable<FloatingIp>> GetFloatingIps()
|
||||
{
|
||||
var client = this.GetRestClient();
|
||||
var resp = await client.GetFloatingIps();
|
||||
|
||||
if (resp.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Failed to get floating ips. The remote server returned the following status code: '{0}'.", resp.StatusCode));
|
||||
}
|
||||
|
||||
var converter = this.ServiceLocator.Locate<IFloatingIpPayloadConverter>();
|
||||
var floatingIps = converter.ConvertFloatingIps(await resp.ReadContentAsStringAsync());
|
||||
|
||||
return floatingIps;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<FloatingIp> GetFloatingIp(string floatingIpId)
|
||||
{
|
||||
var client = this.GetRestClient();
|
||||
var resp = await client.GetFloatingIp(floatingIpId);
|
||||
|
||||
if (resp.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Failed to get floating ip. The remote server returned the following status code: '{0}'.", resp.StatusCode));
|
||||
}
|
||||
|
||||
var converter = this.ServiceLocator.Locate<IFloatingIpPayloadConverter>();
|
||||
var floatingIp = converter.Convert(await resp.ReadContentAsStringAsync());
|
||||
|
||||
return floatingIp;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<FloatingIp> CreateFloatingIp(string networkId)
|
||||
{
|
||||
var client = this.GetRestClient();
|
||||
var resp = await client.CreateFloatingIp(networkId);
|
||||
|
||||
if (resp.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
throw new InvalidOperationException(string.Format("Failed to create floating ip. The remote server returned the following status code: '{0}'.", resp.StatusCode));
|
||||
}
|
||||
|
||||
var converter = this.ServiceLocator.Locate<IFloatingIpPayloadConverter>();
|
||||
var floatingIp = converter.Convert(await resp.ReadContentAsStringAsync());
|
||||
|
||||
return floatingIp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a client that can be used to connect to the REST endpoints of an OpenStack network service.
|
||||
/// </summary>
|
||||
|
@@ -14,8 +14,10 @@
|
||||
// limitations under the License.
|
||||
// ============================================================================ */
|
||||
|
||||
using System.Dynamic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OpenStack.Common;
|
||||
using OpenStack.Common.Http;
|
||||
using OpenStack.Common.ServiceLocation;
|
||||
@@ -26,6 +28,7 @@ namespace OpenStack.Network
|
||||
internal class NetworkServiceRestClient : OpenStackServiceRestClientBase, INetworkServiceRestClient
|
||||
{
|
||||
internal const string NetworksUrlMoniker = "networks";
|
||||
internal const string FloatingIpsUrlMoniker = "floatingips";
|
||||
internal const string NetworkVersionMoniker = "v2.0";
|
||||
|
||||
/// <summary>
|
||||
@@ -47,5 +50,49 @@ namespace OpenStack.Network
|
||||
|
||||
return await client.SendAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IHttpResponseAbstraction> GetFloatingIps()
|
||||
{
|
||||
var client = this.GetHttpClient(this.Context);
|
||||
|
||||
client.Uri = CreateRequestUri(this.Context.PublicEndpoint, NetworkVersionMoniker, FloatingIpsUrlMoniker);
|
||||
client.Method = HttpMethod.Get;
|
||||
|
||||
return await client.SendAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IHttpResponseAbstraction> GetFloatingIp(string floatingIpId)
|
||||
{
|
||||
floatingIpId.AssertIsNotNullOrEmpty("floatingIpId", "Cannot get a floating ip with a null or empty id.");
|
||||
|
||||
var client = this.GetHttpClient(this.Context);
|
||||
|
||||
client.Uri = CreateRequestUri(this.Context.PublicEndpoint, NetworkVersionMoniker, FloatingIpsUrlMoniker, floatingIpId);
|
||||
client.Method = HttpMethod.Get;
|
||||
|
||||
return await client.SendAsync();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IHttpResponseAbstraction> CreateFloatingIp(string networkId)
|
||||
{
|
||||
var client = this.GetHttpClient(this.Context);
|
||||
|
||||
client.Uri = CreateRequestUri(this.Context.PublicEndpoint, NetworkVersionMoniker, FloatingIpsUrlMoniker);
|
||||
client.Method = HttpMethod.Post;
|
||||
client.ContentType = "application/json";
|
||||
|
||||
dynamic body = new ExpandoObject();
|
||||
dynamic networkIdProp = new ExpandoObject();
|
||||
networkIdProp.floating_network_id = networkId;
|
||||
body.floatingip = networkIdProp;
|
||||
string requestBody = JToken.FromObject(body).ToString();
|
||||
|
||||
client.Content = requestBody.ConvertToStream();
|
||||
|
||||
return await client.SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -111,9 +111,12 @@
|
||||
<Compile Include="IOpenStackServiceClient.cs" />
|
||||
<Compile Include="IOpenStackServiceClientDefinition.cs" />
|
||||
<Compile Include="IOpenStackServiceClientManager.cs" />
|
||||
<Compile Include="Network\FloatingIp.cs" />
|
||||
<Compile Include="Network\IFloatingIpPayloadConverter.cs" />
|
||||
<Compile Include="Network\INetworkServiceClient.cs" />
|
||||
<Compile Include="Network\INetworkServicePocoClient.cs" />
|
||||
<Compile Include="Network\INetworkServicePocoClientFactory.cs" />
|
||||
<Compile Include="Network\FloatingIpPayloadConverter.cs" />
|
||||
<Compile Include="Network\NetworkPayloadConverter.cs" />
|
||||
<Compile Include="Network\INetworkPayloadConverter.cs" />
|
||||
<Compile Include="Network\INetworkServiceRestClient.cs" />
|
||||
@@ -125,6 +128,7 @@
|
||||
<Compile Include="Network\NetworkServicePocoClientFactory.cs" />
|
||||
<Compile Include="Network\NetworkServiceRestClient.cs" />
|
||||
<Compile Include="Network\NetworkServiceRestClientFactory.cs" />
|
||||
<Compile Include="Network\FloatingIpStatus.cs" />
|
||||
<Compile Include="Network\NetworkStatus.cs" />
|
||||
<Compile Include="OpenStackClient.cs" />
|
||||
<Compile Include="OpenStackClientFactory.cs" />
|
||||
|
@@ -63,6 +63,7 @@ namespace OpenStack
|
||||
manager.RegisterServiceInstance(typeof(IOpenStackServiceEndpointPayloadConverter), new OpenStackServiceEndpointPayloadConverter());
|
||||
manager.RegisterServiceInstance(typeof(IComputeFlavorPayloadConverter), new ComputeFlavorPayloadConverter());
|
||||
manager.RegisterServiceInstance(typeof(INetworkPayloadConverter), new NetworkPayloadConverter());
|
||||
manager.RegisterServiceInstance(typeof(IFloatingIpPayloadConverter), new FloatingIpPayloadConverter());
|
||||
manager.RegisterServiceInstance(typeof(IComputeImagePayloadConverter), new ComputeImagePayloadConverter());
|
||||
manager.RegisterServiceInstance(typeof(IComputeItemMetadataPayloadConverter), new ComputeItemMetadataPayloadConverter());
|
||||
manager.RegisterServiceInstance(typeof(IComputeServerPayloadConverter), new ComputeServerPayloadConverter());
|
||||
|
@@ -277,6 +277,18 @@
|
||||
<Compile Include="..\OpenStack\IOpenStackServiceClientManager.cs">
|
||||
<Link>IOpenStackServiceClientManager.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\OpenStack\Network\FloatingIp.cs">
|
||||
<Link>Network\FloatingIp.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\OpenStack\Network\FloatingIpPayloadConverter.cs">
|
||||
<Link>Network\FloatingIpPayloadConverter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\OpenStack\Network\FloatingIpStatus.cs">
|
||||
<Link>Network\FloatingIpStatus.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\OpenStack\Network\IFloatingIpPayloadConverter.cs">
|
||||
<Link>Network\IFloatingIpPayloadConverter.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\OpenStack\Network\INetworkPayloadConverter.cs">
|
||||
<Link>Network\INetworkPayloadConverter.cs</Link>
|
||||
</Compile>
|
||||
|
Reference in New Issue
Block a user