Skip to content

Commit 6ead027

Browse files
wyunchi-msBethanyZhouVeryEarlyazure-powershell-botdantedallag
authored
Resolve conflicts between release-2024-02-06 and main (#24097)
* [Account]Redirect DeviceCode Info from warning stream to information stream in `Connect-AzAccount` (#23665) * Redirct DeviceCode Info from warning stream to information stream * add change log * writehighlightedinformation * Formmat device code login message * rename writeinformation * polish code * update comments for CommonRepo.psm1 (#24077) * update comments for CommonRepo.psm1 * update * Sync resourceManagement.yml (#24085) * Implemention of AuxTenant parameter in New-AzResourceGroupDeployment. (#24088) * Implemention of AuxTenant parameter in New-AzResourceGroupDeployment. Allows cmdlet to work with deployments that reference resources in other tenants. For example, it allows vnet peering where the target vnet exists in a different tenant as the source vnet. * Polish ChangeLog.md * Revert Resources.sln --------- Co-authored-by: Jin Lei <[email protected]> Co-authored-by: Lei Jin <[email protected]> * Sync resourceManagement.yml (#24092) * Resolve conflict with main --------- Co-authored-by: Beisi Zhou <[email protected]> Co-authored-by: Yabo Hu <[email protected]> Co-authored-by: Azure PowerShell <[email protected]> Co-authored-by: Dante <[email protected]> Co-authored-by: Jin Lei <[email protected]> Co-authored-by: Lei Jin <[email protected]>
1 parent 30cb499 commit 6ead027

File tree

12 files changed

+211
-55
lines changed

12 files changed

+211
-55
lines changed

.github/policies/resourceManagement.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,6 +1717,22 @@ configuration:
17171717
- hiaga
17181718
replyTemplate: Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc ${mentionees}.
17191719
assignMentionees: False
1720+
- if:
1721+
- or:
1722+
- labelAdded:
1723+
label: Service Attention
1724+
- labelAdded:
1725+
label: DesktopVirtualization
1726+
- hasLabel:
1727+
label: Service Attention
1728+
- hasLabel:
1729+
label: DesktopVirtualization
1730+
then:
1731+
- mentionUsers:
1732+
mentionees:
1733+
- alec-baird,costinhagiu
1734+
replyTemplate: Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc ${mentionees}.
1735+
assignMentionees: False
17201736
- if:
17211737
- or:
17221738
- labelAdded:
@@ -2049,6 +2065,9 @@ configuration:
20492065
then:
20502066
- mentionUsers:
20512067
mentionees:
2068+
- bavneetsingh16
2069+
- Arif-lakhani
2070+
- ramyasreechakka
20522071
- NarayanThiru
20532072
replyTemplate: Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc ${mentionees}.
20542073
assignMentionees: False

src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
using Microsoft.WindowsAzure.Commands.Utilities.Common;
4646
using Microsoft.Azure.PowerShell.Common.Share.Survey;
4747
using Microsoft.Azure.Commands.Profile.Utilities;
48+
using System.Management.Automation.Runspaces;
4849

4950
namespace Microsoft.Azure.Commands.Profile
5051
{
@@ -249,6 +250,7 @@ protected override IAzureContext DefaultContext
249250
protected override void BeginProcessing()
250251
{
251252
base.BeginProcessing();
253+
ValidateActionRequiredMessageCanBePresented();
252254
if (AzureEnvironment.PublicEnvironments.ContainsKey(EnvironmentName.AzureCloud))
253255
{
254256
_environment = AzureEnvironment.PublicEnvironments[EnvironmentName.AzureCloud];
@@ -273,11 +275,19 @@ protected override void BeginProcessing()
273275

274276
_writeWarningEvent -= WriteWarningSender;
275277
_writeWarningEvent += WriteWarningSender;
278+
_writeInformationEvent -= WriteInformationSender;
279+
_writeInformationEvent += WriteInformationSender;
280+
276281
// store the original write warning handler, register a thread safe one
277282
AzureSession.Instance.TryGetComponent(WriteWarningKey, out _originalWriteWarning);
278283
AzureSession.Instance.UnregisterComponent<EventHandler<StreamEventArgs>>(WriteWarningKey);
279284
AzureSession.Instance.RegisterComponent(WriteWarningKey, () => _writeWarningEvent);
280285

286+
// store the original write information handler, register a thread safe one
287+
AzureSession.Instance.TryGetComponent(WriteInformationKey, out _originalWriteInformation);
288+
AzureSession.Instance.UnregisterComponent<EventHandler<StreamEventArgs>>(WriteInformationKey);
289+
AzureSession.Instance.RegisterComponent(WriteInformationKey, () => _writeInformationEvent);
290+
281291
// todo: ideally cancellation token should be passed to authentication factory as a parameter
282292
// however AuthenticationFactory.Authenticate does not support it
283293
// so I store it in AzureSession.Instance as a global variable
@@ -289,11 +299,19 @@ protected override void BeginProcessing()
289299
private event EventHandler<StreamEventArgs> _writeWarningEvent;
290300
private event EventHandler<StreamEventArgs> _originalWriteWarning;
291301

302+
private event EventHandler<StreamEventArgs> _writeInformationEvent;
303+
private event EventHandler<StreamEventArgs> _originalWriteInformation;
304+
292305
private void WriteWarningSender(object sender, StreamEventArgs args)
293306
{
294307
_tasks.Enqueue(new Task(() => this.WriteWarning(args.Message)));
295308
}
296309

310+
private void WriteInformationSender(object sender, StreamEventArgs args)
311+
{
312+
_tasks.Enqueue(new Task(() => this.WriteInformation(args.Message)));
313+
}
314+
297315
protected override void StopProcessing()
298316
{
299317
if (AzureSession.Instance.TryGetComponent("LoginCancellationToken", out CancellationTokenSource cancellationTokenSource))
@@ -562,6 +580,20 @@ public override void ExecuteCmdlet()
562580
}
563581
}
564582

583+
private void ValidateActionRequiredMessageCanBePresented()
584+
{
585+
if (UseDeviceAuthentication.IsPresent && IsWriteInformationIgnored())
586+
{
587+
throw new ActionPreferenceStopException(Resources.DoNotIgnoreInformationIfUserDeviceAuth);
588+
}
589+
}
590+
591+
private bool IsWriteInformationIgnored()
592+
{
593+
return !MyInvocation.BoundParameters.ContainsKey("InformationAction") && ActionPreference.Ignore.ToString().Equals(SessionState?.PSVariable?.GetValue("InformationPreference", ActionPreference.SilentlyContinue)?.ToString() ?? "") ||
594+
MyInvocation.BoundParameters.TryGetValue("InformationAction", out var value) && ActionPreference.Ignore.ToString().Equals(value?.ToString() ?? "", StringComparison.InvariantCultureIgnoreCase);
595+
}
596+
565597
private string PreProcessAuthScope()
566598
{
567599
string mappedScope = AuthScope;
@@ -774,6 +806,9 @@ protected override void EndProcessing()
774806
// unregister the thread-safe write warning, because it won't work out of this cmdlet
775807
AzureSession.Instance.UnregisterComponent<EventHandler<StreamEventArgs>>(WriteWarningKey);
776808
AzureSession.Instance.RegisterComponent(WriteWarningKey, () => _originalWriteWarning);
809+
// unregister the thread-safe write information, because it won't work out of this cmdlet
810+
AzureSession.Instance.UnregisterComponent<EventHandler<StreamEventArgs>>(WriteInformationKey);
811+
AzureSession.Instance.RegisterComponent(WriteInformationKey, () => _originalWriteInformation);
777812
}
778813
}
779814
}

src/Accounts/Accounts/ChangeLog.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@
1919
-->
2020

2121
## Upcoming Release
22+
* Redirected device code login messages from warning stream to information stream if use device authentication in `Connect-AzAccount`.
2223

2324
## Version 2.15.1
2425
* Upgraded the reference of Azure PowerShell Common to 1.3.90-preview.
2526
* Upgraded Azure.Identity to 1.10.3 [#23018].
2627
- Renamed token cache from `msal.cache` to `msal.cache.cae` or `masl.cache.nocae`.
2728
* Enabled Continue Access Evaluation (CAE) for all Service Principals login methods.
2829
* Supported signing in with Microsoft Account (MSA) via Web Account Manager (WAM). Enable it by `Set-AzConfig -EnableLoginByWam $true`.
29-
* Adjusted output format to be more user-friendly for `Get-AzContext/Tenant/Subscription` and `Invoke-AzRestMethod`.
30+
* Adjusted output format to be more user-friendly for `Get-AzContext/Tenant/Subscription` and `Invoke-AzRestMethod`, including
31+
- ordering and grouping output items to make items easy to find.
32+
- re-prioritizing positions for output properties to highlight valuable properties.
3033
* Fixed the multiple `x-ms-unique-id` values issue.
3134

3235
## Version 2.15.0

src/Accounts/Accounts/Properties/Resources.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Accounts/Accounts/Properties/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,4 +595,7 @@
595595
<data name="ProfileCredentialsWriteWarning" xml:space="preserve">
596596
<value>Personally identifiable information and confidential data may be written to the file located at '{0}'. Please ensure that appropriate access controls are assigned to the saved file.</value>
597597
</data>
598+
<data name="DoNotIgnoreInformationIfUserDeviceAuth" xml:space="preserve">
599+
<value>Please do not set InformationAction or $InformationPreference to Ignore if you want to use device code authentication.</value>
600+
</data>
598601
</root>

src/Accounts/Authenticators/DeviceCodeAuthenticator.cs

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212
// limitations under the License.
1313
// ----------------------------------------------------------------------------------
1414

15-
using System;
16-
using System.Threading;
17-
using System.Threading.Tasks;
18-
1915
using Azure.Core;
2016
using Azure.Identity;
2117

@@ -24,6 +20,12 @@
2420
using Microsoft.Azure.Commands.Common.Authentication;
2521
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
2622
using Microsoft.Azure.Commands.ResourceManager.Common;
23+
using Microsoft.WindowsAzure.Commands.Common;
24+
25+
using System;
26+
using System.Text;
27+
using System.Threading;
28+
using System.Threading.Tasks;
2729

2830
namespace Microsoft.Azure.PowerShell.Authenticators
2931
{
@@ -64,7 +66,7 @@ public override Task<IAccessToken> Authenticate(AuthenticationParameters paramet
6466

6567
private Task DeviceCodeFunc(DeviceCodeInfo info, CancellationToken cancellation)
6668
{
67-
WriteWarning(info.Message);
69+
WriteInfomartion(info.Message, info.UserCode);
6870
return Task.CompletedTask;
6971
}
7072

@@ -73,12 +75,29 @@ public override bool CanAuthenticate(AuthenticationParameters parameters)
7375
return (parameters as DeviceCodeParameters) != null;
7476
}
7577

76-
private void WriteWarning(string message)
78+
79+
private void WriteInfomartion(string message, string userCode)
7780
{
78-
EventHandler<StreamEventArgs> writeWarningEvent;
79-
if (AzureSession.Instance.TryGetComponent(AzureRMCmdlet.WriteWarningKey, out writeWarningEvent))
81+
82+
var loginInfo = new StringBuilder();
83+
string LoginToAzurePhrase = $"{PSStyle.Bold}{PSStyle.BackgroundColor.Blue}[Login to Azure]{PSStyle.Reset} ";
84+
loginInfo.Append(LoginToAzurePhrase);
85+
86+
if (!string.IsNullOrEmpty(userCode))
87+
{
88+
var formattedUserCode = $"{PSStyle.Underline}{userCode}{PSStyle.Reset}";
89+
var formattedMessage = message.Replace(userCode, formattedUserCode);
90+
loginInfo.Append(formattedMessage);
91+
}
92+
else
93+
{
94+
loginInfo.Append(message);
95+
}
96+
97+
EventHandler<StreamEventArgs> writeInforamtionEvent;
98+
if (AzureSession.Instance.TryGetComponent(AzureRMCmdlet.WriteInformationKey, out writeInforamtionEvent))
8099
{
81-
writeWarningEvent(this, new StreamEventArgs() { Message = message });
100+
writeInforamtionEvent(this, new StreamEventArgs() { Message = loginInfo.ToString() });
82101
}
83102
}
84103
}

src/Resources/ResourceManager/Implementation/ResourceGroupDeployments/NewAzureResourceGroupDeploymentCmdlet.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ public class NewAzureResourceGroupDeploymentCmdlet : DeploymentCreateCmdlet
7878
[Parameter(Mandatory = false, HelpMessage = "Run cmdlet in the background")]
7979
public SwitchParameter AsJob { get; set; }
8080

81+
[Parameter(Mandatory = false, HelpMessage = "Aux tenant ids for cross tenant references in deployments.")]
82+
public string[] AuxTenant { get; set; }
83+
8184
protected override ConfirmImpact ConfirmImpact => ((CmdletAttribute)Attribute.GetCustomAttribute(
8285
typeof(NewAzureResourceGroupDeploymentCmdlet),
8386
typeof(CmdletAttribute))).ConfirmImpact;
@@ -102,7 +105,8 @@ public class NewAzureResourceGroupDeploymentCmdlet : DeploymentCreateCmdlet
102105
Type = RollbackToLastDeployment ? OnErrorDeploymentType.LastSuccessful : OnErrorDeploymentType.SpecificDeployment,
103106
DeploymentName = RollbackToLastDeployment ? null : RollBackDeploymentName
104107
}
105-
: null
108+
: null,
109+
AuxTenantHeaders = GetAuxiliaryAuthHeaderFromTenantIds(AuxTenant)
106110
};
107111

108112
protected override PSDeploymentWhatIfCmdletParameters BuildWhatIfParameters() => new PSDeploymentWhatIfCmdletParameters(
@@ -117,7 +121,7 @@ public class NewAzureResourceGroupDeploymentCmdlet : DeploymentCreateCmdlet
117121
templateParametersUri: this.TemplateParameterUri,
118122
templateParametersObject: this.GetTemplateParameterObject(),
119123
resultFormat: this.WhatIfResultFormat,
120-
excludeChangeTypes: this.WhatIfExcludeChangeType);
124+
excludeChangeTypes: this.WhatIfExcludeChangeType);
121125

122126
protected override void OnProcessRecord()
123127
{

src/Resources/ResourceManager/SdkClient/NewResourceManagerSdkClient.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,15 @@ private DeploymentValidateResult ValidateDeployment(PSDeploymentCmdletParameters
511511
return ResourceManagementClient.Deployments.ValidateAtManagementGroupScope(parameters.ManagementGroupId, parameters.DeploymentName, scopedDeployment);
512512

513513
case DeploymentScopeType.ResourceGroup:
514-
return ResourceManagementClient.Deployments.Validate(parameters.ResourceGroupName, parameters.DeploymentName, deployment);
514+
if (parameters.AuxTenantHeaders != null)
515+
{
516+
return ResourceManagementClient.Deployments.ValidateWithHttpMessagesAsync(parameters.ResourceGroupName, parameters.DeploymentName, deployment,
517+
customHeaders: ConvertAuxTenantDictionary(parameters.AuxTenantHeaders)).GetAwaiter().GetResult().Body;
518+
}
519+
else
520+
{
521+
return ResourceManagementClient.Deployments.Validate(parameters.ResourceGroupName, parameters.DeploymentName, deployment);
522+
}
515523

516524
case DeploymentScopeType.Subscription:
517525
default:
@@ -647,7 +655,15 @@ private void BeginDeployment(PSDeploymentCmdletParameters parameters, Deployment
647655
break;
648656

649657
case DeploymentScopeType.ResourceGroup:
650-
ResourceManagementClient.Deployments.BeginCreateOrUpdate(parameters.ResourceGroupName, parameters.DeploymentName, deployment);
658+
if (parameters.AuxTenantHeaders != null)
659+
{
660+
ResourceManagementClient.Deployments.BeginCreateOrUpdateWithHttpMessagesAsync(parameters.ResourceGroupName, parameters.DeploymentName, deployment,
661+
customHeaders: ConvertAuxTenantDictionary(parameters.AuxTenantHeaders)).GetAwaiter().GetResult();
662+
}
663+
else
664+
{
665+
ResourceManagementClient.Deployments.BeginCreateOrUpdate(parameters.ResourceGroupName, parameters.DeploymentName, deployment);
666+
}
651667
break;
652668

653669
case DeploymentScopeType.Subscription:
@@ -656,6 +672,22 @@ private void BeginDeployment(PSDeploymentCmdletParameters parameters, Deployment
656672
break;
657673
}
658674
}
675+
/// <summary>
676+
/// Conversion method for aux tenant dictionary to put it in correct format for passing as custom header object in sdk.
677+
/// </summary>
678+
/// <param name="auxTenants">Dictionary of tenant to tokens.</param>
679+
private Dictionary<string, List<string>> ConvertAuxTenantDictionary(IDictionary<string, IList<string>> auxTenants)
680+
{
681+
if (auxTenants == null) return null;
682+
683+
var headers = new Dictionary<string, List<string>> ();
684+
foreach (KeyValuePair<string, IList<string>> entry in auxTenants)
685+
{
686+
headers[entry.Key] = entry.Value.ToList();
687+
}
688+
689+
return headers;
690+
}
659691

660692
private void RunDeploymentValidation(PSDeploymentCmdletParameters parameters, Deployment deployment)
661693
{

src/Resources/ResourceManager/SdkModels/Deployments/PSDeploymentCmdletParameters.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@ public class PSDeploymentCmdletParameters
4141
public string DeploymentDebugLogLevel { get; set; }
4242

4343
public OnErrorDeployment OnErrorDeployment { get; set; }
44+
45+
public IDictionary<string, IList<string>> AuxTenantHeaders { get; set; }
4446
}
4547
}

src/Resources/Resources/ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
-->
2020

2121
## Upcoming Release
22+
* Added `AuxTenant` parameter in `New-AzResourceGroupDeployment`to support cross-tenant deployment.
2223

2324
## Version 6.15.0
2425
* Supported `-SkipClientSideScopeValidation` in RoleAssignment and RoleDefinition related commands. [#22473]

0 commit comments

Comments
 (0)