Skip to content

Commit df7511f

Browse files
committed
Merge branch 'preview' of https://github.com/Azure/azure-powershell into preview
# Conflicts: # tools/StaticAnalysis/Exceptions/BreakingChangeIssues.csv
2 parents 61c1382 + 2a4ab91 commit df7511f

File tree

182 files changed

+302209
-213100
lines changed

Some content is hidden

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

182 files changed

+302209
-213100
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
This repository contains a set of PowerShell cmdlets for developers and administrators to develop, deploy and manage Microsoft Azure applications.
66

7+
Take a test run now from Azure Cloud Shell!
8+
9+
[![](https://shell.azure.com/images/launchcloudshell.png "Launch Azure Cloud Shell")](https://shell.azure.com/powershell)
10+
711
* For documentation on how to build and deploy applications to Microsoft Azure please see the [Microsoft Azure Documentation Center](https://docs.microsoft.com/en-us/azure/).
812
* For comprehensive documentation on the developer cmdlets see the [overview of Azure PowerShell](https://aka.ms/azpsdocs).
913
* For suggesting improvements, join our improvement discussion ([Issue #3692](https://github.com/Azure/azure-powershell/issues/3692)).

documentation/Using-Azure-TestFramework.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ To use this option, set the following environment variable before starting Visua
144144

145145
## Record or Playback Tests
146146

147-
1. Run the test and make sure that you got a generated .json file that matches the test name in the bin folder under *SessionRecords folder
147+
1. [Run the test](https://github.com/Azure/azure-powershell/wiki/Azure-Powershell-Developer-Guide#running-tests) and make sure that you got a generated .json file that matches the test name in the bin folder under *SessionRecords folder
148148
2. Copy SessionRecords folder inside the test project and add all *.json files in Visual Studio setting "Copy to Output Directory" property to "Copy if newer"
149149
3. To assure that the records work fine, delete the connection string (default mode is Playback mode) OR change HttpRecorderMode within the connection string to "Playback"
150150

documentation/azure-powershell-modules.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Below is a table of modules containing ARM cmdlets found in the [`AzureRM`](http
1717
| ------------------------------------- | --------------------------------------- | ----------------------- |
1818
| Analysis Services | `AzureRM.AnalysisServices` | [![Analysis Services](https://img.shields.io/powershellgallery/v/AzureRM.AnalysisServices.svg?style=flat-square&label=AzureRM.AnalysisServices)](https://www.powershellgallery.com/packages/AzureRM.AnalysisServices/) |
1919
| API Management | `AzureRM.ApiManagement` | [![API Management](https://img.shields.io/powershellgallery/v/AzureRM.ApiManagement.svg?style=flat-square&label=AzureRM.ApiManagement)](https://www.powershellgallery.com/packages/AzureRM.ApiManagement/) |
20+
| Application Insights | `AzureRM.ApplicationInsights` | [![Application Insights](https://img.shields.io/powershellgallery/v/AzureRM.ApplicationInsights.svg?style=flat-square&label=AzureRM.ApplicationInsights)](https://www.powershellgallery.com/packages/AzureRM.ApplicationInsights/) |
2021
| Automation | `AzureRM.Automation` | [![Automation](https://img.shields.io/powershellgallery/v/AzureRM.Automation.svg?style=flat-square&label=AzureRM.Automation)](https://www.powershellgallery.com/packages/AzureRM.Automation/) |
2122
| Backup | `AzureRM.Backup` | [![Backup](https://img.shields.io/powershellgallery/v/AzureRM.Backup.svg?style=flat-square&label=AzureRM.Backup)](https://www.powershellgallery.com/packages/AzureRM.Backup/)
2223
| Batch | `AzureRM.Batch` | [![Batch](https://img.shields.io/powershellgallery/v/AzureRM.Batch.svg?style=flat-square&label=AzureRM.Batch)](https://www.powershellgallery.com/packages/AzureRM.Batch/) |
@@ -31,6 +32,7 @@ Below is a table of modules containing ARM cmdlets found in the [`AzureRM`](http
3132
| Data Factory V2 | `AzureRM.DataFactoryV2` | [![Data Factory V2](https://img.shields.io/powershellgallery/v/AzureRM.DataFactoryV2.svg?style=flat-square&label=AzureRM.DataFactoryV2)](https://www.powershellgallery.com/packages/AzureRM.DataFactoryV2/) |
3233
| Data Lake Analytics | `AzureRM.DataLakeAnalytics` | [![Data Lake Analytics](https://img.shields.io/powershellgallery/v/AzureRM.DataLakeAnalytics.svg?style=flat-square&label=AzureRM.DataLakeAnalytics)](https://www.powershellgallery.com/packages/AzureRM.DataLakeAnalytics/) |
3334
| Data Lake Store | `AzureRM.DataLakeStore` | [![Data Lake Store](https://img.shields.io/powershellgallery/v/AzureRM.DataLakeStore.svg?style=flat-square&label=AzureRM.DataLakeStore)](https://www.powershellgallery.com/packages/AzureRM.DataLakeStore/) |
35+
| Data Migration | `AzureRM.DataMigration` | [![Data Migration](https://img.shields.io/powershellgallery/v/AzureRM.DataMigration.svg?style=flat-square&label=AzureRM.DataMigration)](https://www.powershellgallery.com/packages/AzureRM.DataMigration/) |
3436
| DevTest Labs | `AzureRM.DevTestLabs` | [![DevTest Labs](https://img.shields.io/powershellgallery/v/AzureRM.DevTestLabs.svg?style=flat-square&label=AzureRM.DevTestLabs)](https://www.powershellgallery.com/packages/AzureRM.DevTestLabs/) |
3537
| DNS | `AzureRM.Dns` | [![DNS](https://img.shields.io/powershellgallery/v/AzureRM.Dns.svg?style=flat-square&label=AzureRM.Dns)](https://www.powershellgallery.com/packages/AzureRM.Dns/) |
3638
| Event Grid | `AzureRM.EventGrid` | [![Event Grid](https://img.shields.io/powershellgallery/v/AzureRM.EventGrid.svg?style=flat-square&label=AzureRM.EventGrid)](https://www.powershellgallery.com/packages/AzureRM.EventGrid/) |
@@ -54,6 +56,7 @@ Below is a table of modules containing ARM cmdlets found in the [`AzureRM`](http
5456
| Recovery Services - Site Recovery | `AzureRM.RecoveryServices.SiteRecovery` | [![Recovery Services - Site Recovery](https://img.shields.io/powershellgallery/v/AzureRM.RecoveryServices.SiteRecovery.svg?style=flat-square&label=AzureRM.RecoveryServices.SiteRecovery)](https://www.powershellgallery.com/packages/AzureRM.RecoveryServices.SiteRecovery/) |
5557
| Redis Cache | `AzureRM.RedisCache` | [![Redis Cache](https://img.shields.io/powershellgallery/v/AzureRM.RedisCache.svg?style=flat-square&label=AzureRM.RedisCache)](https://www.powershellgallery.com/packages/AzureRM.RedisCache/) |
5658
| Relay | `AzureRM.Relay` | [![Relay](https://img.shields.io/powershellgallery/v/AzureRM.Relay.svg?style=flat-square&label=AzureRM.Relay)](https://www.powershellgallery.com/packages/AzureRM.Relay/) |
59+
| Reservations | `AzureRM.Reservations` | [![Reservations](https://img.shields.io/powershellgallery/v/AzureRM.Reservations.svg?style=flat-square&label=AzureRM.Reservations)](https://www.powershellgallery.com/packages/AzureRM.Reservations/) |
5760
| Resources | `AzureRM.Resources` | [![Resources](https://img.shields.io/powershellgallery/v/AzureRM.Resources.svg?style=flat-square&label=AzureRM.Resources)](https://www.powershellgallery.com/packages/AzureRM.Resources/) |
5861
| Scheduler | `AzureRM.Scheduler` | [![Scheduler](https://img.shields.io/powershellgallery/v/AzureRM.Scheduler.svg?style=flat-square&label=AzureRM.Scheduler)](https://www.powershellgallery.com/packages/AzureRM.Scheduler/) |
5962
| Server Management | `AzureRM.ServerManagement` | [![Server Management](https://img.shields.io/powershellgallery/v/AzureRM.ServerManagement.svg?style=flat-square&label=AzureRM.ServerManagement)](https://www.powershellgallery.com/packages/AzureRM.ServerManagement/) |

src/Common/Commands.Common.Authentication.Abstractions/AzureAccount.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ public static class AccountType
8484
public const string Certificate = "Certificate",
8585
User = "User",
8686
ServicePrincipal = "ServicePrincipal",
87-
AccessToken = "AccessToken";
87+
AccessToken = "AccessToken",
88+
ManagedService = "ManagedService";
8889
}
8990

9091
/// <summary>
@@ -117,7 +118,12 @@ public static class Property
117118
/// <summary>
118119
/// Thumbprint for associated certificate
119120
/// </summary>
120-
CertificateThumbprint = "CertificateThumbprint";
121+
CertificateThumbprint = "CertificateThumbprint",
122+
123+
/// <summary>
124+
/// Login Uri for Managed Service Login
125+
/// </summary>
126+
MSILoginUri = "MSILoginUri";
121127

122128

123129
}

src/Common/Commands.Common.Authentication.Abstractions/Interfaces/IExtensibleSettings.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System;
2-
// ----------------------------------------------------------------------------------
1+
// ----------------------------------------------------------------------------------
32
//
43
// Copyright Microsoft Corporation
54
// Licensed under the Apache License, Version 2.0 (the "License");

src/Common/Commands.Common.Authentication.Abstractions/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@
4747
// by using the '*' as shown below:
4848
// [assembly: AssemblyVersion("1.0.*")]
4949
[assembly: AssemblyVersion("1.0.0.0")]
50-
[assembly: AssemblyFileVersion("1.0.0.0")]
50+
[assembly: AssemblyFileVersion("1.1.0.0")]

src/Common/Commands.Common.Authentication.Test/AuthenticationFactoryTests.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,20 @@
2222
using Xunit;
2323
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
2424
using System.Linq;
25+
using Microsoft.Azure.Commands.Common.Authentication.Test;
26+
using Microsoft.WindowsAzure.Commands.Utilities.Common;
27+
using Xunit.Abstractions;
2528

2629
namespace Common.Authentication.Test
2730
{
2831
public class AuthenticationFactoryTests
2932
{
33+
ITestOutputHelper _output;
34+
public AuthenticationFactoryTests(ITestOutputHelper output)
35+
{
36+
_output = output;
37+
}
38+
3039
[Fact]
3140
[Trait(Category.AcceptanceType, Category.CheckIn)]
3241
public void VerifySubscriptionTokenCacheRemove()
@@ -135,6 +144,59 @@ public void CanAuthenticateWithAccessToken()
135144
VerifyToken(checkKVToken, kvToken, userId, tenant);
136145
}
137146

147+
[Fact]
148+
[Trait(Category.AcceptanceType, Category.CheckIn)]
149+
public void CanAuthenticateUsingMSIDefault()
150+
{
151+
AzureSessionInitializer.InitializeAzureSession();
152+
string expectedAccessToken = Guid.NewGuid().ToString();
153+
_output.WriteLine("Expected access token for default URI: {0}", expectedAccessToken);
154+
string expectedToken2 = Guid.NewGuid().ToString();
155+
string tenant = Guid.NewGuid().ToString();
156+
_output.WriteLine("Expected access token for custom URI: {0}", expectedToken2);
157+
string userId = "[email protected]";
158+
var account = new AzureAccount
159+
{
160+
Id = userId,
161+
Type = AzureAccount.AccountType.ManagedService
162+
};
163+
var environment = AzureEnvironment.PublicEnvironments["AzureCloud"];
164+
var expectedResource = environment.ActiveDirectoryServiceEndpointResourceId;
165+
var builder = new UriBuilder(AuthenticationFactory.DefaultMSILoginUri);
166+
builder.Query = string.Format("resource={0}", Uri.EscapeDataString(environment.ActiveDirectoryServiceEndpointResourceId));
167+
var defaultUri = builder.Uri.ToString();
168+
169+
var responses = new Dictionary<string, ManagedServiceTokenInfo>(StringComparer.OrdinalIgnoreCase)
170+
{
171+
{defaultUri, new ManagedServiceTokenInfo { AccessToken = expectedAccessToken, ExpiresIn = 3600, Resource=expectedResource}},
172+
{"http://myfunkyurl:10432/oauth2/token?resource=foo", new ManagedServiceTokenInfo { AccessToken = expectedToken2, ExpiresIn = 3600, Resource="foo"} }
173+
};
174+
AzureSession.Instance.RegisterComponent(HttpClientOperationsFactory.Name, () => TestHttpOperationsFactory.Create(responses, _output), true);
175+
var authFactory = new AuthenticationFactory();
176+
var token = authFactory.Authenticate(account, environment, tenant, null, null, null);
177+
_output.WriteLine($"Received access token for default Uri ${token.AccessToken}");
178+
Assert.Equal(expectedAccessToken, token.AccessToken);
179+
var account2 = new AzureAccount
180+
{
181+
Id = userId,
182+
Type = AzureAccount.AccountType.ManagedService
183+
};
184+
account2.SetProperty(AzureAccount.Property.MSILoginUri, "http://myfunkyurl:10432/oauth2/token");
185+
var token2 = authFactory.Authenticate(account2, environment, tenant, null, null, null, "foo");
186+
_output.WriteLine($"Received access token for custom Uri ${token2.AccessToken}");
187+
Assert.Equal(expectedToken2, token2.AccessToken);
188+
var token3 = authFactory.Authenticate(account, environment, tenant, null, null, null, "bar");
189+
Assert.Throws<InvalidOperationException>(() => token3.AccessToken);
190+
}
191+
192+
[Fact]
193+
[Trait(Category.AcceptanceType, Category.CheckIn)]
194+
void ResponseRedactionWorks()
195+
{
196+
Assert.Equal(" \"access_token\": \"<redacted>\"", GeneralUtilities.TransformBody(" \"access_token\": \"eyJo1234567\""));
197+
Assert.Equal(" \"foo\": \"bar\"", GeneralUtilities.TransformBody(" \"foo\": \"bar\""));
198+
}
199+
138200
void VerifyToken(IAccessToken checkToken, string expectedAccessToken, string expectedUserId, string expectedTenant)
139201
{
140202

src/Common/Commands.Common.Authentication.Test/Commands.Common.Authentication.Test.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="..\..\packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\..\packages\xunit.runner.visualstudio.2.1.0\build\net20\xunit.runner.visualstudio.props')" />
4-
<Import Project="..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props')" />
4+
<Import Project="..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props" Condition="Exists('..\..\packages\xunit.core.2.1.0\build\portable-net45+win8+wp8+wpa81\xunit.core.props')"/>
55
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
66
<PropertyGroup>
77
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -132,6 +132,7 @@
132132
<DesignTime>True</DesignTime>
133133
<DependentUpon>Resources.resx</DependentUpon>
134134
</Compile>
135+
<Compile Include="TestHttpOperationsFactory.cs" />
135136
<EmbeddedResource Include="Resources\ResourceLocator.cs" />
136137
</ItemGroup>
137138
<ItemGroup>
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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 System;
16+
using System.Collections.Concurrent;
17+
using System.Collections.Generic;
18+
using System.Linq;
19+
using System.Text;
20+
using System.Threading;
21+
using System.Threading.Tasks;
22+
using Xunit.Abstractions;
23+
24+
namespace Microsoft.Azure.Commands.Common.Authentication.Test
25+
{
26+
public class TestHttpOperationsFactory : IHttpOperationsFactory
27+
{
28+
ITestOutputHelper _output;
29+
private TestHttpOperationsFactory()
30+
{
31+
}
32+
33+
IDictionary<string, object> _responses = new ConcurrentDictionary<string, object>(StringComparer.OrdinalIgnoreCase);
34+
public IHttpOperations<T> GetHttpOperations<T>()
35+
{
36+
var result = new TestHttpOperations<T>(_responses, _output);
37+
return result;
38+
}
39+
40+
public static IHttpOperationsFactory Create<T>(IDictionary<string, T> responses, ITestOutputHelper output)
41+
{
42+
var factory = new TestHttpOperationsFactory();
43+
factory._output = output;
44+
foreach (var response in responses)
45+
{
46+
output.WriteLine($"[TestHttpOperationsFactory]: Adding request response pair {response.Key} => {response.Value}");
47+
factory._responses.Add(response.Key, response.Value);
48+
}
49+
50+
return factory;
51+
}
52+
53+
class TestHttpOperations<T> : IHttpOperations<T>
54+
{
55+
ITestOutputHelper _output;
56+
IDictionary<string, T> _responses = new ConcurrentDictionary<string, T>(StringComparer.OrdinalIgnoreCase);
57+
58+
public TestHttpOperations(IDictionary<string, T> responses, ITestOutputHelper output)
59+
{
60+
_output = output;
61+
foreach (var responsePair in responses)
62+
{
63+
output.WriteLine($"[TestHttpOperations]: Adding request response pair {responsePair.Key} => {responsePair.Value}");
64+
_responses.Add(responsePair);
65+
}
66+
}
67+
public TestHttpOperations(IDictionary<string, object> responses, ITestOutputHelper output)
68+
{
69+
_output = output;
70+
foreach (var responsePair in responses)
71+
{
72+
output.WriteLine($"[TestHttpOperations]: Adding request response pair {responsePair.Key} => {responsePair.Value}");
73+
_responses.Add(responsePair.Key, (T)(responsePair.Value));
74+
}
75+
}
76+
77+
public Task DeleteAsync(string requestUri, CancellationToken token)
78+
{
79+
throw new NotImplementedException();
80+
}
81+
82+
public Task<T> GetAsync(string requestUri, CancellationToken token)
83+
{
84+
if (!_responses.ContainsKey(requestUri))
85+
{
86+
throw new InvalidOperationException(string.Format("Unexpected request Uri '{0}'", requestUri));
87+
}
88+
89+
var output = _responses[requestUri];
90+
91+
_output.WriteLine($"[TestHttpOperations]: Sent Response ({output}) to request GET {requestUri}");
92+
return Task.FromResult(output);
93+
}
94+
95+
public Task<bool> HeadAsync(string requestUri, CancellationToken token)
96+
{
97+
throw new NotImplementedException();
98+
}
99+
100+
public Task<IEnumerable<T>> ListAsync(string requestUri, CancellationToken token)
101+
{
102+
throw new NotImplementedException();
103+
}
104+
105+
public Task<T> PutAsync(string requestUri, T payload, CancellationToken token)
106+
{
107+
throw new NotImplementedException();
108+
}
109+
110+
public IHttpOperations<T> WithHeader(string name, IEnumerable<string> value)
111+
{
112+
// Allow the client to set one or more headers, but we are not using these in validation
113+
return this;
114+
}
115+
}
116+
}
117+
}

0 commit comments

Comments
 (0)