Skip to content

Commit d8c81df

Browse files
authored
Merge pull request #6987 from markcowl/coretestperf
Add Az aliases
2 parents e31a468 + 4c00bdb commit d8c81df

File tree

41 files changed

+2657
-103
lines changed

Some content is hidden

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

41 files changed

+2657
-103
lines changed

src/Azure.PowerShell.Netcore.Test.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Commands.DeviceProvisioning
3333
EndProject
3434
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Commands.PolicyInsights.Test.Netcore", "ResourceManager\PolicyInsights\Commands.PolicyInsights.Test\Commands.PolicyInsights.Test.Netcore.csproj", "{AFA65D3A-FB7E-4DAB-9867-1CA4CBA41BFB}"
3535
EndProject
36+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Commands.Resources.Test.Netcore", "ResourceManager\Resources\Commands.Resources.Test\Commands.Resources.Test.Netcore.csproj", "{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}"
37+
EndProject
3638
Global
3739
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3840
Debug|Any CPU = Debug|Any CPU
@@ -223,6 +225,18 @@ Global
223225
{AFA65D3A-FB7E-4DAB-9867-1CA4CBA41BFB}.Release|x64.Build.0 = Release|Any CPU
224226
{AFA65D3A-FB7E-4DAB-9867-1CA4CBA41BFB}.Release|x86.ActiveCfg = Release|Any CPU
225227
{AFA65D3A-FB7E-4DAB-9867-1CA4CBA41BFB}.Release|x86.Build.0 = Release|Any CPU
228+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
229+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Debug|Any CPU.Build.0 = Debug|Any CPU
230+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Debug|x64.ActiveCfg = Debug|Any CPU
231+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Debug|x64.Build.0 = Debug|Any CPU
232+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Debug|x86.ActiveCfg = Debug|Any CPU
233+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Debug|x86.Build.0 = Debug|Any CPU
234+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Release|Any CPU.ActiveCfg = Release|Any CPU
235+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Release|Any CPU.Build.0 = Release|Any CPU
236+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Release|x64.ActiveCfg = Release|Any CPU
237+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Release|x64.Build.0 = Release|Any CPU
238+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Release|x86.ActiveCfg = Release|Any CPU
239+
{50DEDB9D-D379-43CF-9A0F-6C366B4AE400}.Release|x86.Build.0 = Release|Any CPU
226240
EndGlobalSection
227241
GlobalSection(SolutionProperties) = preSolution
228242
HideSolutionNode = FALSE

src/ResourceManager/Common/Commands.ScenarioTests.ResourceManager.Common/EnvironmentSetupHelper.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,13 @@ private void SetupPowerShellModules(System.Management.Automation.PowerShell powe
667667
foreach (string moduleName in modules)
668668
{
669669
powershell.AddScript(string.Format("Import-Module \"{0}\"", moduleName.AsAbsoluteLocation()));
670+
if (moduleName.EndsWith(".psd1"))
671+
{
672+
#if NETSTANDARD
673+
var moduleShortName = moduleName.Split(new string[] { "\\" }, StringSplitOptions.None).Last().Split(new string[] { "/" }, StringSplitOptions.None).Last();
674+
powershell.AddScript("Enable-AzureRmAlias -Module " + moduleShortName.Substring(0, moduleShortName.Length - 5));
675+
#endif
676+
}
670677
}
671678

672679
powershell.AddScript(

src/ResourceManager/Network/Commands.Network.Test/NetworkResourcesController.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
using RestTestFramework = Microsoft.Rest.ClientRuntime.Azure.TestFramework;
3030
using Microsoft.Azure.ServiceManagemenet.Common.Models;
3131
using Microsoft.Azure.Internal.Subscriptions;
32+
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
3233

3334
namespace Commands.Network.Test
3435
{

src/ResourceManager/Profile/Commands.Profile.Test/App.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
55
<dependentAssembly>
66
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
7-
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="9.0.0.0" />
7+
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="9.0.0.0" />
88
</dependentAssembly>
99
</assemblyBinding>
1010

src/ResourceManager/Profile/Commands.Profile/Az.Profile.psd1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ CmdletsToExport = 'Disable-AzDataCollection', 'Disable-AzContextAutosave',
107107
'Rename-AzContext', 'Remove-AzContext',
108108
'Clear-AzContext', 'Disconnect-AzAccount',
109109
'Get-AzContextAutosaveSetting', 'Set-AzDefault',
110-
'Get-AzDefault', 'Clear-AzDefault'
110+
'Get-AzDefault', 'Clear-AzDefault',
111+
'Enable-AzureRmAlias', 'Disable-AzureRmAlias'
111112

112113
# Variables to export from this module
113114
# VariablesToExport = @()
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
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.Commands.Common.Authentication;
16+
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
17+
using System;
18+
using System.Collections.Generic;
19+
using System.IO;
20+
using System.Linq;
21+
using System.Management.Automation;
22+
using System.Text.RegularExpressions;
23+
24+
namespace Microsoft.Azure.Commands.Profile.AzureRmAlias
25+
{
26+
public class AliasHelper
27+
{
28+
private const string STARTALIASIMPORTMARKER = "#Begin Azure PowerShell alias import";
29+
private const string ENDALIASIMPORTMARKER = "#End Azure PowerShell alias import";
30+
31+
private IDataStore _dataStore;
32+
33+
public AliasHelper(IDataStore dataStore)
34+
{
35+
_dataStore = dataStore;
36+
FileUtilities.DataStore = dataStore;
37+
}
38+
39+
public AliasHelper() : this(AzureSession.Instance.DataStore)
40+
{
41+
}
42+
43+
public static string GetProfilePath(string Scope, SessionState sessionState)
44+
{
45+
var userprofile = "";
46+
if (Scope != null && Scope.Equals("CurrentUser"))
47+
{
48+
var editionType = sessionState.PSVariable.GetValue("PSEdition") as string;
49+
var psFolder = string.Equals(editionType, "Desktop", StringComparison.OrdinalIgnoreCase) ? "WindowsPowerShell" : "PowerShell";
50+
userprofile = Path.Combine(sessionState.PSVariable.GetValue("env:USERPROFILE").ToString(), "Documents", psFolder, "profile.ps1");
51+
}
52+
53+
else if (Scope != null && Scope.Equals("LocalMachine"))
54+
{
55+
userprofile = Path.Combine(sessionState.PSVariable.GetValue("PSHOME").ToString(), "profile.ps1");
56+
}
57+
58+
return userprofile;
59+
}
60+
61+
public void RemoveAliasesInProfile(string userprofile, string[] Module, Dictionary<string, object> mapping)
62+
{
63+
ParseFile(userprofile, Module, out string filecontent, out List<string> modulesToKeep, add: false);
64+
65+
// Add script to enable aliases to profile if there are any modules to keep
66+
CreateFileEntry(modulesToKeep, filecontent, userprofile, mapping);
67+
}
68+
69+
public void AddAliasesToProfile(string userprofile, string[] Module, Dictionary<string, object> mapping)
70+
{
71+
CreateProfileIfNotExists(userprofile);
72+
73+
ParseFile(userprofile, Module, out string filecontent, out List<string> modulesToKeep, add: true);
74+
75+
if (Module == null)
76+
{
77+
CreateFileEntry(mapping.Keys.ToList(), filecontent, userprofile, mapping);
78+
}
79+
else
80+
{
81+
CreateFileEntry(modulesToKeep, filecontent, userprofile, mapping);
82+
}
83+
}
84+
85+
public void ParseFile(string userprofile, string[] Module, out string filecontent, out List<string> modulesToKeep, bool add)
86+
{
87+
filecontent = "";
88+
modulesToKeep = new List<String>();
89+
if (add)
90+
{
91+
modulesToKeep = Module?.ToList();
92+
}
93+
94+
95+
string originalText = _dataStore.ReadFileAsText(userprofile.ToString());
96+
if (originalText.Contains(STARTALIASIMPORTMARKER))
97+
{
98+
// Add back profile code unrelated to Azure PowerShell aliases
99+
var splitOriginalText = originalText.Split(new string[] { STARTALIASIMPORTMARKER, ENDALIASIMPORTMARKER }, StringSplitOptions.None);
100+
filecontent += splitOriginalText[0].Trim();
101+
if (splitOriginalText.Length > 2)
102+
{
103+
filecontent += Environment.NewLine + splitOriginalText[2].Trim() + Environment.NewLine;
104+
}
105+
106+
if (Module != null)
107+
{
108+
// Add modules currently in the profile to the list of modules to enable.
109+
var regex = new Regex(@"Az\.[a-zA-Z0-9\.]+(,\s|\s-)");
110+
Match match = regex.Match(splitOriginalText[1].Split(new string[] { "Import-Module Az.Profile" }, StringSplitOptions.None)[1]);
111+
while (match.Success)
112+
{
113+
if (add)
114+
{
115+
if (!modulesToKeep.Contains(match.ToString().Substring(0, match.ToString().Length - 2), StringComparer.CurrentCultureIgnoreCase))
116+
{
117+
modulesToKeep.Add(match.ToString().Substring(0, match.ToString().Length - 2));
118+
}
119+
match = match.NextMatch();
120+
}
121+
else
122+
{
123+
if (!Module.Contains(match.ToString().Substring(0, match.ToString().Length - 2), StringComparer.CurrentCultureIgnoreCase))
124+
{
125+
modulesToKeep.Add(match.ToString().Substring(0, match.ToString().Length - 2));
126+
}
127+
match = match.NextMatch();
128+
}
129+
}
130+
}
131+
}
132+
else
133+
{
134+
filecontent = originalText;
135+
}
136+
}
137+
138+
public void CreateFileEntry(List<string> modulesToKeep, string filecontent, string userprofile, Dictionary<string, object> mapping)
139+
{
140+
if (modulesToKeep.Count > 0)
141+
{
142+
filecontent += STARTALIASIMPORTMARKER + Environment.NewLine + "Import-Module Az.Profile -ErrorAction SilentlyContinue -ErrorVariable importError" +
143+
Environment.NewLine + "if ($importerror.Count -eq 0) { " + Environment.NewLine;
144+
145+
var validModules = new List<string>();
146+
foreach (var name in modulesToKeep)
147+
{
148+
if (mapping.ContainsKey(name))
149+
{
150+
validModules.Add(name);
151+
}
152+
}
153+
filecontent += " Enable-AzureRmAlias -Module " + string.Join(", ", validModules) + " -ErrorAction SilentlyContinue; " + Environment.NewLine;
154+
155+
filecontent += "}" + Environment.NewLine + ENDALIASIMPORTMARKER;
156+
}
157+
158+
ExecuteFileActionWithFriendlyError(() =>
159+
{
160+
FileUtilities.EnsureDirectoryExists(Path.GetDirectoryName(userprofile));
161+
_dataStore.WriteFile(userprofile, filecontent);
162+
});
163+
}
164+
165+
public void CreateProfileIfNotExists(string userprofile)
166+
{
167+
ExecuteFileActionWithFriendlyError(() =>
168+
{
169+
FileUtilities.EnsureDirectoryExists(Path.GetDirectoryName(userprofile));
170+
if (!_dataStore.FileExists(userprofile))
171+
{
172+
_dataStore.WriteFile(userprofile, Environment.NewLine);
173+
}
174+
});
175+
}
176+
177+
private static void ExecuteFileActionWithFriendlyError(Action fileAction)
178+
{
179+
try
180+
{
181+
fileAction();
182+
}
183+
catch (UnauthorizedAccessException accessException) when (accessException?.Message != null && accessException.Message.ToLower().Contains("denied"))
184+
{
185+
throw new UnauthorizedAccessException(Properties.Resources.AliasImportFailure, accessException);
186+
}
187+
}
188+
}
189+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
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.Commands.Common.Authentication;
16+
using Microsoft.Azure.Commands.ResourceManager.Common;
17+
using Newtonsoft.Json;
18+
using System;
19+
using System.Collections.Generic;
20+
using System.IO;
21+
using System.Linq;
22+
using System.Management.Automation;
23+
24+
namespace Microsoft.Azure.Commands.Profile.AzureRmAlias
25+
{
26+
/// <summary>
27+
/// Cmdlet to clear default options.
28+
/// </summary>
29+
[Cmdlet("Disable", "AzureRmAlias", SupportsShouldProcess = true)]
30+
[OutputType(typeof(string))]
31+
public class DisableAzureRmAlias : AzureRMCmdlet
32+
{
33+
[Parameter(Mandatory = false, HelpMessage = "Indicates what scope aliases should be disabled for. Default is 'Process'")]
34+
[ValidateSet("Process", "CurrentUser", "LocalMachine")]
35+
public string Scope { get; set; }
36+
37+
[Parameter(Mandatory = false, HelpMessage = "Indicates which modules to disable aliases for. If none are specified, default is all enabled modules.")]
38+
public string[] Module { get; set; }
39+
40+
[Parameter(Mandatory = false, HelpMessage = "If specified, cmdlet will return all disabled aliases")]
41+
public SwitchParameter PassThru { get; set; }
42+
43+
public override void ExecuteCmdlet()
44+
{
45+
Dictionary<string, object> mapping = Mappings.GetCaseInsensitiveMapping();
46+
47+
// If no modules are specified, disable all aliases
48+
if (Module == null)
49+
{
50+
DisableLocalAliases(mapping.Keys.ToArray(), mapping);
51+
}
52+
else
53+
{
54+
DisableLocalAliases(Module, mapping);
55+
}
56+
57+
// Set path to user profile based on the Scope
58+
string userprofile = AliasHelper.GetProfilePath(Scope, SessionState);
59+
60+
if (Scope != null && (Scope.Equals("CurrentUser") || Scope.Equals("LocalMachine")))
61+
{
62+
if (AzureSession.Instance.DataStore.FileExists(userprofile))
63+
{
64+
var helper = new AliasHelper();
65+
helper.RemoveAliasesInProfile(userprofile, Module, mapping);
66+
}
67+
}
68+
}
69+
70+
public void DisableLocalAliases(string[] modulesToDisable, Dictionary<string, object> mapping)
71+
{
72+
foreach (var module in modulesToDisable)
73+
{
74+
if (mapping.ContainsKey(module))
75+
{
76+
Dictionary<string, string> modulemapping =
77+
(Dictionary<string, string>)JsonConvert.DeserializeObject(mapping[module].ToString(), typeof(Dictionary<string, string>));
78+
foreach (var name in modulemapping.Keys)
79+
{
80+
// For every alias, remove pairing in the Alias provider if it exists
81+
if (SessionState.PSVariable.GetValue("Alias:" + modulemapping[name]) != null)
82+
{
83+
SessionState.PSVariable.Remove("Alias:" + modulemapping[name]);
84+
if (PassThru)
85+
{
86+
WriteObject("Removed: " + modulemapping[name] + " : " + name);
87+
}
88+
}
89+
}
90+
}
91+
else
92+
{
93+
WriteWarning("Module '" + module + "' is not a valid Az module.");
94+
}
95+
}
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)