1
- using System ;
2
- using System . IO ;
1
+ // Copyright (c) .NET Foundation. All rights reserved.
2
+ // Licensed under the MIT License. See LICENSE in the project root for license information.
3
+
3
4
using System . Runtime . InteropServices ;
4
5
using System . Text ;
5
- using System . Threading . Tasks ;
6
- using Azure . Functions . Cli . Arm ;
7
6
using Azure . Functions . Cli . Common ;
8
- using static Azure . Functions . Cli . Common . OutputTheme ;
9
7
using Azure . Functions . Cli . Interfaces ;
10
8
using Colors . Net ;
11
9
using Fclp ;
12
10
using Newtonsoft . Json ;
13
11
using Newtonsoft . Json . Linq ;
14
- using static Colors . Net . StringStaticMethods ;
15
- using Azure . Functions . Cli . Helpers ;
12
+ using static Azure . Functions . Cli . Common . OutputTheme ;
16
13
17
14
namespace Azure . Functions . Cli . Actions . AzureActions
18
15
{
19
- abstract class BaseAzureAction : BaseAction , IInitializableAction
16
+ internal abstract class BaseAzureAction : BaseAction , IInitializableAction
20
17
{
21
18
// Az is the Azure PowerShell module that works in both PowerShell Core and Windows PowerShell
22
- private const string _azProfileModuleName = "Az.Accounts" ;
19
+ private const string AzProfileModuleName = "Az.Accounts" ;
23
20
24
21
// AzureRm is the Azure PowerShell module that only works on Windows PowerShell
25
- private const string _azureRmProfileModuleName = "AzureRM.Profile" ;
22
+ private const string AzureRmProfileModuleName = "AzureRM.Profile" ;
26
23
27
24
// PowerShell Core is version 6.0 and higher that is cross-platform
28
- private const string _powerShellCoreExecutable = "pwsh" ;
25
+ private const string PowerShellCoreExecutable = "pwsh" ;
29
26
30
27
// Windows PowerShell is PowerShell version 5.1 and lower that only works on Windows
31
- private const string _windowsPowerShellExecutable = "powershell" ;
28
+ private const string WindowsPowerShellExecutable = "powershell" ;
32
29
33
- private const string _defaultManagementURL = Constants . DefaultManagementURL ;
30
+ private const string DefaultManagementURL = Constants . DefaultManagementURL ;
34
31
35
32
public string AccessToken { get ; set ; }
33
+
36
34
public bool ReadStdin { get ; set ; }
35
+
37
36
public string ManagementURL { get ; set ; }
37
+
38
38
public string Subscription { get ; private set ; }
39
39
40
40
public override ICommandLineParserResult ParseArgs ( string [ ] args )
@@ -73,6 +73,7 @@ public async Task Initialize()
73
73
{
74
74
AccessToken = accessToken ;
75
75
}
76
+
76
77
if ( string . IsNullOrEmpty ( AccessToken ) )
77
78
{
78
79
throw new CliException ( "Unable to set access token from stdin." ) ;
@@ -101,14 +102,15 @@ private async Task<string> GetManagementURL()
101
102
{
102
103
// TODO: Try with Poweshell if az is non-existent or if the call fails
103
104
// For now, let's default this out
104
- managementURL = _defaultManagementURL ;
105
+ managementURL = DefaultManagementURL ;
105
106
}
107
+
106
108
// Having a trailing slash could cause issues later when we attach it to function IDs
107
109
// It's easier to remove now, than to do that before every ARM call.
108
- return managementURL . EndsWith ( "/" ) ? managementURL . Substring ( 0 , managementURL . Length - 1 ) : managementURL ;
110
+ return managementURL . EndsWith ( "/" ) ? managementURL [ .. ^ 1 ] : managementURL ;
109
111
}
110
112
111
- private async Task < ( bool , string ) > TryGetAzCLIManagementURL ( )
113
+ private async Task < ( bool AzCliSucceeded , string ManagementURL ) > TryGetAzCLIManagementURL ( )
112
114
{
113
115
try
114
116
{
@@ -120,24 +122,33 @@ private async Task<string> GetManagementURL()
120
122
{
121
123
ColoredConsole . WriteLine ( WarningColor ( "Unable to retrieve the resource manager URL from az CLI" ) ) ;
122
124
}
125
+
123
126
return ( false , null ) ;
124
127
}
125
128
}
126
129
127
130
private async Task < string > GetAccessToken ( )
128
131
{
129
132
( bool cliSucceeded , string cliToken ) = await TryGetAzCliToken ( ) ;
130
- if ( cliSucceeded ) return cliToken ;
133
+
134
+ if ( cliSucceeded )
135
+ {
136
+ return cliToken ;
137
+ }
131
138
132
139
( bool powershellSucceeded , string psToken ) = await TryGetAzPowerShellToken ( ) ;
133
- if ( powershellSucceeded ) return psToken ;
140
+
141
+ if ( powershellSucceeded )
142
+ {
143
+ return psToken ;
144
+ }
134
145
135
146
if ( TryGetTokenFromTestEnvironment ( out string envToken ) )
136
147
{
137
148
return envToken ;
138
149
}
139
150
140
- throw new CliException ( $ "Unable to connect to Azure. Make sure you have the `az` CLI or `{ _azProfileModuleName } ` PowerShell module installed and logged in and try again") ;
151
+ throw new CliException ( $ "Unable to connect to Azure. Make sure you have the `az` CLI or `{ AzProfileModuleName } ` PowerShell module installed and logged in and try again") ;
141
152
}
142
153
143
154
private bool TryGetTokenFromTestEnvironment ( out string token )
@@ -146,7 +157,7 @@ private bool TryGetTokenFromTestEnvironment(out string token)
146
157
return ! string . IsNullOrEmpty ( token ) ;
147
158
}
148
159
149
- private async Task < ( bool succeeded , string token ) > TryGetAzCliToken ( )
160
+ private async Task < ( bool Succeeded , string Token ) > TryGetAzCliToken ( )
150
161
{
151
162
try
152
163
{
@@ -158,6 +169,7 @@ private bool TryGetTokenFromTestEnvironment(out string token)
158
169
{
159
170
ColoredConsole . WriteLine ( WarningColor ( "Unable to fetch access token from az CLI" ) ) ;
160
171
}
172
+
161
173
return ( false , null ) ;
162
174
}
163
175
}
@@ -168,13 +180,15 @@ private async Task<string> RunAzCLICommand(string param)
168
180
{
169
181
throw new CliException ( "az CLI not found" ) ;
170
182
}
183
+
171
184
var az = RuntimeInformation . IsOSPlatform ( OSPlatform . Windows )
172
185
? new Executable ( "cmd" , $ "/c az { param } ")
173
186
: new Executable ( "az" , param ) ;
174
187
175
188
var stdout = new StringBuilder ( ) ;
176
189
var stderr = new StringBuilder ( ) ;
177
190
var exitCode = await az . RunAsync ( o => stdout . AppendLine ( o ) , e => stderr . AppendLine ( e ) ) ;
191
+
178
192
if ( exitCode == 0 )
179
193
{
180
194
return stdout . ToString ( ) . Trim ( ' ' , '\n ' , '\r ' , '"' ) ;
@@ -185,18 +199,18 @@ private async Task<string> RunAzCLICommand(string param)
185
199
{
186
200
ColoredConsole . WriteLine ( VerboseColor ( $ "Unable to run az CLI command `az { param } `. Error: { stderr . ToString ( ) . Trim ( ' ' , '\n ' , '\r ' ) } ") ) ;
187
201
}
202
+
188
203
throw new CliException ( "Error running Az CLI command" ) ;
189
204
}
190
205
}
191
206
192
- private async Task < ( bool succeeded , string token ) > TryGetAzPowerShellToken ( )
207
+ private async Task < ( bool Succeeded , string Token ) > TryGetAzPowerShellToken ( )
193
208
{
194
209
// PowerShell Core can only use Az so we can check that it exists and that the Az module exists
195
- if ( CommandChecker . CommandExists ( _powerShellCoreExecutable ) &&
196
- await CommandChecker . PowerShellModuleExistsAsync ( _powerShellCoreExecutable , _azProfileModuleName ) )
210
+ if ( CommandChecker . CommandExists ( PowerShellCoreExecutable ) &&
211
+ await CommandChecker . PowerShellModuleExistsAsync ( PowerShellCoreExecutable , AzProfileModuleName ) )
197
212
{
198
- var az = new Executable ( _powerShellCoreExecutable ,
199
- $ "-NonInteractive -o Text -NoProfile -c { GetPowerShellAccessTokenScript ( _azProfileModuleName ) } ") ;
213
+ var az = new Executable ( PowerShellCoreExecutable , $ "-NonInteractive -o Text -NoProfile -c { GetPowerShellAccessTokenScript ( AzProfileModuleName ) } ") ;
200
214
201
215
var stdout = new StringBuilder ( ) ;
202
216
var stderr = new StringBuilder ( ) ;
@@ -215,18 +229,18 @@ await CommandChecker.PowerShellModuleExistsAsync(_powerShellCoreExecutable, _azP
215
229
}
216
230
217
231
// Windows PowerShell can use Az or AzureRM so first we check if powershell.exe is available
218
- if ( CommandChecker . CommandExists ( _windowsPowerShellExecutable ) )
232
+ if ( CommandChecker . CommandExists ( WindowsPowerShellExecutable ) )
219
233
{
220
234
string moduleToUse ;
221
235
222
236
// depending on if Az.Profile or AzureRM.Profile is available, we need to change the prefix
223
- if ( await CommandChecker . PowerShellModuleExistsAsync ( _windowsPowerShellExecutable , _azProfileModuleName ) )
237
+ if ( await CommandChecker . PowerShellModuleExistsAsync ( WindowsPowerShellExecutable , AzProfileModuleName ) )
224
238
{
225
- moduleToUse = _azProfileModuleName ;
239
+ moduleToUse = AzProfileModuleName ;
226
240
}
227
- else if ( await CommandChecker . PowerShellModuleExistsAsync ( _windowsPowerShellExecutable , _azureRmProfileModuleName ) )
241
+ else if ( await CommandChecker . PowerShellModuleExistsAsync ( WindowsPowerShellExecutable , AzureRmProfileModuleName ) )
228
242
{
229
- moduleToUse = _azureRmProfileModuleName ;
243
+ moduleToUse = AzureRmProfileModuleName ;
230
244
}
231
245
else
232
246
{
@@ -235,6 +249,7 @@ await CommandChecker.PowerShellModuleExistsAsync(_powerShellCoreExecutable, _azP
235
249
{
236
250
ColoredConsole . WriteLine ( VerboseColor ( "Unable to find Az.Profile or AzureRM.Profile." ) ) ;
237
251
}
252
+
238
253
return ( false , null ) ;
239
254
}
240
255
@@ -255,24 +270,25 @@ await CommandChecker.PowerShellModuleExistsAsync(_powerShellCoreExecutable, _azP
255
270
}
256
271
}
257
272
}
273
+
258
274
return ( false , null ) ;
259
275
}
260
276
261
277
// Sets the prefix of the script in case they have Az.Profile or AzureRM.Profile
262
278
private static string GetPowerShellAccessTokenScript ( string module )
263
279
{
264
280
string prefix ;
265
- if ( module == _azProfileModuleName )
281
+ if ( module == AzProfileModuleName )
266
282
{
267
283
prefix = "Az" ;
268
284
}
269
- else if ( module == _azureRmProfileModuleName )
285
+ else if ( module == AzureRmProfileModuleName )
270
286
{
271
287
prefix = "AzureRM" ;
272
288
}
273
289
else
274
290
{
275
- throw new ArgumentException ( $ "Expected module to be '{ _azProfileModuleName } ' or '{ _azureRmProfileModuleName } '") ;
291
+ throw new ArgumentException ( $ "Expected module to be '{ AzProfileModuleName } ' or '{ AzureRmProfileModuleName } '") ;
276
292
}
277
293
278
294
// This PowerShell script first grabs the Azure context, fetches the profile client and requests an accesstoken.
0 commit comments