Skip to content

Commit 15a1724

Browse files
merging changes with master branch
1 parent 2b207e5 commit 15a1724

File tree

2,504 files changed

+1126437
-601444
lines changed

Some content is hidden

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

2,504 files changed

+1126437
-601444
lines changed
Loading
Loading
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Description
2+
3+
The document is for those, who are familiar with SDK-based modules and want to give a try with auto-gen modules. The content will contain the comparation between these two kinds of modules from architecture, cmdlets differences, and onboard process, etc.
4+
5+
# Architecture
6+
7+
## SDK-based Module
8+
![image](images/sdkbased.PNG)
9+
10+
## Auto-gen Module
11+
![image](images/autogen.PNG)
12+
13+
# Cmdlet Parameters
14+
15+
Highlight parameters differences in auto-gen modules as below.
16+
17+
- No Set-* cmdlets, Set-* is replaced by New-* and Update-*
18+
- Add *[-SubscriptionId <String[]>]* parameter for get-* cmdlets and add for *[-SubscriptionId <String>]* parameter for the others
19+
- Do not support breaking change warning yet
20+
- Pipeline
21+
- Do not support to pipe in parent resource
22+
- Unify two types (through *-InputObject and -ResourceId*) of pipeline into one *-InputObject,* Users could either pipe in the resourceId or resource object
23+
# Implementation
24+
25+
## Process
26+
27+
### SDK-based Module
28+
29+
- Design review
30+
- Get a released management SDK for Dotnet
31+
- Implement cmdlets in C# based on management SDK for Dotnet
32+
- Implement testcases
33+
- Generate docs, and populate them with examples
34+
- Create a PR in master branch for code review
35+
36+
### Auto-gen Module
37+
38+
- Design review
39+
- Write a readme.md as the autorest.powershell configuration for the module, and normally, it should contains
40+
- links to swaggers in [azure-rest-api-specs](https://github.com/Azure/azure-rest-api-specs) (should pin to specific version through commit id to avoid potential breaking changes)
41+
- A reference to readme.azure.noprofile.md to inline common configurations
42+
- Module specific configurations, e.g. *module-version, title, subject-prefix...*
43+
- directive
44+
- customization
45+
- Implement testcases
46+
- Generate docs and populate them with examples
47+
- Create a PR in **generation** branch for code review
48+
- Azure team members will help merge code from generation branch to master branch
49+
50+
## Customization
51+
52+
### SDK-based Module
53+
54+
Since the cmdlets are handcrafted by developers, no special customization mechanism is required.
55+
56+
### Auto-gen Module
57+
58+
Customization could be done through three ways.
59+
60+
- Through directive in readme.md, please see [directives.md](https://github.com/Azure/autorest.powershell/blob/master/docs/directives.md) for details
61+
- Through PowerShell script, please see [customization.md](https://github.com/Azure/autorest.powershell/blob/master/docs/customization.md) for details
62+
- Through C# code
63+
64+
## Hero Scenario
65+
66+
### SDK-based Module
67+
68+
If your module relies on some other modules, you will need to rely on dotnet SDK of these modules, which could put in your module if only your module depends on them or in Az.Accouts they are some common modules required by several modules.
69+
70+
### Auto-gen Module
71+
72+
Generally speaking, hero scenarios are implemented through customization through PowerShell script above. Regarding to third party dependencies, there are two ways to handle it.
73+
74+
- Add the swaggers of the dependencies to readme.md either directly or by adding related helpers defined src/helpers if they are common shared modules
75+
- Rely on related Azure PowerShell modules, in this case, it is better you could add the logic to check whether the modules you rely on have installed or not
76+
77+
## Docs and Examples
78+
79+
### SDK-based Module
80+
81+
Docs are generated through playPS, please see [platyPS](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/help-generation.md#Installing-platyPS) for details. And developers should populate generated docs with examples.
82+
83+
### Auto-gen Module
84+
85+
Autorest.powershell will generate example stubs in the examples folder, which should be populated by the developers manually. When building, examples in the examples folder will be automatically merged into docs.
86+
87+
## Test
88+
89+
### SDK-based Module
90+
91+
Tests are written in C# code.
92+
93+
### Auto-gen Module
94+
95+
Tests are written in PowerShell script. And we will leverage PowerShell test framework [Pester](https://github.com/pester/Pester).
96+
97+
# Others
98+
99+
## Data plane support
100+
101+
We are still working on bringing data plane to auto-gen.

src/Accounts/Accounts.Test/AutosaveTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ void ResetState()
5353
Environment.SetEnvironmentVariable("Azure_PS_Data_Collection", "false");
5454
PowerShellTokenCacheProvider tokenProvider = new InMemoryTokenCacheProvider();
5555
AzureSession.Instance.RegisterComponent(PowerShellTokenCacheProvider.PowerShellTokenCacheProviderKey, () => tokenProvider);
56-
AzureSession.Instance.RegisterComponent(nameof(PowerShellTokenCache), () => tokenProvider.GetTokenCache());
5756
}
5857

5958
[Fact]

src/Accounts/Accounts.Test/AzureSessionTestInitializer.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ public static void Initialize()
2929

3030
PowerShellTokenCacheProvider tokenCacheProvider = new InMemoryTokenCacheProvider();
3131
AzureSession.Instance.RegisterComponent(PowerShellTokenCacheProvider.PowerShellTokenCacheProviderKey, () => tokenCacheProvider);
32-
AzureSession.Instance.RegisterComponent(nameof(PowerShellTokenCache), () => tokenCacheProvider.GetTokenCache());
3332
IAuthenticatorBuilder builder = new DefaultAuthenticatorBuilder();
3433
AzureSession.Instance.RegisterComponent(AuthenticatorBuilder.AuthenticatorBuilderKey, () => builder);
3534
AzureSession.Instance.RegisterComponent(nameof(AzureCredentialFactory), () => new AzureCredentialFactory());

src/Accounts/Accounts/Account/ConnectAzureRmAccount.cs

Lines changed: 46 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
using System;
1616
using System.Collections.Concurrent;
17-
using System.Collections.Generic;
1817
using System.Management.Automation;
1918
using System.Security;
2019
using System.Threading;
@@ -31,6 +30,7 @@
3130
using Microsoft.Azure.Commands.Profile.Models.Core;
3231
using Microsoft.Azure.Commands.Profile.Properties;
3332
using Microsoft.Azure.Commands.ResourceManager.Common;
33+
using Microsoft.Azure.Commands.ResourceManager.Common.ArgumentCompleters;
3434
using Microsoft.Azure.PowerShell.Authenticators;
3535
using Microsoft.Azure.PowerShell.Authenticators.Factories;
3636
using Microsoft.Identity.Client;
@@ -57,6 +57,7 @@ public class ConnectAzureRmAccountCommand : AzureContextModificationCmdlet, IMod
5757
public const string MSISecretVariable = "MSI_SECRET";
5858
public const int DefaultMaxContextPopulation = 25;
5959
public const string DefaultMaxContextPopulationString = "25";
60+
private const int DefaultManagedServicePort = 50342;
6061

6162
private IAzureEnvironment _environment;
6263

@@ -127,19 +128,6 @@ public class ConnectAzureRmAccountCommand : AzureContextModificationCmdlet, IMod
127128
[Alias("MSI", "ManagedService")]
128129
public SwitchParameter Identity { get; set; }
129130

130-
[Parameter(ParameterSetName = ManagedServiceParameterSet, Mandatory = false, HelpMessage = "Obsolete. To use customized MSI endpoint, please set environment variable MSI_ENDPOINT, e.g. \"http://localhost:50342/oauth2/token\". Port number for managed service login.")]
131-
[PSDefaultValue(Help = "50342", Value = 50342)]
132-
public int ManagedServicePort { get; set; } = 50342;
133-
134-
[Parameter(ParameterSetName = ManagedServiceParameterSet, Mandatory = false, HelpMessage = "Obsolete. To use customized MSI endpoint, please set environment variable MSI_ENDPOINT, e.g. \"http://localhost:50342/oauth2/token\". Host name for managed service login.")]
135-
[PSDefaultValue(Help = "localhost", Value = "localhost")]
136-
public string ManagedServiceHostName { get; set; } = "localhost";
137-
138-
[Parameter(ParameterSetName = ManagedServiceParameterSet, Mandatory = false, HelpMessage = "Obsolete. To use customized MSI secret, please set environment variable MSI_SECRET. Secret, used for some kinds of managed service login.")]
139-
[ValidateNotNullOrEmpty]
140-
public SecureString ManagedServiceSecret { get; set; }
141-
142-
143131
[Alias("SubscriptionName", "SubscriptionId")]
144132
[Parameter(ParameterSetName = UserParameterSet,
145133
Mandatory = false, HelpMessage = "Subscription Name or ID", ValueFromPipeline = true)]
@@ -156,6 +144,33 @@ public class ConnectAzureRmAccountCommand : AzureContextModificationCmdlet, IMod
156144
[ValidateNotNullOrEmpty]
157145
public string Subscription { get; set; }
158146

147+
private const string AuthScopeHelpMessage = "Optional OAuth scope for login, supported pre-defined values: AadGraph, AnalysisServices, Attestation, Batch, DataLake, KeyVault, OperationalInsights, Storage, Synapse. It also supports resource id like 'https://storage.azure.com/'.";
148+
149+
[Alias("AuthScopeTypeName")]
150+
[Parameter(ParameterSetName = UserParameterSet,
151+
Mandatory = false, HelpMessage = AuthScopeHelpMessage)]
152+
[Parameter(ParameterSetName = UserWithCredentialParameterSet,
153+
Mandatory = false, HelpMessage = AuthScopeHelpMessage)]
154+
[Parameter(ParameterSetName = ServicePrincipalParameterSet,
155+
Mandatory = false, HelpMessage = AuthScopeHelpMessage)]
156+
[Parameter(ParameterSetName = ServicePrincipalCertificateParameterSet,
157+
Mandatory = false, HelpMessage = AuthScopeHelpMessage)]
158+
[Parameter(ParameterSetName = ManagedServiceParameterSet,
159+
Mandatory = false, HelpMessage = AuthScopeHelpMessage)]
160+
[PSArgumentCompleter(
161+
SupportedResourceNames.AadGraph,
162+
SupportedResourceNames.AnalysisServices,
163+
SupportedResourceNames.Attestation,
164+
SupportedResourceNames.Batch,
165+
SupportedResourceNames.DataLake,
166+
SupportedResourceNames.KeyVault,
167+
SupportedResourceNames.ManagedHsm,
168+
SupportedResourceNames.OperationalInsights,
169+
SupportedResourceNames.Storage,
170+
SupportedResourceNames.Synapse
171+
)]
172+
public string AuthScope { get; set; }
173+
159174
[Parameter(Mandatory = false, HelpMessage = "Name of the default context from this login")]
160175
[ValidateNotNullOrEmpty]
161176
public string ContextName { get; set; }
@@ -291,55 +306,7 @@ public override void ExecuteCmdlet()
291306
break;
292307
case ManagedServiceParameterSet:
293308
azureAccount.Type = AzureAccount.AccountType.ManagedService;
294-
var builder = new UriBuilder
295-
{
296-
Scheme = "http",
297-
Host = ManagedServiceHostName,
298-
Port = ManagedServicePort,
299-
Path = "/oauth2/token"
300-
};
301-
302-
//ManagedServiceHostName/ManagedServicePort/ManagedServiceSecret are obsolete, should be removed in next major release
303-
if (this.IsBound(nameof(ManagedServiceHostName)) || this.IsBound(nameof(ManagedServicePort)) || this.IsBound(nameof(ManagedServiceSecret)))
304-
{
305-
WriteWarning(Resources.ObsoleteManagedServiceParameters);
306-
}
307-
308-
var envSecret = System.Environment.GetEnvironmentVariable(MSISecretVariable);
309-
310-
var msiSecret = this.IsBound(nameof(ManagedServiceSecret))
311-
? ManagedServiceSecret.ConvertToString()
312-
: envSecret;
313-
314-
var envUri = System.Environment.GetEnvironmentVariable(MSIEndpointVariable);
315-
316-
var suppliedUri = this.IsBound(nameof(ManagedServiceHostName))
317-
? builder.Uri.ToString()
318-
: envUri;
319-
320-
if (!this.IsBound(nameof(ManagedServiceHostName)) && !string.IsNullOrWhiteSpace(envUri)
321-
&& !this.IsBound(nameof(ManagedServiceSecret)) && !string.IsNullOrWhiteSpace(envSecret))
322-
{
323-
// set flag indicating this is AppService Managed Identity ad hoc mode
324-
azureAccount.SetProperty(AuthenticationFactory.AppServiceManagedIdentityFlag, "the value not used");
325-
}
326-
327-
if (!string.IsNullOrWhiteSpace(msiSecret))
328-
{
329-
azureAccount.SetProperty(AzureAccount.Property.MSILoginSecret, msiSecret);
330-
}
331-
332-
if (!string.IsNullOrWhiteSpace(suppliedUri))
333-
{
334-
azureAccount.SetProperty(AzureAccount.Property.MSILoginUri, suppliedUri);
335-
}
336-
else
337-
{
338-
azureAccount.SetProperty(AzureAccount.Property.MSILoginUriBackup, builder.Uri.ToString());
339-
azureAccount.SetProperty(AzureAccount.Property.MSILoginUri, AuthenticationFactory.DefaultMSILoginUri);
340-
}
341-
342-
azureAccount.Id = this.IsBound(nameof(AccountId)) ? AccountId : string.Format(Constants.DefaultMsiAccountIdPrefix + "{0}", ManagedServicePort);
309+
azureAccount.Id = this.IsBound(nameof(AccountId)) ? AccountId : $"{Constants.DefaultMsiAccountIdPrefix}{DefaultManagedServicePort}";
343310
break;
344311
default:
345312
//Support username + password for both Windows PowerShell and PowerShell 6+
@@ -390,6 +357,8 @@ public override void ExecuteCmdlet()
390357
}
391358
}
392359

360+
var resourceId = PreProcessAuthScope();
361+
393362
if (ShouldProcess(string.Format(Resources.LoginTarget, azureAccount.Type, _environment.Name), "log in"))
394363
{
395364
if (AzureRmProfileProvider.Instance.Profile == null)
@@ -429,7 +398,8 @@ public override void ExecuteCmdlet()
429398
WriteWarningEvent, //Could not use WriteWarning directly because it may be in worker thread
430399
name,
431400
shouldPopulateContextList,
432-
MaxContextPopulation));
401+
MaxContextPopulation,
402+
resourceId));
433403
task.Start();
434404
while (!task.IsCompleted)
435405
{
@@ -467,6 +437,18 @@ public override void ExecuteCmdlet()
467437
}
468438
}
469439

440+
private string PreProcessAuthScope()
441+
{
442+
string mappedScope = AuthScope;
443+
if (!string.IsNullOrEmpty(AuthScope) &&
444+
SupportedResourceNames.DataPlaneResourceNameMap.ContainsKey(AuthScope))
445+
{
446+
mappedScope = SupportedResourceNames.DataPlaneResourceNameMap[AuthScope];
447+
WriteDebug($"Map AuthScope from {AuthScope} to {mappedScope}.");
448+
}
449+
return mappedScope;
450+
}
451+
470452
private bool IsUsingInteractiveAuthentication()
471453
{
472454
return ParameterSetName == UserParameterSet && UseDeviceAuthentication == false;
@@ -616,12 +598,10 @@ public void OnImport()
616598
{
617599
provider = new InMemoryTokenCacheProvider();
618600
}
619-
var tokenCache = provider.GetTokenCache();
620601
IAzureEventListenerFactory azureEventListenerFactory = new AzureEventListenerFactory();
621602
AzureSession.Instance.RegisterComponent(nameof(CommonUtilities), () => new CommonUtilities());
622603
AzureSession.Instance.RegisterComponent(PowerShellTokenCacheProvider.PowerShellTokenCacheProviderKey, () => provider);
623604
AzureSession.Instance.RegisterComponent(nameof(IAzureEventListenerFactory), () => azureEventListenerFactory);
624-
AzureSession.Instance.RegisterComponent(nameof(PowerShellTokenCache), () => tokenCache);
625605
AzureSession.Instance.RegisterComponent(nameof(AzureCredentialFactory), () => new AzureCredentialFactory());
626606
AzureSession.Instance.RegisterComponent(nameof(MsalAccessTokenAcquirerFactory), () => new MsalAccessTokenAcquirerFactory());
627607
#if DEBUG

src/Accounts/Accounts/Accounts.format.ps1xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,5 +240,42 @@
240240
</TableRowEntries>
241241
</TableControl>
242242
</View>
243+
<View>
244+
<Name>Microsoft.Azure.Commands.Profile.Models.PSAzureRmAccount</Name>
245+
<ViewSelectedBy>
246+
<TypeName>Microsoft.Azure.Commands.Profile.Models.PSAzureRmAccount</TypeName>
247+
</ViewSelectedBy>
248+
<ListControl>
249+
<ListEntries>
250+
<ListEntry>
251+
<ListItems>
252+
<ListItem>
253+
<PropertyName>Id</PropertyName>
254+
</ListItem>
255+
<ListItem>
256+
<PropertyName>Type</PropertyName>
257+
</ListItem>
258+
<ListItem>
259+
<PropertyName>Tenants</PropertyName>
260+
</ListItem>
261+
<ListItem>
262+
<PropertyName>Credential</PropertyName>
263+
</ListItem>
264+
<ListItem>
265+
<PropertyName>TenantMap</PropertyName>
266+
</ListItem>
267+
<ListItem>
268+
<PropertyName>CertificateThumbprint</PropertyName>
269+
</ListItem>
270+
<ListItem>
271+
<Label>ExtendedProperties</Label>
272+
<ScriptBlock>$_.ExtendedProperties.GetEnumerator() | Where-Object { $_.Key -ne "ServicePrincipalSecret" }</ScriptBlock>
273+
</ListItem>
274+
</ListItems>
275+
</ListEntry>
276+
</ListEntries>
277+
</ListControl>
278+
</View>
279+
243280
</ViewDefinitions>
244281
</Configuration>

0 commit comments

Comments
 (0)