Skip to content

Commit 7a97e3a

Browse files
committed
Merge pull request #91 from Azure/dev
.
2 parents a38fa2d + 670693b commit 7a97e3a

File tree

80 files changed

+1329
-91
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1329
-91
lines changed

AzurePowershell.Test.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<XUnitTests Include=".\src\ResourceManager\TrafficManager\Commands.TrafficManager2.Test\bin\Debug\Microsoft.Azure.Commands.TrafficManager.Test.ScenarioTests.dll"/>
6868
<XUnitTests Include=".\src\ServiceManagement\Network\Commands.Network.Test\bin\Debug\Microsoft.WindowsAzure.Commands.ServiceManagement.Network.Test.dll"/>
6969
<XUnitTests Include=".\src\ResourceManager\ApiManagement\Commands.ApiManagement.Test\bin\Debug\Microsoft.Azure.Commands.ApiManagement.Test.dll"/>
70+
<XUnitTests Include=".\src\Common\Commands.ResourceManager.Profile.Test\bin\Debug\Microsoft.Azure.Commands.Profile.Test.dll"/>
7071
</ItemGroup>
7172

7273
<Target Name="InvokeMSTest">

src/Common/Commands.Common.Storage/Commands.Common.Storage.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,17 @@
5757
<HintPath>..\..\packages\Microsoft.Azure.Common.2.1.0\lib\net45\Microsoft.Azure.Common.dll</HintPath>
5858
</Reference>
5959
<Reference Include="Microsoft.Azure.Common.Authentication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
60-
<SpecificVersion>False</SpecificVersion>
6160
<HintPath>..\..\packages\Microsoft.Azure.Common.Authentication.1.3.0-preview\lib\net45\Microsoft.Azure.Common.Authentication.dll</HintPath>
61+
<Private>True</Private>
6262
</Reference>
6363
<Reference Include="Microsoft.Azure.Common.NetFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
6464
<SpecificVersion>False</SpecificVersion>
6565
<HintPath>..\..\packages\Microsoft.Azure.Common.2.1.0\lib\net45\Microsoft.Azure.Common.NetFramework.dll</HintPath>
6666
</Reference>
67+
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
68+
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
69+
<Private>True</Private>
70+
</Reference>
6771
<Reference Include="Microsoft.Azure.ResourceManager, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
6872
<SpecificVersion>False</SpecificVersion>
6973
<HintPath>..\..\packages\Microsoft.Azure.Management.Resources.2.18.7-preview\lib\net40\Microsoft.Azure.ResourceManager.dll</HintPath>

src/Common/Commands.Common.Storage/packages.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<package id="Microsoft.Azure.Common" version="2.1.0" targetFramework="net45" />
55
<package id="Microsoft.Azure.Common.Authentication" version="1.3.0-preview" targetFramework="net45" />
66
<package id="Microsoft.Azure.Common.Dependencies" version="1.0.0" targetFramework="net45" />
7+
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net45" />
78
<package id="Microsoft.Azure.Management.Resources" version="2.18.7-preview" targetFramework="net45" />
89
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
910
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
@@ -21,4 +22,4 @@
2122
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
2223
<package id="System.Spatial" version="5.6.4" targetFramework="net45" />
2324
<package id="WindowsAzure.Storage" version="5.0.0" targetFramework="net45" />
24-
</packages>
25+
</packages>

src/Common/Commands.Common/Commands.Common.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@
6464
<HintPath>..\..\packages\Microsoft.Azure.Common.2.1.0\lib\net45\Microsoft.Azure.Common.dll</HintPath>
6565
</Reference>
6666
<Reference Include="Microsoft.Azure.Common.Authentication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
67-
<SpecificVersion>False</SpecificVersion>
6867
<HintPath>..\..\packages\Microsoft.Azure.Common.Authentication.1.3.0-preview\lib\net45\Microsoft.Azure.Common.Authentication.dll</HintPath>
68+
<Private>True</Private>
6969
</Reference>
7070
<Reference Include="Microsoft.Azure.Common.NetFramework">
7171
<SpecificVersion>False</SpecificVersion>

src/Common/Commands.Common/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
<package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="0.9.3" targetFramework="net45" />
1717
<package id="Microsoft.WindowsAzure.Management" version="4.1.1" targetFramework="net45" />
1818
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
19-
</packages>
19+
</packages>

src/Common/Commands.ResourceManager.Common/Commands.ResourceManager.Common.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
<HintPath>..\..\packages\Microsoft.Azure.Common.2.1.0\lib\net45\Microsoft.Azure.Common.dll</HintPath>
6262
</Reference>
6363
<Reference Include="Microsoft.Azure.Common.Authentication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
64-
<SpecificVersion>False</SpecificVersion>
6564
<HintPath>..\..\packages\Microsoft.Azure.Common.Authentication.1.3.0-preview\lib\net45\Microsoft.Azure.Common.Authentication.dll</HintPath>
65+
<Private>True</Private>
6666
</Reference>
6767
<Reference Include="Microsoft.Azure.Common.NetFramework">
6868
<SpecificVersion>False</SpecificVersion>
@@ -184,6 +184,7 @@
184184
</Compile>
185185
<Compile Include="AccessTokenExtensions.cs" />
186186
<Compile Include="AzureRMCmdlet.cs" />
187+
<Compile Include="ModelExtensions.cs" />
187188
<Compile Include="Properties\AssemblyInfo.cs" />
188189
<Compile Include="Properties\Resources.Designer.cs">
189190
<AutoGen>True</AutoGen>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Microsoft.Azure.Common.Authentication.Models;
7+
using Microsoft.Azure.Subscriptions.Models;
8+
9+
namespace Microsoft.Azure.Commands.ResourceManager.Common
10+
{
11+
public static class ModelExtensions
12+
{
13+
14+
public static AzureSubscription ToAzureSubscription(this Subscription other, AzureContext context)
15+
{
16+
var subscription = new AzureSubscription();
17+
subscription.Account = context.Account != null ? context.Account.Id : null;
18+
subscription.Environment = context.Environment != null ? context.Environment.Name : EnvironmentName.AzureCloud;
19+
subscription.Id = new Guid(other.SubscriptionId);
20+
subscription.Name = other.DisplayName;
21+
subscription.SetProperty(AzureSubscription.Property.Tenants,
22+
context.Tenant.Id.ToString());
23+
return subscription;
24+
}
25+
}
26+
}

src/Common/Commands.ResourceManager.Common/RMProfileClient.cs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,18 @@ public List<AzureTenant> ListTenants(string tenant)
140140
.ToList();
141141
}
142142

143+
public bool TryGetSubscription(string tenantId, string subscriptionId, out AzureSubscription subscription)
144+
{
145+
if (string.IsNullOrWhiteSpace(tenantId))
146+
{
147+
throw new ArgumentNullException("Please provide a valid tenant Id");
148+
}
149+
150+
AzureTenant tenant;
151+
return TryGetTenantSubscription(_profile.Context.Account, _profile.Context.Environment,
152+
tenantId, subscriptionId, null, ShowDialog.Never, out subscription, out tenant);
153+
}
154+
143155
private bool TryGetTenantSubscription(
144156
AzureAccount account,
145157
AzureEnvironment environment,
@@ -177,7 +189,8 @@ private bool TryGetTenantSubscription(
177189
if (subscriptions.Count > 1)
178190
{
179191
WriteWarningMessage(string.Format(
180-
"Tenant '{0}' contains more than one subscription. First one will be selected for further use.",
192+
"Tenant '{0}' contains more than one subscription. First one will be selected for further use. " +
193+
"To select another subscription, use Set-AzureRMContext.",
181194
tenantId));
182195
}
183196
subscriptionFromServer = subscriptions.First();
@@ -233,12 +246,91 @@ private List<AzureTenant> ListAccountTenants(AzureAccount account, AzureEnvironm
233246
}
234247
}
235248

249+
/// <summary>
250+
/// List all tenants for the account in the profile context
251+
/// </summary>
252+
/// <returns>The list of tenants for the default account.</returns>
253+
public IEnumerable<AzureTenant> ListTenants()
254+
{
255+
return ListAccountTenants(_profile.Context.Account, _profile.Context.Environment, null, ShowDialog.Never);
256+
}
257+
258+
private IEnumerable<AzureSubscription> ListSubscriptionsForTenant(AzureAccount account, AzureEnvironment environment,
259+
SecureString password, ShowDialog promptBehavior, string tenantId)
260+
{
261+
var accessToken = AzureSession.AuthenticationFactory.Authenticate(
262+
account,
263+
environment,
264+
tenantId,
265+
password,
266+
promptBehavior);
267+
using (var subscriptionClient = AzureSession.ClientFactory.CreateCustomClient<SubscriptionClient>(
268+
new TokenCloudCredentials(accessToken.AccessToken),
269+
environment.GetEndpointAsUri(AzureEnvironment.Endpoint.ResourceManager)))
270+
{
271+
var subscriptions = subscriptionClient.Subscriptions.List();
272+
if (subscriptions != null && subscriptions.Subscriptions != null)
273+
{
274+
return
275+
subscriptions.Subscriptions.Select(
276+
(s) =>
277+
s.ToAzureSubscription(new AzureContext(_profile.Context.Subscription, account,
278+
environment, CreateTenantFromString(tenantId))));
279+
}
280+
281+
return null;
282+
}
283+
}
284+
285+
public IEnumerable<AzureSubscription> ListSubscriptions(string tenant)
286+
{
287+
return ListSubscriptionsForTenant(_profile.Context.Account, _profile.Context.Environment, null,
288+
ShowDialog.Never, tenant);
289+
}
290+
291+
public IEnumerable<AzureSubscription> ListSubscriptions()
292+
{
293+
List<AzureSubscription> subscriptions = new List<AzureSubscription>();
294+
foreach (var tenant in ListTenants())
295+
{
296+
try
297+
{
298+
subscriptions.AddRange(ListSubscriptions(tenant.Id.ToString()));
299+
}
300+
catch (AadAuthenticationException)
301+
{
302+
WriteWarningMessage(string.Format("Could not authenticate user account {0} with tenant {1}. " +
303+
"Subscriptions in this tenant will not be listed. Please login again using Login-AzureRMAccount " +
304+
"to view the subscriptions in this tenant.", _profile.Context.Account, tenant));
305+
}
306+
307+
}
308+
309+
return subscriptions;
310+
}
311+
236312
private void WriteWarningMessage(string message)
237313
{
238314
if (WarningLog != null)
239315
{
240316
WarningLog(message);
241317
}
242318
}
319+
320+
private static AzureTenant CreateTenantFromString(string tenantOrDomain)
321+
{
322+
AzureTenant result = new AzureTenant();
323+
Guid id;
324+
if (Guid.TryParse(tenantOrDomain, out id))
325+
{
326+
result.Id = id;
327+
}
328+
else
329+
{
330+
result.Domain = tenantOrDomain;
331+
}
332+
333+
return result;
334+
}
243335
}
244336
}

src/Common/Commands.ResourceManager.Common/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
<package id="Microsoft.Rest.ClientRuntime.Azure.Authentication" version="0.9.3" targetFramework="net45" />
1717
<package id="Microsoft.WindowsAzure.Management" version="4.1.1" targetFramework="net45" />
1818
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
19-
</packages>
19+
</packages>
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.Common.Authentication;
16+
using Microsoft.Azure.Common.Authentication.Models;
17+
using System.Linq;
18+
using Xunit;
19+
using System;
20+
using Microsoft.WindowsAzure.Commands.Common.Test.Mocks;
21+
using System.Collections.Generic;
22+
using Microsoft.WindowsAzure.Commands.ScenarioTest;
23+
24+
namespace Microsoft.Azure.Commands.ResourceManager.Common.Test
25+
{
26+
27+
public class AzureRMProfileTests
28+
{
29+
private const string DefaultAccount = "admin@contoso.com";
30+
private static Guid DefaultSubscription = Guid.NewGuid();
31+
private static string DefaultSubscriptionName = "Contoso Subscription";
32+
private static string DefaultDomain = "contoso.com";
33+
private static Guid DefaultTenant = Guid.NewGuid();
34+
35+
private static RMProfileClient SetupTestEnvironment(List<string> tenants, params List<string>[] subscriptionLists)
36+
{
37+
AzureSession.AuthenticationFactory = new MockTokenAuthenticationFactory(DefaultAccount,
38+
Guid.NewGuid().ToString(), DefaultTenant.ToString());
39+
var subscriptionList = new Queue<List<string>>(subscriptionLists);
40+
var clientFactory = new MockSubscriptionClientFactory(tenants, subscriptionList);
41+
var mock = new MockClientFactory(new List<object>
42+
{
43+
clientFactory.GetSubscriptionClient()
44+
}, true);
45+
mock.MoqClients = true;
46+
AzureSession.ClientFactory = mock;
47+
var context = new AzureContext(new AzureSubscription()
48+
{
49+
Account = DefaultAccount,
50+
Environment = EnvironmentName.AzureCloud,
51+
Id = DefaultSubscription,
52+
Name = DefaultSubscriptionName
53+
},
54+
new AzureAccount() { Id = DefaultAccount, Type = AzureAccount.AccountType.User },
55+
AzureEnvironment.PublicEnvironments[EnvironmentName.AzureCloud],
56+
new AzureTenant() { Domain = DefaultDomain, Id = DefaultTenant });
57+
var profile = new AzureRMProfile();
58+
profile.Context = context;
59+
return new RMProfileClient(profile);
60+
}
61+
62+
[Fact]
63+
[Trait(Category.AcceptanceType, Category.CheckIn)]
64+
public void MultipleTenantsAndSubscriptionsSucceed()
65+
{
66+
var tenants = new List<string> {Guid.NewGuid().ToString(), DefaultTenant.ToString()};
67+
var firstList = new List<string> { DefaultSubscription.ToString(), Guid.NewGuid().ToString() };
68+
var secondList = new List<string> { Guid.NewGuid().ToString()};
69+
var client = SetupTestEnvironment(tenants, firstList, secondList);
70+
var subResults = new List<AzureSubscription>(client.ListSubscriptions());
71+
Assert.Equal(3, subResults.Count);
72+
var tenantResults = client.ListTenants();
73+
Assert.Equal(2, tenantResults.Count());
74+
tenantResults = client.ListTenants(DefaultTenant.ToString());
75+
Assert.Equal(1, tenantResults.Count());
76+
AzureSubscription subValue;
77+
Assert.True(client.TryGetSubscription(DefaultTenant.ToString(), DefaultSubscription.ToString(), out subValue));
78+
Assert.Equal(DefaultSubscription.ToString(), subValue.Id.ToString());
79+
}
80+
81+
[Fact]
82+
[Trait(Category.AcceptanceType, Category.CheckIn)]
83+
public void SingleTenantAndSubscriptionSucceeds()
84+
{
85+
var tenants = new List<string> {DefaultTenant.ToString()};
86+
var subscriptions = new List<string> {DefaultSubscription.ToString()};
87+
var client = SetupTestEnvironment(tenants, subscriptions);
88+
var subResults = new List<AzureSubscription>(client.ListSubscriptions());
89+
Assert.Equal(1, subResults.Count);
90+
var tenantResults = client.ListTenants();
91+
Assert.Equal(1, tenantResults.Count());
92+
tenantResults = client.ListTenants(DefaultTenant.ToString());
93+
Assert.Equal(1, tenantResults.Count());
94+
AzureSubscription subValue;
95+
Assert.True(client.TryGetSubscription(DefaultTenant.ToString(), DefaultSubscription.ToString(), out subValue));
96+
Assert.Equal(DefaultSubscription.ToString(), subValue.Id.ToString());
97+
}
98+
99+
[Fact]
100+
[Trait(Category.AcceptanceType, Category.CheckIn)]
101+
public void SubscriptionNotFoundDoesNotThrow()
102+
{
103+
var tenants = new List<string> { DefaultTenant.ToString() };
104+
var subscriptions = new List<string> { Guid.NewGuid().ToString() };
105+
var client = SetupTestEnvironment(tenants, subscriptions);
106+
var subResults = new List<AzureSubscription>(client.ListSubscriptions());
107+
Assert.Equal(1, subResults.Count);
108+
AzureSubscription subValue;
109+
Assert.False(client.TryGetSubscription(DefaultTenant.ToString(), DefaultSubscription.ToString(), out subValue));
110+
}
111+
112+
[Fact]
113+
[Trait(Category.AcceptanceType, Category.CheckIn)]
114+
public void NoTenantsDoesNotThrow()
115+
{
116+
var tenants = new List<string> { };
117+
var subscriptions = new List<string> { Guid.NewGuid().ToString() };
118+
var client = SetupTestEnvironment(tenants, subscriptions);
119+
Assert.Equal(0, client.ListSubscriptions().Count());
120+
Assert.Equal(0, client.ListTenants().Count());
121+
}
122+
123+
[Fact]
124+
[Trait(Category.AcceptanceType, Category.CheckIn)]
125+
public void NoSubscriptionsInListThrows()
126+
{
127+
var tenants = new List<string> { DefaultTenant.ToString() };
128+
var subscriptions = new List<string> () ;
129+
var client = SetupTestEnvironment(tenants, subscriptions);
130+
Assert.Equal(0, client.ListSubscriptions().Count());
131+
AzureSubscription subValue;
132+
Assert.False(client.TryGetSubscription(DefaultTenant.ToString(), DefaultSubscription.ToString(), out subValue));
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)