Skip to content

Commit

Permalink
AzureObject, ResourceGroupObject, VirtualNetworkObject.
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-shandar committed Oct 14, 2017
1 parent cf6fd68 commit ebfa508
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Azure.Experiments.Tests
{
internal sealed class AuthenticationResponse
{
public string token_type;
public string access_token;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0-preview-20170425-07" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="xunit" Version="2.3.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,83 +1,38 @@
using Microsoft.Rest;
using Xunit;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Http;
using System;
using System.IO;
using Newtonsoft.Json;
using Microsoft.Azure.Management.Compute;

namespace Azure.Experiments.Tests
{
public class ComputeTest
{
sealed class TokenProvider : ITokenProvider
{
public TokenProvider(Configuration c)
{
var parameters = new[]
{
KeyValuePair.Create("grant_type", "client_credentials"),
KeyValuePair.Create("client_id", c.applicationId),
KeyValuePair.Create("client_secret", c.clientSecret),
KeyValuePair.Create("resource", "https://management.core.windows.net/")
};
Content = new FormUrlEncodedContent(parameters);
Uri = new Uri("https://login.microsoftonline.com/" + c.tenantId + "/oauth2/token");
}

public async Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(
CancellationToken cancellationToken)
{
if (Header == null)
{
using (var client = new HttpClient())
{
var response = await client
.PostAsync(Uri, Content)
.Result
.Content
.ReadAsStringAsync();
var responseObject = JsonConvert.DeserializeObject<AuthenticationResponse>(
response);
Header = new AuthenticationHeaderValue(
responseObject.token_type, responseObject.access_token);
}
}
return Header;
}

private Uri Uri { get; }

private FormUrlEncodedContent Content { get; }

private AuthenticationHeaderValue Header { get; set; }
}

private sealed class AuthenticationResponse
[Fact]
public async void ResourceGroupTest()
{
public string token_type;
public string access_token;
var c = Credentials.Get();
var rg = new ResourceGroupObject("My");
var info = await rg.GetOrNullAsync(c);
var infoCreate = await rg.GetOrCreateAsync(c);
// await rg.DeleteAsync(c);
}

private sealed class Configuration
[Fact]
public async void VirtualNetworkTest()
{
public string applicationId;
public string tenantId;
public string clientSecret;
public string subscriptionId;
var c = Credentials.Get();
var rg = new ResourceGroupObject("My1");
var vn = new VirtualNetworkObject("My1", rg, "192.168.0.0/16");
var info = await vn.GetOrNullAsync(c);
var infoCreate = await vn.GetOrCreateAsync(c);
}

[Fact]
public async void Test1()
{
var text = File.ReadAllText(@"c:\Users\sergey\Desktop\php-test.json");
var c = JsonConvert.DeserializeObject<Configuration>(text);
var credentials = new TokenCredentials(new TokenProvider(c));
var client = new ComputeManagementClient(credentials);
client.SubscriptionId = c.subscriptionId;
var c = Credentials.Get();
var client = new ComputeManagementClient(c.Credentials)
{
SubscriptionId = c.SubscriptionId
};
var list = await client.VirtualMachines.ListAllAsync();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Azure.Experiments.Tests
{
internal sealed class Configuration
{
public string applicationId;
public string tenantId;
public string clientSecret;
public string subscriptionId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.Rest;
using Newtonsoft.Json;
using System.IO;

namespace Azure.Experiments.Tests
{
internal static class Credentials
{
public static Context Get()
{
var text = File.ReadAllText(@"c:\Users\sergey\Desktop\php-test.json");
var c = JsonConvert.DeserializeObject<Configuration>(text);
return new Context(new TokenCredentials(new TokenProvider(c)), c.subscriptionId);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Microsoft.Rest;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Net.Http;
using System;
using Newtonsoft.Json;

namespace Azure.Experiments.Tests
{
sealed class TokenProvider : ITokenProvider
{
public TokenProvider(Configuration c)
{
var parameters = new[]
{
KeyValuePair.Create("grant_type", "client_credentials"),
KeyValuePair.Create("client_id", c.applicationId),
KeyValuePair.Create("client_secret", c.clientSecret),
KeyValuePair.Create("resource", "https://management.core.windows.net/")
};
Content = new FormUrlEncodedContent(parameters);
Uri = new Uri("https://login.microsoftonline.com/" + c.tenantId + "/oauth2/token");
}

public async Task<AuthenticationHeaderValue> GetAuthenticationHeaderAsync(
CancellationToken cancellationToken)
{
if (Header == null)
{
using (var client = new HttpClient())
{
var response = await client
.PostAsync(Uri, Content)
.Result
.Content
.ReadAsStringAsync();
var responseObject = JsonConvert.DeserializeObject<AuthenticationResponse>(
response);
Header = new AuthenticationHeaderValue(
responseObject.token_type,
responseObject.access_token);
}
}
return Header;
}

private Uri Uri { get; }

private FormUrlEncodedContent Content { get; }

private AuthenticationHeaderValue Header { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Management.Compute" Version="16.3.0" />
<PackageReference Include="Microsoft.Azure.Management.Network" Version="15.0.0-preview" />
<PackageReference Include="Microsoft.Azure.Management.ResourceManager" Version="1.6.0-preview" />
</ItemGroup>

</Project>
88 changes: 88 additions & 0 deletions experiments/Azure.Experiments/Azure.Experiments/AzureObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using Microsoft.Rest.Azure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace Azure.Experiments
{
public abstract class AzureObject
{
public static IEnumerable<AzureObject> NoDependencies { get; }
= Enumerable.Empty<AzureObject>();

public string Name { get; }

public IEnumerable<AzureObject> Dependencies { get; }

public abstract Task CheckOrCreateAsync(Context c);

protected AzureObject(string name, IEnumerable<AzureObject> dependencies)
{
Name = name;
Dependencies = dependencies;
}
}

public abstract class AzureObject<T, C> : AzureObject
where T: class
{
public async Task<T> GetOrNullAsync(Context c)
{
if (!IsGetCalled)
{
IsGetCalled = true;
try
{
Info = await GetOrThrowAsync(CreateClient(c));
}
catch (CloudException e)
when (e.Response.StatusCode == HttpStatusCode.NotFound)
{
}
}
return Info;
}

public async Task<T> GetOrCreateAsync(Context c)
{
Info = await GetOrNullAsync(c);
if (Info == null)
{
// this can be optimized by using WaitForAll and a state
// machine for `Task<T> Info`. The state machine is required to
// avoid multiple creations of the same resource group.
foreach (var d in Dependencies)
{
await d.CheckOrCreateAsync(c);
}
Info = await CreateAsync(CreateClient(c));
}
return Info;
}

public Task DeleteAsync(Context c)
=> DeleteAsync(CreateClient(c));

public override Task CheckOrCreateAsync(Context c)
=> GetOrCreateAsync(c);

protected AzureObject(string name, IEnumerable<AzureObject> dependencies)
: base(name, dependencies)
{
}

protected abstract C CreateClient(Context c);

protected abstract Task<T> GetOrThrowAsync(C c);

protected abstract Task<T> CreateAsync(C c);

protected abstract Task DeleteAsync(C c);

private bool IsGetCalled;

private T Info;
}
}
27 changes: 27 additions & 0 deletions experiments/Azure.Experiments/Azure.Experiments/AzureResource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;

namespace Azure.Experiments
{
public abstract class AzureResource<T, C> : AzureObject<T, C>
where T : class
{
protected string ResourceGroupName { get; }

protected AzureResource(
string name,
ResourceGroupObject rg,
IEnumerable<AzureObject> dependencies)
: base(name, dependencies.Concat(new[] { rg }))
{
ResourceGroupName = rg.Name;
}

protected AzureResource(
string name,
ResourceGroupObject rg)
: this(name, rg, Enumerable.Empty<AzureObject>())
{
}
}
}
17 changes: 17 additions & 0 deletions experiments/Azure.Experiments/Azure.Experiments/Context.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Microsoft.Rest;

namespace Azure.Experiments
{
public class Context
{
public Context(ServiceClientCredentials credentials, string subscriptionId)
{
Credentials = credentials;
SubscriptionId = subscriptionId;
}

public ServiceClientCredentials Credentials { get; }

public string SubscriptionId { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Linq;
using Microsoft.Azure.Management.ResourceManager.Models;
using Microsoft.Azure.Management.ResourceManager;
using System.Threading.Tasks;

namespace Azure.Experiments
{
public sealed class ResourceGroupObject : AzureObject<
ResourceGroup, IResourceGroupsOperations>
{
public ResourceGroupObject(string name)
: base(name, NoDependencies)
{
}

protected override IResourceGroupsOperations CreateClient(Context c)
=> new ResourceManagementClient(c.Credentials)
{
SubscriptionId = c.SubscriptionId
}
.ResourceGroups;

protected override Task<ResourceGroup> CreateAsync(IResourceGroupsOperations c)
=> c.CreateOrUpdateAsync(
Name,
new ResourceGroup { Location = "eastus" });

protected override Task<ResourceGroup> GetOrThrowAsync(IResourceGroupsOperations c)
=> c.GetAsync(Name);

protected override Task DeleteAsync(IResourceGroupsOperations c)
=> c.DeleteAsync(Name);
}
}
Loading

0 comments on commit ebfa508

Please sign in to comment.