Skip to content

Commit 76ae1e1

Browse files
Merge pull request #6 from avkaur/dev
update the powershell model for dsc node report
2 parents fbd87bd + d6e3c28 commit 76ae1e1

File tree

9 files changed

+299
-31
lines changed

9 files changed

+299
-31
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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 System;
16+
using System.Collections;
17+
using System.Collections.Generic;
18+
using System.Management.Automation;
19+
using System.Security.Permissions;
20+
using Microsoft.Azure.Commands.Automation.Common;
21+
using Microsoft.Azure.Commands.Automation.Model;
22+
using Microsoft.WindowsAzure.Commands.Utilities.Common;
23+
24+
namespace Microsoft.Azure.Commands.Automation.Cmdlet
25+
{
26+
/// <summary>
27+
/// Imports dsc node configuration script
28+
/// </summary>
29+
[Cmdlet(VerbsData.Import, "AzureAutomationDscNodeConfiguration")]
30+
[OutputType(typeof(NodeConfiguration))]
31+
public class ImportAzureAutomationDscNodeConfiguration : AzureAutomationBaseCmdlet
32+
{
33+
/// <summary>
34+
/// True to overwrite the existing configuration; false otherwise.
35+
/// </summary>
36+
private bool overwriteExistingConfiguration;
37+
38+
/// <summary>
39+
/// Gets or sets the source path.
40+
/// </summary>
41+
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Path to the node configuration .mof to import.")]
42+
[ValidateNotNullOrEmpty]
43+
public string Path { get; set; }
44+
45+
/// <summary>
46+
/// Gets or sets the configuration name for the node configuration.
47+
/// </summary>
48+
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The name of the DSC Configuration to import the Node Configuration under. All Node Configurations in Azure Automation must exist under a Configuration. The name of the Configuration will become the namespace of the imported Node Configuration, in the form of 'ConfigurationName.MofFileName'")]
49+
public string ConfigurationName { get; set; }
50+
51+
52+
/// <summary>
53+
/// Gets or sets switch parameter to confirm overwriting of existing configurations.
54+
/// </summary>
55+
[Parameter(Mandatory = false, HelpMessage = "Forces the command to overwrite an existing Node Configuration.")]
56+
public SwitchParameter Force
57+
{
58+
get { return this.overwriteExistingConfiguration; }
59+
set { this.overwriteExistingConfiguration = value; }
60+
}
61+
62+
/// <summary>
63+
/// Execute this cmdlet.
64+
/// </summary>
65+
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
66+
public override void ExecuteCmdlet()
67+
{
68+
var nodeConfiguration = this.AutomationClient.CreateNodeConfiguration(
69+
this.ResourceGroupName,
70+
this.AutomationAccountName,
71+
this.Path,
72+
this.ConfigurationName,
73+
this.Force);
74+
75+
this.WriteObject(nodeConfiguration);
76+
}
77+
}
78+
}

src/ResourceManager/Automation/Commands.Automation/Cmdlet/StartAzureAutomationDscCompilationJob.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public class StartAzureAutomationDscCompilationJob : AzureAutomationBaseCmdlet
4242
[Parameter(Mandatory = false, HelpMessage = "The compilation job parameters.")]
4343
public IDictionary Parameters { get; set; }
4444

45+
/// <summary>
46+
/// Gets or sets the configuration data.
47+
/// </summary>
48+
[Parameter(Mandatory = false, HelpMessage = "The compilation job configuration data.")]
49+
public IDictionary ConfigurationData { get; set; }
50+
4551
/// <summary>
4652
/// Execute this cmdlet.
4753
/// </summary>
@@ -50,6 +56,10 @@ protected override void AutomationExecuteCmdlet()
5056
{
5157
CompilationJob job = null;
5258

59+
if (this.ConfigurationData != null)
60+
{
61+
Parameters.Add("ConfigurationData", this.ConfigurationData);
62+
}
5363
job = this.AutomationClient.StartCompilationJob(this.ResourceGroupName, this.AutomationAccountName, this.ConfigurationName, this.Parameters);
5464

5565
this.WriteObject(job);

src/ResourceManager/Automation/Commands.Automation/Commands.ResourceManagement.Automation.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
</ItemGroup>
118118
<ItemGroup>
119119
<Compile Include="Cmdlet\AzureAutomationBaseCmdlet.cs" />
120+
<Compile Include="Cmdlet\ImportAzureAutomationDscNodeConfiguration.cs" />
120121
<Compile Include="Cmdlet\ExportAzureAutomationDscConfiguration.cs" />
121122
<Compile Include="Cmdlet\ExportAzureAutomationDscNodeReportContent.cs" />
122123
<Compile Include="Cmdlet\GetAzureAutomationCertificate.cs" />

src/ResourceManager/Automation/Commands.Automation/Common/AutomationClientDSC.cs

Lines changed: 150 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,48 @@ private Model.DscConfiguration TryGetConfigurationModel(string resourceGroupName
257257
return configuration;
258258
}
259259

260+
public Model.DscConfiguration CreateConfiguration(
261+
string resourceGroupName,
262+
string automationAccountName,
263+
string configrationName,
264+
string nodeName)
265+
{
266+
string configurationContent = "Configuration {0} { Node {1} { } } ";
267+
configurationContent = string.Format(configurationContent,configrationName,nodeName);
268+
269+
using (var request = new RequestSettings(this.automationManagementClient))
270+
{
271+
272+
// location of the configuration is set to same as that of automation account
273+
string location = this.GetAutomationAccount(resourceGroupName, automationAccountName).Location;
274+
275+
var configurationCreateParameters = new DscConfigurationCreateOrUpdateParameters()
276+
{
277+
Name = configrationName,
278+
Location = location,
279+
Properties = new DscConfigurationCreateOrUpdateProperties()
280+
{
281+
Description = String.Empty,
282+
LogVerbose = false,
283+
Source = new Microsoft.Azure.Management.Automation.Models.ContentSource()
284+
{
285+
// only embeddedContent supported for now
286+
ContentType = Model.ContentSourceType.embeddedContent.ToString(),
287+
Value = configurationContent
288+
}
289+
}
290+
};
291+
292+
var configuration =
293+
this.automationManagementClient.Configurations.CreateOrUpdate(
294+
resourceGroupName,
295+
automationAccountName,
296+
configurationCreateParameters).Configuration;
297+
298+
return new Model.DscConfiguration(resourceGroupName, automationAccountName, configuration);
299+
}
300+
}
301+
260302
#endregion
261303

262304
#region DscMetaConfig Operations
@@ -1023,6 +1065,21 @@ public Model.CompilationJob StartCompilationJob(string resourceGroupName, string
10231065
#endregion
10241066

10251067
#region node configuration
1068+
public Model.NodeConfiguration TryGetNodeConfiguration(string resourceGroupName, string automationAccountName, string nodeConfigurationName, string rollupStatus)
1069+
{
1070+
using (var request = new RequestSettings(this.automationManagementClient))
1071+
{
1072+
try
1073+
{
1074+
return GetNodeConfiguration(resourceGroupName, automationAccountName, nodeConfigurationName, rollupStatus);
1075+
}
1076+
catch (ResourceNotFoundException)
1077+
{
1078+
return null;
1079+
}
1080+
}
1081+
}
1082+
10261083
public Model.NodeConfiguration GetNodeConfiguration(string resourceGroupName, string automationAccountName, string nodeConfigurationName, string rollupStatus)
10271084
{
10281085
using (var request = new RequestSettings(this.automationManagementClient))
@@ -1118,6 +1175,90 @@ public Model.NodeConfiguration GetNodeConfiguration(string resourceGroupName, st
11181175
}
11191176
}
11201177

1178+
public Model.NodeConfiguration CreateNodeConfiguration(
1179+
string resourceGroupName,
1180+
string automationAccountName,
1181+
string sourcePath,
1182+
string configurationName,
1183+
bool overWrite)
1184+
{
1185+
using (var request = new RequestSettings(this.automationManagementClient))
1186+
{
1187+
Requires.Argument("ResourceGroupName", resourceGroupName).NotNullOrEmpty();
1188+
Requires.Argument("AutomationAccountName", automationAccountName).NotNullOrEmpty();
1189+
Requires.Argument("SourcePath", sourcePath).NotNullOrEmpty();
1190+
Requires.Argument("configurationName", configurationName).NotNullOrEmpty();
1191+
1192+
string fileContent = null;
1193+
string nodeConfigurationName = null;
1194+
string nodeName = null;
1195+
1196+
if (File.Exists(Path.GetFullPath(sourcePath)))
1197+
{
1198+
fileContent = System.IO.File.ReadAllText(sourcePath);
1199+
nodeConfigurationName = configurationName + "." + System.IO.Path.GetFileNameWithoutExtension(sourcePath);
1200+
}
1201+
else
1202+
{
1203+
// file path not valid.
1204+
throw new FileNotFoundException(
1205+
string.Format(
1206+
CultureInfo.CurrentCulture,
1207+
Resources.ConfigurationSourcePathInvalid));
1208+
}
1209+
1210+
// if node configuration already exists, ensure overwrite flag is specified
1211+
var nodeConfigurationModel = this.TryGetNodeConfiguration(
1212+
resourceGroupName,
1213+
automationAccountName,
1214+
nodeConfigurationName,
1215+
null);
1216+
if (nodeConfigurationModel != null)
1217+
{
1218+
if (!overWrite)
1219+
{
1220+
throw new ResourceCommonException(typeof(Model.NodeConfiguration),
1221+
string.Format(CultureInfo.CurrentCulture, Resources.NodeConfigurationAlreadyExists, nodeConfigurationName));
1222+
}
1223+
}
1224+
1225+
// if configuration already exists, ensure overwrite flag is specified
1226+
var configurationModel = this.TryGetConfigurationModel(
1227+
resourceGroupName,
1228+
automationAccountName,
1229+
configurationName);
1230+
if (configurationModel == null)
1231+
{
1232+
//create empty configuration if its empty
1233+
this.CreateConfiguration(resourceGroupName, automationAccountName, configurationName, nodeName);
1234+
}
1235+
1236+
var nodeConfigurationCreateParameters = new DscNodeConfigurationCreateOrUpdateParameters()
1237+
{
1238+
Name = nodeConfigurationName,
1239+
Source = new Microsoft.Azure.Management.Automation.Models.ContentSource()
1240+
{
1241+
// only embeddedContent supported for now
1242+
ContentType = Model.ContentSourceType.embeddedContent.ToString(),
1243+
Value = fileContent
1244+
},
1245+
Configuration = new DscConfigurationAssociationProperty()
1246+
{
1247+
Name = configurationName
1248+
}
1249+
};
1250+
1251+
var nodeConfiguration =
1252+
this.automationManagementClient.NodeConfigurations.CreateOrUpdate(
1253+
resourceGroupName,
1254+
automationAccountName,
1255+
nodeConfigurationCreateParameters).NodeConfiguration;
1256+
1257+
1258+
return new Model.NodeConfiguration(resourceGroupName, automationAccountName, nodeConfiguration, null);
1259+
}
1260+
}
1261+
11211262
#endregion
11221263

11231264
#region dsc reports
@@ -1339,39 +1480,19 @@ private string FormatDateTime(DateTimeOffset dateTime)
13391480
private IDictionary<string, string> ProcessConfigurationParameters(string resourceGroupName, string automationAccountName, string configurationName, IDictionary parameters)
13401481
{
13411482
parameters = parameters ?? new Dictionary<string, string>();
1342-
IEnumerable<KeyValuePair<string, DscConfigurationParameter>> configurationParameters = this.ListConfigurationParameters(resourceGroupName, automationAccountName, configurationName);
1343-
var filteredParameters = new Dictionary<string, string>();
1344-
1345-
foreach (var configParameter in configurationParameters)
1346-
{
1347-
if (parameters.Contains(configParameter.Key))
1483+
var filteredParameters = new Dictionary<string,string>();
1484+
foreach (var key in parameters.Keys)
1485+
{
1486+
try
13481487
{
1349-
object paramValue = parameters[configParameter.Key];
1350-
try
1351-
{
1352-
filteredParameters.Add(configParameter.Key, paramValue.ToString());
1353-
}
1354-
catch (JsonSerializationException)
1355-
{
1356-
throw new ArgumentException(
1357-
string.Format(
1358-
CultureInfo.CurrentCulture, Resources.ConfigurationParameterCannotBeSerializedToJson, configParameter.Key));
1359-
}
1488+
filteredParameters.Add(key.ToString(), Newtonsoft.Json.JsonConvert.SerializeObject(parameters[key]));
13601489
}
1361-
else if (configParameter.Value.IsMandatory)
1490+
catch (JsonSerializationException)
13621491
{
1363-
throw new ArgumentException(
1364-
string.Format(
1365-
CultureInfo.CurrentCulture, Resources.ConfigurationParameterValueRequired, configParameter.Key));
1366-
}
1367-
}
1368-
1369-
if (filteredParameters.Count != parameters.Count)
1370-
{
1371-
throw new ArgumentException(
1372-
string.Format(CultureInfo.CurrentCulture, Resources.InvalidConfigurationParameters));
1492+
throw new ArgumentException(string.Format(
1493+
CultureInfo.CurrentCulture, Resources.ConfigurationParameterCannotBeSerializedToJson, key.ToString()));
1494+
}
13731495
}
1374-
13751496
return filteredParameters;
13761497
}
13771498

src/ResourceManager/Automation/Commands.Automation/Common/IAutomationClient.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public interface IAutomationClient
5959
IEnumerable<NodeConfiguration> ListNodeConfigurationsByConfigurationName(string resourceGroupName, string automationAccountName, string configurationName, string rollupStatus);
6060

6161
IEnumerable<NodeConfiguration> ListNodeConfigurations(string resourceGroupName, string automationAccountName, string rollupStatus);
62+
63+
NodeConfiguration CreateNodeConfiguration(string resourceGroupName, string automationAccountName, string sourcePath, string nodeConfiguraionName, bool overWrite);
6264
#endregion
6365

6466
#region Configurations

src/ResourceManager/Automation/Commands.Automation/Common/Requires.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,24 @@ public ArgumentRequirements<T> NotNull()
7373

7474
return this;
7575
}
76+
77+
/// <summary>
78+
/// Checks argument value for not null or empty
79+
/// </summary>
80+
/// <returns>The not null requirement</returns>
81+
public ArgumentRequirements<T> NotNullOrEmpty()
82+
{
83+
if (this.Value == null)
84+
{
85+
throw new ArgumentNullException(this.Name);
86+
}
87+
else if (string.IsNullOrEmpty(this.Value.ToString()))
88+
{
89+
throw new ArgumentNullException(this.Name);
90+
}
91+
92+
return this;
93+
}
7694
}
7795
}
7896
}

0 commit comments

Comments
 (0)