Skip to content

Commit ffbc689

Browse files
committed
Merge pull request #253 from sharwell/fix-239
Fix 239
2 parents 9843d4c + 0bce5f9 commit ffbc689

4 files changed

Lines changed: 188 additions & 13 deletions

File tree

src/corelib/Providers/Rackspace/CloudDnsProvider.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,8 @@ public Task<DnsJob<DnsRecordsList>> AddPtrRecordsAsync(string serviceName, Uri d
893893
new JProperty("href", new JValue(deviceResourceUri.AbsoluteUri)),
894894
new JProperty("rel", new JValue(serviceName)),
895895
new JProperty("content", new JValue(string.Empty)))),
896-
new JProperty("records", JArray.FromObject(recordConfigurations)));
896+
new JProperty("recordsList", new JObject(
897+
new JProperty("records", JArray.FromObject(recordConfigurations)))));
897898
Func<Task<Tuple<IdentityToken, Uri>>, Task<HttpWebRequest>> prepareRequest =
898899
PrepareRequestAsyncFunc(HttpMethod.POST, template, parameters, request);
899900

@@ -938,8 +939,8 @@ public Task<DnsJob> UpdatePtrRecordsAsync(string serviceName, Uri deviceResource
938939
new JProperty("href", new JValue(deviceResourceUri.AbsoluteUri)),
939940
new JProperty("rel", new JValue(serviceName)),
940941
new JProperty("content", new JValue(string.Empty)))),
941-
new JProperty("recordsList",
942-
new JProperty("records", JArray.FromObject(recordConfigurations))));
942+
new JProperty("recordsList", new JObject(
943+
new JProperty("records", JArray.FromObject(recordConfigurations)))));
943944
Func<Task<Tuple<IdentityToken, Uri>>, Task<HttpWebRequest>> prepareRequest =
944945
PrepareRequestAsyncFunc(HttpMethod.PUT, template, parameters, request);
945946

src/testing/integration/Providers/Rackspace/UserDnsTests.cs

Lines changed: 162 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Diagnostics;
66
using System.Linq;
77
using System.Net;
8+
using System.Net.Sockets;
89
using System.Text.RegularExpressions;
910
using System.Threading;
1011
using System.Threading.Tasks;
@@ -15,6 +16,7 @@
1516
using net.openstack.Core.Providers;
1617
using net.openstack.Providers.Rackspace;
1718
using net.openstack.Providers.Rackspace.Objects.Dns;
19+
using net.openstack.Providers.Rackspace.Objects.LoadBalancers;
1820
using Newtonsoft.Json;
1921
using Path = System.IO.Path;
2022

@@ -54,7 +56,18 @@ public void CleanupTestDomains()
5456
IDnsService provider = CreateProvider();
5557
using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(60))))
5658
{
57-
DnsDomain[] allDomains = ListAllDomains(provider, null, null, cancellationTokenSource.Token).Where(i => i.Name.StartsWith(TestDomainPrefix, StringComparison.OrdinalIgnoreCase)).ToArray();
59+
Func<DnsDomain, bool> domainFilter =
60+
domain =>
61+
{
62+
if (domain.Name.StartsWith(TestDomainPrefix, StringComparison.OrdinalIgnoreCase))
63+
return true;
64+
else if (domain.Name.IndexOf('.' + TestDomainPrefix, StringComparison.OrdinalIgnoreCase) >= 0)
65+
return true;
66+
67+
return false;
68+
};
69+
70+
DnsDomain[] allDomains = ListAllDomains(provider, null, null, cancellationTokenSource.Token).Where(domainFilter).ToArray();
5871

5972
List<Task> deleteTasks = new List<Task>();
6073
for (int i = 0; i < allDomains.Length; i += BatchSize)
@@ -556,22 +569,35 @@ public async Task TestCreateRecords()
556569
Console.WriteLine(await JsonConvert.SerializeObjectAsync(domain, Formatting.Indented));
557570
}
558571

572+
string originalData = "127.0.0.1";
573+
string updatedData = "192.168.0.1";
574+
string originalCommentValue = "Integration test record";
575+
string updatedCommentValue = "Integration test record 2";
576+
TimeSpan? originalTimeToLive;
577+
TimeSpan? updatedTimeToLive = TimeSpan.FromMinutes(12);
578+
559579
DomainId domainId = createResponse.Response.Domains[0].Id;
560580
DnsDomainRecordConfiguration[] recordConfigurations =
561581
{
562582
new DnsDomainRecordConfiguration(
563583
type: DnsRecordType.A,
564584
name: string.Format("www.{0}", domainName),
565-
data: "127.0.0.1",
585+
data: originalData,
566586
timeToLive: null,
567-
comment: "Integration test record",
587+
comment: originalCommentValue,
568588
priority: null)
569-
570589
};
571590
DnsJob<DnsRecordsList> recordsResponse = await provider.AddRecordsAsync(domainId, recordConfigurations, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
572591
Assert.IsNotNull(recordsResponse.Response);
573592
Assert.IsNotNull(recordsResponse.Response.Records);
574593
DnsRecord[] records = recordsResponse.Response.Records.ToArray();
594+
Assert.AreEqual(recordConfigurations.Length, records.Length);
595+
originalTimeToLive = records[0].TimeToLive;
596+
Assert.AreNotEqual(originalTimeToLive, updatedTimeToLive);
597+
598+
Assert.AreEqual(originalData, records[0].Data);
599+
Assert.AreEqual(originalTimeToLive, records[0].TimeToLive);
600+
Assert.AreEqual(originalCommentValue, records[0].Comment);
575601

576602
foreach (var record in records)
577603
{
@@ -581,7 +607,31 @@ public async Task TestCreateRecords()
581607
Console.WriteLine(await JsonConvert.SerializeObjectAsync(record, Formatting.Indented));
582608
}
583609

584-
await provider.UpdateRecordsAsync(domainId, new[] { new DnsDomainRecordUpdateConfiguration(records[0], records[0].Name, comment: "Integration test record 2") }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
610+
DnsDomainRecordUpdateConfiguration recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], records[0].Name, comment: updatedCommentValue);
611+
await provider.UpdateRecordsAsync(domainId, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
612+
DnsRecord updatedRecord = await provider.ListRecordDetailsAsync(domainId, records[0].Id, cancellationTokenSource.Token);
613+
Assert.IsNotNull(updatedRecord);
614+
Assert.AreEqual(originalData, updatedRecord.Data);
615+
Assert.AreEqual(originalTimeToLive, updatedRecord.TimeToLive);
616+
Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);
617+
618+
recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], records[0].Name, timeToLive: updatedTimeToLive);
619+
await provider.UpdateRecordsAsync(domainId, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
620+
updatedRecord = await provider.ListRecordDetailsAsync(domainId, records[0].Id, cancellationTokenSource.Token);
621+
Assert.IsNotNull(updatedRecord);
622+
Assert.AreEqual(originalData, updatedRecord.Data);
623+
Assert.AreEqual(updatedTimeToLive, updatedRecord.TimeToLive);
624+
Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);
625+
626+
recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], records[0].Name, data: updatedData);
627+
await provider.UpdateRecordsAsync(domainId, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
628+
updatedRecord = await provider.ListRecordDetailsAsync(domainId, records[0].Id, cancellationTokenSource.Token);
629+
Assert.IsNotNull(updatedRecord);
630+
Assert.AreEqual(updatedData, updatedRecord.Data);
631+
Assert.AreEqual(updatedTimeToLive, updatedRecord.TimeToLive);
632+
Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);
633+
634+
await provider.RemoveRecordsAsync(domainId, new[] { records[0].Id }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
585635

586636
DnsJob deleteResponse = await provider.RemoveDomainsAsync(createdDomains.Select(i => i.Id), false, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
587637
if (deleteResponse.Status == DnsJobStatus.Error)
@@ -592,6 +642,111 @@ public async Task TestCreateRecords()
592642
}
593643
}
594644

645+
[TestMethod]
646+
[TestCategory(TestCategories.User)]
647+
[TestCategory(TestCategories.Dns)]
648+
public async Task TestCreatePtrRecords()
649+
{
650+
string domainName = CreateRandomDomainName();
651+
string loadBalancerName = UserLoadBalancerTests.CreateRandomLoadBalancerName();
652+
653+
IDnsService provider = CreateProvider();
654+
ILoadBalancerService loadBalancerProvider = UserLoadBalancerTests.CreateProvider();
655+
using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(60))))
656+
{
657+
IEnumerable<LoadBalancingProtocol> protocols = await loadBalancerProvider.ListProtocolsAsync(cancellationTokenSource.Token);
658+
LoadBalancingProtocol httpProtocol = protocols.First(i => i.Name.Equals("HTTP", StringComparison.OrdinalIgnoreCase));
659+
660+
LoadBalancerConfiguration loadBalancerConfiguration = new LoadBalancerConfiguration(
661+
name: loadBalancerName,
662+
nodes: null,
663+
protocol: httpProtocol,
664+
virtualAddresses: new[] { new LoadBalancerVirtualAddress(LoadBalancerVirtualAddressType.Public) },
665+
algorithm: LoadBalancingAlgorithm.RoundRobin);
666+
LoadBalancer loadBalancer = await loadBalancerProvider.CreateLoadBalancerAsync(loadBalancerConfiguration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
667+
Assert.IsNotNull(loadBalancer.VirtualAddresses);
668+
Assert.IsTrue(loadBalancer.VirtualAddresses.Count > 0);
669+
670+
string originalData = loadBalancer.VirtualAddresses[0].Address.ToString();
671+
string originalName = string.Format("www.{0}", domainName);
672+
string updatedName = string.Format("www2.{0}", domainName);
673+
string originalCommentValue = "Integration test record";
674+
string updatedCommentValue = "Integration test record 2";
675+
TimeSpan? originalTimeToLive;
676+
TimeSpan? updatedTimeToLive = TimeSpan.FromMinutes(12);
677+
678+
DnsDomainRecordConfiguration[] recordConfigurations =
679+
{
680+
new DnsDomainRecordConfiguration(
681+
type: DnsRecordType.Ptr,
682+
name: string.Format("www.{0}", domainName),
683+
data: originalData,
684+
timeToLive: null,
685+
comment: originalCommentValue,
686+
priority: null)
687+
};
688+
string serviceName = "cloudLoadBalancers";
689+
Uri deviceResourceUri = await ((UserLoadBalancerTests.TestCloudLoadBalancerProvider)loadBalancerProvider).GetDeviceResourceUri(loadBalancer, cancellationTokenSource.Token);
690+
DnsJob<DnsRecordsList> recordsResponse = await provider.AddPtrRecordsAsync(serviceName, deviceResourceUri, recordConfigurations, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
691+
Assert.IsNotNull(recordsResponse.Response);
692+
Assert.IsNotNull(recordsResponse.Response.Records);
693+
DnsRecord[] records = recordsResponse.Response.Records.ToArray();
694+
Assert.AreEqual(recordConfigurations.Length, records.Length);
695+
originalTimeToLive = records[0].TimeToLive;
696+
Assert.AreNotEqual(originalTimeToLive, updatedTimeToLive);
697+
698+
Assert.AreEqual(originalData, records[0].Data);
699+
Assert.AreEqual(originalTimeToLive, records[0].TimeToLive);
700+
Assert.AreEqual(originalCommentValue, records[0].Comment);
701+
702+
foreach (var record in records)
703+
{
704+
Console.WriteLine();
705+
Console.WriteLine("Record: {0} ({1})", record.Name, record.Id);
706+
Console.WriteLine();
707+
Console.WriteLine(await JsonConvert.SerializeObjectAsync(record, Formatting.Indented));
708+
}
709+
710+
// update the comment and verify nothing else changed
711+
DnsDomainRecordUpdateConfiguration recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], originalName, originalData, comment: updatedCommentValue);
712+
await provider.UpdatePtrRecordsAsync(serviceName, deviceResourceUri, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
713+
DnsRecord updatedRecord = await provider.ListPtrRecordDetailsAsync(serviceName, deviceResourceUri, records[0].Id, cancellationTokenSource.Token);
714+
Assert.IsNotNull(updatedRecord);
715+
Assert.AreEqual(originalData, updatedRecord.Data);
716+
Assert.AreEqual(originalName, updatedRecord.Name);
717+
Assert.AreEqual(originalTimeToLive, updatedRecord.TimeToLive);
718+
Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);
719+
720+
// update the TTL and verify nothing else changed
721+
recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], originalName, originalData, timeToLive: updatedTimeToLive);
722+
await provider.UpdatePtrRecordsAsync(serviceName, deviceResourceUri, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
723+
updatedRecord = await provider.ListPtrRecordDetailsAsync(serviceName, deviceResourceUri, records[0].Id, cancellationTokenSource.Token);
724+
Assert.IsNotNull(updatedRecord);
725+
Assert.AreEqual(originalData, updatedRecord.Data);
726+
Assert.AreEqual(originalName, updatedRecord.Name);
727+
Assert.AreEqual(updatedTimeToLive, updatedRecord.TimeToLive);
728+
Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);
729+
730+
// update the name and verify nothing else changed
731+
recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], updatedName, originalData);
732+
await provider.UpdatePtrRecordsAsync(serviceName, deviceResourceUri, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
733+
updatedRecord = await provider.ListPtrRecordDetailsAsync(serviceName, deviceResourceUri, records[0].Id, cancellationTokenSource.Token);
734+
Assert.IsNotNull(updatedRecord);
735+
Assert.AreEqual(originalData, updatedRecord.Data);
736+
Assert.AreEqual(updatedName, updatedRecord.Name);
737+
Assert.AreEqual(updatedTimeToLive, updatedRecord.TimeToLive);
738+
Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);
739+
740+
// remove the PTR record
741+
// TODO: verify result?
742+
await provider.RemovePtrRecordsAsync(serviceName, deviceResourceUri, loadBalancer.VirtualAddresses[0].Address, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
743+
744+
/* Cleanup
745+
*/
746+
await loadBalancerProvider.RemoveLoadBalancerAsync(loadBalancer.Id, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
747+
}
748+
}
749+
595750
/// <summary>
596751
/// Gets all existing domains through a series of asynchronous operations,
597752
/// each of which requests a subset of the available domains.
@@ -701,12 +856,12 @@ private TimeSpan TestTimeout(TimeSpan timeout)
701856
return timeout;
702857
}
703858

704-
private string CreateRandomDomainName()
859+
internal static string CreateRandomDomainName()
705860
{
706861
return TestDomainPrefix + Path.GetRandomFileName().Replace('.', '-') + ".com";
707862
}
708863

709-
private IDnsService CreateProvider()
864+
internal static IDnsService CreateProvider()
710865
{
711866
CloudDnsProvider provider = new TestCloudDnsProvider(Bootstrapper.Settings.TestIdentity, Bootstrapper.Settings.DefaultRegion, false, null, null);
712867
provider.BeforeAsyncWebRequest +=

src/testing/integration/Providers/Rackspace/UserLoadBalancerTests.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
using Security.Cryptography.X509Certificates;
1919
using CancellationToken = System.Threading.CancellationToken;
2020
using CancellationTokenSource = System.Threading.CancellationTokenSource;
21+
using CloudIdentity = net.openstack.Core.Domain.CloudIdentity;
22+
using IIdentityProvider = net.openstack.Core.Providers.IIdentityProvider;
2123
using Interlocked = System.Threading.Interlocked;
24+
using IRestService = JSIStudios.SimpleRESTServices.Client.IRestService;
2225
using Path = System.IO.Path;
2326
using StringBuilder = System.Text.StringBuilder;
2427

@@ -2045,7 +2048,7 @@ private TimeSpan TestTimeout(TimeSpan timeout)
20452048
/// Creates a random load balancer name with the proper prefix for integration testing.
20462049
/// </summary>
20472050
/// <returns>A unique, randomly-generated load balancer name.</returns>
2048-
private string CreateRandomLoadBalancerName()
2051+
internal static string CreateRandomLoadBalancerName()
20492052
{
20502053
return TestLoadBalancerPrefix + Path.GetRandomFileName();
20512054
}
@@ -2055,9 +2058,9 @@ private string CreateRandomLoadBalancerName()
20552058
/// the <see cref="OpenstackNetSetings.TestIdentity"/>.
20562059
/// </summary>
20572060
/// <returns>An instance of <see cref="ILoadBalancerService"/> for integration testing.</returns>
2058-
private ILoadBalancerService CreateProvider()
2061+
internal static ILoadBalancerService CreateProvider()
20592062
{
2060-
var provider = new CloudLoadBalancerProvider(Bootstrapper.Settings.TestIdentity, Bootstrapper.Settings.DefaultRegion, null, null);
2063+
var provider = new TestCloudLoadBalancerProvider(Bootstrapper.Settings.TestIdentity, Bootstrapper.Settings.DefaultRegion, null, null);
20612064
provider.BeforeAsyncWebRequest +=
20622065
(sender, e) =>
20632066
{
@@ -2073,5 +2076,20 @@ private ILoadBalancerService CreateProvider()
20732076

20742077
return provider;
20752078
}
2079+
2080+
internal class TestCloudLoadBalancerProvider : CloudLoadBalancerProvider
2081+
{
2082+
public TestCloudLoadBalancerProvider(CloudIdentity defaultIdentity, string defaultRegion, IIdentityProvider identityProvider, IRestService restService)
2083+
: base(defaultIdentity, defaultRegion, identityProvider, restService)
2084+
{
2085+
}
2086+
2087+
public async Task<Uri> GetDeviceResourceUri(LoadBalancer loadBalancer, CancellationToken cancellationToken)
2088+
{
2089+
UriTemplate template = new UriTemplate("loadbalancers/{loadBalancerId}");
2090+
Uri baseAddress = await GetBaseUriAsync(cancellationToken);
2091+
return template.BindByName(baseAddress, new Dictionary<string, string> { { "loadBalancerId", loadBalancer.Id.Value } });
2092+
}
2093+
}
20762094
}
20772095
}

src/testing/integration/integration.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
<RequiredTargetFramework>3.5</RequiredTargetFramework>
6464
</Reference>
6565
<Reference Include="System.Net" />
66+
<Reference Include="System.ServiceModel" />
6667
</ItemGroup>
6768
<ItemGroup>
6869
<CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">

0 commit comments

Comments
 (0)