@@ -88,49 +88,295 @@ protected ResourceWithParameterBaseCmdlet()
88
88
Mandatory = true , ValueFromPipelineByPropertyName = true , HelpMessage = "Uri to the template file." ) ]
89
89
[ ValidateNotNullOrEmpty ]
90
90
public string TemplateUri { get ; set ; }
91
-
92
- protected Hashtable GetTemplateParameterObject ( Hashtable templateParameterObject )
93
- {
94
- templateParameterObject = templateParameterObject ?? new Hashtable ( ) ;
95
91
96
- // Load parameters from the file
97
- string templateParameterFilePath = TemplateParameterFile ;
98
- if ( templateParameterFilePath != null && FileUtilities . DataStore . FileExists ( templateParameterFilePath ) )
92
+ public object GetDynamicParameters ( )
93
+ {
94
+ if ( ! string . IsNullOrEmpty ( TemplateFile ) &&
95
+ ! TemplateFile . Equals ( templateFile , StringComparison . OrdinalIgnoreCase ) )
99
96
{
100
- var parametersFromFile = this . ParseTemplateParameterFileContents ( templateParameterFilePath ) ;
101
- parametersFromFile . ForEach ( dp => templateParameterObject [ dp . Key ] = dp . Value . Value ) ;
97
+ templateFile = TemplateFile ;
98
+ if ( string . IsNullOrEmpty ( TemplateParameterUri ) )
99
+ {
100
+ dynamicParameters = GetTemplateParametersFromFile (
101
+ this . TryResolvePath ( TemplateFile ) ,
102
+ TemplateParameterObject ,
103
+ this . TryResolvePath ( TemplateParameterFile ) ,
104
+ MyInvocation . MyCommand . Parameters . Keys . ToArray ( ) ) ;
105
+ }
106
+ else
107
+ {
108
+ dynamicParameters = GetTemplateParametersFromFile (
109
+ this . TryResolvePath ( TemplateFile ) ,
110
+ TemplateParameterObject ,
111
+ TemplateParameterUri ,
112
+ MyInvocation . MyCommand . Parameters . Keys . ToArray ( ) ) ;
113
+ }
114
+ }
115
+ else if ( ! string . IsNullOrEmpty ( TemplateUri ) &&
116
+ ! TemplateUri . Equals ( templateUri , StringComparison . OrdinalIgnoreCase ) )
117
+ {
118
+ templateUri = TemplateUri ;
119
+ if ( string . IsNullOrEmpty ( TemplateParameterUri ) )
120
+ {
121
+ dynamicParameters = GetTemplateParametersFromFile (
122
+ TemplateUri ,
123
+ TemplateParameterObject ,
124
+ this . TryResolvePath ( TemplateParameterFile ) ,
125
+ MyInvocation . MyCommand . Parameters . Keys . ToArray ( ) ) ;
126
+ }
127
+ else
128
+ {
129
+ dynamicParameters = GetTemplateParametersFromFile (
130
+ TemplateUri ,
131
+ TemplateParameterObject ,
132
+ TemplateParameterUri ,
133
+ MyInvocation . MyCommand . Parameters . Keys . ToArray ( ) ) ;
134
+ }
102
135
}
103
136
104
- // Load dynamic parameters
105
- IEnumerable < RuntimeDefinedParameter > parameters = PowerShellUtilities . GetUsedDynamicParameters ( dynamicParameters , MyInvocation ) ;
106
- if ( parameters . Any ( ) )
137
+ return dynamicParameters ;
138
+ }
139
+
140
+ /// <summary>
141
+ /// Gets the parameters for a given template file.
142
+ /// </summary>
143
+ /// <param name="templateFilePath">The gallery template path (local or remote)</param>
144
+ /// <param name="templateParameterObject">Existing template parameter object</param>
145
+ /// <param name="templateParameterFilePath">Path to the template parameter file if present</param>
146
+ /// <param name="staticParameters">The existing PowerShell cmdlet parameters</param>
147
+ /// <returns>The template parameters</returns>
148
+ protected RuntimeDefinedParameterDictionary GetTemplateParametersFromFile ( string templateFilePath , Hashtable templateParameterObject , string templateParameterFilePath , string [ ] staticParameters )
149
+ {
150
+ RuntimeDefinedParameterDictionary dynamicParameters = new RuntimeDefinedParameterDictionary ( ) ;
151
+ string templateContent = null ;
152
+
153
+ if ( templateFilePath != null )
107
154
{
108
- parameters . ForEach ( dp => templateParameterObject [ ( ( ParameterAttribute ) dp . Attributes [ 0 ] ) . HelpMessage ] = dp . Value ) ;
155
+ if ( Uri . IsWellFormedUriString ( templateFilePath , UriKind . Absolute ) )
156
+ {
157
+ templateContent = GeneralUtilities . DownloadFile ( templateFilePath ) ;
158
+ }
159
+ else if ( DataStore . FileExists ( templateFilePath ) )
160
+ {
161
+ templateContent = DataStore . ReadFileAsText ( templateFilePath ) ;
162
+ }
109
163
}
110
164
111
- return templateParameterObject ;
165
+ dynamicParameters = ParseTemplateAndExtractParameters ( templateContent , templateParameterObject , templateParameterFilePath , staticParameters ) ;
166
+
167
+ return dynamicParameters ;
112
168
}
113
169
114
- private Dictionary < string , TemplateFileParameterV1 > ParseTemplateParameterFileContents ( string templateParameterFilePath )
170
+ protected Dictionary < string , TemplateFileParameterV1 > ParseTemplateParameterFileContents ( string templateParameterFilePath )
115
171
{
116
172
Dictionary < string , TemplateFileParameterV1 > parameters = new Dictionary < string , TemplateFileParameterV1 > ( ) ;
117
173
118
- if ( ! string . IsNullOrEmpty ( templateParameterFilePath ) &&
119
- FileUtilities . DataStore . FileExists ( templateParameterFilePath ) )
174
+ if ( ! string . IsNullOrEmpty ( templateParameterFilePath ) &&
175
+ DataStore . FileExists ( templateParameterFilePath ) )
120
176
{
121
177
try
122
178
{
123
179
parameters = JsonConvert . DeserializeObject < Dictionary < string , TemplateFileParameterV1 > > (
124
- FileUtilities . DataStore . ReadFileAsText ( templateParameterFilePath ) ) ;
180
+ DataStore . ReadFileAsText ( templateParameterFilePath ) ) ;
125
181
}
126
182
catch ( JsonSerializationException )
127
183
{
128
184
parameters = new Dictionary < string , TemplateFileParameterV1 > (
129
- JsonConvert . DeserializeObject < TemplateFileParameterV2 > ( FileUtilities . DataStore . ReadFileAsText ( templateParameterFilePath ) ) . Parameters ) ;
185
+ JsonConvert . DeserializeObject < TemplateFileParameterV2 > ( DataStore . ReadFileAsText ( templateParameterFilePath ) ) . Parameters ) ;
130
186
}
131
187
}
132
188
133
189
return parameters ;
134
190
}
191
+
192
+ private RuntimeDefinedParameterDictionary ParseTemplateAndExtractParameters ( string templateContent , Hashtable templateParameterObject , string templateParameterFilePath , string [ ] staticParameters )
193
+ {
194
+ RuntimeDefinedParameterDictionary dynamicParameters = new RuntimeDefinedParameterDictionary ( ) ;
195
+
196
+ if ( ! string . IsNullOrEmpty ( templateContent ) )
197
+ {
198
+ TemplateFile templateFile = null ;
199
+
200
+ try
201
+ {
202
+ templateFile = JsonConvert . DeserializeObject < TemplateFile > ( templateContent ) ;
203
+ if ( templateFile . Parameters == null )
204
+ {
205
+ return dynamicParameters ;
206
+ }
207
+ }
208
+ catch
209
+ {
210
+ // Can't parse the template file, do not generate dynamic parameters
211
+ return dynamicParameters ;
212
+ }
213
+
214
+ foreach ( KeyValuePair < string , TemplateFileParameterV1 > parameter in templateFile . Parameters )
215
+ {
216
+ RuntimeDefinedParameter dynamicParameter = ConstructDynamicParameter ( staticParameters , parameter ) ;
217
+ dynamicParameters . Add ( dynamicParameter . Name , dynamicParameter ) ;
218
+ }
219
+ }
220
+ if ( templateParameterObject != null )
221
+ {
222
+ UpdateParametersWithObject ( dynamicParameters , templateParameterObject ) ;
223
+ }
224
+ if ( templateParameterFilePath != null && DataStore . FileExists ( templateParameterFilePath ) )
225
+ {
226
+ var parametersFromFile = ParseTemplateParameterFileContents ( templateParameterFilePath ) ;
227
+ UpdateParametersWithObject ( dynamicParameters , new Hashtable ( parametersFromFile ) ) ;
228
+ }
229
+ if ( templateParameterFilePath != null && Uri . IsWellFormedUriString ( templateParameterFilePath , UriKind . Absolute ) )
230
+ {
231
+ var parametersFromUri = ParseTemplateParameterContent ( GeneralUtilities . DownloadFile ( templateParameterFilePath ) ) ;
232
+ UpdateParametersWithObject ( dynamicParameters , new Hashtable ( parametersFromUri ) ) ;
233
+ }
234
+ return dynamicParameters ;
235
+ }
236
+ protected Dictionary < string , TemplateFileParameterV1 > ParseTemplateParameterContent ( string templateParameterContent )
237
+ {
238
+ Dictionary < string , TemplateFileParameterV1 > parameters = new Dictionary < string , TemplateFileParameterV1 > ( ) ;
239
+
240
+ if ( ! string . IsNullOrEmpty ( templateParameterContent ) )
241
+ {
242
+ try
243
+ {
244
+ parameters = JsonConvert . DeserializeObject < Dictionary < string , TemplateFileParameterV1 > > ( templateParameterContent ) ;
245
+ }
246
+ catch ( JsonSerializationException )
247
+ {
248
+ parameters = new Dictionary < string , TemplateFileParameterV1 > (
249
+ JsonConvert . DeserializeObject < TemplateFileParameterV2 > ( templateParameterContent ) . Parameters ) ;
250
+ }
251
+ }
252
+
253
+ return parameters ;
254
+ }
255
+
256
+ private void UpdateParametersWithObject ( RuntimeDefinedParameterDictionary dynamicParameters , Hashtable templateParameterObject )
257
+ {
258
+ if ( templateParameterObject != null )
259
+ {
260
+ foreach ( KeyValuePair < string , RuntimeDefinedParameter > dynamicParameter in dynamicParameters )
261
+ {
262
+ try
263
+ {
264
+ foreach ( string key in templateParameterObject . Keys )
265
+ {
266
+ if ( key . Equals ( dynamicParameter . Key , StringComparison . OrdinalIgnoreCase ) )
267
+ {
268
+ if ( templateParameterObject [ key ] is TemplateFileParameterV1 )
269
+ {
270
+ dynamicParameter . Value . Value = ( templateParameterObject [ key ] as TemplateFileParameterV1 ) . Value ;
271
+ }
272
+ else
273
+ {
274
+ dynamicParameter . Value . Value = templateParameterObject [ key ] ;
275
+ }
276
+ dynamicParameter . Value . IsSet = true ;
277
+ ( ( ParameterAttribute ) dynamicParameter . Value . Attributes [ 0 ] ) . Mandatory = false ;
278
+ }
279
+ }
280
+ }
281
+ catch
282
+ {
283
+ throw new ArgumentException ( string . Format ( Resources . Properties . Resources . FailureParsingTemplateParameterObject ,
284
+ dynamicParameter . Key ,
285
+ templateParameterObject [ dynamicParameter . Key ] ) ) ;
286
+ }
287
+ }
288
+ }
289
+ }
290
+
291
+ protected RuntimeDefinedParameter ConstructDynamicParameter ( string [ ] staticParameters , KeyValuePair < string , TemplateFileParameterV1 > parameter )
292
+ {
293
+ const string duplicatedParameterSuffix = "FromTemplate" ;
294
+ string name = parameter . Key ;
295
+ object defaultValue = parameter . Value . DefaultValue ;
296
+
297
+ RuntimeDefinedParameter runtimeParameter = new RuntimeDefinedParameter ( )
298
+ {
299
+ // For duplicated template parameter names, add a suffix FromTemplate to distinguish them from the cmdlet parameter.
300
+ Name = staticParameters . Any ( n => n . StartsWith ( name , StringComparison . OrdinalIgnoreCase ) )
301
+ ? name + duplicatedParameterSuffix : name ,
302
+ ParameterType = GetParameterType ( parameter . Value . Type ) ,
303
+ Value = defaultValue
304
+ } ;
305
+ runtimeParameter . Attributes . Add ( new ParameterAttribute ( )
306
+ {
307
+ Mandatory = defaultValue == null ? true : false ,
308
+ ValueFromPipelineByPropertyName = true ,
309
+ // Rely on the HelpMessage property to detect the original name for the dynamic parameter.
310
+ HelpMessage = name
311
+ } ) ;
312
+
313
+ if ( parameter . Value . AllowedValues != null && parameter . Value . AllowedValues . Count > 0 )
314
+ {
315
+ runtimeParameter . Attributes . Add ( new ValidateSetAttribute ( parameter . Value . AllowedValues . ToArray ( ) )
316
+ {
317
+ IgnoreCase = true ,
318
+ } ) ;
319
+ }
320
+
321
+ if ( ! string . IsNullOrEmpty ( parameter . Value . MinLength ) &&
322
+ ! string . IsNullOrEmpty ( parameter . Value . MaxLength ) )
323
+ {
324
+ runtimeParameter . Attributes . Add ( new ValidateLengthAttribute ( int . Parse ( parameter . Value . MinLength ) , int . Parse ( parameter . Value . MaxLength ) ) ) ;
325
+ }
326
+
327
+ return runtimeParameter ;
328
+ }
329
+
330
+ protected Type GetParameterType ( string resourceParameterType )
331
+ {
332
+
333
+ if ( string . IsNullOrEmpty ( resourceParameterType ) )
334
+ {
335
+ throw new PSArgumentException ( "resourceParameterType" ) ;
336
+ }
337
+
338
+ const string stringType = "string" ;
339
+ const string intType = "int" ;
340
+ const string boolType = "bool" ;
341
+
342
+ Type typeObject = typeof ( object ) ;
343
+
344
+ if ( resourceParameterType . Equals ( stringType , StringComparison . OrdinalIgnoreCase ) )
345
+ {
346
+ typeObject = typeof ( string ) ;
347
+ }
348
+ else if ( resourceParameterType . Equals ( intType , StringComparison . OrdinalIgnoreCase ) )
349
+ {
350
+ typeObject = typeof ( int ) ;
351
+ }
352
+ else if ( resourceParameterType . Equals ( boolType , StringComparison . OrdinalIgnoreCase ) )
353
+ {
354
+ typeObject = typeof ( bool ) ;
355
+ }
356
+
357
+ return typeObject ;
358
+ }
359
+
360
+ protected Hashtable GetTemplateParameterObject ( Hashtable templateParameterObject )
361
+ {
362
+ templateParameterObject = templateParameterObject ?? new Hashtable ( ) ;
363
+
364
+ // Load parameters from the file
365
+ string templateParameterFilePath = TemplateParameterFile ;
366
+ if ( templateParameterFilePath != null && DataStore . FileExists ( templateParameterFilePath ) )
367
+ {
368
+ var parametersFromFile = this . ParseTemplateParameterFileContents ( templateParameterFilePath ) ;
369
+ parametersFromFile . ForEach ( dp => templateParameterObject [ dp . Key ] = dp . Value . Value ) ;
370
+ }
371
+
372
+ // Load dynamic parameters
373
+ IEnumerable < RuntimeDefinedParameter > parameters = PowerShellUtilities . GetUsedDynamicParameters ( dynamicParameters , MyInvocation ) ;
374
+ if ( parameters . Any ( ) )
375
+ {
376
+ parameters . ForEach ( dp => templateParameterObject [ ( ( ParameterAttribute ) dp . Attributes [ 0 ] ) . HelpMessage ] = dp . Value ) ;
377
+ }
378
+
379
+ return templateParameterObject ;
380
+ }
135
381
}
136
382
}
0 commit comments