Skip to content

Commit 5cc9591

Browse files
author
Hovsep Mkrtchyan
committed
Updated to the latest version of CLU
1 parent 4505e41 commit 5cc9591

File tree

7 files changed

+282
-42
lines changed

7 files changed

+282
-42
lines changed

CLUPackages/Microsoft.CLU.0.0.1.nupkg

-54.2 KB
Binary file not shown.

src/CLU/Microsoft.Azure.Commands.Resources/Models.ResourceGroups/ResourceClient.ResourceManager.cs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -228,17 +228,14 @@ public virtual List<PSResource> FilterPSResources(BasePSResourceParameters param
228228
throw new ArgumentException(ProjectResources.InvalidTagFormat);
229229
}
230230
}
231-
var listResult = ResourceManagementClient.Resources.List(new ResourceListParameters
232-
{
233-
ResourceGroupName = parameters.ResourceGroupName,
234-
ResourceType = parameters.ResourceType,
235-
TagName = tagValuePair.Name,
236-
TagValue = tagValuePair.Value
237-
});
231+
var listResult = ResourceManagementClient.Resources.List( item =>
232+
item.ResourceType == parameters.ResourceType &&
233+
item.Tagname == tagValuePair.Name &&
234+
item.Tagvalue == tagValuePair.Value);
238235

239-
if (listResult.Resources != null)
236+
if (listResult != null)
240237
{
241-
resources.AddRange(listResult.Resources.Select(r => r.ToPSResource(this, false)));
238+
resources.AddRange(listResult.Select(r => r.ToPSResource(this, false)));
242239
}
243240
}
244241
return resources;
@@ -320,17 +317,14 @@ public virtual List<GenericResource> FilterResources(FilterResourcesOptions opti
320317
}
321318
else
322319
{
323-
var result = ResourceManagementClient.Resources.List(new GenericResourceFilter
324-
{
325-
ResourceType = options.ResourceType
326-
});
320+
var result = ResourceManagementClient.Resources.List( item => item.ResourceType == options.ResourceType);
327321

328-
resources.AddRange(result.Resources);
322+
resources.AddRange(result);
329323

330-
while (!string.IsNullOrEmpty(result.NextLink))
324+
while (!string.IsNullOrEmpty(result.NextPageLink))
331325
{
332-
result = ResourceManagementClient.Resources.ListNext(result.NextLink);
333-
resources.AddRange(result.Resources);
326+
result = ResourceManagementClient.Resources.ListNext(result.NextPageLink);
327+
resources.AddRange(result);
334328
}
335329
}
336330

src/CLU/Microsoft.Azure.Commands.Resources/Models.ResourceGroups/ResourceClient.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,14 @@ public partial class ResourcesClient
6363

6464
public Action<string> WarningLogger { get; set; }
6565

66+
public IDataStore DataStore { get; set; }
67+
6668
/// <summary>
6769
/// Creates new ResourceManagementClient
6870
/// </summary>
6971
/// <param name="clientFactory">Factory for management cleints</param>
7072
/// <param name="context">Profile containing resources to manipulate</param>
71-
public ResourcesClient(IClientFactory clientFactory, AzureContext context)
73+
public ResourcesClient(IClientFactory clientFactory, AzureContext context, IDataStore dataStore)
7274
: this(
7375
clientFactory.CreateClient<ResourceManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager),
7476
clientFactory.CreateClient<AuthorizationManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager))
@@ -329,7 +331,7 @@ private Deployment CreateBasicDeployment(ValidatePSResourceGroupDeploymentParame
329331
}
330332
else
331333
{
332-
deployment.Properties.Template = FileUtilities.DataStore.ReadFileAsText(parameters.TemplateFile);
334+
deployment.Properties.Template = DataStore.ReadFileAsText(parameters.TemplateFile);
333335
}
334336

335337
if (Uri.IsWellFormedUriString(parameters.ParameterUri, UriKind.Absolute))

src/CLU/Microsoft.Azure.Commands.Resources/Models.ResourceGroups/ResourceWithParameterBaseCmdlet.cs

Lines changed: 265 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -88,49 +88,295 @@ protected ResourceWithParameterBaseCmdlet()
8888
Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Uri to the template file.")]
8989
[ValidateNotNullOrEmpty]
9090
public string TemplateUri { get; set; }
91-
92-
protected Hashtable GetTemplateParameterObject(Hashtable templateParameterObject)
93-
{
94-
templateParameterObject = templateParameterObject ?? new Hashtable();
9591

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))
9996
{
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+
}
102135
}
103136

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)
107154
{
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+
}
109163
}
110164

111-
return templateParameterObject;
165+
dynamicParameters = ParseTemplateAndExtractParameters(templateContent, templateParameterObject, templateParameterFilePath, staticParameters);
166+
167+
return dynamicParameters;
112168
}
113169

114-
private Dictionary<string, TemplateFileParameterV1> ParseTemplateParameterFileContents(string templateParameterFilePath)
170+
protected Dictionary<string, TemplateFileParameterV1> ParseTemplateParameterFileContents(string templateParameterFilePath)
115171
{
116172
Dictionary<string, TemplateFileParameterV1> parameters = new Dictionary<string, TemplateFileParameterV1>();
117173

118-
if (!string.IsNullOrEmpty(templateParameterFilePath) &&
119-
FileUtilities.DataStore.FileExists(templateParameterFilePath))
174+
if (!string.IsNullOrEmpty(templateParameterFilePath) &&
175+
DataStore.FileExists(templateParameterFilePath))
120176
{
121177
try
122178
{
123179
parameters = JsonConvert.DeserializeObject<Dictionary<string, TemplateFileParameterV1>>(
124-
FileUtilities.DataStore.ReadFileAsText(templateParameterFilePath));
180+
DataStore.ReadFileAsText(templateParameterFilePath));
125181
}
126182
catch (JsonSerializationException)
127183
{
128184
parameters = new Dictionary<string, TemplateFileParameterV1>(
129-
JsonConvert.DeserializeObject<TemplateFileParameterV2>(FileUtilities.DataStore.ReadFileAsText(templateParameterFilePath)).Parameters);
185+
JsonConvert.DeserializeObject<TemplateFileParameterV2>(DataStore.ReadFileAsText(templateParameterFilePath)).Parameters);
130186
}
131187
}
132188

133189
return parameters;
134190
}
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+
}
135381
}
136382
}

src/CLU/Microsoft.Azure.Commands.Resources/Models.ResourceGroups/ResourcesBaseCmdlet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public ResourcesClient ResourcesClient
4141
{
4242
if (this.resourcesClient == null)
4343
{
44-
this.resourcesClient = new ResourcesClient(ClientFactory, DefaultContext)
44+
this.resourcesClient = new ResourcesClient(ClientFactory, DefaultContext, DataStore)
4545
{
4646
VerboseLogger = WriteVerboseWithTimestamp,
4747
ErrorLogger = WriteErrorWithTimestamp,

0 commit comments

Comments
 (0)