Skip to content

Commit 648c7ba

Browse files
author
Hovsep
committed
Merge pull request #662 from rahulpandit85/dev
Powershell commandlet to enable diagnostics for V2 VM
2 parents 1d77e70 + d969742 commit 648c7ba

File tree

12 files changed

+646
-93
lines changed

12 files changed

+646
-93
lines changed

src/Common/Commands.Common/Commands.Common.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@
171171
<Compile Include="AzurePSCmdlet.cs" />
172172
<Compile Include="CmdletExtensions.cs" />
173173
<Compile Include="ConfigurationConstants.cs" />
174+
<Compile Include="DiagnosticsHelper.cs" />
174175
<Compile Include="ErrorHelper.cs" />
175176
<Compile Include="IdnHelper.cs" />
176177
<Compile Include="ManagementOperationContext.cs" />
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
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.WindowsAzure.Commands.Common.Properties;
16+
using System;
17+
using System.Collections;
18+
using System.IO;
19+
using System.Linq;
20+
using System.Text;
21+
using System.Xml;
22+
using Newtonsoft.Json;
23+
24+
namespace Microsoft.WindowsAzure.Commands.Utilities.Common
25+
{
26+
public static class DiagnosticsHelper
27+
{
28+
private static string XmlNamespace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration";
29+
private static string EncodedXmlCfg = "xmlCfg";
30+
private static string StorageAccount = "storageAccount";
31+
private static string Path = "path";
32+
private static string ExpandResourceDirectory = "expandResourceDirectory";
33+
private static string LocalResourceDirectory = "localResourceDirectory";
34+
private static string StorageAccountNameTag = "storageAccountName";
35+
private static string StorageAccountKeyTag = "storageAccountKey";
36+
private static string StorageAccountEndPointTag = "storageAccountEndPoint";
37+
38+
public static string GetJsonSerializedPublicDiagnosticsConfigurationFromFile(string configurationPath,
39+
string storageAccountName)
40+
{
41+
return
42+
JsonConvert.SerializeObject(
43+
DiagnosticsHelper.GetPublicDiagnosticsConfigurationFromFile(configurationPath, storageAccountName));
44+
}
45+
46+
public static Hashtable GetPublicDiagnosticsConfigurationFromFile(string configurationPath, string storageAccountName)
47+
{
48+
using (StreamReader reader = new StreamReader(configurationPath))
49+
{
50+
return GetPublicDiagnosticsConfiguration(reader.ReadToEnd(), storageAccountName);
51+
}
52+
}
53+
54+
public static Hashtable GetPublicDiagnosticsConfiguration(string config, string storageAccountName)
55+
{
56+
// find the <WadCfg> element and extract it
57+
int wadCfgBeginIndex = config.IndexOf("<WadCfg>");
58+
if (wadCfgBeginIndex == -1)
59+
{
60+
throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoWadCfg);
61+
}
62+
63+
int wadCfgEndIndex = config.IndexOf("</WadCfg>");
64+
if (wadCfgEndIndex == -1)
65+
{
66+
throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoEndWadCfg);
67+
}
68+
69+
if (wadCfgEndIndex <= wadCfgBeginIndex)
70+
{
71+
throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoMatchingWadCfg);
72+
}
73+
74+
string encodedConfiguration = Convert.ToBase64String(
75+
Encoding.UTF8.GetBytes(
76+
config.Substring(
77+
wadCfgBeginIndex, wadCfgEndIndex + "</WadCfg>".Length - wadCfgBeginIndex).ToCharArray()));
78+
79+
// Now extract the local resource directory element
80+
XmlDocument doc = new XmlDocument();
81+
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
82+
ns.AddNamespace("ns", XmlNamespace);
83+
doc.LoadXml(config);
84+
var node = doc.SelectSingleNode("//ns:LocalResourceDirectory", ns);
85+
string localDirectory = (node != null && node.Attributes != null) ? node.Attributes[Path].Value : null;
86+
string localDirectoryExpand = (node != null && node.Attributes != null)
87+
? node.Attributes["expandEnvironment"].Value
88+
: null;
89+
if (localDirectoryExpand == "0")
90+
{
91+
localDirectoryExpand = "false";
92+
}
93+
if (localDirectoryExpand == "1")
94+
{
95+
localDirectoryExpand = "true";
96+
}
97+
98+
var hashTable = new Hashtable();
99+
hashTable.Add(EncodedXmlCfg, encodedConfiguration);
100+
hashTable.Add(StorageAccount, storageAccountName);
101+
if (!string.IsNullOrEmpty(localDirectory))
102+
{
103+
var localDirectoryHashTable = new Hashtable();
104+
localDirectoryHashTable.Add(Path, localDirectory);
105+
localDirectoryHashTable.Add(ExpandResourceDirectory, localDirectoryExpand);
106+
hashTable.Add(LocalResourceDirectory, localDirectoryHashTable);
107+
}
108+
109+
return hashTable;
110+
}
111+
112+
public static string GetJsonSerializedPrivateDiagnosticsConfiguration(string storageAccountName,
113+
string storageKey, string endpoint)
114+
{
115+
return JsonConvert.SerializeObject(GetPrivateDiagnosticsConfiguration( storageAccountName, storageKey, endpoint));
116+
}
117+
118+
public static Hashtable GetPrivateDiagnosticsConfiguration(string storageAccountName, string storageKey, string endpoint)
119+
{
120+
var hashTable = new Hashtable();
121+
hashTable.Add(StorageAccountNameTag, storageAccountName);
122+
hashTable.Add(StorageAccountKeyTag, storageKey);
123+
hashTable.Add(StorageAccountEndPointTag, endpoint);
124+
return hashTable;
125+
}
126+
}
127+
}

src/Common/Commands.Common/Properties/Resources.Designer.cs

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Common/Commands.Common/Properties/Resources.resx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,4 +1443,13 @@ The file needs to be a PowerShell script (.ps1 or .psm1).</value>
14431443
<value>Cannot delete '{0}': {1}</value>
14441444
<comment>{0} is the path of a file, {1} is an error message</comment>
14451445
</data>
1446+
<data name="IaasDiagnosticsBadConfigNoEndWadCfg" xml:space="preserve">
1447+
<value>Cannot find the WadCfg end element in the config.</value>
1448+
</data>
1449+
<data name="IaasDiagnosticsBadConfigNoMatchingWadCfg" xml:space="preserve">
1450+
<value>WadCfg start element in the config is not matching the end element.</value>
1451+
</data>
1452+
<data name="IaasDiagnosticsBadConfigNoWadCfg" xml:space="preserve">
1453+
<value>Cannot find the WadCfg element in the config.</value>
1454+
</data>
14461455
</root>

src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@
121121
<HintPath>..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
122122
<Private>True</Private>
123123
</Reference>
124+
<Reference Include="Microsoft.WindowsAzure.Management.Storage">
125+
<HintPath>..\..\..\packages\Microsoft.WindowsAzure.Management.Storage.5.1.1\lib\net40\Microsoft.WindowsAzure.Management.Storage.dll</HintPath>
126+
</Reference>
124127
<Reference Include="System" />
125128
<Reference Include="System.Core" />
126129
<Reference Include="System.IO.Compression.FileSystem" />
@@ -161,6 +164,9 @@
161164
<Compile Include="Extension\CustomScript\RemoveAzureVMCustomScriptExtensionCommand.cs" />
162165
<Compile Include="Extension\CustomScript\SetAzureVMCustomScriptExtensionCommand.cs" />
163166
<Compile Include="Extension\CustomScript\VirtualMachineCustomScriptExtensionContext.cs" />
167+
<Compile Include="Extension\Diagnostics\GetAzureVMDiagnosticsExtension.cs" />
168+
<Compile Include="Extension\Diagnostics\RemoveAzureVMDiagnosticsExtension.cs" />
169+
<Compile Include="Extension\Diagnostics\SetAzureVMDiagnosticsExtension.cs" />
164170
<Compile Include="Extension\DSC\DscExtensionCmdletCommonBase.cs" />
165171
<Compile Include="Extension\DSC\PublishAzureVMDscConfigurationCommand.cs" />
166172
<Compile Include="Extension\DSC\RemoveAzureVMDscExtensionCommand.cs" />

src/ResourceManager/Compute/Commands.Compute/Common/ConstantStringTypes.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public static class ProfileNouns
7070
public const string VirtualMachineExtension = "AzureVMExtension";
7171
public const string VirtualMachineCustomScriptExtension = "AzureVMCustomScriptExtension";
7272
public const string VirtualMachineAccessExtension = "AzureVMAccessExtension";
73+
public const string VirtualMachineDiagnosticsExtension = "AzureVMDiagnosticsExtension";
7374
public const string VirtualMachineExtensionImage = "AzureVMExtensionImage";
7475
public const string VirtualMachineExtensionImageVersion = "AzureVMExtensionImageVersion";
7576
public const string VirtualMachineExtensionImageType = "AzureVMExtensionImageType";
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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.Linq;
16+
using System.Management.Automation;
17+
using Microsoft.Azure.Commands.Compute.Common;
18+
using Microsoft.Azure.Commands.Compute.Models;
19+
using Microsoft.Azure.Management.Compute;
20+
using Microsoft.Azure.Management.Compute.Models;
21+
22+
namespace Microsoft.Azure.Commands.Compute
23+
{
24+
[Cmdlet(
25+
VerbsCommon.Get,
26+
ProfileNouns.VirtualMachineDiagnosticsExtension),
27+
OutputType(
28+
typeof(PSVirtualMachineExtension))]
29+
public class GetAzureVMDiagnosticsExtensionCommand : VirtualMachineExtensionBaseCmdlet
30+
{
31+
[Parameter(
32+
Mandatory = true,
33+
Position = 0,
34+
ValueFromPipelineByPropertyName = true,
35+
HelpMessage = "The resource group name.")]
36+
[ValidateNotNullOrEmpty]
37+
public string ResourceGroupName { get; set; }
38+
39+
[Alias("ResourceName")]
40+
[Parameter(
41+
Mandatory = true,
42+
Position = 1,
43+
ValueFromPipelineByPropertyName = true,
44+
HelpMessage = "The virtual machine name.")]
45+
[ValidateNotNullOrEmpty]
46+
public string VMName { get; set; }
47+
48+
[Alias("ExtensionName")]
49+
[Parameter(
50+
Mandatory = true,
51+
Position = 2,
52+
ValueFromPipelineByPropertyName = true,
53+
HelpMessage = "Extension Name.")]
54+
[ValidateNotNullOrEmpty]
55+
public string Name { get; set; }
56+
57+
[Parameter(
58+
Position = 3,
59+
ValueFromPipelineByPropertyName = true,
60+
HelpMessage = "To show the status.")]
61+
[ValidateNotNullOrEmpty]
62+
public SwitchParameter Status { get; set; }
63+
64+
public override void ExecuteCmdlet()
65+
{
66+
base.ExecuteCmdlet();
67+
68+
ExecuteClientAction(() =>
69+
{
70+
VirtualMachineExtensionGetResponse virtualMachineExtensionGetResponse = null;
71+
if (Status.IsPresent)
72+
{
73+
virtualMachineExtensionGetResponse =
74+
this.VirtualMachineExtensionClient.GetWithInstanceView(this.ResourceGroupName,
75+
this.VMName, this.Name);
76+
}
77+
else
78+
{
79+
virtualMachineExtensionGetResponse = this.VirtualMachineExtensionClient.Get(this.ResourceGroupName,
80+
this.VMName, this.Name);
81+
}
82+
83+
var returnedExtension = virtualMachineExtensionGetResponse.ToPSVirtualMachineExtension(this.ResourceGroupName);
84+
WriteObject(returnedExtension);
85+
});
86+
}
87+
}
88+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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.Management.Automation;
17+
using Microsoft.Azure.Commands.Compute.Common;
18+
using Microsoft.Azure.Management.Compute;
19+
using Microsoft.WindowsAzure.Commands.ServiceManagement.Model;
20+
21+
namespace Microsoft.Azure.Commands.Compute
22+
{
23+
[Cmdlet(
24+
VerbsCommon.Remove,
25+
ProfileNouns.VirtualMachineDiagnosticsExtension)]
26+
public class RemoveAzureVMDiagnosticsExtensionCommand : VirtualMachineExtensionBaseCmdlet
27+
{
28+
[Parameter(
29+
Mandatory = true,
30+
Position = 0,
31+
ValueFromPipelineByPropertyName = true,
32+
HelpMessage = "The resource group name.")]
33+
[ValidateNotNullOrEmpty]
34+
public string ResourceGroupName { get; set; }
35+
36+
[Alias("ResourceName")]
37+
[Parameter(
38+
Mandatory = true,
39+
Position = 1,
40+
ValueFromPipelineByPropertyName = true,
41+
HelpMessage = "The virtual machine name.")]
42+
[ValidateNotNullOrEmpty]
43+
public string VMName { get; set; }
44+
45+
[Alias("ExtensionName")]
46+
[Parameter(
47+
Mandatory = true,
48+
Position = 2,
49+
ValueFromPipelineByPropertyName = true,
50+
HelpMessage = "Extension Name.")]
51+
[ValidateNotNullOrEmpty]
52+
public string Name { get; set; }
53+
54+
public override void ExecuteCmdlet()
55+
{
56+
base.ExecuteCmdlet();
57+
58+
ExecuteClientAction(() =>
59+
{
60+
var op = this.VirtualMachineExtensionClient.Delete(this.ResourceGroupName, this.VMName,
61+
this.Name);
62+
WriteObject(op);
63+
});
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)